@@ -4,7 +4,7 @@ use super::{
44use crate :: infer:: InferCtxt ;
55use rustc_hir as hir;
66use rustc_hir:: def_id:: DefId ;
7- use rustc_middle:: ty:: subst:: Subst ;
7+ use rustc_middle:: ty:: subst:: { Subst , SubstsRef } ;
88use rustc_middle:: ty:: { self , GenericParamDefKind } ;
99use rustc_span:: symbol:: sym;
1010use std:: iter;
@@ -17,7 +17,7 @@ crate trait InferCtxtExt<'tcx> {
1717 & self ,
1818 trait_ref : ty:: PolyTraitRef < ' tcx > ,
1919 obligation : & PredicateObligation < ' tcx > ,
20- ) -> Option < DefId > ;
20+ ) -> Option < ( DefId , SubstsRef < ' tcx > ) > ;
2121
2222 /*private*/
2323 fn describe_enclosure ( & self , hir_id : hir:: HirId ) -> Option < & ' static str > ;
@@ -34,7 +34,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
3434 & self ,
3535 trait_ref : ty:: PolyTraitRef < ' tcx > ,
3636 obligation : & PredicateObligation < ' tcx > ,
37- ) -> Option < DefId > {
37+ ) -> Option < ( DefId , SubstsRef < ' tcx > ) > {
3838 let tcx = self . tcx ;
3939 let param_env = obligation. param_env ;
4040 let trait_ref = tcx. erase_late_bound_regions ( trait_ref) ;
@@ -50,28 +50,29 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
5050 let impl_self_ty = impl_trait_ref. self_ty ( ) ;
5151
5252 if let Ok ( ..) = self . can_eq ( param_env, trait_self_ty, impl_self_ty) {
53- self_match_impls. push ( def_id) ;
53+ self_match_impls. push ( ( def_id, impl_substs ) ) ;
5454
5555 if iter:: zip (
5656 trait_ref. substs . types ( ) . skip ( 1 ) ,
5757 impl_trait_ref. substs . types ( ) . skip ( 1 ) ,
5858 )
5959 . all ( |( u, v) | self . fuzzy_match_tys ( u, v, false ) . is_some ( ) )
6060 {
61- fuzzy_match_impls. push ( def_id) ;
61+ fuzzy_match_impls. push ( ( def_id, impl_substs ) ) ;
6262 }
6363 }
6464 } ) ;
6565
66- let impl_def_id = if self_match_impls. len ( ) == 1 {
66+ let impl_def_id_and_substs = if self_match_impls. len ( ) == 1 {
6767 self_match_impls[ 0 ]
6868 } else if fuzzy_match_impls. len ( ) == 1 {
6969 fuzzy_match_impls[ 0 ]
7070 } else {
7171 return None ;
7272 } ;
7373
74- tcx. has_attr ( impl_def_id, sym:: rustc_on_unimplemented) . then_some ( impl_def_id)
74+ tcx. has_attr ( impl_def_id_and_substs. 0 , sym:: rustc_on_unimplemented)
75+ . then_some ( impl_def_id_and_substs)
7576 }
7677
7778 /// Used to set on_unimplemented's `ItemContext`
@@ -120,8 +121,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
120121 trait_ref : ty:: PolyTraitRef < ' tcx > ,
121122 obligation : & PredicateObligation < ' tcx > ,
122123 ) -> OnUnimplementedNote {
123- let def_id =
124- self . impl_similar_to ( trait_ref, obligation) . unwrap_or_else ( || trait_ref. def_id ( ) ) ;
124+ let ( def_id, substs) = self
125+ . impl_similar_to ( trait_ref, obligation)
126+ . unwrap_or_else ( || ( trait_ref. def_id ( ) , trait_ref. skip_binder ( ) . substs ) ) ;
125127 let trait_ref = trait_ref. skip_binder ( ) ;
126128
127129 let mut flags = vec ! [ (
@@ -176,15 +178,15 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
176178 for param in generics. params. iter( ) {
177179 let value = match param. kind {
178180 GenericParamDefKind :: Type { .. } | GenericParamDefKind :: Const { .. } => {
179- trait_ref . substs[ param. index as usize ] . to_string( )
181+ substs[ param. index as usize ] . to_string( )
180182 }
181183 GenericParamDefKind :: Lifetime => continue ,
182184 } ;
183185 let name = param. name;
184186 flags. push( ( name, Some ( value) ) ) ;
185187
186188 if let GenericParamDefKind :: Type { .. } = param. kind {
187- let param_ty = trait_ref . substs[ param. index as usize ] . expect_ty( ) ;
189+ let param_ty = substs[ param. index as usize ] . expect_ty( ) ;
188190 if let Some ( def) = param_ty. ty_adt_def( ) {
189191 // We also want to be able to select the parameter's
190192 // original signature with no type arguments resolved
@@ -229,9 +231,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
229231 }
230232 } ) ;
231233
232- if let Ok ( Some ( command) ) =
233- OnUnimplementedDirective :: of_item ( self . tcx , trait_ref. def_id , def_id)
234- {
234+ if let Ok ( Some ( command) ) = OnUnimplementedDirective :: of_item ( self . tcx , def_id) {
235235 command. evaluate ( self . tcx , trait_ref, & flags)
236236 } else {
237237 OnUnimplementedNote :: default ( )
0 commit comments