diff --git a/crates/ide_completion/src/completions/flyimport.rs b/crates/ide_completion/src/completions/flyimport.rs index cbfe89b911c..1eb45036a9d 100644 --- a/crates/ide_completion/src/completions/flyimport.rs +++ b/crates/ide_completion/src/completions/flyimport.rs @@ -163,11 +163,11 @@ pub(crate) fn position_for_import<'a>( import_candidate: Option<&ImportCandidate>, ) -> Option<&'a SyntaxNode> { Some(match import_candidate { - Some(ImportCandidate::Path(_)) => ctx.name_ref_syntax.as_ref()?.syntax(), + Some(ImportCandidate::Path(_)) => ctx.name_syntax.as_ref()?.syntax(), Some(ImportCandidate::TraitAssocItem(_)) => ctx.path_qual()?.syntax(), Some(ImportCandidate::TraitMethod(_)) => ctx.dot_receiver()?.syntax(), None => ctx - .name_ref_syntax + .name_syntax .as_ref() .map(|name_ref| name_ref.syntax()) .or_else(|| ctx.path_qual().map(|path| path.syntax())) @@ -1203,4 +1203,21 @@ fn func() { "#]], ); } + + #[test] + fn flyimport_pattern() { + check( + r#" +mod module { + pub struct Struct; +} +fn function() { + let Str$0 +} +"#, + expect![[r#" + st Struct (use module::Struct) + "#]], + ); + } } diff --git a/crates/ide_completion/src/completions/lifetime.rs b/crates/ide_completion/src/completions/lifetime.rs index bc9f3913fb1..233bf51ec06 100644 --- a/crates/ide_completion/src/completions/lifetime.rs +++ b/crates/ide_completion/src/completions/lifetime.rs @@ -8,6 +8,7 @@ //! show up for normal completions, or they won't show completions other than lifetimes depending //! on the fixture input. use hir::ScopeDef; +use syntax::ast; use crate::{completions::Completions, context::CompletionContext}; @@ -17,17 +18,15 @@ pub(crate) fn complete_lifetime(acc: &mut Completions, ctx: &CompletionContext) return; } let lp_string; - let param_lifetime = match ( - &ctx.lifetime_syntax, - ctx.lifetime_param_syntax.as_ref().and_then(|lp| lp.lifetime()), - ) { - (Some(lt), Some(lp)) if lp == lt.clone() => return, - (Some(_), Some(lp)) => { - lp_string = lp.to_string(); - Some(&*lp_string) - } - _ => None, - }; + let param_lifetime = + match (&ctx.name_syntax, ctx.lifetime_param_syntax.as_ref().and_then(|lp| lp.lifetime())) { + (Some(ast::NameLike::Lifetime(lt)), Some(lp)) if lp == lt.clone() => return, + (Some(_), Some(lp)) => { + lp_string = lp.to_string(); + Some(&*lp_string) + } + _ => None, + }; ctx.scope.process_all_names(&mut |name, res| { if let ScopeDef::GenericParam(hir::GenericParam::LifetimeParam(_)) = res { diff --git a/crates/ide_completion/src/completions/qualified_path.rs b/crates/ide_completion/src/completions/qualified_path.rs index 970f7db5592..191fdc3d2cc 100644 --- a/crates/ide_completion/src/completions/qualified_path.rs +++ b/crates/ide_completion/src/completions/qualified_path.rs @@ -92,7 +92,7 @@ pub(crate) fn complete_qualified_path(acc: &mut Completions, ctx: &CompletionCon for (name, def) in module_scope { if ctx.in_use_tree() { if let hir::ScopeDef::Unknown = def { - if let Some(name_ref) = ctx.name_ref_syntax.as_ref() { + if let Some(ast::NameLike::NameRef(name_ref)) = ctx.name_syntax.as_ref() { if name_ref.syntax().text() == name.to_string().as_str() { // for `use self::foo$0`, don't suggest `foo` as a completion cov_mark::hit!(dont_complete_current_use); diff --git a/crates/ide_completion/src/context.rs b/crates/ide_completion/src/context.rs index 6c6f8f8512b..4273129dff2 100644 --- a/crates/ide_completion/src/context.rs +++ b/crates/ide_completion/src/context.rs @@ -93,10 +93,9 @@ pub(crate) struct CompletionContext<'a> { pub(super) function_def: Option, /// The parent impl of the cursor position if it exists. pub(super) impl_def: Option, - pub(super) name_ref_syntax: Option, + pub(super) name_syntax: Option, // potentially set if we are completing a lifetime - pub(super) lifetime_syntax: Option, pub(super) lifetime_param_syntax: Option, pub(super) lifetime_allowed: bool, pub(super) is_label_ref: bool, @@ -161,8 +160,7 @@ pub(super) fn new( expected_type: None, function_def: None, impl_def: None, - name_ref_syntax: None, - lifetime_syntax: None, + name_syntax: None, lifetime_param_syntax: None, lifetime_allowed: false, is_label_ref: false, @@ -601,6 +599,8 @@ fn fill( self.completion_location = determine_location(&self.sema, original_file, offset, &name_like); self.prev_sibling = determine_prev_sibling(&name_like); + self.name_syntax = + find_node_at_offset(original_file, name_like.syntax().text_range().start()); match name_like { ast::NameLike::Lifetime(lifetime) => { self.classify_lifetime(original_file, lifetime, offset); @@ -620,8 +620,6 @@ fn classify_lifetime( lifetime: ast::Lifetime, offset: TextSize, ) { - self.lifetime_syntax = - find_node_at_offset(original_file, lifetime.syntax().text_range().start()); if let Some(parent) = lifetime.syntax().parent() { if parent.kind() == ERROR { return; @@ -695,9 +693,6 @@ fn classify_name(&mut self, name: ast::Name) { fn classify_name_ref(&mut self, original_file: &SyntaxNode, name_ref: ast::NameRef) { self.fill_impl_def(); - self.name_ref_syntax = - find_node_at_offset(original_file, name_ref.syntax().text_range().start()); - self.function_def = self .sema .token_ancestors_with_macros(self.token.clone())