@@ -4,7 +4,7 @@ use super::{
4
4
use crate :: infer:: InferCtxt ;
5
5
use rustc_hir as hir;
6
6
use rustc_hir:: def_id:: DefId ;
7
- use rustc_middle:: ty:: subst:: Subst ;
7
+ use rustc_middle:: ty:: subst:: { Subst , SubstsRef } ;
8
8
use rustc_middle:: ty:: { self , GenericParamDefKind } ;
9
9
use rustc_span:: symbol:: sym;
10
10
use std:: iter;
@@ -17,7 +17,7 @@ crate trait InferCtxtExt<'tcx> {
17
17
& self ,
18
18
trait_ref : ty:: PolyTraitRef < ' tcx > ,
19
19
obligation : & PredicateObligation < ' tcx > ,
20
- ) -> Option < DefId > ;
20
+ ) -> Option < ( DefId , SubstsRef < ' tcx > ) > ;
21
21
22
22
/*private*/
23
23
fn describe_enclosure ( & self , hir_id : hir:: HirId ) -> Option < & ' static str > ;
@@ -34,7 +34,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
34
34
& self ,
35
35
trait_ref : ty:: PolyTraitRef < ' tcx > ,
36
36
obligation : & PredicateObligation < ' tcx > ,
37
- ) -> Option < DefId > {
37
+ ) -> Option < ( DefId , SubstsRef < ' tcx > ) > {
38
38
let tcx = self . tcx ;
39
39
let param_env = obligation. param_env ;
40
40
let trait_ref = tcx. erase_late_bound_regions ( trait_ref) ;
@@ -50,28 +50,29 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
50
50
let impl_self_ty = impl_trait_ref. self_ty ( ) ;
51
51
52
52
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 ) ) ;
54
54
55
55
if iter:: zip (
56
56
trait_ref. substs . types ( ) . skip ( 1 ) ,
57
57
impl_trait_ref. substs . types ( ) . skip ( 1 ) ,
58
58
)
59
59
. all ( |( u, v) | self . fuzzy_match_tys ( u, v, false ) . is_some ( ) )
60
60
{
61
- fuzzy_match_impls. push ( def_id) ;
61
+ fuzzy_match_impls. push ( ( def_id, impl_substs ) ) ;
62
62
}
63
63
}
64
64
} ) ;
65
65
66
- let impl_def_id = if self_match_impls. len ( ) == 1 {
66
+ let impl_def_id_and_substs = if self_match_impls. len ( ) == 1 {
67
67
self_match_impls[ 0 ]
68
68
} else if fuzzy_match_impls. len ( ) == 1 {
69
69
fuzzy_match_impls[ 0 ]
70
70
} else {
71
71
return None ;
72
72
} ;
73
73
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)
75
76
}
76
77
77
78
/// Used to set on_unimplemented's `ItemContext`
@@ -120,8 +121,9 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
120
121
trait_ref : ty:: PolyTraitRef < ' tcx > ,
121
122
obligation : & PredicateObligation < ' tcx > ,
122
123
) -> 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 ) ) ;
125
127
let trait_ref = trait_ref. skip_binder ( ) ;
126
128
127
129
let mut flags = vec ! [ (
@@ -176,15 +178,15 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
176
178
for param in generics. params. iter( ) {
177
179
let value = match param. kind {
178
180
GenericParamDefKind :: Type { .. } | GenericParamDefKind :: Const { .. } => {
179
- trait_ref . substs[ param. index as usize ] . to_string( )
181
+ substs[ param. index as usize ] . to_string( )
180
182
}
181
183
GenericParamDefKind :: Lifetime => continue ,
182
184
} ;
183
185
let name = param. name;
184
186
flags. push( ( name, Some ( value) ) ) ;
185
187
186
188
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( ) ;
188
190
if let Some ( def) = param_ty. ty_adt_def( ) {
189
191
// We also want to be able to select the parameter's
190
192
// original signature with no type arguments resolved
@@ -229,9 +231,7 @@ impl<'a, 'tcx> InferCtxtExt<'tcx> for InferCtxt<'a, 'tcx> {
229
231
}
230
232
} ) ;
231
233
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) {
235
235
command. evaluate ( self . tcx , trait_ref, & flags)
236
236
} else {
237
237
OnUnimplementedNote :: default ( )
0 commit comments