@@ -8,23 +8,21 @@ use crate::infer::outlives::env::OutlivesEnvironment;
88use crate :: infer:: InferOk ;
99use crate :: regions:: InferCtxtRegionExt ;
1010use crate :: solve:: inspect:: { InspectGoal , ProofTreeInferCtxtExt , ProofTreeVisitor } ;
11- use crate :: solve:: { deeply_normalize_for_diagnostics, inspect} ;
12- use crate :: traits:: engine:: TraitEngineExt ;
13- use crate :: traits:: query:: evaluate_obligation:: InferCtxtExt ;
11+ use crate :: solve:: { deeply_normalize_for_diagnostics, inspect, FulfillmentCtxt } ;
12+ use crate :: traits:: engine:: TraitEngineExt as _;
1413use crate :: traits:: select:: IntercrateAmbiguityCause ;
1514use crate :: traits:: structural_normalize:: StructurallyNormalizeExt ;
1615use crate :: traits:: NormalizeExt ;
1716use crate :: traits:: SkipLeakCheck ;
1817use crate :: traits:: {
19- Obligation , ObligationCause , ObligationCtxt , PredicateObligation , PredicateObligations ,
20- SelectionContext ,
18+ Obligation , ObligationCause , PredicateObligation , PredicateObligations , SelectionContext ,
2119} ;
2220use rustc_data_structures:: fx:: FxIndexSet ;
2321use rustc_errors:: Diagnostic ;
2422use rustc_hir:: def:: DefKind ;
2523use rustc_hir:: def_id:: { DefId , LOCAL_CRATE } ;
2624use rustc_infer:: infer:: { DefineOpaqueTypes , InferCtxt , TyCtxtInferExt } ;
27- use rustc_infer:: traits:: { util, TraitEngine } ;
25+ use rustc_infer:: traits:: { util, TraitEngine , TraitEngineExt } ;
2826use rustc_middle:: traits:: query:: NoSolution ;
2927use rustc_middle:: traits:: solve:: { CandidateSource , Certainty , Goal } ;
3028use rustc_middle:: traits:: specialization_graph:: OverlapMode ;
@@ -310,29 +308,35 @@ fn equate_impl_headers<'tcx>(
310308fn impl_intersection_has_impossible_obligation < ' a , ' cx , ' tcx > (
311309 selcx : & mut SelectionContext < ' cx , ' tcx > ,
312310 obligations : & ' a [ PredicateObligation < ' tcx > ] ,
313- ) -> Option < & ' a PredicateObligation < ' tcx > > {
311+ ) -> Option < PredicateObligation < ' tcx > > {
314312 let infcx = selcx. infcx ;
315313
316- obligations. iter ( ) . find ( |obligation| {
317- let evaluation_result = if infcx. next_trait_solver ( ) {
318- infcx. evaluate_obligation ( obligation)
319- } else {
314+ if infcx. next_trait_solver ( ) {
315+ let mut fulfill_cx = FulfillmentCtxt :: new ( infcx) ;
316+ fulfill_cx. register_predicate_obligations ( infcx, obligations. iter ( ) . cloned ( ) ) ;
317+
318+ // We only care about the obligations that are *definitely* true errors.
319+ // Ambiguities do not prove the disjointness of two impls.
320+ let mut errors = fulfill_cx. select_where_possible ( infcx) ;
321+ errors. pop ( ) . map ( |err| err. obligation )
322+ } else {
323+ obligations. iter ( ) . cloned ( ) . find ( |obligation| {
320324 // We use `evaluate_root_obligation` to correctly track intercrate
321325 // ambiguity clauses. We cannot use this in the new solver.
322- selcx. evaluate_root_obligation ( obligation)
323- } ;
324-
325- match evaluation_result {
326- Ok ( result ) => !result . may_apply ( ) ,
327- // If overflow occurs, we need to conservatively treat the goal as possibly holding,
328- // since there can be instantiations of this goal that don't overflow and result in
329- // success. This isn't much of a problem in the old solver, since we treat overflow
330- // fatally ( this still can be encountered: <https://github.com/rust-lang/rust/issues/105231>),
331- // but in the new solver, this is very important for correctness, since overflow
332- // *must* be treated as ambiguity for completeness.
333- Err ( _overflow ) => false ,
334- }
335- } )
326+ let evaluation_result = selcx. evaluate_root_obligation ( obligation) ;
327+
328+ match evaluation_result {
329+ Ok ( result ) => !result . may_apply ( ) ,
330+ // If overflow occurs, we need to conservatively treat the goal as possibly holding ,
331+ // since there can be instantiations of this goal that don't overflow and result in
332+ // success. This isn't much of a problem in the old solver, since we treat overflow
333+ // fatally (this still can be encountered: <https://github.com/rust-lang/rust/issues/105231>),
334+ // but in the new solver, this is very important for correctness, since overflow
335+ // *must* be treated as ambiguity for completeness.
336+ Err ( _overflow ) => false ,
337+ }
338+ } )
339+ }
336340}
337341
338342/// Check if both impls can be satisfied by a common type by considering whether
@@ -522,15 +526,13 @@ fn try_prove_negated_where_clause<'tcx>(
522526 // Without this, we over-eagerly register coherence ambiguity candidates when
523527 // impl candidates do exist.
524528 let ref infcx = root_infcx. fork_with_intercrate ( false ) ;
525- let ocx = ObligationCtxt :: new ( infcx) ;
526-
527- ocx. register_obligation ( Obligation :: new (
528- infcx. tcx ,
529- ObligationCause :: dummy ( ) ,
530- param_env,
531- negative_predicate,
532- ) ) ;
533- if !ocx. select_all_or_error ( ) . is_empty ( ) {
529+ let mut fulfill_cx = FulfillmentCtxt :: new ( infcx) ;
530+
531+ fulfill_cx. register_predicate_obligation (
532+ infcx,
533+ Obligation :: new ( infcx. tcx , ObligationCause :: dummy ( ) , param_env, negative_predicate) ,
534+ ) ;
535+ if !fulfill_cx. select_all_or_error ( infcx) . is_empty ( ) {
534536 return false ;
535537 }
536538
0 commit comments