@@ -6,23 +6,42 @@ use rustc_infer::infer::{
6
6
DefineOpaqueTypes , InferCtxt , InferOk , LateBoundRegionConversionTime , TyCtxtInferExt ,
7
7
} ;
8
8
use rustc_infer:: traits:: query:: NoSolution ;
9
- use rustc_infer:: traits:: solve:: { CanonicalGoal , Certainty , MaybeCause , QueryResult } ;
10
9
use rustc_infer:: traits:: ObligationCause ;
11
10
use rustc_middle:: infer:: unify_key:: { ConstVariableOrigin , ConstVariableOriginKind } ;
11
+ use rustc_middle:: traits:: solve:: { CanonicalGoal , Certainty , MaybeCause , QueryResult } ;
12
12
use rustc_middle:: ty:: {
13
13
self , Ty , TyCtxt , TypeFoldable , TypeSuperVisitable , TypeVisitable , TypeVisitableExt ,
14
14
TypeVisitor ,
15
15
} ;
16
16
use rustc_span:: DUMMY_SP ;
17
17
use std:: ops:: ControlFlow ;
18
18
19
+ use crate :: traits:: specialization_graph;
20
+
19
21
use super :: search_graph:: { self , OverflowHandler } ;
20
22
use super :: SolverMode ;
21
23
use super :: { search_graph:: SearchGraph , Goal } ;
22
24
25
+ mod canonical;
26
+
23
27
pub 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
+
26
45
pub ( super ) var_values : CanonicalVarValues < ' tcx > ,
27
46
/// The highest universe index nameable by the caller.
28
47
///
@@ -393,7 +412,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
393
412
if let & ty:: Infer ( ty:: TyVar ( vid) ) = ty. kind ( ) {
394
413
match self . infcx . probe_ty_var ( vid) {
395
414
Ok ( value) => bug ! ( "resolved var in query: {goal:?} {value:?}" ) ,
396
- Err ( universe) => universe == self . universe ( ) ,
415
+ Err ( universe) => universe == self . infcx . universe ( ) ,
397
416
}
398
417
} else {
399
418
false
@@ -403,7 +422,7 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
403
422
if let ty:: ConstKind :: Infer ( ty:: InferConst :: Var ( vid) ) = ct. kind ( ) {
404
423
match self . infcx . probe_const_var ( vid) {
405
424
Ok ( value) => bug ! ( "resolved var in query: {goal:?} {value:?}" ) ,
406
- Err ( universe) => universe == self . universe ( ) ,
425
+ Err ( universe) => universe == self . infcx . universe ( ) ,
407
426
}
408
427
} else {
409
428
false
@@ -545,7 +564,43 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
545
564
self . infcx . fresh_substs_for_item ( DUMMY_SP , def_id)
546
565
}
547
566
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 ( ) ) )
550
605
}
551
606
}
0 commit comments