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