@@ -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}
@@ -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) ;
0 commit comments