@@ -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,35 @@ 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
+ 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| {
320
324
// We use `evaluate_root_obligation` to correctly track intercrate
321
325
// 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
+ }
336
340
}
337
341
338
342
/// 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>(
522
526
// Without this, we over-eagerly register coherence ambiguity candidates when
523
527
// impl candidates do exist.
524
528
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 ( ) {
534
536
return false ;
535
537
}
536
538
0 commit comments