@@ -372,21 +372,34 @@ fn suggest_restriction<'tcx>(
372372 // but instead we choose to suggest replacing all instances of `impl Trait` with `T`
373373 // where `T: Trait`.
374374 let mut ty_spans = vec ! [ ] ;
375- let impl_trait_str = format ! ( "impl {}" , bound_str) ;
376375 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
385392
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) ;
388399 }
389400 }
401+ ReplaceImplTraitVisitor { ty_spans : & mut ty_spans, bound_str : & bound_str }
402+ . visit_ty ( input) ;
390403 }
391404
392405 let type_param_name = generics. params . next_type_param_name ( Some ( & bound_str) ) ;
@@ -396,7 +409,7 @@ fn suggest_restriction<'tcx>(
396409 // FIXME: modify the `trait_pred` instead of string shenanigans.
397410 // Turn `<impl Trait as Foo>::Bar: Qux` into `<T as Foo>::Bar: Qux`.
398411 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) ;
400413 let mut sugg = vec ! [
401414 if let Some ( span) = generics. span_for_param_suggestion( ) {
402415 ( span, format!( ", {}" , type_param) )
@@ -460,6 +473,8 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
460473 trait_pred : ty:: PolyTraitPredicate < ' tcx > ,
461474 body_id : hir:: HirId ,
462475 ) {
476+ let trait_pred = self . resolve_numeric_literals_with_default ( trait_pred) ;
477+
463478 let self_ty = trait_pred. skip_binder ( ) . self_ty ( ) ;
464479 let ( param_ty, projection) = match self_ty. kind ( ) {
465480 ty:: Param ( _) => ( true , None ) ,
0 commit comments