Skip to content

Commit 342db71

Browse files
committed
Account for ?Sized type parameter bounds
1 parent d216b73 commit 342db71

18 files changed

+76
-72
lines changed

src/librustc/traits/error_reporting/suggestions.rs

+11-1
Original file line numberDiff line numberDiff line change
@@ -145,12 +145,14 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
145145
let param_name = self_ty.to_string();
146146
let constraint = trait_ref.print_only_trait_path().to_string();
147147
if suggest_constraining_type_param(
148+
self.tcx,
148149
generics,
149150
&mut err,
150151
&param_name,
151152
&constraint,
152153
self.tcx.sess.source_map(),
153154
*span,
155+
Some(trait_ref.def_id()),
154156
) {
155157
return;
156158
}
@@ -1652,18 +1654,26 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
16521654

16531655
/// Suggest restricting a type param with a new bound.
16541656
pub fn suggest_constraining_type_param(
1657+
tcx: TyCtxt<'_>,
16551658
generics: &hir::Generics<'_>,
16561659
err: &mut DiagnosticBuilder<'_>,
16571660
param_name: &str,
16581661
constraint: &str,
16591662
source_map: &SourceMap,
16601663
span: Span,
1664+
def_id: Option<DefId>,
16611665
) -> bool {
16621666
let restrict_msg = "consider further restricting this bound";
16631667
if let Some(param) =
16641668
generics.params.iter().filter(|p| p.name.ident().as_str() == param_name).next()
16651669
{
1666-
if param_name.starts_with("impl ") {
1670+
if def_id == tcx.lang_items().sized_trait() {
1671+
// Type parameters are already `Sized` by default.
1672+
err.span_label(
1673+
param.span,
1674+
&format!("this type parameter needs to be `{}`", constraint),
1675+
);
1676+
} else if param_name.starts_with("impl ") {
16671677
// `impl Trait` in argument:
16681678
// `fn foo(x: impl Trait) {}` → `fn foo(t: impl Trait + Trait2) {}`
16691679
err.span_suggestion(

src/librustc_mir/borrow_check/diagnostics/conflict_errors.rs

+2
Original file line numberDiff line numberDiff line change
@@ -217,12 +217,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
217217
tcx.hir().get_generics(tcx.closure_base_def_id(self.mir_def_id))
218218
{
219219
suggest_constraining_type_param(
220+
tcx,
220221
generics,
221222
&mut err,
222223
&param.name.as_str(),
223224
"Copy",
224225
tcx.sess.source_map(),
225226
span,
227+
None,
226228
);
227229
}
228230
}

src/test/ui/consts/too_generic_eval_ice.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ LL | pub struct Foo<A, B>(A, B);
1818
| --------------------------- required by `Foo`
1919
LL |
2020
LL | impl<A, B> Foo<A, B> {
21-
| - help: consider restricting this bound: `A: std::marker::Sized`
21+
| - this type parameter needs to be `std::marker::Sized`
2222
...
2323
LL | [5; Self::HOST_SIZE] == [6; 0]
2424
| ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
@@ -33,7 +33,7 @@ LL | pub struct Foo<A, B>(A, B);
3333
| --------------------------- required by `Foo`
3434
LL |
3535
LL | impl<A, B> Foo<A, B> {
36-
| - help: consider restricting this bound: `B: std::marker::Sized`
36+
| - this type parameter needs to be `std::marker::Sized`
3737
...
3838
LL | [5; Self::HOST_SIZE] == [6; 0]
3939
| ^^^^^^^^^^^^^^^ doesn't have a size known at compile-time

src/test/ui/dst/dst-object-from-unsized-type.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim
22
--> $DIR/dst-object-from-unsized-type.rs:8:23
33
|
44
LL | fn test1<T: ?Sized + Foo>(t: &T) {
5-
| -- help: consider further restricting this bound: `T: std::marker::Sized +`
5+
| - this type parameter needs to be `std::marker::Sized`
66
LL | let u: &dyn Foo = t;
77
| ^ doesn't have a size known at compile-time
88
|
@@ -14,7 +14,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim
1414
--> $DIR/dst-object-from-unsized-type.rs:13:23
1515
|
1616
LL | fn test2<T: ?Sized + Foo>(t: &T) {
17-
| -- help: consider further restricting this bound: `T: std::marker::Sized +`
17+
| - this type parameter needs to be `std::marker::Sized`
1818
LL | let v: &dyn Foo = t as &dyn Foo;
1919
| ^ doesn't have a size known at compile-time
2020
|

src/test/ui/issues/issue-27060-2.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim
22
--> $DIR/issue-27060-2.rs:3:5
33
|
44
LL | pub struct Bad<T: ?Sized> {
5-
| -- help: consider further restricting this bound: `T: std::marker::Sized +`
5+
| - this type parameter needs to be `std::marker::Sized`
66
LL | data: T,
77
| ^^^^^^^ doesn't have a size known at compile-time
88
|

src/test/ui/traits/trait-suggest-where-clause.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0277]: the size for values of type `U` cannot be known at compilation tim
22
--> $DIR/trait-suggest-where-clause.rs:11:20
33
|
44
LL | fn check<T: Iterator, U: ?Sized>() {
5-
| -- help: consider further restricting this bound: `U: std::marker::Sized +`
5+
| - this type parameter needs to be `std::marker::Sized`
66
LL | // suggest a where-clause, if needed
77
LL | mem::size_of::<U>();
88
| ^ doesn't have a size known at compile-time
@@ -19,7 +19,7 @@ error[E0277]: the size for values of type `U` cannot be known at compilation tim
1919
--> $DIR/trait-suggest-where-clause.rs:14:5
2020
|
2121
LL | fn check<T: Iterator, U: ?Sized>() {
22-
| -- help: consider further restricting this bound: `U: std::marker::Sized +`
22+
| - this type parameter needs to be `std::marker::Sized`
2323
...
2424
LL | mem::size_of::<Misc<U>>();
2525
| ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time

src/test/ui/union/union-sized-field.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim
22
--> $DIR/union-sized-field.rs:4:5
33
|
44
LL | union Foo<T: ?Sized> {
5-
| -- help: consider further restricting this bound: `T: std::marker::Sized +`
5+
| - this type parameter needs to be `std::marker::Sized`
66
LL | value: T,
77
| ^^^^^^^^ doesn't have a size known at compile-time
88
|
@@ -14,7 +14,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim
1414
--> $DIR/union-sized-field.rs:9:5
1515
|
1616
LL | struct Foo2<T: ?Sized> {
17-
| -- help: consider further restricting this bound: `T: std::marker::Sized +`
17+
| - this type parameter needs to be `std::marker::Sized`
1818
LL | value: T,
1919
| ^^^^^^^^ doesn't have a size known at compile-time
2020
|
@@ -26,7 +26,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim
2626
--> $DIR/union-sized-field.rs:15:11
2727
|
2828
LL | enum Foo3<T: ?Sized> {
29-
| -- help: consider further restricting this bound: `T: std::marker::Sized +`
29+
| - this type parameter needs to be `std::marker::Sized`
3030
LL | Value(T),
3131
| ^ doesn't have a size known at compile-time
3232
|

src/test/ui/unsized/unsized-bare-typaram.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim
44
LL | fn bar<T: Sized>() { }
55
| --- - required by this bound in `bar`
66
LL | fn foo<T: ?Sized>() { bar::<T>() }
7-
| -- ^ doesn't have a size known at compile-time
7+
| - ^ doesn't have a size known at compile-time
88
| |
9-
| help: consider further restricting this bound: `T: std::marker::Sized +`
9+
| this type parameter needs to be `std::marker::Sized`
1010
|
1111
= help: the trait `std::marker::Sized` is not implemented for `T`
1212
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>

src/test/ui/unsized/unsized-enum.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ LL | enum Foo<U> { FooSome(U), FooNone }
55
| ----------- required by `Foo`
66
LL | fn foo1<T>() { not_sized::<Foo<T>>() } // Hunky dory.
77
LL | fn foo2<T: ?Sized>() { not_sized::<Foo<T>>() }
8-
| -- ^^^^^^ doesn't have a size known at compile-time
8+
| - ^^^^^^ doesn't have a size known at compile-time
99
| |
10-
| help: consider further restricting this bound: `T: std::marker::Sized +`
10+
| this type parameter needs to be `std::marker::Sized`
1111
|
1212
= help: the trait `std::marker::Sized` is not implemented for `T`
1313
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>

src/test/ui/unsized/unsized-enum2.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0277]: the size for values of type `W` cannot be known at compilation tim
22
--> $DIR/unsized-enum2.rs:23:8
33
|
44
LL | enum E<W: ?Sized, X: ?Sized, Y: ?Sized, Z: ?Sized> {
5-
| -- help: consider further restricting this bound: `W: std::marker::Sized +`
5+
| - this type parameter needs to be `std::marker::Sized`
66
LL | // parameter
77
LL | VA(W),
88
| ^ doesn't have a size known at compile-time
@@ -15,7 +15,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim
1515
--> $DIR/unsized-enum2.rs:25:8
1616
|
1717
LL | enum E<W: ?Sized, X: ?Sized, Y: ?Sized, Z: ?Sized> {
18-
| -- help: consider further restricting this bound: `X: std::marker::Sized +`
18+
| - this type parameter needs to be `std::marker::Sized`
1919
...
2020
LL | VB{x: X},
2121
| ^^^^ doesn't have a size known at compile-time
@@ -28,7 +28,7 @@ error[E0277]: the size for values of type `Y` cannot be known at compilation tim
2828
--> $DIR/unsized-enum2.rs:27:15
2929
|
3030
LL | enum E<W: ?Sized, X: ?Sized, Y: ?Sized, Z: ?Sized> {
31-
| -- help: consider further restricting this bound: `Y: std::marker::Sized +`
31+
| - this type parameter needs to be `std::marker::Sized`
3232
...
3333
LL | VC(isize, Y),
3434
| ^ doesn't have a size known at compile-time
@@ -41,7 +41,7 @@ error[E0277]: the size for values of type `Z` cannot be known at compilation tim
4141
--> $DIR/unsized-enum2.rs:29:18
4242
|
4343
LL | enum E<W: ?Sized, X: ?Sized, Y: ?Sized, Z: ?Sized> {
44-
| -- help: consider further restricting this bound: `Z: std::marker::Sized +`
44+
| - this type parameter needs to be `std::marker::Sized`
4545
...
4646
LL | VD{u: isize, x: Z},
4747
| ^^^^ doesn't have a size known at compile-time

src/test/ui/unsized/unsized-inherent-impl-self-type.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ LL | struct S5<Y>(Y);
55
| ---------------- required by `S5`
66
LL |
77
LL | impl<X: ?Sized> S5<X> {
8-
| -- ^^^^^ doesn't have a size known at compile-time
8+
| - ^^^^^ doesn't have a size known at compile-time
99
| |
10-
| help: consider further restricting this bound: `X: std::marker::Sized +`
10+
| this type parameter needs to be `std::marker::Sized`
1111
|
1212
= help: the trait `std::marker::Sized` is not implemented for `X`
1313
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>

src/test/ui/unsized/unsized-struct.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ LL | struct Foo<T> { data: T }
55
| ------------- required by `Foo`
66
LL | fn foo1<T>() { not_sized::<Foo<T>>() } // Hunky dory.
77
LL | fn foo2<T: ?Sized>() { not_sized::<Foo<T>>() }
8-
| -- ^^^^^^ doesn't have a size known at compile-time
8+
| - ^^^^^^ doesn't have a size known at compile-time
99
| |
10-
| help: consider further restricting this bound: `T: std::marker::Sized +`
10+
| this type parameter needs to be `std::marker::Sized`
1111
|
1212
= help: the trait `std::marker::Sized` is not implemented for `T`
1313
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
@@ -19,9 +19,9 @@ LL | fn is_sized<T:Sized>() { }
1919
| -------- - required by this bound in `is_sized`
2020
...
2121
LL | fn bar2<T: ?Sized>() { is_sized::<Bar<T>>() }
22-
| -- ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
22+
| - ^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
2323
| |
24-
| help: consider further restricting this bound: `T: std::marker::Sized +`
24+
| this type parameter needs to be `std::marker::Sized`
2525
|
2626
= help: within `Bar<T>`, the trait `std::marker::Sized` is not implemented for `T`
2727
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>

src/test/ui/unsized/unsized-trait-impl-self-type.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -5,9 +5,9 @@ LL | struct S5<Y>(Y);
55
| ---------------- required by `S5`
66
LL |
77
LL | impl<X: ?Sized> T3<X> for S5<X> {
8-
| -- ^^^^^ doesn't have a size known at compile-time
8+
| - ^^^^^ doesn't have a size known at compile-time
99
| |
10-
| help: consider further restricting this bound: `X: std::marker::Sized +`
10+
| this type parameter needs to be `std::marker::Sized`
1111
|
1212
= help: the trait `std::marker::Sized` is not implemented for `X`
1313
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>

src/test/ui/unsized/unsized-trait-impl-trait-arg.stderr

+2-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,9 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim
22
--> $DIR/unsized-trait-impl-trait-arg.rs:8:17
33
|
44
LL | impl<X: ?Sized> T2<X> for S4<X> {
5-
| -- ^^^^^ doesn't have a size known at compile-time
5+
| - ^^^^^ doesn't have a size known at compile-time
66
| |
7-
| help: consider further restricting this bound: `X: std::marker::Sized +`
7+
| this type parameter needs to be `std::marker::Sized`
88
|
99
= help: the trait `std::marker::Sized` is not implemented for `X`
1010
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>

src/test/ui/unsized3.stderr

+14-22
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,34 @@
11
error[E0277]: the size for values of type `X` cannot be known at compilation time
22
--> $DIR/unsized3.rs:7:13
33
|
4+
LL | fn f1<X: ?Sized>(x: &X) {
5+
| - this type parameter needs to be `std::marker::Sized`
46
LL | f2::<X>(x);
57
| ^ doesn't have a size known at compile-time
68
...
79
LL | fn f2<X>(x: &X) {
8-
| -- - required by this bound in `f2`
10+
| -- -- help: consider relaxing the implicit `Sized` restriction: `: ?Sized`
11+
| |
12+
| required by this bound in `f2`
913
|
1014
= help: the trait `std::marker::Sized` is not implemented for `X`
1115
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
12-
help: consider further restricting this bound
13-
|
14-
LL | fn f1<X: std::marker::Sized + ?Sized>(x: &X) {
15-
| ^^^^^^^^^^^^^^^^^^^^^^^
16-
help: consider relaxing the implicit `Sized` restriction
17-
|
18-
LL | fn f2<X: ?Sized>(x: &X) {
19-
| ^^^^^^^^
2016

2117
error[E0277]: the size for values of type `X` cannot be known at compilation time
2218
--> $DIR/unsized3.rs:18:13
2319
|
20+
LL | fn f3<X: ?Sized + T>(x: &X) {
21+
| - this type parameter needs to be `std::marker::Sized`
2422
LL | f4::<X>(x);
2523
| ^ doesn't have a size known at compile-time
2624
...
2725
LL | fn f4<X: T>(x: &X) {
28-
| -- - required by this bound in `f4`
26+
| -- - - help: consider relaxing the implicit `Sized` restriction: `+ ?Sized`
27+
| |
28+
| required by this bound in `f4`
2929
|
3030
= help: the trait `std::marker::Sized` is not implemented for `X`
3131
= note: to learn more, visit <https://doc.rust-lang.org/book/ch19-04-advanced-types.html#dynamically-sized-types-and-the-sized-trait>
32-
help: consider further restricting this bound
33-
|
34-
LL | fn f3<X: std::marker::Sized + ?Sized + T>(x: &X) {
35-
| ^^^^^^^^^^^^^^^^^^^^^^^
36-
help: consider relaxing the implicit `Sized` restriction
37-
|
38-
LL | fn f4<X: T + ?Sized>(x: &X) {
39-
| ^^^^^^^^^
4032

4133
error[E0277]: the size for values of type `X` cannot be known at compilation time
4234
--> $DIR/unsized3.rs:33:8
@@ -45,7 +37,7 @@ LL | fn f5<Y>(x: &Y) {}
4537
| -- - required by this bound in `f5`
4638
...
4739
LL | fn f8<X: ?Sized>(x1: &S<X>, x2: &S<X>) {
48-
| -- help: consider further restricting this bound: `X: std::marker::Sized +`
40+
| - this type parameter needs to be `std::marker::Sized`
4941
LL | f5(x1);
5042
| ^^ doesn't have a size known at compile-time
5143
|
@@ -57,7 +49,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim
5749
--> $DIR/unsized3.rs:40:8
5850
|
5951
LL | fn f9<X: ?Sized>(x1: Box<S<X>>) {
60-
| -- help: consider further restricting this bound: `X: std::marker::Sized +`
52+
| - this type parameter needs to be `std::marker::Sized`
6153
LL | f5(&(*x1, 34));
6254
| ^^^^^^^^^^ doesn't have a size known at compile-time
6355
|
@@ -70,7 +62,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim
7062
--> $DIR/unsized3.rs:45:9
7163
|
7264
LL | fn f10<X: ?Sized>(x1: Box<S<X>>) {
73-
| -- help: consider further restricting this bound: `X: std::marker::Sized +`
65+
| - this type parameter needs to be `std::marker::Sized`
7466
LL | f5(&(32, *x1));
7567
| ^^^^^^^^^ doesn't have a size known at compile-time
7668
|
@@ -87,7 +79,7 @@ LL | fn f5<Y>(x: &Y) {}
8779
| -- - required by this bound in `f5`
8880
...
8981
LL | fn f10<X: ?Sized>(x1: Box<S<X>>) {
90-
| -- help: consider further restricting this bound: `X: std::marker::Sized +`
82+
| - this type parameter needs to be `std::marker::Sized`
9183
LL | f5(&(32, *x1));
9284
| ^^^^^^^^^^ doesn't have a size known at compile-time
9385
|

src/test/ui/unsized5.stderr

+4-4
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim
22
--> $DIR/unsized5.rs:4:5
33
|
44
LL | struct S1<X: ?Sized> {
5-
| -- help: consider further restricting this bound: `X: std::marker::Sized +`
5+
| - this type parameter needs to be `std::marker::Sized`
66
LL | f1: X,
77
| ^^^^^ doesn't have a size known at compile-time
88
|
@@ -14,7 +14,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim
1414
--> $DIR/unsized5.rs:10:5
1515
|
1616
LL | struct S2<X: ?Sized> {
17-
| -- help: consider further restricting this bound: `X: std::marker::Sized +`
17+
| - this type parameter needs to be `std::marker::Sized`
1818
LL | f: isize,
1919
LL | g: X,
2020
| ^^^^ doesn't have a size known at compile-time
@@ -47,7 +47,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim
4747
--> $DIR/unsized5.rs:25:8
4848
|
4949
LL | enum E<X: ?Sized> {
50-
| -- help: consider further restricting this bound: `X: std::marker::Sized +`
50+
| - this type parameter needs to be `std::marker::Sized`
5151
LL | V1(X, isize),
5252
| ^ doesn't have a size known at compile-time
5353
|
@@ -59,7 +59,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim
5959
--> $DIR/unsized5.rs:29:8
6060
|
6161
LL | enum F<X: ?Sized> {
62-
| -- help: consider further restricting this bound: `X: std::marker::Sized +`
62+
| - this type parameter needs to be `std::marker::Sized`
6363
LL | V2{f1: X, f: isize},
6464
| ^^^^^ doesn't have a size known at compile-time
6565
|

0 commit comments

Comments
 (0)