|
1 | 1 | use rustc_hir::def_id::DefId;
|
2 | 2 | use rustc_infer::infer::at::ToTrace;
|
3 |
| -use rustc_infer::infer::canonical::CanonicalVarValues; |
| 3 | +use rustc_infer::infer::canonical::query_response::make_query_region_constraints; |
| 4 | +use rustc_infer::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarValues}; |
4 | 5 | use rustc_infer::infer::type_variable::{TypeVariableOrigin, TypeVariableOriginKind};
|
5 | 6 | use rustc_infer::infer::{
|
6 | 7 | DefineOpaqueTypes, InferCtxt, InferOk, LateBoundRegionConversionTime, TyCtxtInferExt,
|
7 | 8 | };
|
8 | 9 | use rustc_infer::traits::query::NoSolution;
|
9 |
| -use rustc_infer::traits::solve::{CanonicalGoal, Certainty, MaybeCause, QueryResult}; |
10 | 10 | use rustc_infer::traits::ObligationCause;
|
11 | 11 | use rustc_middle::infer::unify_key::{ConstVariableOrigin, ConstVariableOriginKind};
|
| 12 | +use rustc_middle::traits::solve::{ |
| 13 | + CanonicalGoal, Certainty, ExternalConstraints, ExternalConstraintsData, MaybeCause, QueryResult, |
| 14 | +}; |
12 | 15 | use rustc_middle::ty::{
|
13 | 16 | self, Ty, TyCtxt, TypeFoldable, TypeSuperVisitable, TypeVisitable, TypeVisitableExt,
|
14 | 17 | TypeVisitor,
|
15 | 18 | };
|
16 | 19 | use rustc_span::DUMMY_SP;
|
17 | 20 | use std::ops::ControlFlow;
|
18 | 21 |
|
| 22 | +use crate::traits::specialization_graph; |
| 23 | + |
| 24 | +use super::canonical::{CanonicalizeMode, Canonicalizer}; |
19 | 25 | use super::search_graph::{self, OverflowHandler};
|
20 | 26 | use super::SolverMode;
|
21 | 27 | use super::{search_graph::SearchGraph, Goal};
|
22 | 28 |
|
23 | 29 | pub struct EvalCtxt<'a, 'tcx> {
|
24 |
| - // FIXME: should be private. |
25 |
| - pub(super) infcx: &'a InferCtxt<'tcx>, |
| 30 | + /// The inference context that backs (mostly) inference and placeholder terms |
| 31 | + /// instantiated while solving goals. |
| 32 | + /// |
| 33 | + /// NOTE: The `InferCtxt` that backs the `EvalCtxt` is intentionally private, |
| 34 | + /// because the `InferCtxt` is much more general than `EvalCtxt`. Methods such |
| 35 | + /// as `take_registered_region_obligations` can mess up query responses, |
| 36 | + /// using `At::normalize` is totally wrong, calling `evaluate_root_goal` can |
| 37 | + /// cause coinductive unsoundness, etc. |
| 38 | + /// |
| 39 | + /// Methods that are generally of use for trait solving are *intentionally* |
| 40 | + /// re-declared through the `EvalCtxt` below, often with cleaner signatures |
| 41 | + /// since we don't care about things like `ObligationCause`s and `Span`s here. |
| 42 | + /// If some `InferCtxt` method is missing, please first think defensively about |
| 43 | + /// the method's compatibility with this solver, or if an existing one does |
| 44 | + /// the job already. |
| 45 | + infcx: &'a InferCtxt<'tcx>, |
| 46 | + |
26 | 47 | pub(super) var_values: CanonicalVarValues<'tcx>,
|
27 | 48 | /// The highest universe index nameable by the caller.
|
28 | 49 | ///
|
@@ -548,4 +569,87 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
|
548 | 569 | pub(super) fn universe(&self) -> ty::UniverseIndex {
|
549 | 570 | self.infcx.universe()
|
550 | 571 | }
|
| 572 | + |
| 573 | + pub(super) fn create_next_universe(&self) -> ty::UniverseIndex { |
| 574 | + self.infcx.create_next_universe() |
| 575 | + } |
| 576 | + |
| 577 | + pub(super) fn instantiate_canonical_var( |
| 578 | + &self, |
| 579 | + cv_info: CanonicalVarInfo<'tcx>, |
| 580 | + universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex, |
| 581 | + ) -> ty::GenericArg<'tcx> { |
| 582 | + self.infcx.instantiate_canonical_var(DUMMY_SP, cv_info, universe_map) |
| 583 | + } |
| 584 | + |
| 585 | + pub(super) fn translate_substs( |
| 586 | + &self, |
| 587 | + param_env: ty::ParamEnv<'tcx>, |
| 588 | + source_impl: DefId, |
| 589 | + source_substs: ty::SubstsRef<'tcx>, |
| 590 | + target_node: specialization_graph::Node, |
| 591 | + ) -> ty::SubstsRef<'tcx> { |
| 592 | + crate::traits::translate_substs( |
| 593 | + self.infcx, |
| 594 | + param_env, |
| 595 | + source_impl, |
| 596 | + source_substs, |
| 597 | + target_node, |
| 598 | + ) |
| 599 | + } |
| 600 | + |
| 601 | + pub(super) fn register_ty_outlives(&self, ty: Ty<'tcx>, lt: ty::Region<'tcx>) { |
| 602 | + self.infcx.register_region_obligation_with_cause(ty, lt, &ObligationCause::dummy()); |
| 603 | + } |
| 604 | + |
| 605 | + pub(super) fn register_region_outlives(&self, a: ty::Region<'tcx>, b: ty::Region<'tcx>) { |
| 606 | + // `b : a` ==> `a <= b` |
| 607 | + // (inlined from `InferCtxt::region_outlives_predicate`) |
| 608 | + self.infcx.sub_regions( |
| 609 | + rustc_infer::infer::SubregionOrigin::RelateRegionParamBound(DUMMY_SP), |
| 610 | + b, |
| 611 | + a, |
| 612 | + ); |
| 613 | + } |
| 614 | + |
| 615 | + /// Computes the list of goals required for `arg` to be well-formed |
| 616 | + pub(super) fn well_formed_goals( |
| 617 | + &self, |
| 618 | + param_env: ty::ParamEnv<'tcx>, |
| 619 | + arg: ty::GenericArg<'tcx>, |
| 620 | + ) -> Option<impl Iterator<Item = Goal<'tcx, ty::Predicate<'tcx>>>> { |
| 621 | + crate::traits::wf::unnormalized_obligations(self.infcx, param_env, arg) |
| 622 | + .map(|obligations| obligations.into_iter().map(|obligation| obligation.into())) |
| 623 | + } |
| 624 | + |
| 625 | + #[instrument(level = "debug", skip(self), ret)] |
| 626 | + pub(super) fn compute_external_query_constraints( |
| 627 | + &self, |
| 628 | + ) -> Result<ExternalConstraints<'tcx>, NoSolution> { |
| 629 | + // Cannot use `take_registered_region_obligations` as we may compute the response |
| 630 | + // inside of a `probe` whenever we have multiple choices inside of the solver. |
| 631 | + let region_obligations = self.infcx.inner.borrow().region_obligations().to_owned(); |
| 632 | + let region_constraints = self.infcx.with_region_constraints(|region_constraints| { |
| 633 | + make_query_region_constraints( |
| 634 | + self.tcx(), |
| 635 | + region_obligations |
| 636 | + .iter() |
| 637 | + .map(|r_o| (r_o.sup_type, r_o.sub_region, r_o.origin.to_constraint_category())), |
| 638 | + region_constraints, |
| 639 | + ) |
| 640 | + }); |
| 641 | + let opaque_types = self.infcx.clone_opaque_types_for_query_response(); |
| 642 | + Ok(self |
| 643 | + .tcx() |
| 644 | + .mk_external_constraints(ExternalConstraintsData { region_constraints, opaque_types })) |
| 645 | + } |
| 646 | + |
| 647 | + pub(super) fn canonicalize<T: TypeFoldable<TyCtxt<'tcx>>>( |
| 648 | + &self, |
| 649 | + canonicalize_mode: CanonicalizeMode, |
| 650 | + variables: &mut Vec<ty::GenericArg<'tcx>>, |
| 651 | + value: T, |
| 652 | + ) -> Canonical<'tcx, T> { |
| 653 | + Canonicalizer::canonicalize(self.infcx, canonicalize_mode, variables, value) |
| 654 | + } |
551 | 655 | }
|
0 commit comments