66
77use crate :: infer:: outlives:: env:: OutlivesEnvironment ;
88use crate :: infer:: { CombinedSnapshot , InferOk } ;
9+ use crate :: traits:: outlives_bounds:: InferCtxtExt as _;
910use crate :: traits:: select:: IntercrateAmbiguityCause ;
1011use crate :: traits:: util:: impl_subject_and_oblig;
1112use crate :: traits:: SkipLeakCheck ;
1213use crate :: traits:: {
13- self , Normalized , Obligation , ObligationCause , PredicateObligation , PredicateObligations ,
14- SelectionContext ,
14+ self , Normalized , Obligation , ObligationCause , ObligationCtxt , PredicateObligation ,
15+ PredicateObligations , SelectionContext ,
1516} ;
1617use rustc_data_structures:: fx:: FxIndexSet ;
1718use rustc_errors:: Diagnostic ;
@@ -322,7 +323,7 @@ fn negative_impl<'cx, 'tcx>(
322323 let ( subject2, obligations) =
323324 impl_subject_and_oblig ( selcx, impl_env, impl2_def_id, impl2_substs) ;
324325
325- !equate ( & infcx, impl_env, subject1, subject2, obligations)
326+ !equate ( & infcx, impl_env, subject1, subject2, obligations, impl1_def_id )
326327 } )
327328}
328329
@@ -332,6 +333,7 @@ fn equate<'cx, 'tcx>(
332333 subject1 : ImplSubject < ' tcx > ,
333334 subject2 : ImplSubject < ' tcx > ,
334335 obligations : impl Iterator < Item = PredicateObligation < ' tcx > > ,
336+ body_def_id : DefId ,
335337) -> bool {
336338 // do the impls unify? If not, not disjoint.
337339 let Ok ( InferOk { obligations : more_obligations, .. } ) =
@@ -342,8 +344,10 @@ fn equate<'cx, 'tcx>(
342344 } ;
343345
344346 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) ) ;
347351
348352 if let Some ( failing_obligation) = opt_failing_obligation {
349353 debug ! ( "overlap: obligation unsatisfiable {:?}" , failing_obligation) ;
@@ -358,14 +362,15 @@ fn equate<'cx, 'tcx>(
358362fn negative_impl_exists < ' cx , ' tcx > (
359363 selcx : & SelectionContext < ' cx , ' tcx > ,
360364 o : & PredicateObligation < ' tcx > ,
365+ body_def_id : DefId ,
361366) -> bool {
362- if resolve_negative_obligation ( selcx. infcx ( ) . fork ( ) , o) {
367+ if resolve_negative_obligation ( selcx. infcx ( ) . fork ( ) , o, body_def_id ) {
363368 return true ;
364369 }
365370
366371 // Try to prove a negative obligation exists for super predicates
367372 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 ) {
369374 return true ;
370375 }
371376 }
@@ -377,6 +382,7 @@ fn negative_impl_exists<'cx, 'tcx>(
377382fn resolve_negative_obligation < ' cx , ' tcx > (
378383 infcx : InferCtxt < ' cx , ' tcx > ,
379384 o : & PredicateObligation < ' tcx > ,
385+ body_def_id : DefId ,
380386) -> bool {
381387 let tcx = infcx. tcx ;
382388
@@ -390,7 +396,19 @@ fn resolve_negative_obligation<'cx, 'tcx>(
390396 return false ;
391397 }
392398
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+
394412 infcx. process_registered_region_obligations ( outlives_env. region_bound_pairs ( ) , param_env) ;
395413
396414 infcx. resolve_regions ( & outlives_env) . is_empty ( )
0 commit comments