@@ -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