@@ -336,10 +336,14 @@ pub fn suggest_constraining_type_params<'a>(
336
336
}
337
337
338
338
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 | {
340
340
suggestions. push ( (
341
341
span,
342
- format ! ( " + {}" , constraint) ,
342
+ if bound_list_non_empty {
343
+ format ! ( " + {}" , constraint)
344
+ } else {
345
+ format ! ( " {}" , constraint)
346
+ } ,
343
347
SuggestChangingConstraintsMessage :: RestrictBoundFurther ,
344
348
) )
345
349
} ;
@@ -360,7 +364,10 @@ pub fn suggest_constraining_type_params<'a>(
360
364
// |
361
365
// replace with: `impl Foo + Bar`
362
366
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) ;
364
371
continue ;
365
372
}
366
373
@@ -383,15 +390,25 @@ pub fn suggest_constraining_type_params<'a>(
383
390
// --
384
391
// |
385
392
// 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) ;
387
398
} 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
+
388
405
// If user hasn't provided any bounds, suggest adding a new one:
389
406
//
390
407
// fn foo<T>(t: T) { ... }
391
408
// - help: consider restricting this type parameter with `T: Foo`
392
409
suggestions. push ( (
393
- param . span . shrink_to_hi ( ) ,
394
- format ! ( ": {}" , constraint) ,
410
+ span,
411
+ format ! ( "{colon} { constraint}" ) ,
395
412
SuggestChangingConstraintsMessage :: RestrictType { ty : param_name } ,
396
413
) ) ;
397
414
}
@@ -459,17 +476,21 @@ pub fn suggest_constraining_type_params<'a>(
459
476
) ) ;
460
477
} else {
461
478
let mut param_spans = Vec :: new ( ) ;
479
+ let mut non_empty = false ;
462
480
463
481
for predicate in generics. where_clause . predicates {
464
482
if let WherePredicate :: BoundPredicate ( WhereBoundPredicate {
465
483
span,
466
484
bounded_ty,
485
+ bounds,
467
486
..
468
487
} ) = predicate
469
488
{
470
489
if let TyKind :: Path ( QPath :: Resolved ( _, path) ) = & bounded_ty. kind {
471
490
if let Some ( segment) = path. segments . first ( ) {
472
491
if segment. ident . to_string ( ) == param_name {
492
+ non_empty = !bounds. is_empty ( ) ;
493
+
473
494
param_spans. push ( span) ;
474
495
}
475
496
}
@@ -478,7 +499,7 @@ pub fn suggest_constraining_type_params<'a>(
478
499
}
479
500
480
501
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 ) ,
482
503
_ => {
483
504
suggestions. push ( (
484
505
generics. where_clause . tail_span_for_suggestion ( ) ,
0 commit comments