@@ -14,8 +14,8 @@ use rustc_errors::{Applicability, Diagnostic, DiagnosticArgValue, IntoDiagnostic
1414use rustc_hir as hir;
1515use rustc_hir:: def:: DefKind ;
1616use 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 } ;
1919use rustc_type_ir:: sty:: TyKind :: * ;
2020
2121impl < ' 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}
@@ -245,7 +259,7 @@ pub fn suggest_constraining_type_params<'a>(
245259 param. span ,
246260 format ! ( "this type parameter needs to be `{}`" , constraint) ,
247261 ) ;
248- suggest_removing_unsized_bound ( generics, & mut suggestions, param, def_id) ;
262+ suggest_changing_unsized_bound ( generics, & mut suggestions, param, def_id) ;
249263 }
250264 }
251265
@@ -395,9 +409,12 @@ pub fn suggest_constraining_type_params<'a>(
395409 SuggestChangingConstraintsMessage :: RestrictTypeFurther { ty } => {
396410 Cow :: from ( format ! ( "consider further restricting type parameter `{}`" , ty) )
397411 }
398- SuggestChangingConstraintsMessage :: RemovingQSized => {
412+ SuggestChangingConstraintsMessage :: RemoveMaybeUnsized => {
399413 Cow :: from ( "consider removing the `?Sized` bound to make the type parameter `Sized`" )
400414 }
415+ SuggestChangingConstraintsMessage :: ReplaceMaybeUnsizedWithSized => {
416+ Cow :: from ( "consider replacing `?Sized` with `Sized`" )
417+ }
401418 } ;
402419
403420 err. span_suggestion_verbose ( span, msg, suggestion, applicability) ;
0 commit comments