@@ -14,8 +14,8 @@ use rustc_errors::{Applicability, Diagnostic, DiagnosticArgValue, IntoDiagnostic
14
14
use rustc_hir as hir;
15
15
use rustc_hir:: def:: DefKind ;
16
16
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 } ;
19
19
use rustc_type_ir:: sty:: TyKind :: * ;
20
20
21
21
impl < ' tcx > IntoDiagnosticArg for Ty < ' tcx > {
@@ -156,10 +156,11 @@ enum SuggestChangingConstraintsMessage<'a> {
156
156
RestrictBoundFurther ,
157
157
RestrictType { ty : & ' a str } ,
158
158
RestrictTypeFurther { ty : & ' a str } ,
159
- RemovingQSized ,
159
+ RemoveMaybeUnsized ,
160
+ ReplaceMaybeUnsizedWithSized ,
160
161
}
161
162
162
- fn suggest_removing_unsized_bound (
163
+ fn suggest_changing_unsized_bound (
163
164
generics : & hir:: Generics < ' _ > ,
164
165
suggestions : & mut Vec < ( Span , String , SuggestChangingConstraintsMessage < ' _ > ) > ,
165
166
param : & hir:: GenericParam < ' _ > ,
@@ -183,12 +184,25 @@ fn suggest_removing_unsized_bound(
183
184
if poly. trait_ref . trait_def_id ( ) != def_id {
184
185
continue ;
185
186
}
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
+ }
192
206
}
193
207
}
194
208
}
@@ -245,7 +259,7 @@ pub fn suggest_constraining_type_params<'a>(
245
259
param. span ,
246
260
format ! ( "this type parameter needs to be `{}`" , constraint) ,
247
261
) ;
248
- suggest_removing_unsized_bound ( generics, & mut suggestions, param, def_id) ;
262
+ suggest_changing_unsized_bound ( generics, & mut suggestions, param, def_id) ;
249
263
}
250
264
}
251
265
@@ -395,9 +409,12 @@ pub fn suggest_constraining_type_params<'a>(
395
409
SuggestChangingConstraintsMessage :: RestrictTypeFurther { ty } => {
396
410
Cow :: from ( format ! ( "consider further restricting type parameter `{}`" , ty) )
397
411
}
398
- SuggestChangingConstraintsMessage :: RemovingQSized => {
412
+ SuggestChangingConstraintsMessage :: RemoveMaybeUnsized => {
399
413
Cow :: from ( "consider removing the `?Sized` bound to make the type parameter `Sized`" )
400
414
}
415
+ SuggestChangingConstraintsMessage :: ReplaceMaybeUnsizedWithSized => {
416
+ Cow :: from ( "consider replacing `?Sized` with `Sized`" )
417
+ }
401
418
} ;
402
419
403
420
err. span_suggestion_verbose ( span, msg, suggestion, applicability) ;
0 commit comments