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

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

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/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

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

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-
| - 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

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 `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

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

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: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

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/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

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

Lines changed: 4 additions & 0 deletions
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() {}

0 commit comments

Comments
 (0)