Skip to content

Commit af955a6

Browse files
Rollup merge of #112614 - lukas-code:apit-unsized-suggestion, r=compiler-errors
tweak suggestion for argument-position `impl ?Sized` fixes this invalid suggestion: ```text help: consider removing the `?Sized` bound to make the type parameter `Sized` | 1 - fn foo(_: impl ?Sized) {} 1 + fn foo(_: impl ) {} | ```
2 parents d233522 + b6a3f12 commit af955a6

26 files changed

+141
-86
lines changed

compiler/rustc_middle/src/ty/diagnostics.rs

+31-17
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ use rustc_errors::{Applicability, Diagnostic, DiagnosticArgValue, IntoDiagnostic
1414
use rustc_hir as hir;
1515
use rustc_hir::def::DefKind;
1616
use rustc_hir::def_id::DefId;
17-
use rustc_hir::WherePredicate;
18-
use rustc_span::Span;
17+
use rustc_hir::{PredicateOrigin, WherePredicate};
18+
use rustc_span::{BytePos, Span};
1919
use rustc_type_ir::sty::TyKind::*;
2020

2121
impl<'tcx> IntoDiagnosticArg for Ty<'tcx> {
@@ -156,10 +156,11 @@ enum SuggestChangingConstraintsMessage<'a> {
156156
RestrictBoundFurther,
157157
RestrictType { ty: &'a str },
158158
RestrictTypeFurther { ty: &'a str },
159-
RemovingQSized,
159+
RemoveMaybeUnsized,
160+
ReplaceMaybeUnsizedWithSized,
160161
}
161162

162-
fn suggest_removing_unsized_bound(
163+
fn suggest_changing_unsized_bound(
163164
generics: &hir::Generics<'_>,
164165
suggestions: &mut Vec<(Span, String, SuggestChangingConstraintsMessage<'_>)>,
165166
param: &hir::GenericParam<'_>,
@@ -183,12 +184,25 @@ fn suggest_removing_unsized_bound(
183184
if poly.trait_ref.trait_def_id() != def_id {
184185
continue;
185186
}
186-
let sp = generics.span_for_bound_removal(where_pos, pos);
187-
suggestions.push((
188-
sp,
189-
String::new(),
190-
SuggestChangingConstraintsMessage::RemovingQSized,
191-
));
187+
if predicate.origin == PredicateOrigin::ImplTrait && predicate.bounds.len() == 1 {
188+
// For `impl ?Sized` with no other bounds, suggest `impl Sized` instead.
189+
let bound_span = bound.span();
190+
if bound_span.can_be_used_for_suggestions() {
191+
let question_span = bound_span.with_hi(bound_span.lo() + BytePos(1));
192+
suggestions.push((
193+
question_span,
194+
String::new(),
195+
SuggestChangingConstraintsMessage::ReplaceMaybeUnsizedWithSized,
196+
));
197+
}
198+
} else {
199+
let sp = generics.span_for_bound_removal(where_pos, pos);
200+
suggestions.push((
201+
sp,
202+
String::new(),
203+
SuggestChangingConstraintsMessage::RemoveMaybeUnsized,
204+
));
205+
}
192206
}
193207
}
194208
}
@@ -238,14 +252,11 @@ pub fn suggest_constraining_type_params<'a>(
238252
{
239253
let mut sized_constraints =
240254
constraints.extract_if(|(_, def_id)| *def_id == tcx.lang_items().sized_trait());
241-
if let Some((constraint, def_id)) = sized_constraints.next() {
255+
if let Some((_, def_id)) = sized_constraints.next() {
242256
applicability = Applicability::MaybeIncorrect;
243257

244-
err.span_label(
245-
param.span,
246-
format!("this type parameter needs to be `{}`", constraint),
247-
);
248-
suggest_removing_unsized_bound(generics, &mut suggestions, param, def_id);
258+
err.span_label(param.span, "this type parameter needs to be `Sized`");
259+
suggest_changing_unsized_bound(generics, &mut suggestions, param, def_id);
249260
}
250261
}
251262

@@ -395,9 +406,12 @@ pub fn suggest_constraining_type_params<'a>(
395406
SuggestChangingConstraintsMessage::RestrictTypeFurther { ty } => {
396407
Cow::from(format!("consider further restricting type parameter `{}`", ty))
397408
}
398-
SuggestChangingConstraintsMessage::RemovingQSized => {
409+
SuggestChangingConstraintsMessage::RemoveMaybeUnsized => {
399410
Cow::from("consider removing the `?Sized` bound to make the type parameter `Sized`")
400411
}
412+
SuggestChangingConstraintsMessage::ReplaceMaybeUnsizedWithSized => {
413+
Cow::from("consider replacing `?Sized` with `Sized`")
414+
}
401415
};
402416

403417
err.span_suggestion_verbose(span, msg, suggestion, applicability);

tests/ui/const-generics/const-argument-if-length.full.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/const-argument-if-length.rs:15:12
33
|
44
LL | pub struct AtLeastByte<T: ?Sized> {
5-
| - this type parameter needs to be `std::marker::Sized`
5+
| - this type parameter needs to be `Sized`
66
LL | value: T,
77
| ^ doesn't have a size known at compile-time
88
|

tests/ui/const-generics/const-argument-if-length.min.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim
1111
--> $DIR/const-argument-if-length.rs:15:12
1212
|
1313
LL | pub struct AtLeastByte<T: ?Sized> {
14-
| - this type parameter needs to be `std::marker::Sized`
14+
| - this type parameter needs to be `Sized`
1515
LL | value: T,
1616
| ^ doesn't have a size known at compile-time
1717
|

tests/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-
| - this type parameter needs to be `std::marker::Sized`
5+
| - this type parameter needs to be `Sized`
66
LL | let u: &dyn Foo = t;
77
| ^ doesn't have a size known at compile-time
88
|
@@ -17,7 +17,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim
1717
--> $DIR/dst-object-from-unsized-type.rs:13:23
1818
|
1919
LL | fn test2<T: ?Sized + Foo>(t: &T) {
20-
| - this type parameter needs to be `std::marker::Sized`
20+
| - this type parameter needs to be `Sized`
2121
LL | let v: &dyn Foo = t as &dyn Foo;
2222
| ^ doesn't have a size known at compile-time
2323
|

tests/ui/generic-associated-types/issue-88287.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ error[E0277]: the size for values of type `A` cannot be known at compilation tim
22
--> $DIR/issue-88287.rs:34:9
33
|
44
LL | type SearchFutureTy<'f, A, B: 'f>
5-
| - this type parameter needs to be `std::marker::Sized`
5+
| - this type parameter needs to be `Sized`
66
...
77
LL | async move { todo!() }
88
| ^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time

tests/ui/offset-of/offset-of-dst-field.stderr

+1-1
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim
7070
--> $DIR/offset-of-dst-field.rs:50:5
7171
|
7272
LL | fn generic_with_maybe_sized<T: ?Sized>() -> usize {
73-
| - this type parameter needs to be `std::marker::Sized`
73+
| - this type parameter needs to be `Sized`
7474
LL | offset_of!(Delta<T>, z)
7575
| ^^^^^^^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time
7676
|

tests/ui/packed/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:11
33
|
44
LL | pub struct Bad<T: ?Sized> {
5-
| - this type parameter needs to be `std::marker::Sized`
5+
| - this type parameter needs to be `Sized`
66
LL | data: T,
77
| ^ doesn't have a size known at compile-time
88
|

tests/ui/suggestions/adt-param-with-implicit-sized-bound.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/adt-param-with-implicit-sized-bound.rs:25:9
33
|
44
LL | struct Struct5<T: ?Sized>{
5-
| - this type parameter needs to be `std::marker::Sized`
5+
| - this type parameter needs to be `Sized`
66
LL | _t: X<T>,
77
| ^^^^ doesn't have a size known at compile-time
88
|

tests/ui/suggestions/removal-of-multiline-trait-bound-in-where-clause.stderr

+3-3
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim
44
LL | fn foo<T>(foo: Wrapper<T>)
55
| - ^^^^^^^^^^ doesn't have a size known at compile-time
66
| |
7-
| this type parameter needs to be `std::marker::Sized`
7+
| this type parameter needs to be `Sized`
88
|
99
note: required by a bound in `Wrapper`
1010
--> $DIR/removal-of-multiline-trait-bound-in-where-clause.rs:1:16
@@ -33,7 +33,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim
3333
LL | fn bar<T>(foo: Wrapper<T>)
3434
| - ^^^^^^^^^^ doesn't have a size known at compile-time
3535
| |
36-
| this type parameter needs to be `std::marker::Sized`
36+
| this type parameter needs to be `Sized`
3737
|
3838
note: required by a bound in `Wrapper`
3939
--> $DIR/removal-of-multiline-trait-bound-in-where-clause.rs:1:16
@@ -58,7 +58,7 @@ error[E0277]: the size for values of type `T` cannot be known at compilation tim
5858
LL | fn qux<T>(foo: Wrapper<T>)
5959
| - ^^^^^^^^^^ doesn't have a size known at compile-time
6060
| |
61-
| this type parameter needs to be `std::marker::Sized`
61+
| this type parameter needs to be `Sized`
6262
|
6363
note: required by a bound in `Wrapper`
6464
--> $DIR/removal-of-multiline-trait-bound-in-where-clause.rs:1:16

tests/ui/trait-bounds/apit-unsized.rs

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
fn foo(_: impl Iterator<Item = i32> + ?Sized) {} //~ ERROR [E0277]
2+
fn bar(_: impl ?Sized) {} //~ ERROR [E0277]
3+
4+
fn main() {}
+41
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
error[E0277]: the size for values of type `impl Iterator<Item = i32> + ?Sized` cannot be known at compilation time
2+
--> $DIR/apit-unsized.rs:1:8
3+
|
4+
LL | fn foo(_: impl Iterator<Item = i32> + ?Sized) {}
5+
| ^ ---------------------------------- this type parameter needs to be `Sized`
6+
| |
7+
| doesn't have a size known at compile-time
8+
|
9+
= help: unsized fn params are gated as an unstable feature
10+
help: consider removing the `?Sized` bound to make the type parameter `Sized`
11+
|
12+
LL - fn foo(_: impl Iterator<Item = i32> + ?Sized) {}
13+
LL + fn foo(_: impl Iterator<Item = i32>) {}
14+
|
15+
help: function arguments must have a statically known size, borrowed types always have a known size
16+
|
17+
LL | fn foo(_: &impl Iterator<Item = i32> + ?Sized) {}
18+
| +
19+
20+
error[E0277]: the size for values of type `impl ?Sized` cannot be known at compilation time
21+
--> $DIR/apit-unsized.rs:2:8
22+
|
23+
LL | fn bar(_: impl ?Sized) {}
24+
| ^ ----------- this type parameter needs to be `Sized`
25+
| |
26+
| doesn't have a size known at compile-time
27+
|
28+
= help: unsized fn params are gated as an unstable feature
29+
help: consider replacing `?Sized` with `Sized`
30+
|
31+
LL - fn bar(_: impl ?Sized) {}
32+
LL + fn bar(_: impl Sized) {}
33+
|
34+
help: function arguments must have a statically known size, borrowed types always have a known size
35+
|
36+
LL | fn bar(_: &impl ?Sized) {}
37+
| +
38+
39+
error: aborting due to 2 previous errors
40+
41+
For more information about this error, try `rustc --explain E0277`.

tests/ui/trait-bounds/unsized-bound.stderr

+13-17
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ error[E0277]: the size for values of type `B` cannot be known at compilation tim
44
LL | impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {}
55
| - ^^^^^^ doesn't have a size known at compile-time
66
| |
7-
| this type parameter needs to be `std::marker::Sized`
7+
| this type parameter needs to be `Sized`
88
|
99
= note: required because it appears within the type `(A, B)`
1010
note: required by a bound in `Trait`
@@ -28,7 +28,7 @@ error[E0277]: the size for values of type `A` cannot be known at compilation tim
2828
LL | impl<A, B> Trait<(A, B)> for (A, B) where A: ?Sized, B: ?Sized, {}
2929
| - ^^^^^^ doesn't have a size known at compile-time
3030
| |
31-
| this type parameter needs to be `std::marker::Sized`
31+
| this type parameter needs to be `Sized`
3232
|
3333
= note: only the last element of a tuple may have a dynamically sized type
3434
help: consider removing the `?Sized` bound to make the type parameter `Sized`
@@ -43,7 +43,7 @@ error[E0277]: the size for values of type `C` cannot be known at compilation tim
4343
LL | impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
4444
| - ^^^^^^^^^ doesn't have a size known at compile-time
4545
| |
46-
| this type parameter needs to be `std::marker::Sized`
46+
| this type parameter needs to be `Sized`
4747
|
4848
= note: required because it appears within the type `(A, B, C)`
4949
note: required by a bound in `Trait`
@@ -65,9 +65,7 @@ error[E0277]: the size for values of type `A` cannot be known at compilation tim
6565
--> $DIR/unsized-bound.rs:5:52
6666
|
6767
LL | impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
68-
| - ^^^^^^^^^ doesn't have a size known at compile-time
69-
| |
70-
| this type parameter needs to be `std::marker::Sized`
68+
| - this type parameter needs to be `Sized` ^^^^^^^^^ doesn't have a size known at compile-time
7169
|
7270
= note: only the last element of a tuple may have a dynamically sized type
7371
help: consider removing the `?Sized` bound to make the type parameter `Sized`
@@ -80,9 +78,7 @@ error[E0277]: the size for values of type `B` cannot be known at compilation tim
8078
--> $DIR/unsized-bound.rs:5:52
8179
|
8280
LL | impl<A, B: ?Sized, C: ?Sized> Trait<(A, B, C)> for (A, B, C) where A: ?Sized, {}
83-
| - ^^^^^^^^^ doesn't have a size known at compile-time
84-
| |
85-
| this type parameter needs to be `std::marker::Sized`
81+
| - this type parameter needs to be `Sized` ^^^^^^^^^ doesn't have a size known at compile-time
8682
|
8783
= note: only the last element of a tuple may have a dynamically sized type
8884
help: consider removing the `?Sized` bound to make the type parameter `Sized`
@@ -97,7 +93,7 @@ error[E0277]: the size for values of type `B` cannot be known at compilation tim
9793
LL | impl<A: ?Sized, B: ?Sized> Trait2<(A, B)> for (A, B) {}
9894
| - ^^^^^^ doesn't have a size known at compile-time
9995
| |
100-
| this type parameter needs to be `std::marker::Sized`
96+
| this type parameter needs to be `Sized`
10197
|
10298
= note: required because it appears within the type `(A, B)`
10399
note: required by a bound in `Trait2`
@@ -121,7 +117,7 @@ error[E0277]: the size for values of type `A` cannot be known at compilation tim
121117
LL | impl<A: ?Sized, B: ?Sized> Trait2<(A, B)> for (A, B) {}
122118
| - ^^^^^^ doesn't have a size known at compile-time
123119
| |
124-
| this type parameter needs to be `std::marker::Sized`
120+
| this type parameter needs to be `Sized`
125121
|
126122
= note: only the last element of a tuple may have a dynamically sized type
127123
help: consider removing the `?Sized` bound to make the type parameter `Sized`
@@ -136,7 +132,7 @@ error[E0277]: the size for values of type `A` cannot be known at compilation tim
136132
LL | impl<A> Trait3<A> for A where A: ?Sized {}
137133
| - ^ doesn't have a size known at compile-time
138134
| |
139-
| this type parameter needs to be `std::marker::Sized`
135+
| this type parameter needs to be `Sized`
140136
|
141137
note: required by a bound in `Trait3`
142138
--> $DIR/unsized-bound.rs:13:14
@@ -159,7 +155,7 @@ error[E0277]: the size for values of type `A` cannot be known at compilation tim
159155
LL | impl<A: ?Sized> Trait4<A> for A {}
160156
| - ^ doesn't have a size known at compile-time
161157
| |
162-
| this type parameter needs to be `std::marker::Sized`
158+
| this type parameter needs to be `Sized`
163159
|
164160
note: required by a bound in `Trait4`
165161
--> $DIR/unsized-bound.rs:16:14
@@ -182,7 +178,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim
182178
LL | impl<X, Y> Trait5<X, Y> for X where X: ?Sized {}
183179
| - ^ doesn't have a size known at compile-time
184180
| |
185-
| this type parameter needs to be `std::marker::Sized`
181+
| this type parameter needs to be `Sized`
186182
|
187183
note: required by a bound in `Trait5`
188184
--> $DIR/unsized-bound.rs:19:14
@@ -205,7 +201,7 @@ error[E0277]: the size for values of type `X` cannot be known at compilation tim
205201
LL | impl<X: ?Sized, Y> Trait6<X, Y> for X {}
206202
| - ^ doesn't have a size known at compile-time
207203
| |
208-
| this type parameter needs to be `std::marker::Sized`
204+
| this type parameter needs to be `Sized`
209205
|
210206
note: required by a bound in `Trait6`
211207
--> $DIR/unsized-bound.rs:22:14
@@ -228,7 +224,7 @@ error[E0277]: the size for values of type `Y` cannot be known at compilation tim
228224
LL | impl<X, Y> Trait7<X, Y> for X where Y: ?Sized {}
229225
| - ^^^^^^^^^^^^ doesn't have a size known at compile-time
230226
| |
231-
| this type parameter needs to be `std::marker::Sized`
227+
| this type parameter needs to be `Sized`
232228
|
233229
note: required by a bound in `Trait7`
234230
--> $DIR/unsized-bound.rs:25:17
@@ -251,7 +247,7 @@ error[E0277]: the size for values of type `Y` cannot be known at compilation tim
251247
LL | impl<X, Y: ?Sized> Trait8<X, Y> for X {}
252248
| - ^^^^^^^^^^^^ doesn't have a size known at compile-time
253249
| |
254-
| this type parameter needs to be `std::marker::Sized`
250+
| this type parameter needs to be `Sized`
255251
|
256252
note: required by a bound in `Trait8`
257253
--> $DIR/unsized-bound.rs:28:17

tests/ui/traits/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/suggest-where-clause.rs:7:20
33
|
44
LL | fn check<T: Iterator, U: ?Sized>() {
5-
| - this type parameter needs to be `std::marker::Sized`
5+
| - this type parameter needs to be `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/suggest-where-clause.rs:10:20
2020
|
2121
LL | fn check<T: Iterator, U: ?Sized>() {
22-
| - this type parameter needs to be `std::marker::Sized`
22+
| - this type parameter needs to be `Sized`
2323
...
2424
LL | mem::size_of::<Misc<U>>();
2525
| ^^^^^^^ doesn't have a size known at compile-time

0 commit comments

Comments
 (0)