@@ -372,21 +372,34 @@ fn suggest_restriction<'tcx>(
372
372
// but instead we choose to suggest replacing all instances of `impl Trait` with `T`
373
373
// where `T: Trait`.
374
374
let mut ty_spans = vec ! [ ] ;
375
- let impl_trait_str = format ! ( "impl {}" , bound_str) ;
376
375
for input in fn_sig. decl . inputs {
377
- if let hir:: TyKind :: Path ( hir:: QPath :: Resolved (
378
- None ,
379
- hir:: Path { segments : [ segment] , .. } ,
380
- ) ) = input. kind
381
- {
382
- if segment. ident . as_str ( ) == impl_trait_str. as_str ( ) {
383
- // `fn foo(t: impl Trait)`
384
- // ^^^^^^^^^^ get this to suggest `T` instead
376
+ struct ReplaceImplTraitVisitor < ' a > {
377
+ ty_spans : & ' a mut Vec < Span > ,
378
+ bound_str : & ' a str ,
379
+ }
380
+ impl < ' a , ' hir > hir:: intravisit:: Visitor < ' hir > for ReplaceImplTraitVisitor < ' a > {
381
+ fn visit_ty ( & mut self , t : & ' hir hir:: Ty < ' hir > ) {
382
+ if let hir:: TyKind :: Path ( hir:: QPath :: Resolved (
383
+ None ,
384
+ hir:: Path { segments : [ segment] , .. } ,
385
+ ) ) = t. kind
386
+ {
387
+ if segment. ident . as_str ( ) . strip_prefix ( "impl " ) . map ( |s| s. trim_start ( ) )
388
+ == Some ( self . bound_str )
389
+ {
390
+ // `fn foo(t: impl Trait)`
391
+ // ^^^^^^^^^^ get this to suggest `T` instead
385
392
386
- // There might be more than one `impl Trait`.
387
- ty_spans. push ( input. span ) ;
393
+ // There might be more than one `impl Trait`.
394
+ self . ty_spans . push ( t. span ) ;
395
+ return ;
396
+ }
397
+ }
398
+ hir:: intravisit:: walk_ty ( self , t) ;
388
399
}
389
400
}
401
+ ReplaceImplTraitVisitor { ty_spans : & mut ty_spans, bound_str : & bound_str }
402
+ . visit_ty ( input) ;
390
403
}
391
404
392
405
let type_param_name = generics. params . next_type_param_name ( Some ( & bound_str) ) ;
@@ -396,7 +409,7 @@ fn suggest_restriction<'tcx>(
396
409
// FIXME: modify the `trait_pred` instead of string shenanigans.
397
410
// Turn `<impl Trait as Foo>::Bar: Qux` into `<T as Foo>::Bar: Qux`.
398
411
let pred = trait_pred. to_predicate ( tcx) . to_string ( ) ;
399
- let pred = pred. replace ( & impl_trait_str , & type_param_name) ;
412
+ let pred = pred. replace ( & format ! ( "impl {}" , bound_str ) , & type_param_name) ;
400
413
let mut sugg = vec ! [
401
414
if let Some ( span) = generics. span_for_param_suggestion( ) {
402
415
( span, format!( ", {}" , type_param) )
@@ -460,6 +473,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
460
473
trait_pred : ty:: PolyTraitPredicate < ' tcx > ,
461
474
body_id : hir:: HirId ,
462
475
) {
476
+ let trait_pred = self . resolve_numeric_literals_with_default ( trait_pred) ;
477
+
463
478
let self_ty = trait_pred. skip_binder ( ) . self_ty ( ) ;
464
479
let ( param_ty, projection) = match self_ty. kind ( ) {
465
480
ty:: Param ( _) => ( true , None ) ,
0 commit comments