1
1
use rustc_middle:: ty;
2
+ use rustc_session:: config:: TraitSolver ;
2
3
3
4
use crate :: infer:: canonical:: OriginalQueryValues ;
4
5
use crate :: infer:: InferCtxt ;
6
+ use crate :: solve:: { Certainty , Goal , InferCtxtEvalExt , MaybeCause } ;
5
7
use crate :: traits:: { EvaluationResult , OverflowError , PredicateObligation , SelectionContext } ;
6
8
7
9
pub trait InferCtxtExt < ' tcx > {
@@ -77,12 +79,38 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
77
79
_ => obligation. param_env . without_const ( ) ,
78
80
} ;
79
81
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
+ }
86
114
}
87
115
88
116
// Helper function that canonicalizes and runs the query. If an
@@ -92,6 +120,9 @@ impl<'tcx> InferCtxtExt<'tcx> for InferCtxt<'tcx> {
92
120
& self ,
93
121
obligation : & PredicateObligation < ' tcx > ,
94
122
) -> 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`.
95
126
match self . evaluate_obligation ( obligation) {
96
127
Ok ( result) => result,
97
128
Err ( OverflowError :: Canonical ) => {
0 commit comments