@@ -6,23 +6,42 @@ use rustc_infer::infer::{
66    DefineOpaqueTypes ,  InferCtxt ,  InferOk ,  LateBoundRegionConversionTime ,  TyCtxtInferExt , 
77} ; 
88use  rustc_infer:: traits:: query:: NoSolution ; 
9- use  rustc_infer:: traits:: solve:: { CanonicalGoal ,  Certainty ,  MaybeCause ,  QueryResult } ; 
109use  rustc_infer:: traits:: ObligationCause ; 
1110use  rustc_middle:: infer:: unify_key:: { ConstVariableOrigin ,  ConstVariableOriginKind } ; 
11+ use  rustc_middle:: traits:: solve:: { CanonicalGoal ,  Certainty ,  MaybeCause ,  QueryResult } ; 
1212use  rustc_middle:: ty:: { 
1313    self ,  Ty ,  TyCtxt ,  TypeFoldable ,  TypeSuperVisitable ,  TypeVisitable ,  TypeVisitableExt , 
1414    TypeVisitor , 
1515} ; 
1616use  rustc_span:: DUMMY_SP ; 
1717use  std:: ops:: ControlFlow ; 
1818
19+ use  crate :: traits:: specialization_graph; 
20+ 
1921use  super :: search_graph:: { self ,  OverflowHandler } ; 
2022use  super :: SolverMode ; 
2123use  super :: { search_graph:: SearchGraph ,  Goal } ; 
2224
25+ mod  canonical; 
26+ 
2327pub  struct  EvalCtxt < ' a ,  ' tcx >  { 
24-     // FIXME: should be private. 
25-     pub ( super )  infcx :  & ' a  InferCtxt < ' tcx > , 
28+     /// The inference context that backs (mostly) inference and placeholder terms 
29+ /// instantiated while solving goals. 
30+ /// 
31+ /// NOTE: The `InferCtxt` that backs the `EvalCtxt` is intentionally private, 
32+ /// because the `InferCtxt` is much more general than `EvalCtxt`. Methods such 
33+ /// as  `take_registered_region_obligations` can mess up query responses, 
34+ /// using `At::normalize` is totally wrong, calling `evaluate_root_goal` can 
35+ /// cause coinductive unsoundness, etc. 
36+ /// 
37+ /// Methods that are generally of use for trait solving are *intentionally* 
38+ /// re-declared through the `EvalCtxt` below, often with cleaner signatures 
39+ /// since we don't care about things like `ObligationCause`s and `Span`s here. 
40+ /// If some `InferCtxt` method is missing, please first think defensively about 
41+ /// the method's compatibility with this solver, or if an existing one does 
42+ /// the job already. 
43+ infcx :  & ' a  InferCtxt < ' tcx > , 
44+ 
2645    pub ( super )  var_values :  CanonicalVarValues < ' tcx > , 
2746    /// The highest universe index nameable by the caller. 
2847/// 
@@ -393,7 +412,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
393412                if  let  & ty:: Infer ( ty:: TyVar ( vid) )  = ty. kind ( )  { 
394413                    match  self . infcx . probe_ty_var ( vid)  { 
395414                        Ok ( value)  => bug ! ( "resolved var in query: {goal:?} {value:?}" ) , 
396-                         Err ( universe)  => universe == self . universe ( ) , 
415+                         Err ( universe)  => universe == self . infcx . universe ( ) , 
397416                    } 
398417                }  else  { 
399418                    false 
@@ -403,7 +422,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
403422                if  let  ty:: ConstKind :: Infer ( ty:: InferConst :: Var ( vid) )  = ct. kind ( )  { 
404423                    match  self . infcx . probe_const_var ( vid)  { 
405424                        Ok ( value)  => bug ! ( "resolved var in query: {goal:?} {value:?}" ) , 
406-                         Err ( universe)  => universe == self . universe ( ) , 
425+                         Err ( universe)  => universe == self . infcx . universe ( ) , 
407426                    } 
408427                }  else  { 
409428                    false 
@@ -545,7 +564,43 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
545564        self . infcx . fresh_substs_for_item ( DUMMY_SP ,  def_id) 
546565    } 
547566
548-     pub ( super )  fn  universe ( & self )  -> ty:: UniverseIndex  { 
549-         self . infcx . universe ( ) 
567+     pub ( super )  fn  translate_substs ( 
568+         & self , 
569+         param_env :  ty:: ParamEnv < ' tcx > , 
570+         source_impl :  DefId , 
571+         source_substs :  ty:: SubstsRef < ' tcx > , 
572+         target_node :  specialization_graph:: Node , 
573+     )  -> ty:: SubstsRef < ' tcx >  { 
574+         crate :: traits:: translate_substs ( 
575+             self . infcx , 
576+             param_env, 
577+             source_impl, 
578+             source_substs, 
579+             target_node, 
580+         ) 
581+     } 
582+ 
583+     pub ( super )  fn  register_ty_outlives ( & self ,  ty :  Ty < ' tcx > ,  lt :  ty:: Region < ' tcx > )  { 
584+         self . infcx . register_region_obligation_with_cause ( ty,  lt,  & ObligationCause :: dummy ( ) ) ; 
585+     } 
586+ 
587+     pub ( super )  fn  register_region_outlives ( & self ,  a :  ty:: Region < ' tcx > ,  b :  ty:: Region < ' tcx > )  { 
588+         // `b : a` ==> `a <= b` 
589+         // (inlined from `InferCtxt::region_outlives_predicate`) 
590+         self . infcx . sub_regions ( 
591+             rustc_infer:: infer:: SubregionOrigin :: RelateRegionParamBound ( DUMMY_SP ) , 
592+             b, 
593+             a, 
594+         ) ; 
595+     } 
596+ 
597+     /// Computes the list of goals required for `arg` to be well-formed 
598+ pub ( super )  fn  well_formed_goals ( 
599+         & self , 
600+         param_env :  ty:: ParamEnv < ' tcx > , 
601+         arg :  ty:: GenericArg < ' tcx > , 
602+     )  -> Option < impl  Iterator < Item  = Goal < ' tcx ,  ty:: Predicate < ' tcx > > > >  { 
603+         crate :: traits:: wf:: unnormalized_obligations ( self . infcx ,  param_env,  arg) 
604+             . map ( |obligations| obligations. into_iter ( ) . map ( |obligation| obligation. into ( ) ) ) 
550605    } 
551606} 
0 commit comments