diff options
| author | Marcel Hellwig <github@cookiesoft.de> | 2022-07-07 12:24:17 +0200 |
|---|---|---|
| committer | Marcel Hellwig <github@cookiesoft.de> | 2022-07-07 12:43:16 +0200 |
| commit | ead2c4f1222c7c9023f02bf6dceaa49eb987c716 (patch) | |
| tree | f8c3b15386e215d627e085afe5e96272f9ea3a36 | |
| parent | f2bef55389e3e053cab50d91a674739d8a1ca036 (diff) | |
| download | rust-ead2c4f1222c7c9023f02bf6dceaa49eb987c716.tar.gz rust-ead2c4f1222c7c9023f02bf6dceaa49eb987c716.zip | |
fix incorrect suggestion for maybe trait bounds
| -rw-r--r-- | clippy_lints/src/trait_bounds.rs | 19 | ||||
| -rw-r--r-- | tests/ui/type_repetition_in_bounds.rs | 12 | ||||
| -rw-r--r-- | 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<T: ?Sized>() +where + T: Clone, +{ +} +pub fn g<T: Clone>() +where + T: ?Sized, +{ +} + // This should not lint fn impl_trait(_: impl AsRef<str>, _: impl AsRef<str>) {} 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 |
