11use crate :: traits:: { ObligationCause , ObligationCauseCode } ;
22use crate :: ty:: diagnostics:: suggest_constraining_type_param;
3+ use crate :: ty:: print:: { FmtPrinter , Printer } ;
34use crate :: ty:: { self , BoundRegionKind , Region , Ty , TyCtxt } ;
45use rustc_errors:: Applicability :: { MachineApplicable , MaybeIncorrect } ;
56use rustc_errors:: { pluralize, DiagnosticBuilder } ;
@@ -400,14 +401,22 @@ impl<'tcx> TyCtxt<'tcx> {
400401 {
401402 // Synthesize the associated type restriction `Add<Output = Expected>`.
402403 // FIXME: extract this logic for use in other diagnostics.
403- let trait_ref = proj. trait_ref ( self ) ;
404+ let ( trait_ref, assoc_substs ) = proj. trait_ref_and_own_substs ( self ) ;
404405 let path =
405406 self . def_path_str_with_substs ( trait_ref. def_id , trait_ref. substs ) ;
406407 let item_name = self . item_name ( proj. item_def_id ) ;
408+ let item_args = self . format_generic_args ( assoc_substs) ;
409+
407410 let path = if path. ends_with ( '>' ) {
408- format ! ( "{}, {} = {}>" , & path[ ..path. len( ) - 1 ] , item_name, p)
411+ format ! (
412+ "{}, {}{} = {}>" ,
413+ & path[ ..path. len( ) - 1 ] ,
414+ item_name,
415+ item_args,
416+ p
417+ )
409418 } else {
410- format ! ( "{}<{} = {}>" , path, item_name, p)
419+ format ! ( "{}<{}{} = {}>" , path, item_name, item_args , p)
411420 } ;
412421 note = !suggest_constraining_type_param (
413422 self ,
@@ -556,7 +565,7 @@ impl<T> Trait<T> for X {
556565 ty : Ty < ' tcx > ,
557566 ) -> bool {
558567 let assoc = self . associated_item ( proj_ty. item_def_id ) ;
559- let trait_ref = proj_ty. trait_ref ( self ) ;
568+ let ( trait_ref, assoc_substs ) = proj_ty. trait_ref_and_own_substs ( self ) ;
560569 if let Some ( item) = self . hir ( ) . get_if_local ( body_owner_def_id) {
561570 if let Some ( hir_generics) = item. generics ( ) {
562571 // Get the `DefId` for the type parameter corresponding to `A` in `<A as T>::Foo`.
@@ -590,6 +599,7 @@ impl<T> Trait<T> for X {
590599 & trait_ref,
591600 pred. bounds ,
592601 & assoc,
602+ assoc_substs,
593603 ty,
594604 msg,
595605 ) {
@@ -607,6 +617,7 @@ impl<T> Trait<T> for X {
607617 & trait_ref,
608618 param. bounds ,
609619 & assoc,
620+ assoc_substs,
610621 ty,
611622 msg,
612623 ) ;
@@ -692,6 +703,7 @@ impl<T> Trait<T> for X {
692703 db,
693704 self . def_span ( def_id) ,
694705 & assoc,
706+ proj_ty. trait_ref_and_own_substs ( self ) . 1 ,
695707 values. found ,
696708 & msg,
697709 ) {
@@ -856,6 +868,7 @@ fn foo(&self) -> Self::T { String::new() }
856868 trait_ref : & ty:: TraitRef < ' tcx > ,
857869 bounds : hir:: GenericBounds < ' _ > ,
858870 assoc : & ty:: AssocItem ,
871+ assoc_substs : & [ ty:: GenericArg < ' tcx > ] ,
859872 ty : Ty < ' tcx > ,
860873 msg : & str ,
861874 ) -> bool {
@@ -865,7 +878,12 @@ fn foo(&self) -> Self::T { String::new() }
865878 // Relate the type param against `T` in `<A as T>::Foo`.
866879 ptr. trait_ref . trait_def_id ( ) == Some ( trait_ref. def_id )
867880 && self . constrain_associated_type_structured_suggestion (
868- db, ptr. span , assoc, ty, msg,
881+ db,
882+ ptr. span ,
883+ assoc,
884+ assoc_substs,
885+ ty,
886+ msg,
869887 )
870888 }
871889 _ => false ,
@@ -879,6 +897,7 @@ fn foo(&self) -> Self::T { String::new() }
879897 db : & mut DiagnosticBuilder < ' _ > ,
880898 span : Span ,
881899 assoc : & ty:: AssocItem ,
900+ assoc_substs : & [ ty:: GenericArg < ' tcx > ] ,
882901 ty : Ty < ' tcx > ,
883902 msg : & str ,
884903 ) -> bool {
@@ -890,11 +909,20 @@ fn foo(&self) -> Self::T { String::new() }
890909 let span = Span :: new ( pos, pos, span. ctxt ( ) ) ;
891910 ( span, format ! ( ", {} = {}" , assoc. ident, ty) )
892911 } else {
893- ( span. shrink_to_hi ( ) , format ! ( "<{} = {}>" , assoc. ident, ty) )
912+ let item_args = self . format_generic_args ( assoc_substs) ;
913+ ( span. shrink_to_hi ( ) , format ! ( "<{}{} = {}>" , assoc. ident, item_args, ty) )
894914 } ;
895915 db. span_suggestion_verbose ( span, msg, sugg, MaybeIncorrect ) ;
896916 return true ;
897917 }
898918 false
899919 }
920+
921+ fn format_generic_args ( self , args : & [ ty:: GenericArg < ' tcx > ] ) -> String {
922+ let mut item_args = String :: new ( ) ;
923+ FmtPrinter :: new ( self , & mut item_args, hir:: def:: Namespace :: TypeNS )
924+ . path_generic_args ( Ok , args)
925+ . expect ( "could not write to `String`." ) ;
926+ item_args
927+ }
900928}
0 commit comments