Skip to content

Commit 8a6f65d

Browse files
committed
Don't reject *multiple* relaxed bounds, reject *duplicate* ones.
Having multiple relaxed bounds like `?Sized + ?Iterator` is actually *fine*. We actually want to reject *duplicate* relaxed bounds like `?Sized + ?Sized` because these most certainly represent a user error. Note that this doesn't mean that we accept more code because a bound like `?Iterator` is still invalid as it's not relaxing a *default* trait and the only way to define / use more default bounds is under the experimental and internal feature `more_maybe_bounds` plus `lang_items` plus unstable flag `-Zexperimental-default-bounds`. Ultimately, this simply *reframes* the diagnostic. The scope of `more_maybe_bounds` / `-Zexperimental-default-bounds` remains unchanged as well.
1 parent e564a69 commit 8a6f65d

13 files changed

+118
-140
lines changed

compiler/rustc_hir_analysis/messages.ftl

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -368,9 +368,6 @@ hir_analysis_missing_type_params =
368368
*[other] parameters
369369
} must be specified on the object type
370370
371-
hir_analysis_multiple_relaxed_default_bounds =
372-
type parameter has more than one relaxed default bound, only one is supported
373-
374371
hir_analysis_must_be_name_of_associated_function = must be a name of an associated function
375372
376373
hir_analysis_must_implement_not_function = not a function

compiler/rustc_hir_analysis/src/errors.rs

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -277,13 +277,6 @@ pub(crate) struct CopyImplOnTypeWithDtor {
277277
pub span: Span,
278278
}
279279

