mirror of
https://github.com/rust-lang/rust-analyzer
synced 2025-01-16 07:03:57 +00:00
Deduplicate field names for completion
This commit is contained in:
parent
b4795507e3
commit
42eab5e100
1 changed files with 50 additions and 2 deletions
|
@ -105,9 +105,12 @@ fn complete_fields(
|
||||||
mut named_field: impl FnMut(&mut Completions, hir::Field, hir::Type),
|
mut named_field: impl FnMut(&mut Completions, hir::Field, hir::Type),
|
||||||
mut tuple_index: impl FnMut(&mut Completions, usize, hir::Type),
|
mut tuple_index: impl FnMut(&mut Completions, usize, hir::Type),
|
||||||
) {
|
) {
|
||||||
|
let mut seen_names = FxHashSet::default();
|
||||||
for receiver in receiver.autoderef(ctx.db) {
|
for receiver in receiver.autoderef(ctx.db) {
|
||||||
for (field, ty) in receiver.fields(ctx.db) {
|
for (field, ty) in receiver.fields(ctx.db) {
|
||||||
named_field(acc, field, ty);
|
if seen_names.insert(field.name(ctx.db)) {
|
||||||
|
named_field(acc, field, ty);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
for (i, ty) in receiver.tuple_fields(ctx.db).into_iter().enumerate() {
|
for (i, ty) in receiver.tuple_fields(ctx.db).into_iter().enumerate() {
|
||||||
// Tuple fields are always public (tuple struct fields are handled above).
|
// Tuple fields are always public (tuple struct fields are handled above).
|
||||||
|
@ -671,6 +674,52 @@ impl T {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_field_no_same_name() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
//- minicore: deref
|
||||||
|
struct A { field: u8 }
|
||||||
|
struct B { field: u16, another: u32 }
|
||||||
|
impl core::ops::Deref for A {
|
||||||
|
type Target = B;
|
||||||
|
fn deref(&self) -> &Self::Target { loop {} }
|
||||||
|
}
|
||||||
|
fn test(a: A) {
|
||||||
|
a.$0
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
fd another u32
|
||||||
|
fd field u8
|
||||||
|
me deref() (use core::ops::Deref) fn(&self) -> &<Self as Deref>::Target
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_tuple_field_no_same_index() {
|
||||||
|
check(
|
||||||
|
r#"
|
||||||
|
//- minicore: deref
|
||||||
|
struct A(u8);
|
||||||
|
struct B(u16, u32);
|
||||||
|
impl core::ops::Deref for A {
|
||||||
|
type Target = B;
|
||||||
|
fn deref(&self) -> &Self::Target { loop {} }
|
||||||
|
}
|
||||||
|
fn test(a: A) {
|
||||||
|
a.$0
|
||||||
|
}
|
||||||
|
"#,
|
||||||
|
expect![[r#"
|
||||||
|
fd 0 u8
|
||||||
|
fd 1 u32
|
||||||
|
me deref() (use core::ops::Deref) fn(&self) -> &<Self as Deref>::Target
|
||||||
|
"#]],
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_completion_works_in_consts() {
|
fn test_completion_works_in_consts() {
|
||||||
check(
|
check(
|
||||||
|
@ -1000,7 +1049,6 @@ fn test(a: A) {
|
||||||
}
|
}
|
||||||
"#,
|
"#,
|
||||||
expect![[r#"
|
expect![[r#"
|
||||||
fd 0 u16
|
|
||||||
fd 0 u8
|
fd 0 u8
|
||||||
me deref() (use core::ops::Deref) fn(&self) -> &<Self as Deref>::Target
|
me deref() (use core::ops::Deref) fn(&self) -> &<Self as Deref>::Target
|
||||||
"#]],
|
"#]],
|
||||||
|
|
Loading…
Reference in a new issue