10264: fix: Don't seek outside of character boundaries in completion handler r=Veykril a=iDawer

Fixes #10219 panic when entering `:` in `$0` places:
```rust
fn main() {
    "⊞$0";
}
```

```rust
struct S {
    д$0 u8
}
```


Co-authored-by: Dawer <7803845+iDawer@users.noreply.github.com>
This commit is contained in:
bors[bot] 2021-09-17 18:28:55 +00:00 committed by GitHub
commit 5964750e95
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -27,7 +27,7 @@
use project_model::TargetKind; use project_model::TargetKind;
use serde_json::json; use serde_json::json;
use stdx::{format_to, never}; use stdx::{format_to, never};
use syntax::{algo, ast, AstNode, TextRange, TextSize}; use syntax::{algo, ast, AstNode, TextRange, TextSize, T};
use crate::{ use crate::{
cargo_target_spec::CargoTargetSpec, cargo_target_spec::CargoTargetSpec,
@ -727,16 +727,13 @@ pub(crate) fn handle_completion(
let completion_triggered_after_single_colon = { let completion_triggered_after_single_colon = {
let mut res = false; let mut res = false;
if let Some(ctx) = params.context { 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 source_file = snap.analysis.parse(position.file_id)?;
let syntax = source_file.syntax(); let left_token =
let text = syntax.text(); source_file.syntax().token_at_offset(position.offset).left_biased();
if let Some(next_char) = text.char_at(position.offset) { match left_token {
let diff = TextSize::of(next_char) + TextSize::of(':'); Some(left_token) => res = left_token.kind() == T![:],
let prev_char = position.offset - diff; None => res = true,
if text.char_at(prev_char) != Some(':') {
res = true;
}
} }
} }
} }