@@ -370,21 +370,34 @@ fn suggest_restriction<'tcx>(
370370 // but instead we choose to suggest replacing all instances of `impl Trait` with `T`
371371 // where `T: Trait`.
372372 let mut ty_spans = vec ! [ ] ;
373- let impl_trait_str = format ! ( "impl {}" , bound_str) ;
374373 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
383390
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) ;
386397 }
387398 }
399+ ReplaceImplTraitVisitor { ty_spans : & mut ty_spans, bound_str : & bound_str }
400+ . visit_ty ( input) ;
388401 }
389402
390403 let type_param_name = generics. params . next_type_param_name ( Some ( & bound_str) ) ;
@@ -394,7 +407,7 @@ fn suggest_restriction<'tcx>(
394407 // FIXME: modify the `trait_pred` instead of string shenanigans.
395408 // Turn `<impl Trait as Foo>::Bar: Qux` into `<T as Foo>::Bar: Qux`.
396409 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) ;
398411 let mut sugg = vec ! [
399412 if let Some ( span) = generics. span_for_param_suggestion( ) {
400413 ( span, format!( ", {}" , type_param) )
@@ -458,6 +471,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
458471 trait_pred : ty:: PolyTraitPredicate < ' tcx > ,
459472 body_id : hir:: HirId ,
460473 ) {
474+ let trait_pred = self . resolve_numeric_literals_with_default ( trait_pred) ;
475+
461476 let self_ty = trait_pred. skip_binder ( ) . self_ty ( ) ;
462477 let ( param_ty, projection) = match self_ty. kind ( ) {
463478 ty:: Param ( _) => ( true , None ) ,
0 commit comments