@@ -120,7 +120,7 @@ pub fn overlapping_inherent_impls(
120120 return None ;
121121 }
122122
123- overlapping_impls ( tcx, impl1_def_id, impl2_def_id, skip_leak_check, overlap_mode, false )
123+ overlapping_impls ( tcx, impl1_def_id, impl2_def_id, skip_leak_check, overlap_mode, None )
124124}
125125
126126/// If there are types that satisfy both impls, returns `Some`
@@ -137,8 +137,10 @@ pub fn overlapping_trait_impls(
137137 // Before doing expensive operations like entering an inference context, do
138138 // a quick check via fast_reject to tell if the impl headers could possibly
139139 // unify.
140- let impl1_args = tcx. impl_trait_ref ( impl1_def_id) . unwrap ( ) . skip_binder ( ) . args ;
141- let impl2_args = tcx. impl_trait_ref ( impl2_def_id) . unwrap ( ) . skip_binder ( ) . args ;
140+ let trait_ref1 = tcx. impl_trait_ref ( impl1_def_id) . unwrap ( ) ;
141+ let trait_ref2 = tcx. impl_trait_ref ( impl2_def_id) . unwrap ( ) ;
142+ let impl1_args = trait_ref1. skip_binder ( ) . args ;
143+ let impl2_args = trait_ref2. skip_binder ( ) . args ;
142144 let may_overlap =
143145 DeepRejectCtxt :: relate_infer_infer ( tcx) . args_may_unify ( impl1_args, impl2_args) ;
144146
@@ -148,17 +150,21 @@ pub fn overlapping_trait_impls(
148150 return None ;
149151 }
150152
151- overlapping_impls ( tcx, impl1_def_id, impl2_def_id, skip_leak_check, overlap_mode, true )
153+ let trait_refs = Some ( ( trait_ref1, trait_ref2) ) ;
154+ overlapping_impls ( tcx, impl1_def_id, impl2_def_id, skip_leak_check, overlap_mode, trait_refs)
152155}
153156
154- fn overlapping_impls (
155- tcx : TyCtxt < ' _ > ,
157+ fn overlapping_impls < ' tcx > (
158+ tcx : TyCtxt < ' tcx > ,
156159 impl1_def_id : DefId ,
157160 impl2_def_id : DefId ,
158161 skip_leak_check : SkipLeakCheck ,
159162 overlap_mode : OverlapMode ,
160- is_of_trait : bool ,
161- ) -> Option < OverlapResult < ' _ > > {
163+ trait_refs : Option < (
164+ ty:: EarlyBinder < ' tcx , ty:: TraitRef < ' tcx > > ,
165+ ty:: EarlyBinder < ' tcx , ty:: TraitRef < ' tcx > > ,
166+ ) > ,
167+ ) -> Option < OverlapResult < ' tcx > > {
162168 if tcx. next_trait_solver_in_coherence ( ) {
163169 overlap (
164170 tcx,
@@ -167,7 +173,7 @@ fn overlapping_impls(
167173 impl1_def_id,
168174 impl2_def_id,
169175 overlap_mode,
170- is_of_trait ,
176+ trait_refs ,
171177 )
172178 } else {
173179 let _overlap_with_bad_diagnostics = overlap (
@@ -177,7 +183,7 @@ fn overlapping_impls(
177183 impl1_def_id,
178184 impl2_def_id,
179185 overlap_mode,
180- is_of_trait ,
186+ trait_refs ,
181187 ) ?;
182188
183189 // In the case where we detect an error, run the check again, but
@@ -190,7 +196,7 @@ fn overlapping_impls(
190196 impl1_def_id,
191197 impl2_def_id,
192198 overlap_mode,
193- is_of_trait ,
199+ trait_refs ,
194200 )
195201 . unwrap ( ) ;
196202 Some ( overlap)
@@ -200,7 +206,7 @@ fn overlapping_impls(
200206fn fresh_impl_header < ' tcx > (
201207 infcx : & InferCtxt < ' tcx > ,
202208 impl_def_id : DefId ,
203- is_of_trait : bool ,
209+ trait_ref : Option < ty :: EarlyBinder < ' tcx , ty :: TraitRef < ' tcx > > > ,
204210) -> ImplHeader < ' tcx > {
205211 let tcx = infcx. tcx ;
206212 let impl_args = infcx. fresh_args_for_item ( DUMMY_SP , impl_def_id) ;
@@ -209,8 +215,7 @@ fn fresh_impl_header<'tcx>(
209215 impl_def_id,
210216 impl_args,
211217 self_ty : tcx. type_of ( impl_def_id) . instantiate ( tcx, impl_args) ,
212- trait_ref : is_of_trait
213- . then ( || tcx. impl_trait_ref ( impl_def_id) . unwrap ( ) . instantiate ( tcx, impl_args) ) ,
218+ trait_ref : trait_ref. map ( |trait_ref| trait_ref. instantiate ( tcx, impl_args) ) ,
214219 predicates : tcx
215220 . predicates_of ( impl_def_id)
216221 . instantiate ( tcx, impl_args)
@@ -224,9 +229,9 @@ fn fresh_impl_header_normalized<'tcx>(
224229 infcx : & InferCtxt < ' tcx > ,
225230 param_env : ty:: ParamEnv < ' tcx > ,
226231 impl_def_id : DefId ,
227- is_of_trait : bool ,
232+ trait_ref : Option < ty :: EarlyBinder < ' tcx , ty :: TraitRef < ' tcx > > > ,
228233) -> ImplHeader < ' tcx > {
229- let header = fresh_impl_header ( infcx, impl_def_id, is_of_trait ) ;
234+ let header = fresh_impl_header ( infcx, impl_def_id, trait_ref ) ;
230235
231236 let InferOk { value : mut header, obligations } =
232237 infcx. at ( & ObligationCause :: dummy ( ) , param_env) . normalize ( header) ;
@@ -245,15 +250,18 @@ fn overlap<'tcx>(
245250 impl1_def_id : DefId ,
246251 impl2_def_id : DefId ,
247252 overlap_mode : OverlapMode ,
248- is_of_trait : bool ,
253+ trait_refs : Option < (
254+ ty:: EarlyBinder < ' tcx , ty:: TraitRef < ' tcx > > ,
255+ ty:: EarlyBinder < ' tcx , ty:: TraitRef < ' tcx > > ,
256+ ) > ,
249257) -> Option < OverlapResult < ' tcx > > {
250258 if overlap_mode. use_negative_impl ( ) {
251- if impl_intersection_has_negative_obligation ( tcx, impl1_def_id, impl2_def_id, is_of_trait )
259+ if impl_intersection_has_negative_obligation ( tcx, impl1_def_id, impl2_def_id, trait_refs )
252260 || impl_intersection_has_negative_obligation (
253261 tcx,
254262 impl2_def_id,
255263 impl1_def_id,
256- is_of_trait ,
264+ trait_refs ,
257265 )
258266 {
259267 return None ;
@@ -276,10 +284,11 @@ fn overlap<'tcx>(
276284 // empty environment.
277285 let param_env = ty:: ParamEnv :: empty ( ) ;
278286
287+ let ( trait_ref1, trait_ref2) = trait_refs. unzip ( ) ;
279288 let impl1_header =
280- fresh_impl_header_normalized ( selcx. infcx , param_env, impl1_def_id, is_of_trait ) ;
289+ fresh_impl_header_normalized ( selcx. infcx , param_env, impl1_def_id, trait_ref1 ) ;
281290 let impl2_header =
282- fresh_impl_header_normalized ( selcx. infcx , param_env, impl2_def_id, is_of_trait ) ;
291+ fresh_impl_header_normalized ( selcx. infcx , param_env, impl2_def_id, trait_ref2 ) ;
283292
284293 // Equate the headers to find their intersection (the general type, with infer vars,
285294 // that may apply both impls).
@@ -489,11 +498,14 @@ fn impl_intersection_has_impossible_obligation<'a, 'cx, 'tcx>(
489498/// after negating, giving us `&str: !Error`. This is a negative impl provided by
490499/// libstd, and therefore we can guarantee for certain that libstd will never add
491500/// a positive impl for `&str: Error` (without it being a breaking change).
492- fn impl_intersection_has_negative_obligation (
493- tcx : TyCtxt < ' _ > ,
501+ fn impl_intersection_has_negative_obligation < ' tcx > (
502+ tcx : TyCtxt < ' tcx > ,
494503 impl1_def_id : DefId ,
495504 impl2_def_id : DefId ,
496- is_of_trait : bool ,
505+ trait_refs : Option < (
506+ ty:: EarlyBinder < ' tcx , ty:: TraitRef < ' tcx > > ,
507+ ty:: EarlyBinder < ' tcx , ty:: TraitRef < ' tcx > > ,
508+ ) > ,
497509) -> bool {
498510 debug ! ( "negative_impl(impl1_def_id={:?}, impl2_def_id={:?})" , impl1_def_id, impl2_def_id) ;
499511
@@ -503,11 +515,12 @@ fn impl_intersection_has_negative_obligation(
503515 let root_universe = infcx. universe ( ) ;
504516 assert_eq ! ( root_universe, ty:: UniverseIndex :: ROOT ) ;
505517
506- let impl1_header = fresh_impl_header ( infcx, impl1_def_id, is_of_trait) ;
518+ let ( trait_ref1, trait_ref2) = trait_refs. unzip ( ) ;
519+ let impl1_header = fresh_impl_header ( infcx, impl1_def_id, trait_ref1) ;
507520 let param_env =
508521 ty:: EarlyBinder :: bind ( tcx. param_env ( impl1_def_id) ) . instantiate ( tcx, impl1_header. impl_args ) ;
509522
510- let impl2_header = fresh_impl_header ( infcx, impl2_def_id, is_of_trait ) ;
523+ let impl2_header = fresh_impl_header ( infcx, impl2_def_id, trait_ref2 ) ;
511524
512525 // Equate the headers to find their intersection (the general type, with infer vars,
513526 // that may apply both impls).
0 commit comments