about summary refs log tree commit diff
diff options
context:
space:
mode:
authorRyo Yoshida <low.ryoshida@gmail.com>2023-06-13 17:32:00 +0900
committerRyo Yoshida <low.ryoshida@gmail.com>2023-06-13 18:01:54 +0900
commitd01283b1f7e36ce81579fa524cd449cd5de7a3d4 (patch)
tree84eb3bb1c577d05845535c220a285a9422a7f92a
parent42eab5e10048869ab5119efd57adc6790f63bad3 (diff)
downloadrust-d01283b1f7e36ce81579fa524cd449cd5de7a3d4.tar.gz
rust-d01283b1f7e36ce81579fa524cd449cd5de7a3d4.zip
Deduplicate tuple indices for completion
-rw-r--r--crates/ide-completion/src/completions/dot.rs30
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 a00c6ecb91f..c5bbb7f8d75 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#"