@@ -8,23 +8,21 @@ use crate::infer::outlives::env::OutlivesEnvironment;
8
8
use crate :: infer:: InferOk ;
9
9
use crate :: regions:: InferCtxtRegionExt ;
10
10
use 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 _;
14
13
use crate :: traits:: select:: IntercrateAmbiguityCause ;
15
14
use crate :: traits:: structural_normalize:: StructurallyNormalizeExt ;
16
15
use crate :: traits:: NormalizeExt ;
17
16
use crate :: traits:: SkipLeakCheck ;
18
17
use crate :: traits:: {
19
- Obligation , ObligationCause , ObligationCtxt , PredicateObligation , PredicateObligations ,
20
- SelectionContext ,
18
+ Obligation , ObligationCause , PredicateObligation , PredicateObligations , SelectionContext ,
21
19
} ;
22
20
use rustc_data_structures:: fx:: FxIndexSet ;
23
21
use rustc_errors:: Diagnostic ;
24
22
use rustc_hir:: def:: DefKind ;
25
23
use rustc_hir:: def_id:: { DefId , LOCAL_CRATE } ;
26
24
use rustc_infer:: infer:: { DefineOpaqueTypes , InferCtxt , TyCtxtInferExt } ;
27
- use rustc_infer:: traits:: { util, TraitEngine } ;
25
+ use rustc_infer:: traits:: { util, TraitEngine , TraitEngineExt } ;
28
26
use rustc_middle:: traits:: query:: NoSolution ;
29
27
use rustc_middle:: traits:: solve:: { CandidateSource , Certainty , Goal } ;
30
28
use rustc_middle:: traits:: specialization_graph:: OverlapMode ;
@@ -310,29 +308,37 @@ fn equate_impl_headers<'tcx>(
310
308
fn impl_intersection_has_impossible_obligation < ' a , ' cx , ' tcx > (
311
309
selcx : & mut SelectionContext < ' cx , ' tcx > ,
312
310
obligations : & ' a [ PredicateObligation < ' tcx > ] ,
313
- ) -> Option < & ' a PredicateObligation < ' tcx > > {
311
+ ) -> Option < PredicateObligation < ' tcx > > {
314
312
let infcx = selcx. infcx ;
315
313
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
+ infcx. probe ( |_| {
316
+ let mut fulfill_cx = FulfillmentCtxt :: new ( infcx) ;
317
+ fulfill_cx. register_predicate_obligations ( infcx, obligations. iter ( ) . cloned ( ) ) ;
318
+
319
+ // We only care about the obligations that are *definitely* true errors.
320
+ // Ambiguities do not prove the disjointness of two impls.
321
+ let mut errors = fulfill_cx. select_where_possible ( infcx) ;
322
+ errors. pop ( ) . map ( |err| err. obligation )
323
+ } )
324
+ } else {
325
+ obligations. iter ( ) . cloned ( ) . find ( |obligation| {
320
326
// We use `evaluate_root_obligation` to correctly track intercrate
321
327
// 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
- } )
328
+ let evaluation_result = selcx. evaluate_root_obligation ( obligation) ;
329
+
330
+ match evaluation_result {
331
+ Ok ( result ) => !result . may_apply ( ) ,
332
+ // If overflow occurs, we need to conservatively treat the goal as possibly holding ,
333
+ // since there can be instantiations of this goal that don't overflow and result in
334
+ // success. This isn't much of a problem in the old solver, since we treat overflow
335
+ // fatally (this still can be encountered: <https://github.com/rust-lang/rust/issues/105231>),
336
+ // but in the new solver, this is very important for correctness, since overflow
337
+ // *must* be treated as ambiguity for completeness.
338
+ Err ( _overflow ) => false ,
339
+ }
340
+ } )
341
+ }
336
342
}
337
343
338
344
/// Check if both impls can be satisfied by a common type by considering whether
@@ -522,15 +528,13 @@ fn try_prove_negated_where_clause<'tcx>(
522
528
// Without this, we over-eagerly register coherence ambiguity candidates when
523
529
// impl candidates do exist.
524
530
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 ( ) {
531
+ let mut fulfill_cx = FulfillmentCtxt :: new ( infcx) ;
532
+
533
+ fulfill_cx. register_predicate_obligation (
534
+ infcx,
535
+ Obligation :: new ( infcx. tcx , ObligationCause :: dummy ( ) , param_env, negative_predicate) ,
536
+ ) ;
537
+ if !fulfill_cx. select_all_or_error ( infcx) . is_empty ( ) {
534
538
return false ;
535
539
}
536
540
0 commit comments