about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_typeck/src/collect.rs26
-rw-r--r--src/test/ui/traits/default-method/rustc_must_implement_one_of_duplicates.rs19
-rw-r--r--src/test/ui/traits/default-method/rustc_must_implement_one_of_duplicates.stderr34
3 files changed, 79 insertions, 0 deletions
diff --git a/compiler/rustc_typeck/src/collect.rs b/compiler/rustc_typeck/src/collect.rs
index b95a2b6fa49..23b328b9186 100644
--- a/compiler/rustc_typeck/src/collect.rs
+++ b/compiler/rustc_typeck/src/collect.rs
@@ -1303,6 +1303,32 @@ fn trait_def(tcx: TyCtxt<'_>, def_id: DefId) -> ty::TraitDef {
             });
 
             (errors.count() == 0).then_some(list)
+        })
+        // Check for duplicates
+        .and_then(|list| {
+            let mut set: FxHashSet<&Ident> = FxHashSet::default();
+            let mut no_dups = true;
+
+            for ident in &*list {
+                if let Some(dup) = set.replace(ident) {
+                    let dup2 = set.get(&dup).copied().unwrap(); // We've just inserted it
+
+                    tcx.sess
+                        .struct_span_err(
+                            vec![dup.span, dup2.span],
+                            "Functions names are duplicated",
+                        )
+                        .note(
+                            "All `#[rustc_must_implement_one_of]` arguments \
+                            must be unique",
+                        )
+                        .emit();
+
+                    no_dups = false;
+                }
+            }
+
+            no_dups.then_some(list)
         });
 
     ty::TraitDef::new(
diff --git a/src/test/ui/traits/default-method/rustc_must_implement_one_of_duplicates.rs b/src/test/ui/traits/default-method/rustc_must_implement_one_of_duplicates.rs
new file mode 100644
index 00000000000..56e8fcff0fc
--- /dev/null
+++ b/src/test/ui/traits/default-method/rustc_must_implement_one_of_duplicates.rs
@@ -0,0 +1,19 @@
+#![feature(rustc_attrs)]
+
+#[rustc_must_implement_one_of(a, a)]
+//~^ Functions names are duplicated
+trait Trait {
+    fn a() {}
+}
+
+#[rustc_must_implement_one_of(b, a, a, c, b, c)]
+//~^ Functions names are duplicated
+//~| Functions names are duplicated
+//~| Functions names are duplicated
+trait Trait1 {
+    fn a() {}
+    fn b() {}
+    fn c() {}
+}
+
+fn main() {}
diff --git a/src/test/ui/traits/default-method/rustc_must_implement_one_of_duplicates.stderr b/src/test/ui/traits/default-method/rustc_must_implement_one_of_duplicates.stderr
new file mode 100644
index 00000000000..777beba6182
--- /dev/null
+++ b/src/test/ui/traits/default-method/rustc_must_implement_one_of_duplicates.stderr
@@ -0,0 +1,34 @@
+error: Functions names are duplicated
+  --> $DIR/rustc_must_implement_one_of_duplicates.rs:3:31
+   |
+LL | #[rustc_must_implement_one_of(a, a)]
+   |                               ^  ^
+   |
+   = note: All `#[rustc_must_implement_one_of]` arguments must be unique
+
+error: Functions names are duplicated
+  --> $DIR/rustc_must_implement_one_of_duplicates.rs:9:34
+   |
+LL | #[rustc_must_implement_one_of(b, a, a, c, b, c)]
+   |                                  ^  ^
+   |
+   = note: All `#[rustc_must_implement_one_of]` arguments must be unique
+
+error: Functions names are duplicated
+  --> $DIR/rustc_must_implement_one_of_duplicates.rs:9:31
+   |
+LL | #[rustc_must_implement_one_of(b, a, a, c, b, c)]
+   |                               ^           ^
+   |
+   = note: All `#[rustc_must_implement_one_of]` arguments must be unique
+
+error: Functions names are duplicated
+  --> $DIR/rustc_must_implement_one_of_duplicates.rs:9:40
+   |
+LL | #[rustc_must_implement_one_of(b, a, a, c, b, c)]
+   |                                        ^     ^
+   |
+   = note: All `#[rustc_must_implement_one_of]` arguments must be unique
+
+error: aborting due to 4 previous errors
+