Skip to content

Commit

Permalink
extend duplicate_bounds to handle region where predicates
Browse files Browse the repository at this point in the history
  • Loading branch information
ibraheemdev committed Aug 17, 2021
1 parent ab0a962 commit 9e7c714
Show file tree
Hide file tree
Showing 3 changed files with 123 additions and 39 deletions.
58 changes: 37 additions & 21 deletions compiler/rustc_lint/src/builtin.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3247,27 +3247,43 @@ impl<'tcx> LateLintPass<'tcx> for DuplicateBounds {
}

for predicate in gen.where_clause.predicates {
if let hir::WherePredicate::BoundPredicate(ref bound_predicate) = predicate {
if let hir::TyKind::Path(hir::QPath::Resolved(_, hir::Path { segments, .. })) =
bound_predicate.bounded_ty.kind
{
if let Some(segment) = segments.first() {
if let Some(bounds) = bounds.get_mut(&segment.ident) {
for res in bound_predicate.bounds.iter().filter_map(Bound::from_generic)
{
let span = res.span.clone();
let kind = res.kind.as_str();
if !bounds.insert(res) {
cx.struct_span_lint(DUPLICATE_BOUNDS, span, |lint| {
lint.build(&format!(
"this {} bound has already been specified",
kind
))
.help(&format!("consider removing this {} bound", kind))
.emit()
});
}
}
let res = match &predicate {
hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
bounded_ty:
hir::Ty {
kind:
hir::TyKind::Path(hir::QPath::Resolved(_, hir::Path { segments, .. })),
..
},
bounds,
..
}) => segments.first().map(|s| (s.ident, *bounds)),
hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
lifetime:
hir::Lifetime {
name: hir::LifetimeName::Param(hir::ParamName::Plain(ident)),
..
},
bounds,
..
}) => Some((*ident, *bounds)),
_ => None,
};

if let Some((ident, where_predicate_bounds)) = res {
if let Some(bounds) = bounds.get_mut(&ident) {
for res in where_predicate_bounds.iter().filter_map(Bound::from_generic) {
let span = res.span.clone();
let kind = res.kind.as_str();
if !bounds.insert(res) {
cx.struct_span_lint(DUPLICATE_BOUNDS, span, |lint| {
lint.build(&format!(
"this {} bound has already been specified",
kind
))
.help(&format!("consider removing this {} bound", kind))
.emit()
});
}
}
}
Expand Down
30 changes: 25 additions & 5 deletions src/test/ui/lint/duplicate_bounds.rs
Original file line number Diff line number Diff line change
Expand Up @@ -31,15 +31,18 @@ fn not_dup<T: NotDup, U: NotDup>((t, u): (T, U)) {
unimplemented!();
}

fn dup_lifetimes<'a, 'b: 'a + 'a>() {}
fn dup_lifetimes<'a, 'b: 'a + 'a>()
//~^ ERROR this lifetime bound has already been specified
where
'b: 'a,
//~^ ERROR this lifetime bound has already been specified
{
}

fn dup_lifetimes_generic<'a, T: 'a + 'a>() {}
fn dup_lifetimes_generic<'a, T: 'a + 'a>()
//~^ ERROR this lifetime bound has already been specified

fn dup_lifetimes_where<T: 'static>()
where
T: 'static,
T: 'a,
//~^ ERROR this lifetime bound has already been specified
{
}
Expand All @@ -59,4 +62,21 @@ where
unimplemented!();
}

trait DupStructBound {}
struct DupStruct<T: DupStructBound + DupStructBound>(T)
//~^ ERROR this trait bound has already been specified
where
T: DupStructBound;
//~^ ERROR this trait bound has already been specified

impl<'a, T: 'a + DupStructBound + DupStructBound> DupStruct<T>
//~^ ERROR this trait bound has already been specified
where
T: 'a + DupStructBound,
//~^ ERROR this lifetime bound has already been specified
//~| ERROR this trait bound has already been specified
{
fn _x() {}
}

fn main() {}
74 changes: 61 additions & 13 deletions src/test/ui/lint/duplicate_bounds.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -38,74 +38,122 @@ LL | T: DupWhere + DupWhere,
error: this lifetime bound has already been specified
--> $DIR/duplicate_bounds.rs:34:31
|
LL | fn dup_lifetimes<'a, 'b: 'a + 'a>() {}
LL | fn dup_lifetimes<'a, 'b: 'a + 'a>()
| ^^
|
= help: consider removing this lifetime bound

error: this lifetime bound has already been specified
--> $DIR/duplicate_bounds.rs:37:38
--> $DIR/duplicate_bounds.rs:37:9
|
LL | fn dup_lifetimes_generic<'a, T: 'a + 'a>() {}
LL | 'b: 'a,
| ^^
|
= help: consider removing this lifetime bound

error: this lifetime bound has already been specified
--> $DIR/duplicate_bounds.rs:42:38
|
LL | fn dup_lifetimes_generic<'a, T: 'a + 'a>()
| ^^
|
= help: consider removing this lifetime bound

error: this lifetime bound has already been specified
--> $DIR/duplicate_bounds.rs:42:8
--> $DIR/duplicate_bounds.rs:45:8
|
LL | T: 'static,
| ^^^^^^^
LL | T: 'a,
| ^^
|
= help: consider removing this lifetime bound

error: this trait bound has already been specified
--> $DIR/duplicate_bounds.rs:48:31
--> $DIR/duplicate_bounds.rs:51:31
|
LL | fn everything<T: Everything + Everything, U: Everything + Everything>((t, u): (T, U))
| ^^^^^^^^^^
|
= help: consider removing this trait bound

error: this trait bound has already been specified
--> $DIR/duplicate_bounds.rs:48:59
--> $DIR/duplicate_bounds.rs:51:59
|
LL | fn everything<T: Everything + Everything, U: Everything + Everything>((t, u): (T, U))
| ^^^^^^^^^^
|
= help: consider removing this trait bound

error: this trait bound has already been specified
--> $DIR/duplicate_bounds.rs:52:8
--> $DIR/duplicate_bounds.rs:55:8
|
LL | T: Everything + Everything + Everything,
| ^^^^^^^^^^
|
= help: consider removing this trait bound

error: this trait bound has already been specified
--> $DIR/duplicate_bounds.rs:52:21
--> $DIR/duplicate_bounds.rs:55:21
|
LL | T: Everything + Everything + Everything,
| ^^^^^^^^^^
|
= help: consider removing this trait bound

error: this trait bound has already been specified
--> $DIR/duplicate_bounds.rs:52:34
--> $DIR/duplicate_bounds.rs:55:34
|
LL | T: Everything + Everything + Everything,
| ^^^^^^^^^^
|
= help: consider removing this trait bound

error: this trait bound has already been specified
--> $DIR/duplicate_bounds.rs:56:8
--> $DIR/duplicate_bounds.rs:59:8
|
LL | U: Everything,
| ^^^^^^^^^^
|
= help: consider removing this trait bound

error: aborting due to 13 previous errors
error: this trait bound has already been specified
--> $DIR/duplicate_bounds.rs:66:38
|
LL | struct DupStruct<T: DupStructBound + DupStructBound>(T)
| ^^^^^^^^^^^^^^
|
= help: consider removing this trait bound

error: this trait bound has already been specified
--> $DIR/duplicate_bounds.rs:69:8
|
LL | T: DupStructBound;
| ^^^^^^^^^^^^^^
|
= help: consider removing this trait bound

error: this trait bound has already been specified
--> $DIR/duplicate_bounds.rs:72:35
|
LL | impl<'a, T: 'a + DupStructBound + DupStructBound> DupStruct<T>
| ^^^^^^^^^^^^^^
|
= help: consider removing this trait bound

error: this lifetime bound has already been specified
--> $DIR/duplicate_bounds.rs:75:8
|
LL | T: 'a + DupStructBound,
| ^^
|
= help: consider removing this lifetime bound

error: this trait bound has already been specified
--> $DIR/duplicate_bounds.rs:75:13
|
LL | T: 'a + DupStructBound,
| ^^^^^^^^^^^^^^
|
= help: consider removing this trait bound

error: aborting due to 19 previous errors

0 comments on commit 9e7c714

Please sign in to comment.