@@ -38,6 +38,8 @@ use rustc_errors::Diagnostic;
3838use rustc_hir as hir;
3939use rustc_hir:: def_id:: DefId ;
4040use rustc_infer:: infer:: LateBoundRegionConversionTime ;
41+ use rustc_infer:: traits:: TraitEngine ;
42+ use rustc_infer:: traits:: TraitEngineExt ;
4143use rustc_middle:: dep_graph:: { DepKind , DepNodeIndex } ;
4244use rustc_middle:: mir:: interpret:: ErrorHandled ;
4345use rustc_middle:: ty:: abstract_const:: NotConstEvaluatable ;
@@ -47,6 +49,7 @@ use rustc_middle::ty::relate::TypeRelation;
4749use rustc_middle:: ty:: SubstsRef ;
4850use rustc_middle:: ty:: { self , EarlyBinder , PolyProjectionPredicate , ToPolyTraitRef , ToPredicate } ;
4951use rustc_middle:: ty:: { Ty , TyCtxt , TypeFoldable , TypeVisitable } ;
52+ use rustc_session:: config:: TraitSolver ;
5053use rustc_span:: symbol:: sym;
5154
5255use std:: cell:: { Cell , RefCell } ;
@@ -544,10 +547,14 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
544547 obligation : & PredicateObligation < ' tcx > ,
545548 ) -> Result < EvaluationResult , OverflowError > {
546549 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+ }
551558 } )
552559 }
553560
@@ -586,18 +593,40 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
586593 where
587594 I : IntoIterator < Item = PredicateObligation < ' tcx > > + std:: fmt:: Debug ,
588595 {
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+ }
598607 }
608+ Ok ( result)
609+ } else {
610+ self . evaluate_predicates_recursively_in_new_solver ( predicates)
599611 }
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 )
601630 }
602631
603632 #[ instrument(
0 commit comments