From 0ff271d38ff436f988d366561027d8d185e05692 Mon Sep 17 00:00:00 2001 From: Dawer <7803845+iDawer@users.noreply.github.com> Date: Fri, 17 Sep 2021 23:04:20 +0500 Subject: [PATCH] fix completion handler trying to seek outside of character boundaries. MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit With this patch, in these examples ```rust fn main() { "⊞$0"; } ``` ```rust struct S { д$0 u8 } ``` entering ':' character in `$0` places shouldn't cause panics. --- crates/rust-analyzer/src/handlers.rs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/crates/rust-analyzer/src/handlers.rs b/crates/rust-analyzer/src/handlers.rs index 9de059a2c38..dbbe1841fc9 100644 --- a/crates/rust-analyzer/src/handlers.rs +++ b/crates/rust-analyzer/src/handlers.rs @@ -27,7 +27,7 @@ use lsp_types::{ use project_model::TargetKind; use serde_json::json; use stdx::{format_to, never}; -use syntax::{algo, ast, AstNode, TextRange, TextSize}; +use syntax::{algo, ast, AstNode, TextRange, TextSize, T}; use crate::{ cargo_target_spec::CargoTargetSpec, @@ -727,16 +727,13 @@ pub(crate) fn handle_completion( let completion_triggered_after_single_colon = { let mut res = false; if let Some(ctx) = params.context { - if ctx.trigger_character.unwrap_or_default() == ":" { + if ctx.trigger_character.as_deref() == Some(":") { let source_file = snap.analysis.parse(position.file_id)?; - let syntax = source_file.syntax(); - let text = syntax.text(); - if let Some(next_char) = text.char_at(position.offset) { - let diff = TextSize::of(next_char) + TextSize::of(':'); - let prev_char = position.offset - diff; - if text.char_at(prev_char) != Some(':') { - res = true; - } + let left_token = + source_file.syntax().token_at_offset(position.offset).left_biased(); + match left_token { + Some(left_token) => res = left_token.kind() == T![:], + None => res = true, } } }