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

Lines changed: 11 additions & 1 deletion
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

Lines changed: 2 additions & 0 deletions
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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 3 additions & 3 deletions
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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 2 additions & 2 deletions
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

Lines changed: 4 additions & 4 deletions
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

0 commit comments

Comments
 (0)