@@ -336,10 +336,14 @@ pub fn suggest_constraining_type_params<'a>(
336336 }
337337
338338 let constraint = constraints. iter ( ) . map ( |& ( c, _) | c) . collect :: < Vec < _ > > ( ) . join ( " + " ) ;
339- let mut suggest_restrict = |span| {
339+ let mut suggest_restrict = |span, bound_list_non_empty | {
340340 suggestions. push ( (
341341 span,
342- format ! ( " + {}" , constraint) ,
342+ if bound_list_non_empty {
343+ format ! ( " + {}" , constraint)
344+ } else {
345+ format ! ( " {}" , constraint)
346+ } ,
343347 SuggestChangingConstraintsMessage :: RestrictBoundFurther ,
344348 ) )
345349 } ;
@@ -360,7 +364,10 @@ pub fn suggest_constraining_type_params<'a>(
360364 // |
361365 // replace with: `impl Foo + Bar`
362366
363- suggest_restrict ( param. span . shrink_to_hi ( ) ) ;
367+ // `impl Trait` must have at least one trait in the list
368+ let bound_list_non_empty = true ;
369+
370+ suggest_restrict ( param. span . shrink_to_hi ( ) , bound_list_non_empty) ;
364371 continue ;
365372 }
366373
@@ -383,15 +390,25 @@ pub fn suggest_constraining_type_params<'a>(
383390 // --
384391 // |
385392 // replace with: `T: Bar +`
386- suggest_restrict ( span) ;
393+
394+ // `bounds_span_for_suggestions` returns `None` if the list is empty
395+ let bound_list_non_empty = true ;
396+
397+ suggest_restrict ( span, bound_list_non_empty) ;
387398 } else {
399+ let ( colon, span) = match param. colon_span_for_suggestions ( tcx. sess . source_map ( ) ) {
400+ // If there is already a colon after generic, do not suggest adding it again
401+ Some ( sp) => ( "" , sp. shrink_to_hi ( ) ) ,
402+ None => ( ":" , param. span . shrink_to_hi ( ) ) ,
403+ } ;
404+
388405 // If user hasn't provided any bounds, suggest adding a new one:
389406 //
390407 // fn foo<T>(t: T) { ... }
391408 // - help: consider restricting this type parameter with `T: Foo`
392409 suggestions. push ( (
393- param . span . shrink_to_hi ( ) ,
394- format ! ( ": {}" , constraint) ,
410+ span,
411+ format ! ( "{colon} { constraint}" ) ,
395412 SuggestChangingConstraintsMessage :: RestrictType { ty : param_name } ,
396413 ) ) ;
397414 }
@@ -459,17 +476,21 @@ pub fn suggest_constraining_type_params<'a>(
459476 ) ) ;
460477 } else {
461478 let mut param_spans = Vec :: new ( ) ;
479+ let mut non_empty = false ;
462480
463481 for predicate in generics. where_clause . predicates {
464482 if let WherePredicate :: BoundPredicate ( WhereBoundPredicate {
465483 span,
466484 bounded_ty,
485+ bounds,
467486 ..
468487 } ) = predicate
469488 {
470489 if let TyKind :: Path ( QPath :: Resolved ( _, path) ) = & bounded_ty. kind {
471490 if let Some ( segment) = path. segments . first ( ) {
472491 if segment. ident . to_string ( ) == param_name {
492+ non_empty = !bounds. is_empty ( ) ;
493+
473494 param_spans. push ( span) ;
474495 }
475496 }
@@ -478,7 +499,7 @@ pub fn suggest_constraining_type_params<'a>(
478499 }
479500
480501 match param_spans[ ..] {
481- [ & param_span] => suggest_restrict ( param_span. shrink_to_hi ( ) ) ,
502+ [ & param_span] => suggest_restrict ( param_span. shrink_to_hi ( ) , non_empty ) ,
482503 _ => {
483504 suggestions. push ( (
484505 generics. where_clause . tail_span_for_suggestion ( ) ,
0 commit comments