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