diff options
| author | Lukas Wirth <lukastw97@gmail.com> | 2022-06-18 08:58:47 +0200 |
|---|---|---|
| committer | Lukas Wirth <lukastw97@gmail.com> | 2022-06-18 08:58:47 +0200 |
| commit | 309ecdd71cc09625052f3d358a3bd9c2b245119d (patch) | |
| tree | 4f738d7b9bf33b10170e3297ff71d483309cebeb | |
| parent | 12dd81092e37df28b7a3591cae9675e668927198 (diff) | |
| download | rust-309ecdd71cc09625052f3d358a3bd9c2b245119d.tar.gz rust-309ecdd71cc09625052f3d358a3bd9c2b245119d.zip | |
internal: NameRefKind classification is not optional
| -rw-r--r-- | crates/ide-completion/src/completions/flyimport.rs | 12 | ||||
| -rw-r--r-- | crates/ide-completion/src/completions/item_list/trait_impl.rs | 4 | ||||
| -rw-r--r-- | crates/ide-completion/src/completions/pattern.rs | 2 | ||||
| -rw-r--r-- | crates/ide-completion/src/completions/use_.rs | 4 | ||||
| -rw-r--r-- | crates/ide-completion/src/context.rs | 16 | ||||
| -rw-r--r-- | crates/ide-completion/src/context/analysis.rs | 129 | ||||
| -rw-r--r-- | crates/ide-completion/src/lib.rs | 36 | ||||
| -rw-r--r-- | crates/ide-completion/src/render.rs | 8 | ||||
| -rw-r--r-- | crates/ide-completion/src/render/function.rs | 14 | ||||
| -rw-r--r-- | crates/ide-completion/src/render/literal.rs | 9 | ||||
| -rw-r--r-- | crates/ide-completion/src/render/macro_.rs | 2 | ||||
| -rw-r--r-- | crates/ide-completion/src/render/pattern.rs | 34 | ||||
| -rw-r--r-- | crates/ide-completion/src/tests/flyimport.rs | 17 |
13 files changed, 144 insertions, 143 deletions
diff --git a/crates/ide-completion/src/completions/flyimport.rs b/crates/ide-completion/src/completions/flyimport.rs index 15e431f9c50..608a74dc152 100644 --- a/crates/ide-completion/src/completions/flyimport.rs +++ b/crates/ide-completion/src/completions/flyimport.rs @@ -123,7 +123,7 @@ pub(crate) fn import_on_the_fly_path( | PathKind::Type { .. } | PathKind::Attr { .. } | PathKind::Derive { .. } - | PathKind::Pat), + | PathKind::Pat { .. }), qualified, .. } => (Some(kind), qualified), @@ -183,7 +183,7 @@ pub(crate) fn import_on_the_fly_pat( return None; } let kind = match pat_ctx { - PatternContext { record_pat: None, .. } => PathKind::Pat, + PatternContext { record_pat: None, .. } => PathKind::Pat { pat_ctx: pat_ctx.clone() }, _ => return None, }; @@ -229,15 +229,17 @@ fn import_on_the_fly( PathKind::Expr { .. } | PathKind::Type { .. } | PathKind::Item { .. } - | PathKind::Pat, + | PathKind::Pat { .. }, ItemInNs::Macros(mac), ) => mac.is_fn_like(ctx.db), (PathKind::Item { .. }, _) => true, (PathKind::Expr { .. }, ItemInNs::Types(_) | ItemInNs::Values(_)) => true, - (PathKind::Pat, ItemInNs::Types(_)) => true, - (PathKind::Pat, ItemInNs::Values(def)) => matches!(def, hir::ModuleDef::Const(_)), + (PathKind::Pat { .. }, ItemInNs::Types(_)) => true, + (PathKind::Pat { .. }, ItemInNs::Values(def)) => { + matches!(def, hir::ModuleDef::Const(_)) + } (PathKind::Type { location }, ItemInNs::Types(ty)) => { if matches!(location, TypeLocation::TypeBound) { diff --git a/crates/ide-completion/src/completions/item_list/trait_impl.rs b/crates/ide-completion/src/completions/item_list/trait_impl.rs index 701985d507d..c0c29d4cd22 100644 --- a/crates/ide-completion/src/completions/item_list/trait_impl.rs +++ b/crates/ide-completion/src/completions/item_list/trait_impl.rs @@ -95,12 +95,12 @@ pub(crate) fn complete_trait_impl_name_ref( NameRefContext { nameref, kind: - Some(NameRefKind::Path( + NameRefKind::Path( path_ctx @ PathCompletionCtx { kind: PathKind::Item { kind: ItemListKind::TraitImpl }, .. }, - )), + ), } if path_ctx.is_trivial_path() => complete_trait_impl( acc, ctx, diff --git a/crates/ide-completion/src/completions/pattern.rs b/crates/ide-completion/src/completions/pattern.rs index 1ecae1c4846..dd08ef703e4 100644 --- a/crates/ide-completion/src/completions/pattern.rs +++ b/crates/ide-completion/src/completions/pattern.rs @@ -107,7 +107,7 @@ pub(crate) fn pattern_path_completion( ctx: &CompletionContext, PathCompletionCtx { qualified, kind, .. }: &PathCompletionCtx, ) { - if !matches!(kind, PathKind::Pat) { + if !matches!(kind, PathKind::Pat { .. }) { return; } match qualified { diff --git a/crates/ide-completion/src/completions/use_.rs b/crates/ide-completion/src/completions/use_.rs index 9ffcee400d9..2cdd93f95bd 100644 --- a/crates/ide-completion/src/completions/use_.rs +++ b/crates/ide-completion/src/completions/use_.rs @@ -20,12 +20,12 @@ pub(crate) fn complete_use_tree( let (qualified, name_ref, use_tree_parent) = match name_ref_ctx { NameRefContext { kind: - Some(NameRefKind::Path(PathCompletionCtx { + NameRefKind::Path(PathCompletionCtx { kind: PathKind::Use, qualified, use_tree_parent, .. - })), + }), nameref, .. } => (qualified, nameref, use_tree_parent), diff --git a/crates/ide-completion/src/context.rs b/crates/ide-completion/src/context.rs index 5c408c0cc05..d73cb6034d2 100644 --- a/crates/ide-completion/src/context.rs +++ b/crates/ide-completion/src/context.rs @@ -85,7 +85,7 @@ impl PathCompletionCtx { } /// The kind of path we are completing right now. -#[derive(Clone, Debug, PartialEq, Eq)] +#[derive(Debug, PartialEq, Eq)] pub(super) enum PathKind { Expr { in_block_expr: bool, @@ -110,7 +110,9 @@ pub(super) enum PathKind { Item { kind: ItemListKind, }, - Pat, + Pat { + pat_ctx: PatternContext, + }, Vis { has_in_token: bool, }, @@ -164,7 +166,7 @@ pub(super) enum Qualified { } /// The state of the pattern we are completing. -#[derive(Debug)] +#[derive(Debug, Clone, PartialEq, Eq)] pub(super) struct PatternContext { pub(super) refutability: PatternRefutability, pub(super) param_ctx: Option<(ast::ParamList, ast::Param, ParamKind)>, @@ -208,7 +210,7 @@ pub(super) enum NameKind { ConstParam, Enum, Function, - IdentPat, + IdentPat(PatternContext), MacroDef, MacroRules, /// Fake node @@ -230,8 +232,7 @@ pub(super) enum NameKind { pub(super) struct NameRefContext { /// NameRef syntax in the original file pub(super) nameref: Option<ast::NameRef>, - // FIXME: This shouldn't be an Option - pub(super) kind: Option<NameRefKind>, + pub(super) kind: NameRefKind, } /// The kind of the NameRef we are completing. @@ -243,6 +244,7 @@ pub(super) enum NameRefKind { Keyword(ast::Item), /// The record expression this nameref is a field of RecordExpr(ast::RecordExpr), + Pattern(PatternContext), } /// The identifier we are currently completing. @@ -330,7 +332,6 @@ pub(crate) struct CompletionContext<'a> { // We might wanna split these out of CompletionContext pub(super) ident_ctx: IdentContext, - pub(super) pattern_ctx: Option<PatternContext>, pub(super) qualifier_ctx: QualifierCtx, pub(super) locals: FxHashMap<Name, Local>, @@ -505,7 +506,6 @@ impl<'a> CompletionContext<'a> { previous_token: None, // dummy value, will be overwritten ident_ctx: IdentContext::UnexpandedAttrTT { fake_attribute_under_caret: None }, - pattern_ctx: None, qualifier_ctx: Default::default(), locals, }; diff --git a/crates/ide-completion/src/context/analysis.rs b/crates/ide-completion/src/context/analysis.rs index 0efeb852071..fc6ee70a0bc 100644 --- a/crates/ide-completion/src/context/analysis.rs +++ b/crates/ide-completion/src/context/analysis.rs @@ -343,9 +343,9 @@ impl<'a> CompletionContext<'a> { find_node_at_offset(&file_with_fake_ident, offset) { let parent = name_ref.syntax().parent()?; - let (mut nameref_ctx, _, _) = - Self::classify_name_ref(&self.sema, &original_file, name_ref, parent); - if let Some(NameRefKind::Path(path_ctx)) = &mut nameref_ctx.kind { + let (mut nameref_ctx, _) = + Self::classify_name_ref(&self.sema, &original_file, name_ref, parent)?; + if let NameRefKind::Path(path_ctx) = &mut nameref_ctx.kind { path_ctx.kind = PathKind::Derive { existing_derives: self .sema @@ -427,19 +427,14 @@ impl<'a> CompletionContext<'a> { } ast::NameLike::NameRef(name_ref) => { let parent = name_ref.syntax().parent()?; - let (nameref_ctx, pat_ctx, qualifier_ctx) = - Self::classify_name_ref(&self.sema, &original_file, name_ref, parent.clone()); + let (nameref_ctx, qualifier_ctx) = + Self::classify_name_ref(&self.sema, &original_file, name_ref, parent.clone())?; - if !matches!(nameref_ctx.kind, Some(NameRefKind::Path(_))) { - // FIXME: Pattern context should probably be part of ident_ctx - self.pattern_ctx = pat_ctx; - } self.qualifier_ctx = qualifier_ctx; self.ident_ctx = IdentContext::NameRef(nameref_ctx); } ast::NameLike::Name(name) => { - let (name_ctx, pat_ctx) = Self::classify_name(&self.sema, original_file, name)?; - self.pattern_ctx = pat_ctx; + let name_ctx = Self::classify_name(&self.sema, original_file, name)?; self.ident_ctx = IdentContext::Name(name_ctx); } } @@ -477,9 +472,8 @@ impl<'a> CompletionContext<'a> { _sema: &Semantics<RootDatabase>, original_file: &SyntaxNode, name: ast::Name, - ) -> Option<(NameContext, Option<PatternContext>)> { + ) -> Option<NameContext> { let parent = name.syntax().parent()?; - let mut pat_ctx = None; let kind = match_ast! { match parent { ast::Const(_) => NameKind::Const, @@ -487,15 +481,12 @@ impl<'a> CompletionContext<'a> { ast::Enum(_) => NameKind::Enum, ast::Fn(_) => NameKind::Function, ast::IdentPat(bind_pat) => { - pat_ctx = Some({ - let mut pat_ctx = pattern_context_for(original_file, bind_pat.into()); - if let Some(record_field) = ast::RecordPatField::for_field_name(&name) { - pat_ctx.record_pat = find_node_in_file_compensated(original_file, &record_field.parent_record_pat()); - } - pat_ctx - }); + let mut pat_ctx = pattern_context_for(original_file, bind_pat.into()); + if let Some(record_field) = ast::RecordPatField::for_field_name(&name) { + pat_ctx.record_pat = find_node_in_file_compensated(original_file, &record_field.parent_record_pat()); + } - NameKind::IdentPat + NameKind::IdentPat(pat_ctx) }, ast::MacroDef(_) => NameKind::MacroDef, ast::MacroRules(_) => NameKind::MacroRules, @@ -514,7 +505,7 @@ impl<'a> CompletionContext<'a> { } }; let name = find_node_at_offset(&original_file, name.syntax().text_range().start()); - Some((NameContext { name, kind }, pat_ctx)) + Some(NameContext { name, kind }) } fn classify_name_ref( @@ -522,20 +513,19 @@ impl<'a> CompletionContext<'a> { original_file: &SyntaxNode, name_ref: ast::NameRef, parent: SyntaxNode, - ) -> (NameRefContext, Option<PatternContext>, QualifierCtx) { + ) -> Option<(NameRefContext, QualifierCtx)> { let nameref = find_node_at_offset(&original_file, name_ref.syntax().text_range().start()); - let mut res = (NameRefContext { nameref, kind: None }, None, QualifierCtx::default()); - let (nameref_ctx, pattern_ctx, qualifier_ctx) = &mut res; + let make_res = + |kind| (NameRefContext { nameref: nameref.clone(), kind }, Default::default()); if let Some(record_field) = ast::RecordExprField::for_field_name(&name_ref) { - nameref_ctx.kind = - find_node_in_file_compensated(original_file, &record_field.parent_record_lit()) - .map(NameRefKind::RecordExpr); - return res; + return find_node_in_file_compensated(original_file, &record_field.parent_record_lit()) + .map(NameRefKind::RecordExpr) + .map(make_res); } if let Some(record_field) = ast::RecordPatField::for_field_name_ref(&name_ref) { - *pattern_ctx = Some(PatternContext { + let kind = NameRefKind::Pattern(PatternContext { param_ctx: None, has_type_ascription: false, ref_token: None, @@ -549,7 +539,7 @@ impl<'a> CompletionContext<'a> { record_field.parent_record_pat().clone().into(), ) }); - return res; + return Some(make_res(kind)); } let segment = match_ast! { @@ -564,23 +554,23 @@ impl<'a> CompletionContext<'a> { }, _ => false, }; - nameref_ctx.kind = Some(NameRefKind::DotAccess(DotAccess { + let kind = NameRefKind::DotAccess(DotAccess { receiver_ty: receiver.as_ref().and_then(|it| sema.type_of_expr(it)), kind: DotAccessKind::Field { receiver_is_ambiguous_float_literal }, receiver - })); - return res; + }); + return Some(make_res(kind)); }, ast::MethodCallExpr(method) => { let receiver = find_opt_node_in_file(original_file, method.receiver()); - nameref_ctx.kind = Some(NameRefKind::DotAccess(DotAccess { + let kind = NameRefKind::DotAccess(DotAccess { receiver_ty: receiver.as_ref().and_then(|it| sema.type_of_expr(it)), kind: DotAccessKind::Method { has_parens: method.arg_list().map_or(false, |it| it.l_paren_token().is_some()) }, receiver - })); - return res; + }); + return Some(make_res(kind)); }, - _ => return res, + _ => return None, } }; @@ -755,52 +745,47 @@ impl<'a> CompletionContext<'a> { }; // Infer the path kind - let kind = path.syntax().parent().and_then(|it| { - match_ast! { - match it { - ast::PathType(it) => Some(make_path_kind_type(it.into())), + let parent = path.syntax().parent()?; + let kind = match_ast! { + match parent { + ast::PathType(it) => make_path_kind_type(it.into()), ast::PathExpr(it) => { if let Some(p) = it.syntax().parent() { if ast::ExprStmt::can_cast(p.kind()) { if let Some(kind) = inbetween_body_and_decl_check(p) { - nameref_ctx.kind = Some(NameRefKind::Keyword(kind)); - return None; + return Some(make_res(NameRefKind::Keyword(kind))); } } } path_ctx.has_call_parens = it.syntax().parent().map_or(false, |it| ast::CallExpr::can_cast(it.kind())); - Some(make_path_kind_expr(it.into())) + make_path_kind_expr(it.into()) }, ast::TupleStructPat(it) => { path_ctx.has_call_parens = true; - *pattern_ctx = Some(pattern_context_for(original_file, it.into())); - Some(PathKind::Pat) + PathKind::Pat { pat_ctx: pattern_context_for(original_file, it.into())} }, ast::RecordPat(it) => { path_ctx.has_call_parens = true; - *pattern_ctx = Some(pattern_context_for(original_file, it.into())); - Some(PathKind::Pat) + PathKind::Pat { pat_ctx: pattern_context_for(original_file, it.into())} }, ast::PathPat(it) => { - *pattern_ctx = Some(pattern_context_for(original_file, it.into())); - Some(PathKind::Pat) + PathKind::Pat { pat_ctx: pattern_context_for(original_file, it.into())} }, ast::MacroCall(it) => { // A macro call in this position is usually a result of parsing recovery, so check that if let Some(kind) = inbetween_body_and_decl_check(it.syntax().clone()) { - nameref_ctx.kind = Some(NameRefKind::Keyword(kind)); - return None; + return Some(make_res(NameRefKind::Keyword(kind))); } path_ctx.has_macro_bang = it.excl_token().is_some(); let parent = it.syntax().parent()?; // Any path in an item list will be treated as a macro call by the parser - let res = match_ast! { + match_ast! { match parent { ast::MacroExpr(expr) => make_path_kind_expr(expr.into()), - ast::MacroPat(_) => PathKind::Pat, + ast::MacroPat(it) => PathKind::Pat { pat_ctx: pattern_context_for(original_file, it.into())}, ast::MacroType(ty) => make_path_kind_type(ty.into()), ast::ItemList(_) => PathKind::Item { kind: ItemListKind::Module }, ast::AssocItemList(_) => PathKind::Item { kind: match parent.parent() { @@ -821,10 +806,9 @@ impl<'a> CompletionContext<'a> { ast::SourceFile(_) => PathKind::Item { kind: ItemListKind::SourceFile }, _ => return None, } - }; - Some(res) + } }, - ast::Meta(meta) => (|| { + ast::Meta(meta) => { let attr = meta.parent_attr()?; let kind = attr.kind(); let attached = attr.syntax().parent()?; @@ -835,24 +819,19 @@ impl<'a> CompletionContext<'a> { } else { Some(attached.kind()) }; - Some(PathKind::Attr { + PathKind::Attr { kind, annotated_item_kind, - }) - })(), - ast::Visibility(it) => Some(PathKind::Vis { has_in_token: it.in_token().is_some() }), - ast::UseTree(_) => Some(PathKind::Use), + } + }, + ast::Visibility(it) => PathKind::Vis { has_in_token: it.in_token().is_some() }, + ast::UseTree(_) => PathKind::Use, _ => return None, - } + } - }); + }; - match kind { - Some(kind) => path_ctx.kind = kind, - // unresolved path kind, so this isn't really a path we should be completing, - // just some random identifier which might be in keyword position - None => return res, - } + path_ctx.kind = kind; path_ctx.has_type_args = segment.generic_arg_list().is_some(); // calculate the qualifier context @@ -893,6 +872,7 @@ impl<'a> CompletionContext<'a> { } } + let mut qualifier_ctx = QualifierCtx::default(); if path_ctx.is_trivial_path() { // fetch the full expression that may have qualifiers attached to it let top_node = match path_ctx.kind { @@ -937,8 +917,8 @@ impl<'a> CompletionContext<'a> { if ![T![;], T!['}'], T!['{']].contains(&prev.kind()) { // This was inferred to be an item position path, but it seems // to be part of some other broken node which leaked into an item - // list, so return without setting the path context - return res; + // list + return None; } } } @@ -946,8 +926,7 @@ impl<'a> CompletionContext<'a> { } } } - nameref_ctx.kind = Some(NameRefKind::Path(path_ctx)); - res + Some((NameRefContext { nameref, kind: NameRefKind::Path(path_ctx) }, qualifier_ctx)) } } diff --git a/crates/ide-completion/src/lib.rs b/crates/ide-completion/src/lib.rs index b5022dab932..27fe66e385a 100644 --- a/crates/ide-completion/src/lib.rs +++ b/crates/ide-completion/src/lib.rs @@ -24,7 +24,7 @@ use text_edit::TextEdit; use crate::{ completions::Completions, - context::{CompletionContext, IdentContext, NameRefContext, NameRefKind}, + context::{CompletionContext, IdentContext, NameKind, NameRefContext, NameRefKind}, }; pub use crate::{ @@ -151,10 +151,8 @@ pub fn completions( // prevent `(` from triggering unwanted completion noise if trigger_character == Some('(') { - if let IdentContext::NameRef(NameRefContext { - kind: Some(NameRefKind::Path(path_ctx)), - .. - }) = &ctx.ident_ctx + if let IdentContext::NameRef(NameRefContext { kind: NameRefKind::Path(path_ctx), .. }) = + &ctx.ident_ctx { completions::vis::complete_vis_path(&mut completions, ctx, path_ctx); } @@ -170,6 +168,12 @@ pub fn completions( completions::field::complete_field_list_record_variant(acc, ctx, name_ctx); completions::item_list::trait_impl::complete_trait_impl_name(acc, ctx, name_ctx); completions::mod_::complete_mod(acc, ctx, name_ctx); + if let NameKind::IdentPat(pattern_ctx) = &name_ctx.kind { + completions::flyimport::import_on_the_fly_pat(acc, ctx, pattern_ctx); + completions::fn_param::complete_fn_param(acc, ctx, pattern_ctx); + completions::pattern::complete_pattern(acc, ctx, pattern_ctx); + completions::record::complete_record_pattern_fields(acc, ctx, pattern_ctx); + } } IdentContext::NameRef(name_ctx @ NameRefContext { kind, .. }) => { completions::item_list::trait_impl::complete_trait_impl_name_ref( @@ -178,7 +182,7 @@ pub fn completions( completions::use_::complete_use_tree(acc, ctx, name_ctx); match kind { - Some(NameRefKind::Path(path_ctx)) => { + NameRefKind::Path(path_ctx) => { completions::attribute::complete_attribute(acc, ctx, path_ctx); completions::attribute::complete_derive(acc, ctx, path_ctx); completions::dot::complete_undotted_self(acc, ctx, path_ctx); @@ -194,22 +198,27 @@ pub fn completions( completions::snippet::complete_item_snippet(acc, ctx, path_ctx); completions::vis::complete_vis_path(acc, ctx, path_ctx); } - Some(NameRefKind::DotAccess(dot_access)) => { + NameRefKind::DotAccess(dot_access) => { completions::flyimport::import_on_the_fly_dot(acc, ctx, dot_access); completions::dot::complete_dot(acc, ctx, dot_access); completions::postfix::complete_postfix(acc, ctx, dot_access); } - Some(NameRefKind::Keyword(item)) => { + NameRefKind::Keyword(item) => { completions::keyword::complete_special_keywords(acc, ctx, item); } - Some(NameRefKind::RecordExpr(record_expr)) => { + NameRefKind::RecordExpr(record_expr) => { completions::record::complete_record_expr_fields_record_expr( acc, ctx, record_expr, ); } - None => (), + NameRefKind::Pattern(pattern_ctx) => { + completions::flyimport::import_on_the_fly_pat(acc, ctx, pattern_ctx); + completions::fn_param::complete_fn_param(acc, ctx, pattern_ctx); + completions::pattern::complete_pattern(acc, ctx, pattern_ctx); + completions::record::complete_record_pattern_fields(acc, ctx, pattern_ctx); + } } } IdentContext::Lifetime(lifetime_ctx) => { @@ -225,13 +234,6 @@ pub fn completions( } IdentContext::UnexpandedAttrTT { .. } | IdentContext::String { .. } => (), } - - if let Some(pattern_ctx) = &ctx.pattern_ctx { - completions::flyimport::import_on_the_fly_pat(acc, ctx, pattern_ctx); - completions::fn_param::complete_fn_param(acc, ctx, pattern_ctx); - completions::pattern::complete_pattern(acc, ctx, pattern_ctx); - completions::record::complete_record_pattern_fields(acc, ctx, pattern_ctx); - } } Some(completions) diff --git a/crates/ide-completion/src/render.rs b/crates/ide-completion/src/render.rs index 68908e330a4..c6091645ca8 100644 --- a/crates/ide-completion/src/render.rs +++ b/crates/ide-completion/src/render.rs @@ -78,7 +78,7 @@ impl<'a> RenderContext<'a> { matches!( self.completion.ident_ctx, IdentContext::NameRef(NameRefContext { - kind: Some(NameRefKind::Path(PathCompletionCtx { has_call_parens: true, .. })), + kind: NameRefKind::Path(PathCompletionCtx { has_call_parens: true, .. }), .. }) ) @@ -218,7 +218,7 @@ fn render_resolution_( let ctx = ctx.import_to_add(import_to_add); return render_fn(ctx, Some(local_name), func); } - ScopeDef::ModuleDef(Variant(var)) if ctx.completion.pattern_ctx.is_none() => { + ScopeDef::ModuleDef(Variant(var)) => { let ctx = ctx.clone().import_to_add(import_to_add.clone()); if let Some(item) = render_variant_lit(ctx, Some(local_name.clone()), var, None) { return item; @@ -293,11 +293,11 @@ fn render_resolution_simple_( let type_path_no_ty_args = matches!( ctx.completion.ident_ctx, IdentContext::NameRef(NameRefContext { - kind: Some(NameRefKind::Path(PathCompletionCtx { + kind: NameRefKind::Path(PathCompletionCtx { kind: PathKind::Type { .. }, has_type_args: false, .. - })), + }), .. }) ) && ctx.completion.config.callable.is_some(); diff --git a/crates/ide-completion/src/render/function.rs b/crates/ide-completion/src/render/function.rs index 811a88704d5..48539a03b18 100644 --- a/crates/ide-completion/src/render/function.rs +++ b/crates/ide-completion/src/render/function.rs @@ -83,10 +83,10 @@ fn render( let qualified_path = matches!( ctx.completion.ident_ctx, IdentContext::NameRef(NameRefContext { - kind: Some(NameRefKind::Path(PathCompletionCtx { + kind: NameRefKind::Path(PathCompletionCtx { qualified: Qualified::With { .. }, .. - })), + }), .. }) ); @@ -262,24 +262,24 @@ fn params( let has_dot_receiver = match ctx.ident_ctx { IdentContext::NameRef(NameRefContext { kind: - Some(NameRefKind::DotAccess(DotAccess { + NameRefKind::DotAccess(DotAccess { kind: DotAccessKind::Method { has_parens: true }, .. - })), + }), .. }) => return None, IdentContext::NameRef(NameRefContext { - kind: Some(NameRefKind::DotAccess(DotAccess { .. })), + kind: NameRefKind::DotAccess(DotAccess { .. }), .. }) => true, IdentContext::NameRef(NameRefContext { kind: - Some(NameRefKind::Path( + NameRefKind::Path( PathCompletionCtx { kind: PathKind::Expr { .. }, has_call_parens: true, .. } | PathCompletionCtx { kind: PathKind::Use | PathKind::Type { .. }, .. }, - )), + ), .. }) => return None, _ => false, diff --git a/crates/ide-completion/src/render/literal.rs b/crates/ide-completion/src/render/literal.rs index 1e03d066d14..042c9742579 100644 --- a/crates/ide-completion/src/render/literal.rs +++ b/crates/ide-completion/src/render/literal.rs @@ -55,15 +55,14 @@ fn render( let mut kind = thing.kind(db); let should_add_parens = match &completion.ident_ctx { IdentContext::NameRef(NameRefContext { - kind: Some(NameRefKind::Path(PathCompletionCtx { has_call_parens: true, .. })), + kind: NameRefKind::Path(PathCompletionCtx { has_call_parens: true, .. }), .. }) => false, IdentContext::NameRef(NameRefContext { kind: - Some(NameRefKind::Path(PathCompletionCtx { - kind: PathKind::Use | PathKind::Type { .. }, - .. - })), + NameRefKind::Path(PathCompletionCtx { + kind: PathKind::Use | PathKind::Type { .. }, .. + }), .. }) => false, _ => true, diff --git a/crates/ide-completion/src/render/macro_.rs b/crates/ide-completion/src/render/macro_.rs index 26690d22abe..0c9c65f4231 100644 --- a/crates/ide-completion/src/render/macro_.rs +++ b/crates/ide-completion/src/render/macro_.rs @@ -35,7 +35,7 @@ fn render( let needs_bang = match &completion.ident_ctx { IdentContext::NameRef(NameRefContext { - kind: Some(NameRefKind::Path(PathCompletionCtx { kind, has_macro_bang, .. })), + kind: NameRefKind::Path(PathCompletionCtx { kind, has_macro_bang, .. }), .. }) => is_fn_like && *kind != PathKind::Use && !has_macro_bang, _ => is_fn_like, diff --git a/crates/ide-completion/src/render/pattern.rs b/crates/ide-completion/src/render/pattern.rs index 33f169c1b9b..74564bb3aae 100644 --- a/crates/ide-completion/src/render/pattern.rs +++ b/crates/ide-completion/src/render/pattern.rs @@ -7,7 +7,8 @@ use syntax::SmolStr; use crate::{ context::{ - IdentContext, NameRefContext, NameRefKind, ParamKind, PathCompletionCtx, PatternContext, + IdentContext, NameContext, NameKind, NameRefContext, NameRefKind, ParamKind, + PathCompletionCtx, PathKind, PatternContext, }, render::{variant::visible_fields, RenderContext}, CompletionItem, CompletionItemKind, @@ -82,7 +83,7 @@ fn render_pat( let has_call_parens = matches!( ctx.completion.ident_ctx, IdentContext::NameRef(NameRefContext { - kind: Some(NameRefKind::Path(PathCompletionCtx { has_call_parens: true, .. })), + kind: NameRefKind::Path(PathCompletionCtx { has_call_parens: true, .. }), .. }) ); @@ -97,14 +98,27 @@ fn render_pat( _ => name.to_owned(), }; - if matches!( - ctx.completion.pattern_ctx, - Some(PatternContext { - param_ctx: Some((.., ParamKind::Function(_))), - has_type_ascription: false, - .. - }) if !has_call_parens - ) { + let needs_ascription = !has_call_parens + && matches!( + &ctx.completion.ident_ctx, + IdentContext::NameRef(NameRefContext { + kind: NameRefKind::Path(PathCompletionCtx { + kind: PathKind::Pat { + pat_ctx + }, + .. + }), + .. + }) | IdentContext::Name(NameContext { + kind: NameKind::IdentPat(pat_ctx), ..} + ) + if matches!(pat_ctx, PatternContext { + param_ctx: Some((.., ParamKind::Function(_))), + has_type_ascription: false, + .. + }) + ); + if needs_ascription { pat.push(':'); pat.push(' '); pat.push_str(name); diff --git a/crates/ide-completion/src/tests/flyimport.rs b/crates/ide-completion/src/tests/flyimport.rs index ca9408fb138..a3bc1025e95 100644 --- a/crates/ide-completion/src/tests/flyimport.rs +++ b/crates/ide-completion/src/tests/flyimport.rs @@ -1,7 +1,7 @@ use expect_test::{expect, Expect}; use crate::{ - context::NameRefKind, + context::{IdentContext, NameContext, NameKind, NameRefKind}, tests::{check_edit, check_edit_with_config, TEST_CONFIG}, }; @@ -11,17 +11,22 @@ fn check(ra_fixture: &str, expect: Expect) { let ctx = crate::context::CompletionContext::new(&db, position, &config).unwrap(); let mut acc = crate::completions::Completions::default(); - if let Some(pattern_ctx) = &ctx.pattern_ctx { - crate::completions::flyimport::import_on_the_fly_pat(&mut acc, &ctx, pattern_ctx); + if let IdentContext::Name(NameContext { kind: NameKind::IdentPat(pat_ctx), .. }) = + &ctx.ident_ctx + { + crate::completions::flyimport::import_on_the_fly_pat(&mut acc, &ctx, pat_ctx); } - if let crate::context::IdentContext::NameRef(name_ref_ctx) = &ctx.ident_ctx { + if let IdentContext::NameRef(name_ref_ctx) = &ctx.ident_ctx { match &name_ref_ctx.kind { - Some(NameRefKind::Path(path)) => { + NameRefKind::Path(path) => { crate::completions::flyimport::import_on_the_fly_path(&mut acc, &ctx, path); } - Some(NameRefKind::DotAccess(dot_access)) => { + NameRefKind::DotAccess(dot_access) => { crate::completions::flyimport::import_on_the_fly_dot(&mut acc, &ctx, dot_access); } + NameRefKind::Pattern(pattern) => { + crate::completions::flyimport::import_on_the_fly_pat(&mut acc, &ctx, pattern); + } _ => (), } } |
