@@ -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
}
@@ -238,14 +252,11 @@ pub fn suggest_constraining_type_params<'a>(
238
252
{
239
253
let mut sized_constraints =
240
254
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 ( ) {
242
256
applicability = Applicability :: MaybeIncorrect ;
243
257
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) ;
249
260
}
250
261
}
251
262
@@ -395,9 +406,12 @@ pub fn suggest_constraining_type_params<'a>(
395
406
SuggestChangingConstraintsMessage :: RestrictTypeFurther { ty } => {
396
407
Cow :: from ( format ! ( "consider further restricting type parameter `{}`" , ty) )
397
408
}
398
- SuggestChangingConstraintsMessage :: RemovingQSized => {
409
+ SuggestChangingConstraintsMessage :: RemoveMaybeUnsized => {
399
410
Cow :: from ( "consider removing the `?Sized` bound to make the type parameter `Sized`" )
400
411
}
412
+ SuggestChangingConstraintsMessage :: ReplaceMaybeUnsizedWithSized => {
413
+ Cow :: from ( "consider replacing `?Sized` with `Sized`" )
414
+ }
401
415
} ;
402
416
403
417
err. span_suggestion_verbose ( span, msg, suggestion, applicability) ;
0 commit comments