Unnamed repository; edit this file 'description' to name the repository.
| -rw-r--r-- | crates/ide-completion/src/completions.rs | 2 | ||||
| -rw-r--r-- | crates/ide-completion/src/completions/type.rs | 51 | ||||
| -rw-r--r-- | crates/ide-completion/src/context.rs | 21 | ||||
| -rw-r--r-- | crates/ide-completion/src/context/analysis.rs | 15 |
4 files changed, 53 insertions, 36 deletions
diff --git a/crates/ide-completion/src/completions.rs b/crates/ide-completion/src/completions.rs index 125ebc98a5..7e2ecdbb85 100644 --- a/crates/ide-completion/src/completions.rs +++ b/crates/ide-completion/src/completions.rs @@ -703,7 +703,7 @@ pub(super) fn complete_name_ref( TypeLocation::TypeAscription(ascription) => { r#type::complete_ascribed_type(acc, ctx, path_ctx, ascription); } - TypeLocation::GenericArg(_) + TypeLocation::GenericArg { .. } | TypeLocation::AssocConstEq | TypeLocation::AssocTypeEq | TypeLocation::TypeBound diff --git a/crates/ide-completion/src/completions/type.rs b/crates/ide-completion/src/completions/type.rs index 621dea0b9a..a30fd13b1d 100644 --- a/crates/ide-completion/src/completions/type.rs +++ b/crates/ide-completion/src/completions/type.rs @@ -42,7 +42,7 @@ pub(crate) fn complete_type_path( }; let add_assoc_item = |acc: &mut Completions, item| match item { - hir::AssocItem::Const(ct) if matches!(location, TypeLocation::GenericArg(_)) => { + hir::AssocItem::Const(ct) if matches!(location, TypeLocation::GenericArg { .. }) => { acc.add_const(ctx, ct) } hir::AssocItem::Function(_) | hir::AssocItem::Const(_) => (), @@ -156,33 +156,30 @@ pub(crate) fn complete_type_path( }); return; } - TypeLocation::GenericArg(Some((arg_list, in_trait, _))) => { - if let Some(trait_) = in_trait { - if arg_list.syntax().ancestors().find_map(ast::TypeBound::cast).is_some() { - let arg_idx = arg_list - .generic_args() - .filter(|arg| { - arg.syntax().text_range().end() - < ctx.original_token.text_range().start() - }) - .count(); - - let n_required_params = - trait_.type_or_const_param_count(ctx.sema.db, true); - if arg_idx >= n_required_params { - trait_.items_with_supertraits(ctx.sema.db).into_iter().for_each( - |it| { - if let hir::AssocItem::TypeAlias(alias) = it { - cov_mark::hit!(complete_assoc_type_in_generics_list); - acc.add_type_alias_with_eq(ctx, alias); - } - }, - ); - - let n_params = trait_.type_or_const_param_count(ctx.sema.db, false); - if arg_idx >= n_params { - return; // only show assoc types + TypeLocation::GenericArg { + args: Some(arg_list), of_trait: Some(trait_), .. + } => { + if arg_list.syntax().ancestors().find_map(ast::TypeBound::cast).is_some() { + let arg_idx = arg_list + .generic_args() + .filter(|arg| { + arg.syntax().text_range().end() + < ctx.original_token.text_range().start() + }) + .count(); + + let n_required_params = trait_.type_or_const_param_count(ctx.sema.db, true); + if arg_idx >= n_required_params { + trait_.items_with_supertraits(ctx.sema.db).into_iter().for_each(|it| { + if let hir::AssocItem::TypeAlias(alias) = it { + cov_mark::hit!(complete_assoc_type_in_generics_list); + acc.add_type_alias_with_eq(ctx, alias); } + }); + + let n_params = trait_.type_or_const_param_count(ctx.sema.db, false); + if arg_idx >= n_params { + return; // only show assoc types } } } diff --git a/crates/ide-completion/src/context.rs b/crates/ide-completion/src/context.rs index 90ad2ecaf9..1fd635ba2e 100644 --- a/crates/ide-completion/src/context.rs +++ b/crates/ide-completion/src/context.rs @@ -156,7 +156,14 @@ pub(crate) enum TypeLocation { TupleField, TypeAscription(TypeAscriptionTarget), /// Generic argument position e.g. `Foo<$0>` - GenericArg(Option<(ast::GenericArgList, Option<hir::Trait>, Option<ast::GenericParam>)>), + GenericArg { + /// The generic argument list containing the generic arg + args: Option<ast::GenericArgList>, + /// `Some(trait_)` if `trait_` is being instantiated with `args` + of_trait: Option<hir::Trait>, + /// The generic parameter being filled in by the generic arg + corresponding_param: Option<ast::GenericParam>, + }, /// Associated type equality constraint e.g. `Foo<Bar = $0>` AssocTypeEq, /// Associated constant equality constraint e.g. `Foo<X = $0>` @@ -171,13 +178,19 @@ impl TypeLocation { pub(crate) fn complete_lifetimes(&self) -> bool { matches!( self, - TypeLocation::GenericArg(Some((_, _, Some(ast::GenericParam::LifetimeParam(_))))) + TypeLocation::GenericArg { + corresponding_param: Some(ast::GenericParam::LifetimeParam(_)), + .. + } ) } pub(crate) fn complete_consts(&self) -> bool { match self { - TypeLocation::GenericArg(Some((_, _, Some(ast::GenericParam::ConstParam(_))))) => true, + TypeLocation::GenericArg { + corresponding_param: Some(ast::GenericParam::ConstParam(_)), + .. + } => true, TypeLocation::AssocConstEq => true, _ => false, } @@ -185,7 +198,7 @@ impl TypeLocation { pub(crate) fn complete_types(&self) -> bool { match self { - TypeLocation::GenericArg(Some((_, _, Some(param)))) => { + TypeLocation::GenericArg { corresponding_param: Some(param), .. } => { matches!(param, ast::GenericParam::TypeParam(_)) } TypeLocation::AssocConstEq => false, diff --git a/crates/ide-completion/src/context/analysis.rs b/crates/ide-completion/src/context/analysis.rs index 2064ae34dd..c66cb987fe 100644 --- a/crates/ide-completion/src/context/analysis.rs +++ b/crates/ide-completion/src/context/analysis.rs @@ -838,7 +838,15 @@ fn classify_name_ref( })(); (args, in_trait, param) }); - override_location.unwrap_or(TypeLocation::GenericArg(location)) + let (arg_list, of_trait, corresponding_param) = match location { + Some((arg_list, of_trait, param)) => (Some(arg_list), of_trait, param), + _ => (None, None, None), + }; + override_location.unwrap_or(TypeLocation::GenericArg { + args: arg_list, + of_trait, + corresponding_param, + }) }; let type_location = |node: &SyntaxNode| { @@ -899,9 +907,8 @@ fn classify_name_ref( ast::GenericArg(it) => generic_arg_location(it), // is this case needed? ast::GenericArgList(it) => { - let location = find_opt_node_in_file_compensated(sema, original_file, Some(it)) - .map(|node| (node, None, None)); - TypeLocation::GenericArg(location) + let args = find_opt_node_in_file_compensated(sema, original_file, Some(it)); + TypeLocation::GenericArg { args, of_trait: None, corresponding_param: None } }, ast::TupleField(_) => TypeLocation::TupleField, _ => return None, |