11use rustc_middle:: ty;
2+ use rustc_session:: config:: TraitSolver ;
23
34use crate :: infer:: canonical:: OriginalQueryValues ;
45use crate :: infer:: InferCtxt ;
6+ use crate :: solve:: { Certainty , Goal , InferCtxtEvalExt , MaybeCause } ;
57use crate :: traits:: { EvaluationResult , OverflowError , PredicateObligation , SelectionContext } ;
68
79pub trait InferCtxtExt < ' tcx > {
@@ -77,12 +79,38 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
7779 _ => obligation. param_env . without_const ( ) ,
7880 } ;
7981
80- let c_pred = self
81- . canonicalize_query_keep_static ( param_env. and ( obligation. predicate ) , & mut _orig_values) ;
82- // Run canonical query. If overflow occurs, rerun from scratch but this time
83- // in standard trait query mode so that overflow is handled appropriately
84- // within `SelectionContext`.
85- self . tcx . at ( obligation. cause . span ( ) ) . evaluate_obligation ( c_pred)
82+ if self . tcx . sess . opts . unstable_opts . trait_solver != TraitSolver :: Next {
83+ let c_pred = self . canonicalize_query_keep_static (
84+ param_env. and ( obligation. predicate ) ,
85+ & mut _orig_values,
86+ ) ;
87+ self . tcx . at ( obligation. cause . span ( ) ) . evaluate_obligation ( c_pred)
88+ } else {
89+ self . probe ( |snapshot| {
90+ if let Ok ( ( _, certainty) ) =
91+ self . evaluate_root_goal ( Goal :: new ( self . tcx , param_env, obligation. predicate ) )
92+ {
93+ match certainty {
94+ Certainty :: Yes => {
95+ if self . opaque_types_added_in_snapshot ( snapshot) {
96+ Ok ( EvaluationResult :: EvaluatedToOkModuloOpaqueTypes )
97+ } else if self . region_constraints_added_in_snapshot ( snapshot) . is_some ( )
98+ {
99+ Ok ( EvaluationResult :: EvaluatedToOkModuloRegions )
100+ } else {
101+ Ok ( EvaluationResult :: EvaluatedToOk )
102+ }
103+ }
104+ Certainty :: Maybe ( MaybeCause :: Ambiguity ) => {
105+ Ok ( EvaluationResult :: EvaluatedToAmbig )
106+ }
107+ Certainty :: Maybe ( MaybeCause :: Overflow ) => Err ( OverflowError :: Canonical ) ,
108+ }
109+ } else {
110+ Ok ( EvaluationResult :: EvaluatedToErr )
111+ }
112+ } )
113+ }
86114 }
87115
88116 // Helper function that canonicalizes and runs the query. If an
@@ -92,6 +120,9 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
92120 & self ,
93121 obligation : & PredicateObligation < ' tcx > ,
94122 ) -> EvaluationResult {
123+ // Run canonical query. If overflow occurs, rerun from scratch but this time
124+ // in standard trait query mode so that overflow is handled appropriately
125+ // within `SelectionContext`.
95126 match self . evaluate_obligation ( obligation) {
96127 Ok ( result) => result,
97128 Err ( OverflowError :: Canonical ) => {
0 commit comments