280-
#[derive(Diagnostic)]
281-
#[diag(hir_analysis_multiple_relaxed_default_bounds, code = E0203)]
282-
pub(crate) struct MultipleRelaxedDefaultBounds {
283-
#[primary_span]
284-
pub spans: Vec<Span>,
285-
}
286-
287280
#[derive(Diagnostic)]
288281
#[diag(hir_analysis_copy_impl_on_non_adt, code = E0206)]
289282
pub(crate) struct CopyImplOnNonAdt {

compiler/rustc_hir_analysis/src/hir_ty_lowering/errors.rs

Lines changed: 11 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -41,24 +41,22 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ {
4141
) {
4242
let tcx = self.tcx();
4343

44-
let mut unique_bounds = FxIndexSet::default();
45-
let mut seen_repeat = false;
44+
let mut grouped_bounds = FxIndexMap::<_, Vec<_>>::default();
45+
4646
for bound in &relaxed_bounds {
4747
if let Res::Def(DefKind::Trait, trait_def_id) = bound.trait_ref.path.res {
48-
seen_repeat |= !unique_bounds.insert(trait_def_id);
48+
grouped_bounds.entry(trait_def_id).or_default().push(bound.span);
4949
}
5050
}
5151

52-
if relaxed_bounds.len() > 1 {
53-
let err = errors::MultipleRelaxedDefaultBounds {
54-
spans: relaxed_bounds.iter().map(|ptr| ptr.span).collect(),
55-
};
56-
57-
if seen_repeat {
58-
tcx.dcx().emit_err(err);
59-
} else if !tcx.features().more_maybe_bounds() {
60-
tcx.sess.create_feature_err(err, sym::more_maybe_bounds).emit();
61-
};
52+
for (trait_def_id, spans) in grouped_bounds {
53+
if spans.len() > 1 {
54+
let name = tcx.item_name(trait_def_id);
55+
self.dcx()
56+
.struct_span_err(spans, format!("duplicate relaxed `{name}` bounds"))
57+
.with_code(E0203)
58+
.emit();
59+
}
6260
}
6361

6462
let sized_def_id = tcx.require_lang_item(hir::LangItem::Sized, DUMMY_SP);

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

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,15 +8,7 @@ trait Trait4 where Self: ?Trait1 {} //~ ERROR this relaxed bound is not permitte
88
fn foo(_: Box<dyn Trait1 + ?Trait2>) {}
99
//~^ ERROR relaxed bounds are not permitted in trait object types
1010
fn bar<T: ?Trait1 + ?Trait2>(_: T) {}
11-
//~^ ERROR type parameter has more than one relaxed default bound, only one is supported
12-
//~| ERROR bound modifier `?` can only be applied to `Sized`
13-
//~| ERROR bound modifier `?` can only be applied to `Sized`
14-
15-
trait Trait {}
16-
// Do not suggest `#![feature(more_maybe_bounds)]` for repetitions
17-
fn baz<T: ?Trait + ?Trait>(_ : T) {}
18-
//~^ ERROR type parameter has more than one relaxed default bound, only one is supported
19-
//~| ERROR bound modifier `?` can only be applied to `Sized`
11+
//~^ ERROR bound modifier `?` can only be applied to `Sized`
2012
//~| ERROR bound modifier `?` can only be applied to `Sized`
2113

2214
fn main() {}

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

Lines changed: 2 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -26,15 +26,6 @@ LL | fn foo(_: Box<dyn Trait1 + ?Trait2>) {}
2626
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
2727
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
2828

29-
error[E0203]: type parameter has more than one relaxed default bound, only one is supported
30-
--> $DIR/feature-gate-more-maybe-bounds.rs:10:11
31-
|
32-
LL | fn bar<T: ?Trait1 + ?Trait2>(_: T) {}
33-
| ^^^^^^^ ^^^^^^^
34-
|
35-
= help: add `#![feature(more_maybe_bounds)]` to the crate attributes to enable
36-
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
37-
3829
error: bound modifier `?` can only be applied to `Sized`
3930
--> $DIR/feature-gate-more-maybe-bounds.rs:10:11
4031
|
@@ -47,25 +38,6 @@ error: bound modifier `?` can only be applied to `Sized`
4738
LL | fn bar<T: ?Trait1 + ?Trait2>(_: T) {}
4839
| ^^^^^^^
4940

50-
error[E0203]: type parameter has more than one relaxed default bound, only one is supported
51-
--> $DIR/feature-gate-more-maybe-bounds.rs:17:11
52-
|
53-
LL | fn baz<T: ?Trait + ?Trait>(_ : T) {}
54-
| ^^^^^^ ^^^^^^
55-
56-
error: bound modifier `?` can only be applied to `Sized`
57-
--> $DIR/feature-gate-more-maybe-bounds.rs:17:11
58-
|
59-
LL | fn baz<T: ?Trait + ?Trait>(_ : T) {}
60-
| ^^^^^^
61-
62-
error: bound modifier `?` can only be applied to `Sized`
63-
--> $DIR/feature-gate-more-maybe-bounds.rs:17:20
64-
|
65-
LL | fn baz<T: ?Trait + ?Trait>(_ : T) {}
66-
| ^^^^^^
67-
68-
error: aborting due to 9 previous errors
41+
error: aborting due to 5 previous errors
6942

70-
Some errors have detailed explanations: E0203, E0658.
71-
For more information about an error, try `rustc --explain E0203`.
43+
For more information about this error, try `rustc --explain E0658`.
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
fn dupes<T: ?Sized + ?Sized + ?Iterator + ?Iterator>() {}
2+
//~^ ERROR duplicate relaxed `Sized` bounds
3+
//~| ERROR duplicate relaxed `Iterator` bounds
4+
//~| ERROR bound modifier `?` can only be applied to `Sized`
5+
//~| ERROR bound modifier `?` can only be applied to `Sized`
6+
7+
trait Trait {
8+
// We used to say "type parameter has more than one relaxed default bound"
9+
// even on *associated types* like here. Test that we no longer do that.
10+
type Type: ?Sized + ?Sized;
11+
//~^ ERROR duplicate relaxed `Sized` bounds
12+
//~| ERROR duplicate relaxed `Sized` bounds
13+
}
14+
15+
// We used to emit an additional error about "multiple relaxed default bounds".
16+
// However, multiple relaxed bounds are actually *fine* if they're distinct.
17+
// Ultimately, we still reject this, so we're fine.
18+
fn not_dupes<T: ?Sized + ?Iterator>() {}
19+
//~^ ERROR bound modifier `?` can only be applied to `Sized`
20+
21+
fn main() {}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
error[E0203]: duplicate relaxed `Sized` bounds
2+
--> $DIR/duplicate-relaxed-bounds.rs:1:13
3+
|
4+
LL | fn dupes<T: ?Sized + ?Sized + ?Iterator + ?Iterator>() {}
5+
| ^^^^^^ ^^^^^^
6+
7+
error[E0203]: duplicate relaxed `Iterator` bounds
8+
--> $DIR/duplicate-relaxed-bounds.rs:1:31
9+
|
10+
LL | fn dupes<T: ?Sized + ?Sized + ?Iterator + ?Iterator>() {}
11+
| ^^^^^^^^^ ^^^^^^^^^
12+
13+
error: bound modifier `?` can only be applied to `Sized`
14+
--> $DIR/duplicate-relaxed-bounds.rs:1:31
15+
|
16+
LL | fn dupes<T: ?Sized + ?Sized + ?Iterator + ?Iterator>() {}
17+
| ^^^^^^^^^
18+
19+
error: bound modifier `?` can only be applied to `Sized`
20+
--> $DIR/duplicate-relaxed-bounds.rs:1:43
21+
|
22+
LL | fn dupes<T: ?Sized + ?Sized + ?Iterator + ?Iterator>() {}
23+
| ^^^^^^^^^
24+
25+
error: bound modifier `?` can only be applied to `Sized`
26+
--> $DIR/duplicate-relaxed-bounds.rs:18:26
27+
|
28+
LL | fn not_dupes<T: ?Sized + ?Iterator>() {}
29+
| ^^^^^^^^^
30+
31+
error[E0203]: duplicate relaxed `Sized` bounds
32+
--> $DIR/duplicate-relaxed-bounds.rs:10:16
33+
|
34+
LL | type Type: ?Sized + ?Sized;
35+
| ^^^^^^ ^^^^^^
36+
37+
error[E0203]: duplicate relaxed `Sized` bounds
38+
--> $DIR/duplicate-relaxed-bounds.rs:10:16
39+
|
40+
LL | type Type: ?Sized + ?Sized;
41+
| ^^^^^^ ^^^^^^
42+
|
43+
= note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
44+
45+
error: aborting due to 7 previous errors
46+
47+
For more information about this error, try `rustc --explain E0203`.
Original file line numberDiff line numberDiff line change
@@ -1,39 +1,38 @@
1-
// Regression test for #127441
2-
3-
// Tests that we make the correct suggestion
4-
// in case there are more than one `?Sized`
5-
// bounds on a function parameter
1+
// Test that we emit a correct structured suggestions for dynamically sized ("maybe unsized")
2+
// function parameters.
3+
// We used to emit a butchered suggestion if duplicate relaxed `Sized` bounds were present.
4+
// issue: <https://github.com/rust-lang/rust/issues/127441>.
65

76
use std::fmt::Debug;
87

98
fn foo1<T: ?Sized>(a: T) {}
10-
//~^ ERROR he size for values of type `T` cannot be known at compilation time
9+
//~^ ERROR the size for values of type `T` cannot be known at compilation time
1110

1211
fn foo2<T: ?Sized + ?Sized>(a: T) {}
13-
//~^ ERROR type parameter has more than one relaxed default bound, only one is supported
12+
//~^ ERROR duplicate relaxed `Sized` bounds
1413
//~| ERROR the size for values of type `T` cannot be known at compilation time
1514

1615
fn foo3<T: ?Sized + ?Sized + Debug>(a: T) {}
17-
//~^ ERROR type parameter has more than one relaxed default bound, only one is supported
18-
//~| ERROR he size for values of type `T` cannot be known at compilation time
16+
//~^ ERROR duplicate relaxed `Sized` bounds
17+
//~| ERROR the size for values of type `T` cannot be known at compilation time
1918

2019
fn foo4<T: ?Sized + Debug + ?Sized >(a: T) {}
21-
//~^ ERROR type parameter has more than one relaxed default bound, only one is supported
20+
//~^ ERROR duplicate relaxed `Sized` bounds
2221
//~| ERROR the size for values of type `T` cannot be known at compilation time
2322

2423
fn foo5(_: impl ?Sized) {}
2524
//~^ ERROR the size for values of type `impl ?Sized` cannot be known at compilation time
2625

2726
fn foo6(_: impl ?Sized + ?Sized) {}
28-
//~^ ERROR type parameter has more than one relaxed default bound, only one is supported
27+
//~^ ERROR duplicate relaxed `Sized` bounds
2928
//~| ERROR the size for values of type `impl ?Sized + ?Sized` cannot be known at compilation tim
3029

3130
fn foo7(_: impl ?Sized + ?Sized + Debug) {}
32-
//~^ ERROR type parameter has more than one relaxed default bound, only one is supported
31+
//~^ ERROR duplicate relaxed `Sized` bounds
3332
//~| ERROR the size for values of type `impl ?Sized + ?Sized + Debug` cannot be known at compilation time
3433

3534
fn foo8(_: impl ?Sized + Debug + ?Sized ) {}
36-
//~^ ERROR type parameter has more than one relaxed default bound, only one is supported
35+
//~^ ERROR duplicate relaxed `Sized` bounds
3736
//~| ERROR the size for values of type `impl ?Sized + Debug + ?Sized` cannot be known at compilation time
3837

3938
fn main() {}
Lines changed: 20 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,41 +1,41 @@
1-
error[E0203]: type parameter has more than one relaxed default bound, only one is supported
2-
--> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:12:12
1+
error[E0203]: duplicate relaxed `Sized` bounds
2+
--> $DIR/fix-dyn-sized-fn-param-sugg.rs:11:12
33
|
44
LL | fn foo2<T: ?Sized + ?Sized>(a: T) {}
55
| ^^^^^^ ^^^^^^
66

7-
error[E0203]: type parameter has more than one relaxed default bound, only one is supported
8-
--> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:16:12
7+
error[E0203]: duplicate relaxed `Sized` bounds
8+
--> $DIR/fix-dyn-sized-fn-param-sugg.rs:15:12
99
|
1010
LL | fn foo3<T: ?Sized + ?Sized + Debug>(a: T) {}
1111
| ^^^^^^ ^^^^^^
1212

13-
error[E0203]: type parameter has more than one relaxed default bound, only one is supported
14-
--> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:20:12
13+
error[E0203]: duplicate relaxed `Sized` bounds
14+
--> $DIR/fix-dyn-sized-fn-param-sugg.rs:19:12
1515
|
1616
LL | fn foo4<T: ?Sized + Debug + ?Sized >(a: T) {}
1717
| ^^^^^^ ^^^^^^
1818

19-
error[E0203]: type parameter has more than one relaxed default bound, only one is supported
20-
--> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:27:17
19+
error[E0203]: duplicate relaxed `Sized` bounds
20+
--> $DIR/fix-dyn-sized-fn-param-sugg.rs:26:17
2121
|
2222
LL | fn foo6(_: impl ?Sized + ?Sized) {}
2323
| ^^^^^^ ^^^^^^
2424

25-
error[E0203]: type parameter has more than one relaxed default bound, only one is supported
26-
--> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:31:17
25+
error[E0203]: duplicate relaxed `Sized` bounds
26+
--> $DIR/fix-dyn-sized-fn-param-sugg.rs:30:17
2727
|
2828
LL | fn foo7(_: impl ?Sized + ?Sized + Debug) {}
2929
| ^^^^^^ ^^^^^^
3030

31-
error[E0203]: type parameter has more than one relaxed default bound, only one is supported
32-
--> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:35:17
31+
error[E0203]: duplicate relaxed `Sized` bounds
32+
--> $DIR/fix-dyn-sized-fn-param-sugg.rs:34:17
3333
|
3434
LL | fn foo8(_: impl ?Sized + Debug + ?Sized ) {}
3535
| ^^^^^^ ^^^^^^
3636

3737
error[E0277]: the size for values of type `T` cannot be known at compilation time
38-
--> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:9:23
38+
--> $DIR/fix-dyn-sized-fn-param-sugg.rs:8:23
3939
|
4040
LL | fn foo1<T: ?Sized>(a: T) {}
4141
| - ^ doesn't have a size known at compile-time
@@ -54,7 +54,7 @@ LL | fn foo1<T: ?Sized>(a: &T) {}
5454
| +
5555

5656
error[E0277]: the size for values of type `T` cannot be known at compilation time
57-
--> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:12:32
57+
--> $DIR/fix-dyn-sized-fn-param-sugg.rs:11:32
5858
|
5959
LL | fn foo2<T: ?Sized + ?Sized>(a: T) {}
6060
| - ^ doesn't have a size known at compile-time
@@ -73,7 +73,7 @@ LL | fn foo2<T: ?Sized + ?Sized>(a: &T) {}
7373
| +
7474

7575
error[E0277]: the size for values of type `T` cannot be known at compilation time
76-
--> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:16:40
76+
--> $DIR/fix-dyn-sized-fn-param-sugg.rs:15:40
7777
|
7878
LL | fn foo3<T: ?Sized + ?Sized + Debug>(a: T) {}
7979
| - ^ doesn't have a size known at compile-time
@@ -92,7 +92,7 @@ LL | fn foo3<T: ?Sized + ?Sized + Debug>(a: &T) {}
9292
| +
9393

9494
error[E0277]: the size for values of type `T` cannot be known at compilation time
95-
--> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:20:41
95+
--> $DIR/fix-dyn-sized-fn-param-sugg.rs:19:41
9696
|
9797
LL | fn foo4<T: ?Sized + Debug + ?Sized >(a: T) {}
9898
| - ^ doesn't have a size known at compile-time
@@ -111,7 +111,7 @@ LL | fn foo4<T: ?Sized + Debug + ?Sized >(a: &T) {}
111111
| +
112112

113113
error[E0277]: the size for values of type `impl ?Sized` cannot be known at compilation time
114-
--> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:24:12
114+
--> $DIR/fix-dyn-sized-fn-param-sugg.rs:23:12
115115
|
116116
LL | fn foo5(_: impl ?Sized) {}
117117
| ^^^^^^^^^^^
@@ -131,7 +131,7 @@ LL | fn foo5(_: &impl ?Sized) {}
131131
| +
132132

133133
error[E0277]: the size for values of type `impl ?Sized + ?Sized` cannot be known at compilation time
134-
--> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:27:12
134+
--> $DIR/fix-dyn-sized-fn-param-sugg.rs:26:12
135135
|
136136
LL | fn foo6(_: impl ?Sized + ?Sized) {}
137137
| ^^^^^^^^^^^^^^^^^^^^
@@ -151,7 +151,7 @@ LL | fn foo6(_: &impl ?Sized + ?Sized) {}
151151
| +
152152

153153
error[E0277]: the size for values of type `impl ?Sized + ?Sized + Debug` cannot be known at compilation time
154-
--> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:31:12
154+
--> $DIR/fix-dyn-sized-fn-param-sugg.rs:30:12
155155
|
156156
LL | fn foo7(_: impl ?Sized + ?Sized + Debug) {}
157157
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
@@ -171,7 +171,7 @@ LL | fn foo7(_: &impl ?Sized + ?Sized + Debug) {}
171171
| +
172172

173173
error[E0277]: the size for values of type `impl ?Sized + Debug + ?Sized` cannot be known at compilation time
174-
--> $DIR/bad-suggestionf-for-repeated-unsized-bound-127441.rs:35:12
174+
--> $DIR/fix-dyn-sized-fn-param-sugg.rs:34:12
175175
|
176176
LL | fn foo8(_: impl ?Sized + Debug + ?Sized ) {}
177177
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^

tests/ui/traits/maybe-polarity-repeated.rs

Lines changed: 0 additions & 9 deletions
This file was deleted.

tests/ui/traits/maybe-polarity-repeated.stderr

Lines changed: 0 additions & 21 deletions
This file was deleted.

0 commit comments

Comments
 (0)