From ead2c4f1222c7c9023f02bf6dceaa49eb987c716 Mon Sep 17 00:00:00 2001 From: Marcel Hellwig Date: Thu, 7 Jul 2022 12:24:17 +0200 Subject: [PATCH] fix incorrect suggestion for maybe trait bounds --- clippy_lints/src/trait_bounds.rs | 19 ++++++++++++++----- tests/ui/type_repetition_in_bounds.rs | 12 ++++++++++++ tests/ui/type_repetition_in_bounds.stderr | 18 +++++++++++++++++- 3 files changed, 43 insertions(+), 6 deletions(-) diff --git a/clippy_lints/src/trait_bounds.rs b/clippy_lints/src/trait_bounds.rs index 76b739c48f1..2741179074b 100644 --- a/clippy_lints/src/trait_bounds.rs +++ b/clippy_lints/src/trait_bounds.rs @@ -9,12 +9,12 @@ use rustc_data_structures::unhash::UnhashMap; use rustc_errors::Applicability; use rustc_hir::def::Res; use rustc_hir::{ - GenericBound, Generics, Item, ItemKind, Node, Path, PathSegment, PredicateOrigin, QPath, TraitItem, Ty, TyKind, - WherePredicate, + GenericBound, Generics, Item, ItemKind, Node, Path, PathSegment, PredicateOrigin, QPath, TraitBoundModifier, + TraitItem, Ty, TyKind, WherePredicate, }; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::{declare_tool_lint, impl_lint_pass}; -use rustc_span::Span; +use rustc_span::{BytePos, Span}; declare_clippy_lint! { /// ### What it does @@ -242,8 +242,17 @@ fn check_trait_bound_duplication(cx: &LateContext<'_>, gen: &'_ Generics<'_>) { } fn get_trait_info_from_bound<'a>(bound: &'a GenericBound<'_>) -> Option<(Res, &'a [PathSegment<'a>], Span)> { - if let GenericBound::Trait(t, _) = bound { - Some((t.trait_ref.path.res, t.trait_ref.path.segments, t.span)) + if let GenericBound::Trait(t, tbm) = bound { + let trait_path = t.trait_ref.path; + let trait_span = { + let path_span = trait_path.span; + if let TraitBoundModifier::Maybe = tbm { + path_span.with_lo(path_span.lo() - BytePos(1)) // include the `?` + } else { + path_span + } + }; + Some((trait_path.res, trait_path.segments, trait_span)) } else { None } diff --git a/tests/ui/type_repetition_in_bounds.rs b/tests/ui/type_repetition_in_bounds.rs index d11432f9046..2eca1f4701c 100644 --- a/tests/ui/type_repetition_in_bounds.rs +++ b/tests/ui/type_repetition_in_bounds.rs @@ -79,6 +79,18 @@ where u: U, } +// Check for the `?` in `?Sized` +pub fn f() +where + T: Clone, +{ +} +pub fn g() +where + T: ?Sized, +{ +} + // This should not lint fn impl_trait(_: impl AsRef, _: impl AsRef) {} diff --git a/tests/ui/type_repetition_in_bounds.stderr b/tests/ui/type_repetition_in_bounds.stderr index 148c19c7d07..1d88714814d 100644 --- a/tests/ui/type_repetition_in_bounds.stderr +++ b/tests/ui/type_repetition_in_bounds.stderr @@ -19,5 +19,21 @@ LL | Self: Copy + Default + Ord, | = help: consider combining the bounds: `Self: Clone + Copy + Default + Ord` -error: aborting due to 2 previous errors +error: this type has already been used as a bound predicate + --> $DIR/type_repetition_in_bounds.rs:85:5 + | +LL | T: Clone, + | ^^^^^^^^ + | + = help: consider combining the bounds: `T: ?Sized + Clone` + +error: this type has already been used as a bound predicate + --> $DIR/type_repetition_in_bounds.rs:90:5 + | +LL | T: ?Sized, + | ^^^^^^^^^ + | + = help: consider combining the bounds: `T: Clone + ?Sized` + +error: aborting due to 4 previous errors