@@ -13,8 +13,7 @@ use rustc_middle::ty::{
1313use rustc_span:: DUMMY_SP ;
1414use std:: ops:: ControlFlow ;
1515
16- use super :: search_graph:: SearchGraph ;
17- use super :: Goal ;
16+ use super :: { search_graph:: SearchGraph , Goal } ;
1817
1918pub struct EvalCtxt < ' a , ' tcx > {
2019 // FIXME: should be private.
@@ -33,14 +32,35 @@ pub struct EvalCtxt<'a, 'tcx> {
3332
3433 pub ( super ) search_graph : & ' a mut SearchGraph < ' tcx > ,
3534
36- /// This field is used by a debug assertion in [`EvalCtxt::evaluate_goal`],
37- /// see the comment in that method for more details.
38- pub in_projection_eq_hack : bool ,
35+ pub ( super ) nested_goals : NestedGoals < ' tcx > ,
36+ }
37+
38+ #[ derive( Debug , Clone ) ]
39+ pub ( super ) struct NestedGoals < ' tcx > {
40+ pub ( super ) projection_eq_hack_goal : Option < Goal < ' tcx , ty:: ProjectionPredicate < ' tcx > > > ,
41+ pub ( super ) goals : Vec < Goal < ' tcx , ty:: Predicate < ' tcx > > > ,
42+ }
43+
44+ impl NestedGoals < ' _ > {
45+ pub ( super ) fn new ( ) -> Self {
46+ Self { projection_eq_hack_goal : None , goals : Vec :: new ( ) }
47+ }
48+
49+ pub ( super ) fn is_empty ( & self ) -> bool {
50+ self . projection_eq_hack_goal . is_none ( ) && self . goals . is_empty ( )
51+ }
3952}
4053
4154impl < ' tcx > EvalCtxt < ' _ , ' tcx > {
4255 pub ( super ) fn probe < T > ( & mut self , f : impl FnOnce ( & mut EvalCtxt < ' _ , ' tcx > ) -> T ) -> T {
43- self . infcx . probe ( |_| f ( self ) )
56+ let mut ecx = EvalCtxt {
57+ infcx : self . infcx ,
58+ var_values : self . var_values ,
59+ max_input_universe : self . max_input_universe ,
60+ search_graph : self . search_graph ,
61+ nested_goals : self . nested_goals . clone ( ) ,
62+ } ;
63+ self . infcx . probe ( |_| f ( & mut ecx) )
4464 }
4565
4666 pub ( super ) fn tcx ( & self ) -> TyCtxt < ' tcx > {
@@ -61,6 +81,15 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
6181 )
6282 }
6383
84+ /// Returns a ty infer or a const infer depending on whether `kind` is a `Ty` or `Const`.
85+ /// If `kind` is an integer inference variable this will still return a ty infer var.
86+ pub ( super ) fn next_term_infer_of_kind ( & self , kind : ty:: Term < ' tcx > ) -> ty:: Term < ' tcx > {
87+ match kind. unpack ( ) {
88+ ty:: TermKind :: Ty ( _) => self . next_ty_infer ( ) . into ( ) ,
89+ ty:: TermKind :: Const ( ct) => self . next_const_infer ( ct. ty ( ) ) . into ( ) ,
90+ }
91+ }
92+
6493 /// Is the projection predicate is of the form `exists<T> <Ty as Trait>::Assoc = T`.
6594 ///
6695 /// This is the case if the `term` is an inference variable in the innermost universe
@@ -137,6 +166,25 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
137166
138167 #[ instrument( level = "debug" , skip( self , param_env) , ret) ]
139168 pub ( super ) fn eq < T : ToTrace < ' tcx > > (
169+ & mut self ,
170+ param_env : ty:: ParamEnv < ' tcx > ,
171+ lhs : T ,
172+ rhs : T ,
173+ ) -> Result < ( ) , NoSolution > {
174+ self . infcx
175+ . at ( & ObligationCause :: dummy ( ) , param_env)
176+ . eq ( DefineOpaqueTypes :: No , lhs, rhs)
177+ . map ( |InferOk { value : ( ) , obligations } | {
178+ self . add_goals ( obligations. into_iter ( ) . map ( |o| o. into ( ) ) ) ;
179+ } )
180+ . map_err ( |e| {
181+ debug ! ( ?e, "failed to equate" ) ;
182+ NoSolution
183+ } )
184+ }
185+
186+ #[ instrument( level = "debug" , skip( self , param_env) , ret) ]
187+ pub ( super ) fn eq_and_get_goals < T : ToTrace < ' tcx > > (
140188 & self ,
141189 param_env : ty:: ParamEnv < ' tcx > ,
142190 lhs : T ,
0 commit comments