@@ -19,7 +19,8 @@ use rustc_middle::traits::solve::{CandidateSource, Certainty, Goal};
1919use rustc_middle:: traits:: specialization_graph:: OverlapMode ;
2020use rustc_middle:: ty:: fast_reject:: DeepRejectCtxt ;
2121use rustc_middle:: ty:: {
22- self , Ty , TyCtxt , TypeSuperVisitable , TypeVisitable , TypeVisitableExt , TypeVisitor , TypingMode ,
22+ self , EarlyBinder , Ty , TyCtxt , TypeSuperVisitable , TypeVisitable , TypeVisitableExt ,
23+ TypeVisitor , TypingMode ,
2324} ;
2425pub use rustc_next_trait_solver:: coherence:: * ;
2526use rustc_next_trait_solver:: solve:: SolverDelegateEvalExt ;
@@ -120,7 +121,7 @@ pub fn overlapping_inherent_impls(
120121 return None ;
121122 }
122123
123- overlapping_impls ( tcx, impl1_def_id, impl2_def_id, skip_leak_check, overlap_mode, false )
124+ overlapping_impls ( tcx, impl1_def_id, impl2_def_id, skip_leak_check, overlap_mode, None )
124125}
125126
126127/// If there are types that satisfy both impls, returns `Some`
@@ -137,8 +138,10 @@ pub fn overlapping_trait_impls(
137138 // Before doing expensive operations like entering an inference context, do
138139 // a quick check via fast_reject to tell if the impl headers could possibly
139140 // 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 ;
141+ let trait_ref1 = tcx. impl_trait_ref ( impl1_def_id) . unwrap ( ) ;
142+ let trait_ref2 = tcx. impl_trait_ref ( impl2_def_id) . unwrap ( ) ;
143+ let impl1_args = trait_ref1. skip_binder ( ) . args ;
144+ let impl2_args = trait_ref2. skip_binder ( ) . args ;
142145 let may_overlap =
143146 DeepRejectCtxt :: relate_infer_infer ( tcx) . args_may_unify ( impl1_args, impl2_args) ;
144147
@@ -148,17 +151,21 @@ pub fn overlapping_trait_impls(
148151 return None ;
149152 }
150153
151- overlapping_impls ( tcx, impl1_def_id, impl2_def_id, skip_leak_check, overlap_mode, true )
154+ let trait_refs = Some ( ( trait_ref1, trait_ref2) ) ;
155+ overlapping_impls ( tcx, impl1_def_id, impl2_def_id, skip_leak_check, overlap_mode, trait_refs)
152156}
153157
154- fn overlapping_impls (
155- tcx : TyCtxt < ' _ > ,
158+ fn overlapping_impls < ' tcx > (
159+ tcx : TyCtxt < ' tcx > ,
156160 impl1_def_id : DefId ,
157161 impl2_def_id : DefId ,
158162 skip_leak_check : SkipLeakCheck ,
159163 overlap_mode : OverlapMode ,
160- is_of_trait : bool ,
161- ) -> Option < OverlapResult < ' _ > > {
164+ trait_refs : Option < (
165+ EarlyBinder < ' tcx , ty:: TraitRef < ' tcx > > ,
166+ EarlyBinder < ' tcx , ty:: TraitRef < ' tcx > > ,
167+ ) > ,
168+ ) -> Option < OverlapResult < ' tcx > > {
162169 if tcx. next_trait_solver_in_coherence ( ) {
163170 overlap (
164171 tcx,
@@ -167,7 +174,7 @@ fn overlapping_impls(
167174 impl1_def_id,
168175 impl2_def_id,
169176 overlap_mode,
170- is_of_trait ,
177+ trait_refs ,
171178 )
172179 } else {
173180 let _overlap_with_bad_diagnostics = overlap (
@@ -177,7 +184,7 @@ fn overlapping_impls(
177184 impl1_def_id,
178185 impl2_def_id,
179186 overlap_mode,
180- is_of_trait ,
187+ trait_refs ,
181188 ) ?;
182189
183190 // In the case where we detect an error, run the check again, but
@@ -190,7 +197,7 @@ fn overlapping_impls(
190197 impl1_def_id,
191198 impl2_def_id,
192199 overlap_mode,
193- is_of_trait ,
200+ trait_refs ,
194201 )
195202 . unwrap ( ) ;
196203 Some ( overlap)
@@ -200,7 +207,7 @@ fn overlapping_impls(
200207fn fresh_impl_header < ' tcx > (
201208 infcx : & InferCtxt < ' tcx > ,
202209 impl_def_id : DefId ,
203- is_of_trait : bool ,
210+ trait_ref : Option < EarlyBinder < ' tcx , ty :: TraitRef < ' tcx > > > ,
204211) -> ImplHeader < ' tcx > {
205212 let tcx = infcx. tcx ;
206213 let impl_args = infcx. fresh_args_for_item ( DUMMY_SP , impl_def_id) ;
@@ -209,8 +216,7 @@ fn fresh_impl_header<'tcx>(
209216 impl_def_id,
210217 impl_args,
211218 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) ) ,
219+ trait_ref : trait_ref. map ( |trait_ref| trait_ref. instantiate ( tcx, impl_args) ) ,
214220 predicates : tcx
215221 . predicates_of ( impl_def_id)
216222 . instantiate ( tcx, impl_args)
@@ -224,9 +230,9 @@ fn fresh_impl_header_normalized<'tcx>(
224230 infcx : & InferCtxt < ' tcx > ,
225231 param_env : ty:: ParamEnv < ' tcx > ,
226232 impl_def_id : DefId ,
227- is_of_trait : bool ,
233+ trait_ref : Option < EarlyBinder < ' tcx , ty :: TraitRef < ' tcx > > > ,
228234) -> ImplHeader < ' tcx > {
229- let header = fresh_impl_header ( infcx, impl_def_id, is_of_trait ) ;
235+ let header = fresh_impl_header ( infcx, impl_def_id, trait_ref ) ;
230236
231237 let InferOk { value : mut header, obligations } =
232238 infcx. at ( & ObligationCause :: dummy ( ) , param_env) . normalize ( header) ;
@@ -245,15 +251,18 @@ fn overlap<'tcx>(
245251 impl1_def_id : DefId ,
246252 impl2_def_id : DefId ,
247253 overlap_mode : OverlapMode ,
248- is_of_trait : bool ,
254+ trait_refs : Option < (
255+ EarlyBinder < ' tcx , ty:: TraitRef < ' tcx > > ,
256+ EarlyBinder < ' tcx , ty:: TraitRef < ' tcx > > ,
257+ ) > ,
249258) -> Option < OverlapResult < ' tcx > > {
250259 if overlap_mode. use_negative_impl ( ) {
251- if impl_intersection_has_negative_obligation ( tcx, impl1_def_id, impl2_def_id, is_of_trait )
260+ if impl_intersection_has_negative_obligation ( tcx, impl1_def_id, impl2_def_id, trait_refs )
252261 || impl_intersection_has_negative_obligation (
253262 tcx,
254263 impl2_def_id,
255264 impl1_def_id,
256- is_of_trait ,
265+ trait_refs ,
257266 )
258267 {
259268 return None ;
@@ -276,10 +285,11 @@ fn overlap<'tcx>(
276285 // empty environment.
277286 let param_env = ty:: ParamEnv :: empty ( ) ;
278287
288+ let ( trait_ref1, trait_ref2) = trait_refs. unzip ( ) ;
279289 let impl1_header =
280- fresh_impl_header_normalized ( selcx. infcx , param_env, impl1_def_id, is_of_trait ) ;
290+ fresh_impl_header_normalized ( selcx. infcx , param_env, impl1_def_id, trait_ref1 ) ;
281291 let impl2_header =
282- fresh_impl_header_normalized ( selcx. infcx , param_env, impl2_def_id, is_of_trait ) ;
292+ fresh_impl_header_normalized ( selcx. infcx , param_env, impl2_def_id, trait_ref2 ) ;
283293
284294 // Equate the headers to find their intersection (the general type, with infer vars,
285295 // that may apply both impls).
@@ -489,11 +499,14 @@ fn impl_intersection_has_impossible_obligation<'a, 'cx, 'tcx>(
489499/// after negating, giving us `&str: !Error`. This is a negative impl provided by
490500/// libstd, and therefore we can guarantee for certain that libstd will never add
491501/// a positive impl for `&str: Error` (without it being a breaking change).
492- fn impl_intersection_has_negative_obligation (
493- tcx : TyCtxt < ' _ > ,
502+ fn impl_intersection_has_negative_obligation < ' tcx > (
503+ tcx : TyCtxt < ' tcx > ,
494504 impl1_def_id : DefId ,
495505 impl2_def_id : DefId ,
496- is_of_trait : bool ,
506+ trait_refs : Option < (
507+ EarlyBinder < ' tcx , ty:: TraitRef < ' tcx > > ,
508+ EarlyBinder < ' tcx , ty:: TraitRef < ' tcx > > ,
509+ ) > ,
497510) -> bool {
498511 debug ! ( "negative_impl(impl1_def_id={:?}, impl2_def_id={:?})" , impl1_def_id, impl2_def_id) ;
499512
@@ -503,11 +516,12 @@ fn impl_intersection_has_negative_obligation(
503516 let root_universe = infcx. universe ( ) ;
504517 assert_eq ! ( root_universe, ty:: UniverseIndex :: ROOT ) ;
505518
506- let impl1_header = fresh_impl_header ( infcx, impl1_def_id, is_of_trait) ;
519+ let ( trait_ref1, trait_ref2) = trait_refs. unzip ( ) ;
520+ let impl1_header = fresh_impl_header ( infcx, impl1_def_id, trait_ref1) ;
507521 let param_env =
508522 ty:: EarlyBinder :: bind ( tcx. param_env ( impl1_def_id) ) . instantiate ( tcx, impl1_header. impl_args ) ;
509523
510- let impl2_header = fresh_impl_header ( infcx, impl2_def_id, is_of_trait ) ;
524+ let impl2_header = fresh_impl_header ( infcx, impl2_def_id, trait_ref2 ) ;
511525
512526 // Equate the headers to find their intersection (the general type, with infer vars,
513527 // that may apply both impls).
0 commit comments