@@ -38,6 +38,8 @@ use rustc_errors::Diagnostic;
38
38
use rustc_hir as hir;
39
39
use rustc_hir:: def_id:: DefId ;
40
40
use rustc_infer:: infer:: LateBoundRegionConversionTime ;
41
+ use rustc_infer:: traits:: TraitEngine ;
42
+ use rustc_infer:: traits:: TraitEngineExt ;
41
43
use rustc_middle:: dep_graph:: { DepKind , DepNodeIndex } ;
42
44
use rustc_middle:: mir:: interpret:: ErrorHandled ;
43
45
use rustc_middle:: ty:: abstract_const:: NotConstEvaluatable ;
@@ -47,6 +49,7 @@ use rustc_middle::ty::relate::TypeRelation;
47
49
use rustc_middle:: ty:: SubstsRef ;
48
50
use rustc_middle:: ty:: { self , EarlyBinder , PolyProjectionPredicate , ToPolyTraitRef , ToPredicate } ;
49
51
use rustc_middle:: ty:: { Ty , TyCtxt , TypeFoldable , TypeVisitable } ;
52
+ use rustc_session:: config:: TraitSolver ;
50
53
use rustc_span:: symbol:: sym;
51
54
52
55
use std:: cell:: { Cell , RefCell } ;
@@ -544,10 +547,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
544
547
obligation : & PredicateObligation < ' tcx > ,
545
548
) -> Result < EvaluationResult , OverflowError > {
546
549
self . evaluation_probe ( |this| {
547
- this. evaluate_predicate_recursively (
548
- TraitObligationStackList :: empty ( & ProvisionalEvaluationCache :: default ( ) ) ,
549
- obligation. clone ( ) ,
550
- )
550
+ if this. tcx ( ) . sess . opts . unstable_opts . trait_solver != TraitSolver :: Next {
551
+ this. evaluate_predicate_recursively (
552
+ TraitObligationStackList :: empty ( & ProvisionalEvaluationCache :: default ( ) ) ,
553
+ obligation. clone ( ) ,
554
+ )
555
+ } else {
556
+ this. evaluate_predicates_recursively_in_new_solver ( [ obligation. clone ( ) ] )
557
+ }
551
558
} )
552
559
}
553
560
@@ -586,18 +593,40 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
586
593
where
587
594
I : IntoIterator < Item = PredicateObligation < ' tcx > > + std:: fmt:: Debug ,
588
595
{
589
- let mut result = EvaluatedToOk ;
590
- for obligation in predicates {
591
- let eval = self . evaluate_predicate_recursively ( stack, obligation. clone ( ) ) ?;
592
- if let EvaluatedToErr = eval {
593
- // fast-path - EvaluatedToErr is the top of the lattice,
594
- // so we don't need to look on the other predicates.
595
- return Ok ( EvaluatedToErr ) ;
596
- } else {
597
- result = cmp:: max ( result, eval) ;
596
+ if self . tcx ( ) . sess . opts . unstable_opts . trait_solver != TraitSolver :: Next {
597
+ let mut result = EvaluatedToOk ;
598
+ for obligation in predicates {
599
+ let eval = self . evaluate_predicate_recursively ( stack, obligation. clone ( ) ) ?;
600
+ if let EvaluatedToErr = eval {
601
+ // fast-path - EvaluatedToErr is the top of the lattice,
602
+ // so we don't need to look on the other predicates.
603
+ return Ok ( EvaluatedToErr ) ;
604
+ } else {
605
+ result = cmp:: max ( result, eval) ;
606
+ }
598
607
}
608
+ Ok ( result)
609
+ } else {
610
+ self . evaluate_predicates_recursively_in_new_solver ( predicates)
599
611
}
600
- Ok ( result)
612
+ }
613
+
614
+ /// Evaluates the predicates using the new solver when `-Ztrait-solver=next` is enabled
615
+ fn evaluate_predicates_recursively_in_new_solver (
616
+ & mut self ,
617
+ predicates : impl IntoIterator < Item = PredicateObligation < ' tcx > > ,
618
+ ) -> Result < EvaluationResult , OverflowError > {
619
+ let mut fulfill_cx = crate :: solve:: FulfillmentCtxt :: new ( ) ;
620
+ fulfill_cx. register_predicate_obligations ( self . infcx , predicates) ;
621
+ // True errors
622
+ if !fulfill_cx. select_where_possible ( self . infcx ) . is_empty ( ) {
623
+ return Ok ( EvaluatedToErr ) ;
624
+ }
625
+ if !fulfill_cx. select_all_or_error ( self . infcx ) . is_empty ( ) {
626
+ return Ok ( EvaluatedToAmbig ) ;
627
+ }
628
+ // Regions and opaques are handled in the `evaluation_probe` by looking at the snapshot
629
+ Ok ( EvaluatedToOk )
601
630
}
602
631
603
632
#[ instrument(
0 commit comments