Skip to content

Commit b9ee4a5

Browse files
committed
working for path segments
1 parent c4cff80 commit b9ee4a5

File tree

4 files changed

+76
-38
lines changed

4 files changed

+76
-38
lines changed

crates/ide-completion/src/completions/type.rs

Lines changed: 24 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -24,12 +24,23 @@ pub(crate) fn complete_type_path(
2424
// no values in type places
2525
ScopeDef::ModuleDef(Function(_) | Variant(_) | Static(_)) | ScopeDef::Local(_) => false,
2626
// unless its a constant in a generic arg list position
27-
ScopeDef::ModuleDef(Const(_)) | ScopeDef::GenericParam(ConstParam(_)) => {
28-
matches!(location, TypeLocation::GenericArgList(_))
29-
}
30-
ScopeDef::ImplSelfType(_) => {
31-
!matches!(location, TypeLocation::ImplTarget | TypeLocation::ImplTrait)
32-
}
27+
ScopeDef::ModuleDef(Const(_)) | ScopeDef::GenericParam(ConstParam(_)) => match location
28+
{
29+
TypeLocation::GenericArgList(location) => match location {
30+
Some((_, Some(generic_param))) => {
31+
matches!(generic_param, ast::GenericParam::ConstParam(_))
32+
}
33+
_ => true,
34+
},
35+
_ => false,
36+
},
37+
ScopeDef::ImplSelfType(_) => match location {
38+
TypeLocation::ImplTarget | TypeLocation::ImplTrait => false,
39+
TypeLocation::GenericArgList(Some((_, Some(generic_param)))) => {
40+
matches!(generic_param, ast::GenericParam::TypeParam(_))
41+
}
42+
_ => true,
43+
},
3344
// Don't suggest attribute macros and derives.
3445
ScopeDef::ModuleDef(Macro(mac)) => mac.is_fn_like(ctx.db),
3546
// Type things are fine
@@ -38,7 +49,12 @@ pub(crate) fn complete_type_path(
3849
)
3950
| ScopeDef::AdtSelfType(_)
4051
| ScopeDef::Unknown
41-
| ScopeDef::GenericParam(TypeParam(_)) => true,
52+
| ScopeDef::GenericParam(TypeParam(_)) => match location {
53+
TypeLocation::GenericArgList(Some((_, Some(generic_param)))) => {
54+
matches!(generic_param, ast::GenericParam::TypeParam(_))
55+
}
56+
_ => true,
57+
},
4258
}
4359
};
4460

@@ -157,7 +173,7 @@ pub(crate) fn complete_type_path(
157173
});
158174
return;
159175
}
160-
TypeLocation::GenericArgList(Some(arg_list)) => {
176+
TypeLocation::GenericArgList(Some((arg_list, generic_param))) => {
161177
let in_assoc_type_arg = ctx
162178
.original_token
163179
.parent_ancestors()

crates/ide-completion/src/context.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ pub(crate) struct ExprCtx {
155155
pub(crate) enum TypeLocation {
156156
TupleField,
157157
TypeAscription(TypeAscriptionTarget),
158-
GenericArgList(Option<ast::GenericArgList>),
158+
GenericArgList(Option<(ast::GenericArgList, Option<ast::GenericParam>)>),
159159
TypeBound,
160160
ImplTarget,
161161
ImplTrait,

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

Lines changed: 37 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
//! Module responsible for analyzing the code surrounding the cursor for completion.
22
use std::iter;
33

4-
use hir::{Semantics, Type, TypeInfo, Variant};
4+
use hir::{HasSource, Semantics, Type, TypeInfo, Variant};
55
use ide_db::{active_parameter::ActiveParameter, RootDatabase};
66
use syntax::{
77
algo::{find_node_at_offset, non_trivia_sibling},
8-
ast::{self, AttrKind, HasArgList, HasLoopBody, HasName, NameOrNameRef},
8+
ast::{self, AttrKind, HasArgList, HasGenericParams, HasLoopBody, HasName, NameOrNameRef},
99
match_ast, AstNode, AstToken, Direction, NodeOrToken, SyntaxElement, SyntaxKind, SyntaxNode,
1010
SyntaxToken, TextRange, TextSize, T,
1111
};
@@ -774,9 +774,40 @@ fn classify_name_ref(
774774
ast::TypeBound(_) => TypeLocation::TypeBound,
775775
// is this case needed?
776776
ast::TypeBoundList(_) => TypeLocation::TypeBound,
777-
ast::GenericArg(it) => TypeLocation::GenericArgList(find_opt_node_in_file_compensated(sema, original_file, it.syntax().parent().and_then(ast::GenericArgList::cast))),
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+
},
778805
// is this case needed?
779-
ast::GenericArgList(it) => TypeLocation::GenericArgList(find_opt_node_in_file_compensated(sema, original_file, Some(it))),
806+
ast::GenericArgList(it) => {
807+
let location = find_opt_node_in_file_compensated(sema, original_file, Some(it))
808+
.map(|node| (node, None));
809+
TypeLocation::GenericArgList(location)
810+
},
780811
ast::TupleField(_) => TypeLocation::TupleField,
781812
_ => return None,
782813
}
@@ -883,25 +914,8 @@ fn classify_name_ref(
883914
}
884915
};
885916
let make_path_kind_type = |ty: ast::Type| {
886-
let location = type_location(ty.syntax()).unwrap_or(TypeLocation::Other);
887-
match &location {
888-
TypeLocation::TupleField => (),
889-
TypeLocation::TypeAscription(_) => (),
890-
TypeLocation::GenericArgList(args) => {
891-
dbg!(&args);
892-
if let Some(segment) =
893-
args.as_ref().and_then(|args| ast::PathSegment::cast(args.syntax().parent()?))
894-
{
895-
let path = dbg!(segment.parent_path().top_path());
896-
dbg!(sema.resolve_path(&path));
897-
}
898-
}
899-
TypeLocation::TypeBound => (),
900-
TypeLocation::ImplTarget => (),
901-
TypeLocation::ImplTrait => (),
902-
TypeLocation::Other => (),
903-
}
904-
PathKind::Type { location }
917+
let location = type_location(ty.syntax());
918+
PathKind::Type { location: location.unwrap_or(TypeLocation::Other) }
905919
};
906920

907921
let mut kind_macro_call = |it: ast::MacroCall| {

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

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -726,15 +726,21 @@ fn completes_const_and_type_generics_separately() {
726726
r#"
727727
struct Foo;
728728
const X: usize = 0;
729-
mod foo {
730-
fn foo<T>() {}
731-
}
729+
fn foo<T, const N: usize>() {}
732730
fn main() {
733-
self::foo::foo::<F$0>();
731+
foo::<F$0, _>();
734732
}
735733
"#,
736734
expect![[r#"
735+
en Enum
736+
ma makro!(…) macro_rules! makro
737+
md module
737738
st Foo
739+
st Record
740+
st Tuple
741+
st Unit
742+
tt Trait
743+
un Union
738744
bt u32
739745
kw crate::
740746
kw self::
@@ -744,13 +750,15 @@ fn main() {
744750
r#"
745751
struct Foo;
746752
const X: usize = 0;
747-
fn foo<const X: usize>() {}
753+
fn foo<T, const N: usize>() {}
748754
fn main() {
749-
foo::<F$0>();
755+
foo::<_, $0>();
750756
}
751757
"#,
752758
expect![[r#"
759+
ct CONST
753760
ct X
761+
ma makro!(…) macro_rules! makro
754762
kw crate::
755763
kw self::
756764
"#]],

0 commit comments

Comments
 (0)