@@ -82,6 +82,30 @@ pub fn translate_substs<'tcx>(
82
82
source_impl : DefId ,
83
83
source_substs : SubstsRef < ' tcx > ,
84
84
target_node : specialization_graph:: Node ,
85
+ ) -> SubstsRef < ' tcx > {
86
+ translate_substs_with_cause (
87
+ infcx,
88
+ param_env,
89
+ source_impl,
90
+ source_substs,
91
+ target_node,
92
+ |_, _| ObligationCause :: dummy ( ) ,
93
+ )
94
+ }
95
+
96
+ /// Like [translate_substs], but obligations from the parent implementation
97
+ /// are registered with the provided `ObligationCause`.
98
+ ///
99
+ /// This is for reporting *region* errors from those bounds. Type errors should
100
+ /// not happen because the specialization graph already checks for those, and
101
+ /// will result in an ICE.
102
+ pub fn translate_substs_with_cause < ' tcx > (
103
+ infcx : & InferCtxt < ' tcx > ,
104
+ param_env : ty:: ParamEnv < ' tcx > ,
105
+ source_impl : DefId ,
106
+ source_substs : SubstsRef < ' tcx > ,
107
+ target_node : specialization_graph:: Node ,
108
+ cause : impl Fn ( usize , Span ) -> ObligationCause < ' tcx > ,
85
109
) -> SubstsRef < ' tcx > {
86
110
debug ! (
87
111
"translate_substs({:?}, {:?}, {:?}, {:?})" ,
@@ -99,7 +123,7 @@ pub fn translate_substs<'tcx>(
99
123
return source_substs;
100
124
}
101
125
102
- fulfill_implication ( infcx, param_env, source_trait_ref, source_impl, target_impl)
126
+ fulfill_implication ( infcx, param_env, source_trait_ref, source_impl, target_impl, cause )
103
127
. unwrap_or_else ( |( ) | {
104
128
bug ! (
105
129
"When translating substitutions from {source_impl:?} to {target_impl:?}, \
@@ -154,7 +178,10 @@ pub(super) fn specializes(tcx: TyCtxt<'_>, (impl1_def_id, impl2_def_id): (DefId,
154
178
let infcx = tcx. infer_ctxt ( ) . build ( ) ;
155
179
156
180
// Attempt to prove that impl2 applies, given all of the above.
157
- fulfill_implication ( & infcx, penv, impl1_trait_ref, impl1_def_id, impl2_def_id) . is_ok ( )
181
+ fulfill_implication ( & infcx, penv, impl1_trait_ref, impl1_def_id, impl2_def_id, |_, _| {
182
+ ObligationCause :: dummy ( )
183
+ } )
184
+ . is_ok ( )
158
185
}
159
186
160
187
/// Attempt to fulfill all obligations of `target_impl` after unification with
@@ -168,6 +195,7 @@ fn fulfill_implication<'tcx>(
168
195
source_trait_ref : ty:: TraitRef < ' tcx > ,
169
196
source_impl : DefId ,
170
197
target_impl : DefId ,
198
+ error_cause : impl Fn ( usize , Span ) -> ObligationCause < ' tcx > ,
171
199
) -> Result < SubstsRef < ' tcx > , ( ) > {
172
200
debug ! (
173
201
"fulfill_implication({:?}, trait_ref={:?} |- {:?} applies)" ,
@@ -195,7 +223,7 @@ fn fulfill_implication<'tcx>(
195
223
let selcx = & mut SelectionContext :: new ( & infcx) ;
196
224
let target_substs = infcx. fresh_substs_for_item ( DUMMY_SP , target_impl) ;
197
225
let ( target_trait, obligations) =
198
- util:: impl_subject_and_oblig ( selcx, param_env, target_impl, target_substs) ;
226
+ util:: impl_subject_and_oblig ( selcx, param_env, target_impl, target_substs, error_cause ) ;
199
227
200
228
// do the impls unify? If not, no specialization.
201
229
let Ok ( InferOk { obligations : more_obligations, .. } ) =
0 commit comments