@@ -204,18 +204,25 @@ fn overlap<'tcx>(
204
204
205
205
// Equate the headers to find their intersection (the general type, with infer vars,
206
206
// 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) ?;
208
208
debug ! ( "overlap: unification check succeeded" ) ;
209
209
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) {
219
226
return None ;
220
227
}
221
228
@@ -226,7 +233,12 @@ fn overlap<'tcx>(
226
233
return None ;
227
234
}
228
235
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
+
230
242
debug ! ( "overlap: intercrate_ambiguity_causes={:#?}" , intercrate_ambiguity_causes) ;
231
243
let involves_placeholder = infcx
232
244
. inner
@@ -282,14 +294,11 @@ fn equate_impl_headers<'tcx>(
282
294
/// Importantly, this works even if there isn't a `impl !Error for MyLocalType`.
283
295
fn impl_intersection_has_impossible_obligation < ' cx , ' tcx > (
284
296
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 > ] ,
289
298
) -> bool {
290
299
let infcx = selcx. infcx ;
291
300
292
- let obligation_guaranteed_to_fail = move |obligation : & PredicateObligation < ' tcx > | {
301
+ let obligation_guaranteed_to_fail = move |obligation : & & PredicateObligation < ' tcx > | {
293
302
if infcx. next_trait_solver ( ) {
294
303
infcx. evaluate_obligation ( obligation) . map_or ( false , |result| !result. may_apply ( ) )
295
304
} else {
@@ -303,15 +312,7 @@ fn impl_intersection_has_impossible_obligation<'cx, 'tcx>(
303
312
}
304
313
} ;
305
314
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) ;
315
316
if let Some ( failing_obligation) = opt_failing_obligation {
316
317
debug ! ( "overlap: obligation unsatisfiable {:?}" , failing_obligation) ;
317
318
true
0 commit comments