From c30ec5a6fd3ba5e742d14d0a2089b04e43ee4e32 Mon Sep 17 00:00:00 2001 From: Maybe Waffle Date: Fri, 14 Jan 2022 16:38:47 +0300 Subject: [PATCH] Check for duplicate arguments in `#[rustc_must_implement_one_of]` --- compiler/rustc_typeck/src/collect.rs | 26 ++++++++++++++ .../rustc_must_implement_one_of_duplicates.rs | 19 +++++++++++ ...tc_must_implement_one_of_duplicates.stderr | 34 +++++++++++++++++++ 3 files changed, 79 insertions(+) create mode 100644 src/test/ui/traits/default-method/rustc_must_implement_one_of_duplicates.rs create mode 100644 src/test/ui/traits/default-method/rustc_must_implement_one_of_duplicates.stderr 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 +