6
6
7
7
use crate :: infer:: outlives:: env:: OutlivesEnvironment ;
8
8
use crate :: infer:: { CombinedSnapshot , InferOk } ;
9
+ use crate :: traits:: outlives_bounds:: InferCtxtExt as _;
9
10
use crate :: traits:: select:: IntercrateAmbiguityCause ;
10
11
use crate :: traits:: util:: impl_subject_and_oblig;
11
12
use crate :: traits:: SkipLeakCheck ;
12
13
use crate :: traits:: {
13
- self , Normalized , Obligation , ObligationCause , PredicateObligation , PredicateObligations ,
14
- SelectionContext ,
14
+ self , Normalized , Obligation , ObligationCause , ObligationCtxt , PredicateObligation ,
15
+ PredicateObligations , SelectionContext ,
15
16
} ;
16
17
use rustc_data_structures:: fx:: FxIndexSet ;
17
18
use rustc_errors:: Diagnostic ;
@@ -322,7 +323,7 @@ fn negative_impl<'cx, 'tcx>(
322
323
let ( subject2, obligations) =
323
324
impl_subject_and_oblig ( selcx, impl_env, impl2_def_id, impl2_substs) ;
324
325
325
- !equate ( & infcx, impl_env, subject1, subject2, obligations)
326
+ !equate ( & infcx, impl_env, subject1, subject2, obligations, impl1_def_id )
326
327
} )
327
328
}
328
329
@@ -332,6 +333,7 @@ fn equate<'cx, 'tcx>(
332
333
subject1 : ImplSubject < ' tcx > ,
333
334
subject2 : ImplSubject < ' tcx > ,
334
335
obligations : impl Iterator < Item = PredicateObligation < ' tcx > > ,
336
+ body_def_id : DefId ,
335
337
) -> bool {
336
338
// do the impls unify? If not, not disjoint.
337
339
let Ok ( InferOk { obligations : more_obligations, .. } ) =
@@ -342,8 +344,10 @@ fn equate<'cx, 'tcx>(
342
344
} ;
343
345
344
346
let selcx = & mut SelectionContext :: new ( & infcx) ;
345
- let opt_failing_obligation =
346
- obligations. into_iter ( ) . chain ( more_obligations) . find ( |o| negative_impl_exists ( selcx, o) ) ;
347
+ let opt_failing_obligation = obligations
348
+ . into_iter ( )
349
+ . chain ( more_obligations)
350
+ . find ( |o| negative_impl_exists ( selcx, o, body_def_id) ) ;
347
351
348
352
if let Some ( failing_obligation) = opt_failing_obligation {
349
353
debug ! ( "overlap: obligation unsatisfiable {:?}" , failing_obligation) ;
@@ -358,14 +362,15 @@ fn equate<'cx, 'tcx>(
358
362
fn negative_impl_exists < ' cx , ' tcx > (
359
363
selcx : & SelectionContext < ' cx , ' tcx > ,
360
364
o : & PredicateObligation < ' tcx > ,
365
+ body_def_id : DefId ,
361
366
) -> bool {
362
- if resolve_negative_obligation ( selcx. infcx ( ) . fork ( ) , o) {
367
+ if resolve_negative_obligation ( selcx. infcx ( ) . fork ( ) , o, body_def_id ) {
363
368
return true ;
364
369
}
365
370
366
371
// Try to prove a negative obligation exists for super predicates
367
372
for o in util:: elaborate_predicates ( selcx. tcx ( ) , iter:: once ( o. predicate ) ) {
368
- if resolve_negative_obligation ( selcx. infcx ( ) . fork ( ) , & o) {
373
+ if resolve_negative_obligation ( selcx. infcx ( ) . fork ( ) , & o, body_def_id ) {
369
374
return true ;
370
375
}
371
376
}
@@ -377,6 +382,7 @@ fn negative_impl_exists<'cx, 'tcx>(
377
382
fn resolve_negative_obligation < ' cx , ' tcx > (
378
383
infcx : InferCtxt < ' cx , ' tcx > ,
379
384
o : & PredicateObligation < ' tcx > ,
385
+ body_def_id : DefId ,
380
386
) -> bool {
381
387
let tcx = infcx. tcx ;
382
388
@@ -390,7 +396,19 @@ fn resolve_negative_obligation<'cx, 'tcx>(
390
396
return false ;
391
397
}
392
398
393
- let outlives_env = OutlivesEnvironment :: new ( param_env) ;
399
+ let outlives_env = if let Some ( body_def_id) = body_def_id. as_local ( ) {
400
+ let body_id = tcx. hir ( ) . local_def_id_to_hir_id ( body_def_id) ;
401
+ let ocx = ObligationCtxt :: new ( & infcx) ;
402
+ let wf_tys = ocx. assumed_wf_types ( param_env, DUMMY_SP , body_def_id) ;
403
+ OutlivesEnvironment :: with_bounds (
404
+ param_env,
405
+ Some ( & infcx) ,
406
+ infcx. implied_bounds_tys ( param_env, body_id, wf_tys) ,
407
+ )
408
+ } else {
409
+ OutlivesEnvironment :: new ( param_env)
410
+ } ;
411
+
394
412
infcx. process_registered_region_obligations ( outlives_env. region_bound_pairs ( ) , param_env) ;
395
413
396
414
infcx. resolve_regions ( & outlives_env) . is_empty ( )
0 commit comments