Skip to content

Commit 9e7c714

Browse files
committed
extend duplicate_bounds to handle region where predicates
1 parent ab0a962 commit 9e7c714

File tree

3 files changed

+123
-39
lines changed

3 files changed

+123
-39
lines changed

compiler/rustc_lint/src/builtin.rs

+37-21
Original file line numberDiff line numberDiff line change
@@ -3247,27 +3247,43 @@ impl<'tcx> LateLintPass<'tcx> for DuplicateBounds {
32473247
}
32483248

32493249
for predicate in gen.where_clause.predicates {
3250-
if let hir::WherePredicate::BoundPredicate(ref bound_predicate) = predicate {
3251-
if let hir::TyKind::Path(hir::QPath::Resolved(_, hir::Path { segments, .. })) =
3252-
bound_predicate.bounded_ty.kind
3253-
{
3254-
if let Some(segment) = segments.first() {
3255-
if let Some(bounds) = bounds.get_mut(&segment.ident) {
3256-
for res in bound_predicate.bounds.iter().filter_map(Bound::from_generic)
3257-
{
3258-
let span = res.span.clone();
3259-
let kind = res.kind.as_str();
3260-
if !bounds.insert(res) {
3261-
cx.struct_span_lint(DUPLICATE_BOUNDS, span, |lint| {
3262-
lint.build(&format!(
3263-
"this {} bound has already been specified",
3264-
kind
3265-
))
3266-
.help(&format!("consider removing this {} bound", kind))
3267-
.emit()
3268-
});
3269-
}
3270-
}
3250+
let res = match &predicate {
3251+
hir::WherePredicate::BoundPredicate(hir::WhereBoundPredicate {
3252+
bounded_ty:
3253+
hir::Ty {
3254+
kind:
3255+
hir::TyKind::Path(hir::QPath::Resolved(_, hir::Path { segments, .. })),
3256+
..
3257+
},
3258+
bounds,
3259+
..
3260+
}) => segments.first().map(|s| (s.ident, *bounds)),
3261+
hir::WherePredicate::RegionPredicate(hir::WhereRegionPredicate {
3262+
lifetime:
3263+
hir::Lifetime {
3264+
name: hir::LifetimeName::Param(hir::ParamName::Plain(ident)),
3265+
..
3266+
},
3267+
bounds,
3268+
..
3269+
}) => Some((*ident, *bounds)),
3270+
_ => None,
3271+
};
3272+
3273+
if let Some((ident, where_predicate_bounds)) = res {
3274+
if let Some(bounds) = bounds.get_mut(&ident) {
3275+
for res in where_predicate_bounds.iter().filter_map(Bound::from_generic) {
3276+
let span = res.span.clone();
3277+
let kind = res.kind.as_str();
3278+
if !bounds.insert(res) {
3279+
cx.struct_span_lint(DUPLICATE_BOUNDS, span, |lint| {
3280+
lint.build(&format!(
3281+
"this {} bound has already been specified",
3282+
kind
3283+
))
3284+
.help(&format!("consider removing this {} bound", kind))
3285+
.emit()
3286+
});
32713287
}
32723288
}
32733289
}

src/test/ui/lint/duplicate_bounds.rs

+25-5
Original file line numberDiff line numberDiff line change
@@ -31,15 +31,18 @@ fn not_dup<T: NotDup, U: NotDup>((t, u): (T, U)) {
3131
unimplemented!();
3232
}
3333

34-
fn dup_lifetimes<'a, 'b: 'a + 'a>() {}
34+
fn dup_lifetimes<'a, 'b: 'a + 'a>()
3535
//~^ ERROR this lifetime bound has already been specified
36+
where
37+
'b: 'a,
38+
//~^ ERROR this lifetime bound has already been specified
39+
{
40+
}
3641

37-
fn dup_lifetimes_generic<'a, T: 'a + 'a>() {}
42+
fn dup_lifetimes_generic<'a, T: 'a + 'a>()
3843
//~^ ERROR this lifetime bound has already been specified
39-
40-
fn dup_lifetimes_where<T: 'static>()
4144
where
42-
T: 'static,
45+
T: 'a,
4346
//~^ ERROR this lifetime bound has already been specified
4447
{
4548
}
@@ -59,4 +62,21 @@ where
5962
unimplemented!();
6063
}
6164

65+
trait DupStructBound {}
66+
struct DupStruct<T: DupStructBound + DupStructBound>(T)
67+
//~^ ERROR this trait bound has already been specified
68+
where
69+
T: DupStructBound;
70+
//~^ ERROR this trait bound has already been specified
71+
72+
impl<'a, T: 'a + DupStructBound + DupStructBound> DupStruct<T>
73+
//~^ ERROR this trait bound has already been specified
74+
where
75+
T: 'a + DupStructBound,
76+
//~^ ERROR this lifetime bound has already been specified
77+
//~| ERROR this trait bound has already been specified
78+
{
79+
fn _x() {}
80+
}
81+
6282
fn main() {}

src/test/ui/lint/duplicate_bounds.stderr

+61-13
Original file line numberDiff line numberDiff line change
@@ -38,74 +38,122 @@ LL | T: DupWhere + DupWhere,
3838
error: this lifetime bound has already been specified
3939
--> $DIR/duplicate_bounds.rs:34:31
4040
|
41-
LL | fn dup_lifetimes<'a, 'b: 'a + 'a>() {}
41+
LL | fn dup_lifetimes<'a, 'b: 'a + 'a>()
4242
| ^^
4343
|
4444
= help: consider removing this lifetime bound
4545

4646
error: this lifetime bound has already been specified
47-
--> $DIR/duplicate_bounds.rs:37:38
47+
--> $DIR/duplicate_bounds.rs:37:9
4848
|
49-
LL | fn dup_lifetimes_generic<'a, T: 'a + 'a>() {}
49+
LL | 'b: 'a,
50+
| ^^
51+
|
52+
= help: consider removing this lifetime bound
53+
54+
error: this lifetime bound has already been specified
55+
--> $DIR/duplicate_bounds.rs:42:38
56+
|
57+
LL | fn dup_lifetimes_generic<'a, T: 'a + 'a>()
5058
| ^^
5159
|
5260
= help: consider removing this lifetime bound
5361

5462
error: this lifetime bound has already been specified
55-
--> $DIR/duplicate_bounds.rs:42:8
63+
--> $DIR/duplicate_bounds.rs:45:8
5664
|
57-
LL | T: 'static,
58-
| ^^^^^^^
65+
LL | T: 'a,
66+
| ^^
5967
|
6068
= help: consider removing this lifetime bound
6169

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

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

7886
error: this trait bound has already been specified
79-
--> $DIR/duplicate_bounds.rs:52:8
87+
--> $DIR/duplicate_bounds.rs:55:8
8088
|
8189
LL | T: Everything + Everything + Everything,
8290
| ^^^^^^^^^^
8391
|
8492
= help: consider removing this trait bound
8593

8694
error: this trait bound has already been specified
87-
--> $DIR/duplicate_bounds.rs:52:21
95+
--> $DIR/duplicate_bounds.rs:55:21
8896
|
8997
LL | T: Everything + Everything + Everything,
9098
| ^^^^^^^^^^
9199
|
92100
= help: consider removing this trait bound
93101

94102
error: this trait bound has already been specified
95-
--> $DIR/duplicate_bounds.rs:52:34
103+
--> $DIR/duplicate_bounds.rs:55:34
96104
|
97105
LL | T: Everything + Everything + Everything,
98106
| ^^^^^^^^^^
99107
|
100108
= help: consider removing this trait bound
101109

102110
error: this trait bound has already been specified
103-
--> $DIR/duplicate_bounds.rs:56:8
111+
--> $DIR/duplicate_bounds.rs:59:8
104112
|
105113
LL | U: Everything,
106114
| ^^^^^^^^^^
107115
|
108116
= help: consider removing this trait bound
109117

110-
error: aborting due to 13 previous errors
118+
error: this trait bound has already been specified
119+
--> $DIR/duplicate_bounds.rs:66:38
120+
|
121+
LL | struct DupStruct<T: DupStructBound + DupStructBound>(T)
122+
| ^^^^^^^^^^^^^^
123+
|
124+
= help: consider removing this trait bound
125+
126+
error: this trait bound has already been specified
127+
--> $DIR/duplicate_bounds.rs:69:8
128+
|
129+
LL | T: DupStructBound;
130+
| ^^^^^^^^^^^^^^
131+
|
132+
= help: consider removing this trait bound
133+
134+
error: this trait bound has already been specified
135+
--> $DIR/duplicate_bounds.rs:72:35
136+
|
137+
LL | impl<'a, T: 'a + DupStructBound + DupStructBound> DupStruct<T>
138+
| ^^^^^^^^^^^^^^
139+
|
140+
= help: consider removing this trait bound
141+
142+
error: this lifetime bound has already been specified
143+
--> $DIR/duplicate_bounds.rs:75:8
144+
|
145+
LL | T: 'a + DupStructBound,
146+
| ^^
147+
|
148+
= help: consider removing this lifetime bound
149+
150+
error: this trait bound has already been specified
151+
--> $DIR/duplicate_bounds.rs:75:13
152+
|
153+
LL | T: 'a + DupStructBound,
154+
| ^^^^^^^^^^^^^^
155+
|
156+
= help: consider removing this trait bound
157+
158+
error: aborting due to 19 previous errors
111159

0 commit comments

Comments
 (0)