Skip to content

Commit fd9d0bf

Browse files
committed
Forbid ?Trait bounds repetitions
1 parent 2a73553 commit fd9d0bf

File tree

5 files changed

+72
-11
lines changed

5 files changed

+72
-11
lines changed

compiler/rustc_hir_analysis/src/hir_ty_lowering/bounds.rs

+16-10
Original file line numberDiff line numberDiff line change
@@ -75,16 +75,22 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
7575
}
7676
}
7777

78-
if unbounds.len() > 1 && !tcx.features().more_maybe_bounds {
79-
self.tcx()
80-
.sess
81-
.create_feature_err(
82-
errors::MultipleRelaxedDefaultBounds {
83-
spans: unbounds.iter().map(|ptr| ptr.span).collect(),
84-
},
85-
sym::more_maybe_bounds,
86-
)
87-
.emit();
78+
let mut unique_bounds = FxIndexSet::default();
79+
let mut seen_repeat = false;
80+
for unbound in &unbounds {
81+
if let Res::Def(DefKind::Trait, unbound_def_id) = unbound.trait_ref.path.res {
82+
seen_repeat |= !unique_bounds.insert(unbound_def_id);
83+
}
84+
}
85+
if unbounds.len() > 1 {
86+
let err = errors::MultipleRelaxedDefaultBounds {
87+
spans: unbounds.iter().map(|ptr| ptr.span).collect(),
88+
};
89+
if seen_repeat {
90+
self.dcx().emit_err(err);
91+
} else if !tcx.features().more_maybe_bounds {
92+
self.tcx().sess.create_feature_err(err, sym::more_maybe_bounds).emit();
93+
};
8894
}
8995

9096
let mut seen_sized_unbound = false;

tests/ui/feature-gates/feature-gate-more-maybe-bounds.rs

+7
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,11 @@ fn bar<T: ?Trait1 + ?Trait2>(_: T) {}
1414
//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
1515
//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
1616

17+
trait Trait {}
18+
// Do not suggest `#![feature(more_maybe_bounds)]` for repetitions
19+
fn baz<T: ?Trait + ?Trait>(_ : T) {}
20+
//~^ ERROR type parameter has more than one relaxed default bound, only one is supported
21+
//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
22+
//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
23+
1724
fn main() {}

tests/ui/feature-gates/feature-gate-more-maybe-bounds.stderr

+19-1
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,25 @@ warning: relaxing a default bound only does something for `?Sized`; all other tr
4747
LL | fn bar<T: ?Trait1 + ?Trait2>(_: T) {}
4848
| ^^^^^^^
4949

50-
error: aborting due to 4 previous errors; 2 warnings emitted
50+
error[E0203]: type parameter has more than one relaxed default bound, only one is supported
51+
--> $DIR/feature-gate-more-maybe-bounds.rs:19:11
52+
|
53+
LL | fn baz<T: ?Trait + ?Trait>(_ : T) {}
54+
| ^^^^^^ ^^^^^^
55+
56+
warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
57+
--> $DIR/feature-gate-more-maybe-bounds.rs:19:11
58+
|
59+
LL | fn baz<T: ?Trait + ?Trait>(_ : T) {}
60+
| ^^^^^^
61+
62+
warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
63+
--> $DIR/feature-gate-more-maybe-bounds.rs:19:20
64+
|
65+
LL | fn baz<T: ?Trait + ?Trait>(_ : T) {}
66+
| ^^^^^^
67+
68+
error: aborting due to 5 previous errors; 4 warnings emitted
5169

5270
Some errors have detailed explanations: E0203, E0658.
5371
For more information about an error, try `rustc --explain E0203`.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#![feature(more_maybe_bounds)]
2+
3+
trait Trait {}
4+
fn foo<T: ?Trait + ?Trait>(_: T) {}
5+
//~^ ERROR type parameter has more than one relaxed default bound, only one is supported
6+
//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
7+
//~| WARN relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
8+
9+
fn main() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0203]: type parameter has more than one relaxed default bound, only one is supported
2+
--> $DIR/maybe-polarity-repeated.rs:4:11
3+
|
4+
LL | fn foo<T: ?Trait + ?Trait>(_: T) {}
5+
| ^^^^^^ ^^^^^^
6+
7+
warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
8+
--> $DIR/maybe-polarity-repeated.rs:4:11
9+
|
10+
LL | fn foo<T: ?Trait + ?Trait>(_: T) {}
11+
| ^^^^^^
12+
13+
warning: relaxing a default bound only does something for `?Sized`; all other traits are not bound by default
14+
--> $DIR/maybe-polarity-repeated.rs:4:20
15+
|
16+
LL | fn foo<T: ?Trait + ?Trait>(_: T) {}
17+
| ^^^^^^
18+
19+
error: aborting due to 1 previous error; 2 warnings emitted
20+
21+
For more information about this error, try `rustc --explain E0203`.

0 commit comments

Comments
 (0)