Skip to content

Commit f4038a6

Browse files
committed
support AssocTypeArg and MethodCalls
1 parent b9ee4a5 commit f4038a6

File tree

2 files changed

+158
-34
lines changed

2 files changed

+158
-34
lines changed

crates/ide-completion/src/context/analysis.rs

Lines changed: 66 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -719,6 +719,70 @@ fn classify_name_ref(
719719
None
720720
};
721721

722+
let generic_arg_location = |arg: ast::GenericArg| {
723+
let location = find_opt_node_in_file_compensated(
724+
sema,
725+
original_file,
726+
arg.syntax().parent().and_then(ast::GenericArgList::cast),
727+
)
728+
.map(|args| {
729+
// Determine the index of the parameter in the `GenericArgList`
730+
// (subtract 1 because `siblings` includes the node itself)
731+
let param_idx = arg.syntax().siblings(Direction::Prev).count() - 1;
732+
let parent = args.syntax().parent();
733+
let param = parent.and_then(|parent| {
734+
match_ast! {
735+
match parent {
736+
ast::PathSegment(segment) => {
737+
match sema.resolve_path(&segment.parent_path().top_path())? {
738+
hir::PathResolution::Def(def) => match def {
739+
hir::ModuleDef::Function(func) => {
740+
let src = func.source(sema.db)?;
741+
let params = src.value.generic_param_list()?;
742+
params.generic_params().nth(param_idx)
743+
}
744+
_ => None,
745+
},
746+
_ => None,
747+
}
748+
},
749+
ast::MethodCallExpr(call) => {
750+
let func = sema.resolve_method_call(&call)?;
751+
let src = func.source(sema.db)?;
752+
let params = src.value.generic_param_list()?;
753+
params.generic_params().nth(param_idx)
754+
},
755+
ast::AssocTypeArg(arg) => {
756+
let trait_ = ast::PathSegment::cast(arg.syntax().parent()?.parent()?)?;
757+
match sema.resolve_path(&trait_.parent_path().top_path())? {
758+
hir::PathResolution::Def(def) => match def {
759+
hir::ModuleDef::Trait(trait_) => {
760+
let trait_items = trait_.items(sema.db);
761+
let assoc_ty = trait_items.iter().find_map(|item| match item {
762+
hir::AssocItem::TypeAlias(assoc_ty) => {
763+
(assoc_ty.name(sema.db).as_str()? == arg.name_ref()?.text())
764+
.then_some(assoc_ty)
765+
},
766+
_ => None,
767+
})?;
768+
let src = assoc_ty.source(sema.db)?;
769+
let params = src.value.generic_param_list()?;
770+
params.generic_params().nth(param_idx)
771+
}
772+
_ => None,
773+
},
774+
_ => None,
775+
}
776+
},
777+
_ => None,
778+
}
779+
}
780+
});
781+
(args, param)
782+
});
783+
TypeLocation::GenericArgList(location)
784+
};
785+
722786
let type_location = |node: &SyntaxNode| {
723787
let parent = node.parent()?;
724788
let res = match_ast! {
@@ -774,34 +838,8 @@ fn classify_name_ref(
774838
ast::TypeBound(_) => TypeLocation::TypeBound,
775839
// is this case needed?
776840
ast::TypeBoundList(_) => TypeLocation::TypeBound,
777-
ast::GenericArg(it) => {
778-
let location = find_opt_node_in_file_compensated(sema, original_file, it.syntax().parent().and_then(ast::GenericArgList::cast))
779-
.map(|args| {
780-
// Determine the index of the parameter in the `GenericArgList`
781-
// (subtract 1 because `siblings` includes the node itself)
782-
let param_idx = it.syntax().siblings(Direction::Prev).count() - 1;
783-
let param = args
784-
.syntax()
785-
.parent()
786-
.and_then(|p| ast::PathSegment::cast(p))
787-
.and_then(|segment| sema.resolve_path(&segment.parent_path().top_path()))
788-
.and_then(|resolved| {
789-
match resolved {
790-
hir::PathResolution::Def(def) => match def {
791-
hir::ModuleDef::Function(func) => {
792-
let src = func.source(sema.db)?;
793-
let params = src.value.generic_param_list()?;
794-
params.generic_params().nth(param_idx)
795-
}
796-
_ => None,
797-
},
798-
_ => None,
799-
}
800-
});
801-
(args, param)
802-
});
803-
TypeLocation::GenericArgList(location)
804-
},
841+
ast::TypeArg(it) => generic_arg_location(ast::GenericArg::TypeArg(it)),
842+
ast::GenericArg(it) => generic_arg_location(it),
805843
// is this case needed?
806844
ast::GenericArgList(it) => {
807845
let location = find_opt_node_in_file_compensated(sema, original_file, Some(it))

crates/ide-completion/src/tests/type_pos.rs

Lines changed: 92 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -724,11 +724,70 @@ pub struct S;
724724
fn completes_const_and_type_generics_separately() {
725725
check(
726726
r#"
727+
struct Foo;
728+
const X: usize = 0;
729+
fn foo<T, const N: usize>() {}
730+
fn main() {
731+
foo::<F$0, _>();
732+
}
733+
"#,
734+
expect![[r#"
735+
en Enum
736+
ma makro!(…) macro_rules! makro
737+
md module
738+
st Foo
739+
st Record
740+
st Tuple
741+
st Unit
742+
tt Trait
743+
un Union
744+
bt u32
745+
kw crate::
746+
kw self::
747+
"#]],
748+
);
749+
check(
750+
r#"
751+
struct Foo;
752+
const X: usize = 0;
753+
fn foo<T, const N: usize>() {}
754+
fn main() {
755+
foo::<_, $0>();
756+
}
757+
"#,
758+
expect![[r#"
759+
ct CONST
760+
ct X
761+
ma makro!(…) macro_rules! makro
762+
kw crate::
763+
kw self::
764+
"#]],
765+
);
766+
767+
check(
768+
r#"
769+
const X: usize = 0;
727770
struct Foo;
771+
impl Foo { fn bar<const N: usize, T>(self) {} }
772+
fn main() {
773+
Foo.bar::<X$0, _>();
774+
}
775+
"#,
776+
expect![[r#"
777+
ct CONST
778+
ct X
779+
ma makro!(…) macro_rules! makro
780+
kw crate::
781+
kw self::
782+
"#]],
783+
);
784+
check(
785+
r#"
728786
const X: usize = 0;
729-
fn foo<T, const N: usize>() {}
787+
struct Foo;
788+
impl Foo { fn bar<const N: usize, T>(self) {} }
730789
fn main() {
731-
foo::<F$0, _>();
790+
Foo.bar::<_, $0>();
732791
}
733792
"#,
734793
expect![[r#"
@@ -746,14 +805,15 @@ fn main() {
746805
kw self::
747806
"#]],
748807
);
808+
749809
check(
750810
r#"
751-
struct Foo;
752811
const X: usize = 0;
753-
fn foo<T, const N: usize>() {}
754-
fn main() {
755-
foo::<_, $0>();
812+
struct Foo;
813+
trait Bar {
814+
type Baz<T, const X: usize>;
756815
}
816+
fn foo<T: Bar<Baz<(), $0> = ()>>() {}
757817
"#,
758818
expect![[r#"
759819
ct CONST
@@ -763,4 +823,30 @@ fn main() {
763823
kw self::
764824
"#]],
765825
);
826+
check(
827+
r#"
828+
const X: usize = 0;
829+
struct Foo;
830+
trait Bar {
831+
type Baz<T, const X: usize>;
832+
}
833+
fn foo<T: Bar<Baz<F$0, 0> = ()>>() {}
834+
"#,
835+
expect![[r#"
836+
en Enum
837+
ma makro!(…) macro_rules! makro
838+
md module
839+
st Foo
840+
st Record
841+
st Tuple
842+
st Unit
843+
tt Bar
844+
tt Trait
845+
tp T
846+
un Union
847+
bt u32
848+
kw crate::
849+
kw self::
850+
"#]],
851+
);
766852
}

0 commit comments

Comments
 (0)