From 416195ecea18bffc835dc0fcf2a3d35d08f8619f Mon Sep 17 00:00:00 2001 From: pierwill Date: Thu, 17 Mar 2022 15:17:06 -0500 Subject: [PATCH 1/4] Add duplicate trait bound lint Co-authored-by: Esteban Kuber --- compiler/rustc_lint/src/lib.rs | 1 + compiler/rustc_lint/src/traits.rs | 43 +++++++++++++++++++ src/test/ui/traits/duplicate-trait-bounds.rs | 12 ++++++ .../ui/traits/duplicate-trait-bounds.stderr | 15 +++++++ 4 files changed, 71 insertions(+) create mode 100644 src/test/ui/traits/duplicate-trait-bounds.rs create mode 100644 src/test/ui/traits/duplicate-trait-bounds.stderr diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index aaee0caa070e7..43b2428b28a42 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -209,6 +209,7 @@ macro_rules! late_lint_mod_passes { UnstableFeatures: UnstableFeatures, ArrayIntoIter: ArrayIntoIter::default(), DropTraitConstraints: DropTraitConstraints, + DuplicateTraitBounds: DuplicateTraitBounds, TemporaryCStringAsPtr: TemporaryCStringAsPtr, NonPanicFmt: NonPanicFmt, NoopMethodCall: NoopMethodCall, diff --git a/compiler/rustc_lint/src/traits.rs b/compiler/rustc_lint/src/traits.rs index df1587c5948f5..1be80fa98ef54 100644 --- a/compiler/rustc_lint/src/traits.rs +++ b/compiler/rustc_lint/src/traits.rs @@ -1,6 +1,8 @@ use crate::LateContext; use crate::LateLintPass; use crate::LintContext; +use hir::GenericBound; +use rustc_data_structures::stable_set::FxHashSet; use rustc_errors::fluent; use rustc_hir as hir; use rustc_span::symbol::sym; @@ -132,3 +134,44 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints { } } } + +declare_lint! { + pub DUP_TRAIT_BOUNDS, + Deny, + "duplicate trait bounds" +} + +declare_lint_pass!( + DuplicateTraitBounds => [DUP_TRAIT_BOUNDS] +); + +impl<'tcx> LateLintPass<'tcx> for DuplicateTraitBounds { + fn check_item(&mut self, cx: &LateContext<'_>, item: &'tcx hir::Item<'tcx>) { + let bounds: &[hir::GenericBound<'_>] = match &item.kind { + hir::ItemKind::Trait(_, _, _, bounds, _) => bounds, + hir::ItemKind::TraitAlias(_, bounds) => bounds, + _ => return, + }; + + let mut set = FxHashSet::default(); + for bound in bounds.into_iter() { + match bound { + GenericBound::Trait(polytraitref, _) => { + let Some(did) = polytraitref.trait_ref.trait_def_id() else { continue; }; + // If inserting the trait bound into the set returns `false`, + // there is a duplicate. + if !set.insert(did) { + let span = polytraitref.span; + cx.struct_span_lint(DUP_TRAIT_BOUNDS, span, |lint| { + let msg = format!("Duplicate trait bound"); + lint.build(&msg) + .span_help(span, "Remove this duplicate trait bound") + .emit(); + }); + }; + } + _ => continue, + } + } + } +} diff --git a/src/test/ui/traits/duplicate-trait-bounds.rs b/src/test/ui/traits/duplicate-trait-bounds.rs new file mode 100644 index 0000000000000..246f95d576b44 --- /dev/null +++ b/src/test/ui/traits/duplicate-trait-bounds.rs @@ -0,0 +1,12 @@ +pub trait DirectedGraph {} +pub trait WithStartNode {} +pub trait WithPredecessors {} +pub trait WithSuccessors {} +pub trait WithNumNodes {} + +pub trait ControlFlowGraph: + DirectedGraph + WithStartNode + WithPredecessors + WithStartNode + WithSuccessors + WithNumNodes + //~ ERROR duplicate trait bound +{} + +fn main() {} diff --git a/src/test/ui/traits/duplicate-trait-bounds.stderr b/src/test/ui/traits/duplicate-trait-bounds.stderr new file mode 100644 index 0000000000000..ba39e68f5415e --- /dev/null +++ b/src/test/ui/traits/duplicate-trait-bounds.stderr @@ -0,0 +1,15 @@ +error: Duplicate trait bound + --> $DIR/duplicate-trait-bounds.rs:8:56 + | +LL | DirectedGraph + WithStartNode + WithPredecessors + WithStartNode + WithSuccessors + WithNumNodes + | ^^^^^^^^^^^^^ + | + = note: `#[deny(dup_trait_bounds)]` on by default +help: Remove this duplicate trait bound + --> $DIR/duplicate-trait-bounds.rs:8:56 + | +LL | DirectedGraph + WithStartNode + WithPredecessors + WithStartNode + WithSuccessors + WithNumNodes + | ^^^^^^^^^^^^^ + +error: aborting due to previous error + From f0c5c3085bfe9f2da07cd6484d9c61af5a60e0a9 Mon Sep 17 00:00:00 2001 From: pierwill Date: Wed, 20 Jul 2022 12:07:31 -0500 Subject: [PATCH 2/4] Bless test --- compiler/rustc_lint/src/traits.rs | 4 ++-- src/test/ui/traits/duplicate-trait-bounds.stderr | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_lint/src/traits.rs b/compiler/rustc_lint/src/traits.rs index 1be80fa98ef54..5a4c0a875dd9d 100644 --- a/compiler/rustc_lint/src/traits.rs +++ b/compiler/rustc_lint/src/traits.rs @@ -138,7 +138,7 @@ impl<'tcx> LateLintPass<'tcx> for DropTraitConstraints { declare_lint! { pub DUP_TRAIT_BOUNDS, Deny, - "duplicate trait bounds" + "Duplicate trait bounds are meaningless" } declare_lint_pass!( @@ -163,7 +163,7 @@ impl<'tcx> LateLintPass<'tcx> for DuplicateTraitBounds { if !set.insert(did) { let span = polytraitref.span; cx.struct_span_lint(DUP_TRAIT_BOUNDS, span, |lint| { - let msg = format!("Duplicate trait bound"); + let msg = format!("duplicate trait bound"); lint.build(&msg) .span_help(span, "Remove this duplicate trait bound") .emit(); diff --git a/src/test/ui/traits/duplicate-trait-bounds.stderr b/src/test/ui/traits/duplicate-trait-bounds.stderr index ba39e68f5415e..0ff5f33357540 100644 --- a/src/test/ui/traits/duplicate-trait-bounds.stderr +++ b/src/test/ui/traits/duplicate-trait-bounds.stderr @@ -1,4 +1,4 @@ -error: Duplicate trait bound +error: duplicate trait bound --> $DIR/duplicate-trait-bounds.rs:8:56 | LL | DirectedGraph + WithStartNode + WithPredecessors + WithStartNode + WithSuccessors + WithNumNodes From 486fb44b3f0102787aae23d94a6b27e5451241fe Mon Sep 17 00:00:00 2001 From: pierwill <19642016+pierwill@users.noreply.github.com> Date: Wed, 20 Jul 2022 14:57:30 -0500 Subject: [PATCH 3/4] Update compiler/rustc_lint/src/traits.rs Co-authored-by: Esteban Kuber --- compiler/rustc_lint/src/traits.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_lint/src/traits.rs b/compiler/rustc_lint/src/traits.rs index 5a4c0a875dd9d..107f2e59bb098 100644 --- a/compiler/rustc_lint/src/traits.rs +++ b/compiler/rustc_lint/src/traits.rs @@ -165,7 +165,7 @@ impl<'tcx> LateLintPass<'tcx> for DuplicateTraitBounds { cx.struct_span_lint(DUP_TRAIT_BOUNDS, span, |lint| { let msg = format!("duplicate trait bound"); lint.build(&msg) - .span_help(span, "Remove this duplicate trait bound") + .span_help(span, "remove the duplicate trait bound") .emit(); }); }; From 0b346be62c0dd278d52a6cc30cbb497a929cbbb1 Mon Sep 17 00:00:00 2001 From: pierwill Date: Thu, 21 Jul 2022 09:45:13 -0500 Subject: [PATCH 4/4] rename var --- compiler/rustc_lint/src/traits.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/compiler/rustc_lint/src/traits.rs b/compiler/rustc_lint/src/traits.rs index 107f2e59bb098..d25369f507a31 100644 --- a/compiler/rustc_lint/src/traits.rs +++ b/compiler/rustc_lint/src/traits.rs @@ -161,11 +161,11 @@ impl<'tcx> LateLintPass<'tcx> for DuplicateTraitBounds { // If inserting the trait bound into the set returns `false`, // there is a duplicate. if !set.insert(did) { - let span = polytraitref.span; - cx.struct_span_lint(DUP_TRAIT_BOUNDS, span, |lint| { + let span_of_dup = polytraitref.span; + cx.struct_span_lint(DUP_TRAIT_BOUNDS, span_of_dup, |lint| { let msg = format!("duplicate trait bound"); lint.build(&msg) - .span_help(span, "remove the duplicate trait bound") + .span_help(span_of_dup, "Remove this duplicate trait bound") .emit(); }); };