Unnamed repository; edit this file 'description' to name the repository.
Auto merge of #15044 - lowr:fix/deduplicate-compl-fields, r=lnicola
Deduplicate tuple indices for completion
Follow-up to #15026
A tuple struct may dereference to a primitive tuple (though unusual, which is why I previously overlooked this case). We should not show the same tuple index in completion in such cases.
Deduplication of indices among multiple tuple structs is already handled in the previous PR.
| -rw-r--r-- | crates/ide-completion/src/completions/dot.rs | 30 |
1 files changed, 28 insertions, 2 deletions
diff --git a/crates/ide-completion/src/completions/dot.rs b/crates/ide-completion/src/completions/dot.rs index a00c6ecb91..c5bbb7f8d7 100644 --- a/crates/ide-completion/src/completions/dot.rs +++ b/crates/ide-completion/src/completions/dot.rs @@ -113,8 +113,12 @@ fn complete_fields( } } for (i, ty) in receiver.tuple_fields(ctx.db).into_iter().enumerate() { - // Tuple fields are always public (tuple struct fields are handled above). - tuple_index(acc, i, ty); + // Tuples are always the last type in a deref chain, so just check if the name is + // already seen without inserting into the hashset. + if !seen_names.contains(&hir::Name::new_tuple_field(i)) { + // Tuple fields are always public (tuple struct fields are handled above). + tuple_index(acc, i, ty); + } } } } @@ -721,6 +725,28 @@ fn test(a: A) { } #[test] + fn test_tuple_struct_deref_to_tuple_no_same_index() { + check( + r#" +//- minicore: deref +struct A(u8); +impl core::ops::Deref for A { + type Target = (u16, u32); + 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] fn test_completion_works_in_consts() { check( r#" |