11713: Complete associated consts in patterns  r=jonas-schievink a=hi-rustin

Try close https://github.com/rust-analyzer/rust-analyzer/issues/11555

Co-authored-by: hi-rustin <rustin.liu@gmail.com>
Co-authored-by: Jonas Schievink <jonasschievink@gmail.com>
This commit is contained in:
bors[bot] 2022-03-18 13:54:09 +00:00 committed by GitHub
commit 849ac25f05
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 103 additions and 18 deletions

View File

@ -137,25 +137,30 @@ fn pattern_path_completion(
}
}
}
res @ (hir::PathResolution::TypeParam(_)
| hir::PathResolution::SelfType(_)
| hir::PathResolution::Def(hir::ModuleDef::Adt(hir::Adt::Struct(_)))
| hir::PathResolution::Def(hir::ModuleDef::Adt(hir::Adt::Enum(_)))
| hir::PathResolution::Def(hir::ModuleDef::Adt(hir::Adt::Union(_)))) => {
let ty = match res {
hir::PathResolution::TypeParam(param) => param.ty(ctx.db),
hir::PathResolution::SelfType(impl_def) => impl_def.self_ty(ctx.db),
hir::PathResolution::Def(hir::ModuleDef::Adt(hir::Adt::Struct(s))) => {
s.ty(ctx.db)
}
hir::PathResolution::Def(hir::ModuleDef::Adt(hir::Adt::Enum(e))) => {
cov_mark::hit!(enum_plain_qualified_use_tree);
e.variants(ctx.db)
.into_iter()
.for_each(|variant| acc.add_enum_variant(ctx, variant, None));
e.ty(ctx.db)
}
hir::PathResolution::Def(hir::ModuleDef::Adt(hir::Adt::Union(u))) => {
u.ty(ctx.db)
}
res @ (hir::PathResolution::TypeParam(_) | hir::PathResolution::SelfType(_)) => {
let ty = match res {
hir::PathResolution::TypeParam(param) => param.ty(ctx.db),
hir::PathResolution::SelfType(impl_def) => impl_def.self_ty(ctx.db),
_ => return,
};
if let Some(hir::Adt::Enum(e)) = ty.as_adt() {
e.variants(ctx.db)
.into_iter()
.for_each(|variant| acc.add_enum_variant(ctx, variant, None));
}
let traits_in_scope = ctx.scope.visible_traits();
let mut seen = FxHashSet::default();
ty.iterate_path_candidates(
@ -165,13 +170,20 @@ fn pattern_path_completion(
ctx.module,
None,
|item| {
// Note associated consts cannot be referenced in patterns
if let AssocItem::TypeAlias(ta) = item {
match item {
AssocItem::TypeAlias(ta) => {
// We might iterate candidates of a trait multiple times here, so deduplicate them.
if seen.insert(item) {
acc.add_type_alias(ctx, ta);
}
}
AssocItem::Const(c) => {
if seen.insert(item) {
acc.add_const(ctx, c);
}
}
_ => {}
}
None::<()>
},
);

View File

@ -306,6 +306,7 @@ fn func() {
ev TupleV() TupleV(u32)
ev RecordV {} RecordV { field: u32 }
ev UnitV UnitV
ct ASSOC_CONST const ASSOC_CONST: ()
"#]],
);
}
@ -444,3 +445,75 @@ fn foo() {
expect![[r#""#]],
);
}
#[test]
fn completes_associated_const() {
check_empty(
r#"
#[derive(PartialEq, Eq)]
struct Ty(u8);
impl Ty {
const ABC: Self = Self(0);
}
fn f(t: Ty) {
match t {
Ty::$0 => {}
_ => {}
}
}
"#,
expect![[r#"
ct ABC const ABC: Self
"#]],
);
check_empty(
r#"
enum MyEnum {}
impl MyEnum {
pub const A: i32 = 123;
pub const B: i32 = 456;
}
fn f(e: MyEnum) {
match e {
MyEnum::$0 => {}
_ => {}
}
}
"#,
expect![[r#"
ct A pub const A: i32
ct B pub const B: i32
"#]],
);
check_empty(
r#"
#[repr(C)]
union U {
i: i32,
f: f32,
}
impl U {
pub const C: i32 = 123;
pub const D: i32 = 456;
}
fn f(u: U) {
match u {
U::$0 => {}
_ => {}
}
}
"#,
expect![[r#"
ct C pub const C: i32
ct D pub const D: i32
"#]],
)
}