@@ -204,18 +204,25 @@ fn overlap<'tcx>(
204204
205205 // Equate the headers to find their intersection (the general type, with infer vars,
206206 // that may apply both impls).
207- let equate_obligations = equate_impl_headers ( selcx. infcx , & impl1_header, & impl2_header) ?;
207+ let mut obligations = equate_impl_headers ( selcx. infcx , & impl1_header, & impl2_header) ?;
208208 debug ! ( "overlap: unification check succeeded" ) ;
209209
210- if overlap_mode. use_implicit_negative ( )
211- && impl_intersection_has_impossible_obligation (
212- selcx,
213- param_env,
214- & impl1_header,
215- impl2_header,
216- equate_obligations,
217- )
218- {
210+ if !overlap_mode. use_implicit_negative ( ) {
211+ let impl_header = selcx. infcx . resolve_vars_if_possible ( impl1_header) ;
212+ return Some ( OverlapResult {
213+ impl_header,
214+ intercrate_ambiguity_causes : Default :: default ( ) ,
215+ involves_placeholder : false ,
216+ } ) ;
217+ } ;
218+
219+ obligations. extend (
220+ [ & impl1_header. predicates , & impl2_header. predicates ] . into_iter ( ) . flatten ( ) . map (
221+ |& predicate| Obligation :: new ( infcx. tcx , ObligationCause :: dummy ( ) , param_env, predicate) ,
222+ ) ,
223+ ) ;
224+
225+ if impl_intersection_has_impossible_obligation ( selcx, & obligations) {
219226 return None ;
220227 }
221228
@@ -226,7 +233,12 @@ fn overlap<'tcx>(
226233 return None ;
227234 }
228235
229- let intercrate_ambiguity_causes = selcx. take_intercrate_ambiguity_causes ( ) ;
236+ let intercrate_ambiguity_causes = if infcx. next_trait_solver ( ) {
237+ crate :: solve:: compute_intercrate_ambiguity_causes ( & infcx, & obligations)
238+ } else {
239+ selcx. take_intercrate_ambiguity_causes ( )
240+ } ;
241+
230242 debug ! ( "overlap: intercrate_ambiguity_causes={:#?}" , intercrate_ambiguity_causes) ;
231243 let involves_placeholder = infcx
232244 . inner
@@ -282,14 +294,11 @@ fn equate_impl_headers<'tcx>(
282294/// Importantly, this works even if there isn't a `impl !Error for MyLocalType`.
283295fn impl_intersection_has_impossible_obligation < ' cx , ' tcx > (
284296 selcx : & mut SelectionContext < ' cx , ' tcx > ,
285- param_env : ty:: ParamEnv < ' tcx > ,
286- impl1_header : & ty:: ImplHeader < ' tcx > ,
287- impl2_header : ty:: ImplHeader < ' tcx > ,
288- obligations : PredicateObligations < ' tcx > ,
297+ obligations : & [ PredicateObligation < ' tcx > ] ,
289298) -> bool {
290299 let infcx = selcx. infcx ;
291300
292- let obligation_guaranteed_to_fail = move |obligation : & PredicateObligation < ' tcx > | {
301+ let obligation_guaranteed_to_fail = move |obligation : & & PredicateObligation < ' tcx > | {
293302 if infcx. next_trait_solver ( ) {
294303 infcx. evaluate_obligation ( obligation) . map_or ( false , |result| !result. may_apply ( ) )
295304 } else {
@@ -303,15 +312,7 @@ fn impl_intersection_has_impossible_obligation<'cx, 'tcx>(
303312 }
304313 } ;
305314
306- let opt_failing_obligation = [ & impl1_header. predicates , & impl2_header. predicates ]
307- . into_iter ( )
308- . flatten ( )
309- . map ( |& predicate| {
310- Obligation :: new ( infcx. tcx , ObligationCause :: dummy ( ) , param_env, predicate)
311- } )
312- . chain ( obligations)
313- . find ( obligation_guaranteed_to_fail) ;
314-
315+ let opt_failing_obligation = obligations. iter ( ) . find ( obligation_guaranteed_to_fail) ;
315316 if let Some ( failing_obligation) = opt_failing_obligation {
316317 debug ! ( "overlap: obligation unsatisfiable {:?}" , failing_obligation) ;
317318 true
0 commit comments