Show only assoc type args in the correct arg pos

This commit is contained in:
Hongxu Xu 2022-07-06 22:58:27 +08:00
parent 441e659aa1
commit 0f2eba54db
3 changed files with 69 additions and 3 deletions

View file

@ -41,6 +41,7 @@ use hir_def::{
adt::{ReprKind, VariantData},
body::{BodyDiagnostic, SyntheticSyntax},
expr::{BindingAnnotation, LabelId, Pat, PatId},
generics::{TypeOrConstParamData, TypeParamProvenance},
item_tree::ItemTreeNode,
lang_item::LangItemTarget,
nameres::{self, diagnostics::DefDiagnostic},
@ -1707,6 +1708,22 @@ impl Trait {
pub fn is_unsafe(&self, db: &dyn HirDatabase) -> bool {
db.trait_data(self.id).is_unsafe
}
pub fn type_parameters(&self, db: &dyn HirDatabase) -> Vec<TypeOrConstParamData> {
db.generic_params(GenericDefId::from(self.id))
.type_or_consts
.iter()
.filter(|(_, ty)| match ty {
TypeOrConstParamData::TypeParamData(ty)
if ty.provenance != TypeParamProvenance::TypeParamList =>
{
false
}
_ => true,
})
.map(|(_, ty)|ty.clone())
.collect()
}
}
impl HasVisibility for Trait {

View file

@ -1,6 +1,7 @@
//! Completion of names from the current scope in type position.
use hir::{HirDisplay, ScopeDef};
use itertools::Itertools;
use syntax::{ast, AstNode};
use crate::{
@ -140,6 +141,18 @@ pub(crate) fn complete_type_path(
return;
}
TypeLocation::GenericArgList(Some(arg_list)) => {
// the current token is in which generic arg
let arg_pos = if let Some((pos, _)) =
arg_list.generic_args().find_position(|arg| {
arg.syntax()
.descendants_with_tokens()
.any(|t| t.as_token() == Some(&ctx.original_token))
}) {
pos
} else {
0
};
match arg_list.generic_args().next() {
Some(ast::GenericArg::AssocTypeArg(_)) => {}
_ => {
@ -167,7 +180,10 @@ pub(crate) fn complete_type_path(
acc.add_type_alias_with_eq(ctx, alias);
}
});
return; // only AssocTypeArgs make sense
if arg_pos >= trait_.type_parameters(ctx.sema.db).len() {
return; // only AssocTypeArgs make sense
}
}
}
}

View file

@ -386,6 +386,39 @@ fn foo<'lt, T: Trait2<$0>, const CONST_PARAM: usize>(_: T) {}
);
check(
r#"
trait Trait1 {
type Super;
}
trait Trait2<T>: Trait1 {
type Foo;
}
fn foo<'lt, T: Trait2<$0>, const CONST_PARAM: usize>(_: T) {}
"#,
expect![[r#"
ct CONST
cp CONST_PARAM
en Enum
ma makro!() macro_rules! makro
md module
st Record
st Tuple
st Unit
tt Trait
tt Trait1
tt Trait2
ta Foo = (as Trait2) type Foo
ta Super = (as Trait1) type Super
tp T
un Union
bt u32
kw crate::
kw self::
kw super::
"#]],
);
check(
r#"
trait Trait2 {
type Foo;
}
@ -460,11 +493,11 @@ fn func(_: Enum::$0) {}
fn completes_associated_type_only() {
check(
r#"
trait MyTrait {
trait MyTrait<T> {
type Item;
};
fn f(t: impl MyTrait<I$0
fn f(t: impl MyTrait<u8,I$0
"#,
expect![[r#"
ta Item = (as MyTrait) type Item