@@ -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, None , impl2_def_id, None , skip_leak_check , overlap_mode )
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 impl1_trait_ref = tcx. impl_trait_ref ( impl1_def_id) . unwrap ( ) ;
141+ let impl2_trait_ref = tcx. impl_trait_ref ( impl2_def_id) . unwrap ( ) ;
142+ let impl1_args = impl1_trait_ref. skip_binder ( ) . args ;
143+ let impl2_args = impl2_trait_ref. skip_binder ( ) . args ;
142144 let may_overlap =
143145 DeepRejectCtxt :: relate_infer_infer ( tcx) . args_may_unify ( impl1_args, impl2_args) ;
144146
@@ -148,36 +150,47 @@ 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+ overlapping_impls (
154+ tcx,
155+ impl1_def_id,
156+ Some ( impl1_trait_ref) ,
157+ impl2_def_id,
158+ Some ( impl2_trait_ref) ,
159+ skip_leak_check,
160+ overlap_mode,
161+ )
152162}
153163
154- fn overlapping_impls (
155- tcx : TyCtxt < ' _ > ,
164+ fn overlapping_impls < ' tcx > (
165+ tcx : TyCtxt < ' tcx > ,
156166 impl1_def_id : DefId ,
167+ impl1_trait_ref : Option < ty:: EarlyBinder < ' tcx , ty:: TraitRef < ' tcx > > > ,
157168 impl2_def_id : DefId ,
169+ impl2_trait_ref : Option < ty:: EarlyBinder < ' tcx , ty:: TraitRef < ' tcx > > > ,
158170 skip_leak_check : SkipLeakCheck ,
159171 overlap_mode : OverlapMode ,
160- is_of_trait : bool ,
161- ) -> Option < OverlapResult < ' _ > > {
172+ ) -> Option < OverlapResult < ' tcx > > {
162173 if tcx. next_trait_solver_in_coherence ( ) {
163174 overlap (
164175 tcx,
165176 TrackAmbiguityCauses :: Yes ,
166177 skip_leak_check,
167178 impl1_def_id,
179+ impl1_trait_ref,
168180 impl2_def_id,
181+ impl2_trait_ref,
169182 overlap_mode,
170- is_of_trait,
171183 )
172184 } else {
173185 let _overlap_with_bad_diagnostics = overlap (
174186 tcx,
175187 TrackAmbiguityCauses :: No ,
176188 skip_leak_check,
177189 impl1_def_id,
190+ impl1_trait_ref,
178191 impl2_def_id,
192+ impl2_trait_ref,
179193 overlap_mode,
180- is_of_trait,
181194 ) ?;
182195
183196 // In the case where we detect an error, run the check again, but
@@ -188,9 +201,10 @@ fn overlapping_impls(
188201 TrackAmbiguityCauses :: Yes ,
189202 skip_leak_check,
190203 impl1_def_id,
204+ impl1_trait_ref,
191205 impl2_def_id,
206+ impl2_trait_ref,
192207 overlap_mode,
193- is_of_trait,
194208 )
195209 . unwrap ( ) ;
196210 Some ( overlap)
@@ -200,7 +214,7 @@ fn overlapping_impls(
200214fn fresh_impl_header < ' tcx > (
201215 infcx : & InferCtxt < ' tcx > ,
202216 impl_def_id : DefId ,
203- is_of_trait : bool ,
217+ trait_ref : Option < ty :: EarlyBinder < ' tcx , ty :: TraitRef < ' tcx > > > ,
204218) -> ImplHeader < ' tcx > {
205219 let tcx = infcx. tcx ;
206220 let impl_args = infcx. fresh_args_for_item ( DUMMY_SP , impl_def_id) ;
@@ -209,8 +223,7 @@ fn fresh_impl_header<'tcx>(
209223 impl_def_id,
210224 impl_args,
211225 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) ) ,
226+ trait_ref : trait_ref. map ( |trait_ref| trait_ref. instantiate ( tcx, impl_args) ) ,
214227 predicates : tcx
215228 . predicates_of ( impl_def_id)
216229 . instantiate ( tcx, impl_args)
@@ -224,9 +237,9 @@ fn fresh_impl_header_normalized<'tcx>(
224237 infcx : & InferCtxt < ' tcx > ,
225238 param_env : ty:: ParamEnv < ' tcx > ,
226239 impl_def_id : DefId ,
227- is_of_trait : bool ,
240+ trait_ref : Option < ty :: EarlyBinder < ' tcx , ty :: TraitRef < ' tcx > > > ,
228241) -> ImplHeader < ' tcx > {
229- let header = fresh_impl_header ( infcx, impl_def_id, is_of_trait ) ;
242+ let header = fresh_impl_header ( infcx, impl_def_id, trait_ref ) ;
230243
231244 let InferOk { value : mut header, obligations } =
232245 infcx. at ( & ObligationCause :: dummy ( ) , param_env) . normalize ( header) ;
@@ -243,19 +256,25 @@ fn overlap<'tcx>(
243256 track_ambiguity_causes : TrackAmbiguityCauses ,
244257 skip_leak_check : SkipLeakCheck ,
245258 impl1_def_id : DefId ,
259+ impl1_trait_ref : Option < ty:: EarlyBinder < ' tcx , ty:: TraitRef < ' tcx > > > ,
246260 impl2_def_id : DefId ,
261+ impl2_trait_ref : Option < ty:: EarlyBinder < ' tcx , ty:: TraitRef < ' tcx > > > ,
247262 overlap_mode : OverlapMode ,
248- is_of_trait : bool ,
249263) -> Option < OverlapResult < ' tcx > > {
250264 if overlap_mode. use_negative_impl ( ) {
251- if impl_intersection_has_negative_obligation ( tcx, impl1_def_id, impl2_def_id, is_of_trait)
252- || impl_intersection_has_negative_obligation (
253- tcx,
254- impl2_def_id,
255- impl1_def_id,
256- is_of_trait,
257- )
258- {
265+ if impl_intersection_has_negative_obligation (
266+ tcx,
267+ impl1_def_id,
268+ impl1_trait_ref,
269+ impl2_def_id,
270+ impl2_trait_ref,
271+ ) || impl_intersection_has_negative_obligation (
272+ tcx,
273+ impl2_def_id,
274+ impl2_trait_ref,
275+ impl1_def_id,
276+ impl1_trait_ref,
277+ ) {
259278 return None ;
260279 }
261280 }
@@ -277,9 +296,9 @@ fn overlap<'tcx>(
277296 let param_env = ty:: ParamEnv :: empty ( ) ;
278297
279298 let impl1_header =
280- fresh_impl_header_normalized ( selcx. infcx , param_env, impl1_def_id, is_of_trait ) ;
299+ fresh_impl_header_normalized ( selcx. infcx , param_env, impl1_def_id, impl1_trait_ref ) ;
281300 let impl2_header =
282- fresh_impl_header_normalized ( selcx. infcx , param_env, impl2_def_id, is_of_trait ) ;
301+ fresh_impl_header_normalized ( selcx. infcx , param_env, impl2_def_id, impl2_trait_ref ) ;
283302
284303 // Equate the headers to find their intersection (the general type, with infer vars,
285304 // that may apply both impls).
@@ -489,11 +508,12 @@ fn impl_intersection_has_impossible_obligation<'a, 'cx, 'tcx>(
489508/// after negating, giving us `&str: !Error`. This is a negative impl provided by
490509/// libstd, and therefore we can guarantee for certain that libstd will never add
491510/// a positive impl for `&str: Error` (without it being a breaking change).
492- fn impl_intersection_has_negative_obligation (
493- tcx : TyCtxt < ' _ > ,
511+ fn impl_intersection_has_negative_obligation < ' tcx > (
512+ tcx : TyCtxt < ' tcx > ,
494513 impl1_def_id : DefId ,
514+ impl1_trait_ref : Option < ty:: EarlyBinder < ' tcx , ty:: TraitRef < ' tcx > > > ,
495515 impl2_def_id : DefId ,
496- is_of_trait : bool ,
516+ impl2_trait_ref : Option < ty :: EarlyBinder < ' tcx , ty :: TraitRef < ' tcx > > > ,
497517) -> bool {
498518 debug ! ( "negative_impl(impl1_def_id={:?}, impl2_def_id={:?})" , impl1_def_id, impl2_def_id) ;
499519
@@ -503,11 +523,11 @@ fn impl_intersection_has_negative_obligation(
503523 let root_universe = infcx. universe ( ) ;
504524 assert_eq ! ( root_universe, ty:: UniverseIndex :: ROOT ) ;
505525
506- let impl1_header = fresh_impl_header ( infcx, impl1_def_id, is_of_trait ) ;
526+ let impl1_header = fresh_impl_header ( infcx, impl1_def_id, impl1_trait_ref ) ;
507527 let param_env =
508528 ty:: EarlyBinder :: bind ( tcx. param_env ( impl1_def_id) ) . instantiate ( tcx, impl1_header. impl_args ) ;
509529
510- let impl2_header = fresh_impl_header ( infcx, impl2_def_id, is_of_trait ) ;
530+ let impl2_header = fresh_impl_header ( infcx, impl2_def_id, impl2_trait_ref ) ;
511531
512532 // Equate the headers to find their intersection (the general type, with infer vars,
513533 // that may apply both impls).
0 commit comments