Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/ide-completion/src/context.rs')
-rw-r--r--crates/ide-completion/src/context.rs42
1 files changed, 41 insertions, 1 deletions
diff --git a/crates/ide-completion/src/context.rs b/crates/ide-completion/src/context.rs
index 9850813a0c..27f6745d24 100644
--- a/crates/ide-completion/src/context.rs
+++ b/crates/ide-completion/src/context.rs
@@ -19,7 +19,7 @@ use syntax::{
ast::{self, AttrKind, NameOrNameRef},
AstNode,
SyntaxKind::{self, *},
- SyntaxToken, TextRange, TextSize,
+ SyntaxToken, TextRange, TextSize, T,
};
use text_edit::Indel;
@@ -569,6 +569,28 @@ impl<'a> CompletionContext<'a> {
// completing on
let original_token = original_file.syntax().token_at_offset(offset).left_biased()?;
+ // try to skip completions on path with qinvalid colons
+ // this approach works in normal path and inside token tree
+ match original_token.kind() {
+ T![:] => {
+ // return if no prev token before colon
+ let prev_token = original_token.prev_token()?;
+
+ // only has a single colon
+ if prev_token.kind() != T![:] {
+ return None;
+ }
+
+ if !is_prev_token_valid_path_start_or_segment(&prev_token) {
+ return None;
+ }
+ }
+ T![::] if !is_prev_token_valid_path_start_or_segment(&original_token) => {
+ return None;
+ }
+ _ => {}
+ }
+
let AnalysisResult {
analysis,
expected: (expected_type, expected_name),
@@ -618,6 +640,24 @@ impl<'a> CompletionContext<'a> {
}
}
+fn is_prev_token_valid_path_start_or_segment(token: &SyntaxToken) -> bool {
+ if let Some(prev_token) = token.prev_token() {
+ // token before coloncolon is invalid
+ if !matches!(
+ prev_token.kind(),
+ // trival
+ WHITESPACE | COMMENT
+ // PathIdentSegment
+ | IDENT | T![super] | T![self] | T![Self] | T![crate]
+ // QualifiedPath
+ | T![>]
+ ) {
+ return false;
+ }
+ }
+ true
+}
+
const OP_TRAIT_LANG_NAMES: &[&str] = &[
"add_assign",
"add",