Skip to main content

rustc_next_trait_solver/
delegate.rs

1use std::fmt::Debug;
2use std::ops::Deref;
3
4use rustc_type_ir::solve::{
5    Certainty, ComputeGoalFastPathOutcome, FetchEligibleAssocItemResponse, Goal, NoSolution,
6    VisibleForLeakCheck,
7};
8use rustc_type_ir::{self as ty, CanonicalizerState, InferCtxtLike, Interner, TypeFoldable};
9
10/// `SolverDelegate` is one of the two traits in the `rustc_type_ir` shared abstraction layer
11/// between rustc and rust-analyzer abstracting over the [InferCtxt][inferctxt-doc], which had to be
12/// split due to coherence reasons:
13/// - `SolverDelegate` contains the parts depending on trait-solving logic, to provide functionality
14///   in `rustc_trait_selection`, and is implemented by a [simple wrapper over
15///   `InferCtxt`][inferctxt-wrapper-doc] there,
16/// - [InferCtxtLike] contains the other parts, and is implemented [directly on
17///   `InferCtxt`][inferctxtlike-impl-doc].
18///
19/// More information can also be found in the dedicated chapter in the dev-guide, in [this
20/// section][dev-guide].
21///
22/// [inferctxt-doc]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/struct.InferCtxt.html
23/// [inferctxt-wrapper-doc]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/solve/delegate/struct.SolverDelegate.html
24/// [inferctxtlike-impl-doc]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/struct.InferCtxt.html#impl-InferCtxtLike-for-InferCtxt%3C'tcx%3E
25/// [dev-guide]: https://rustc-dev-guide.rust-lang.org/solve/sharing-crates-with-rust-analyzer.html#trait-inferctxtlike-and-trait-solverdelegate
26pub trait SolverDelegate: Deref<Target = Self::Infcx> + Sized {
27    type Infcx: InferCtxtLike<Interner = Self::Interner>;
28    type Interner: Interner;
29    fn cx(&self) -> Self::Interner {
30        (**self).cx()
31    }
32
33    fn build_with_canonical<V>(
34        cx: Self::Interner,
35        canonical: &ty::CanonicalQueryInput<Self::Interner, V>,
36    ) -> (Self, V, ty::CanonicalVarValues<Self::Interner>)
37    where
38        V: TypeFoldable<Self::Interner>;
39
40    fn compute_goal_fast_path(
41        &self,
42        goal: Goal<Self::Interner, <Self::Interner as Interner>::Predicate>,
43        span: <Self::Interner as Interner>::Span,
44    ) -> ComputeGoalFastPathOutcome<Self::Interner>;
45
46    fn fresh_var_for_kind(
47        &self,
48        arg: <Self::Interner as Interner>::GenericArg,
49        span: <Self::Interner as Interner>::Span,
50        universe: ty::UniverseIndex,
51    ) -> <Self::Interner as Interner>::GenericArg;
52
53    // FIXME: Uplift the leak check into this crate.
54    fn leak_check(&self, max_input_universe: ty::UniverseIndex) -> Result<(), NoSolution>;
55
56    /// Evaluate a const, normalizing the type of the resulting value with `normalize_ty`.
57    /// Returns `Ok(None)` if the const is too generic, and `Err(_)` only if `normalize_ty`
58    /// failed.
59    fn evaluate_const<E: Debug>(
60        &self,
61        param_env: <Self::Interner as Interner>::ParamEnv,
62        alias_const: ty::AliasConst<Self::Interner>,
63        normalize_ty: impl FnOnce(
64            ty::Unnormalized<Self::Interner, <Self::Interner as Interner>::Ty>,
65        ) -> Result<<Self::Interner as Interner>::Ty, E>,
66    ) -> Result<Option<<Self::Interner as Interner>::Const>, E>;
67
68    // FIXME: This only is here because `wf::obligations` is in `rustc_trait_selection`!
69    fn well_formed_goals(
70        &self,
71        param_env: <Self::Interner as Interner>::ParamEnv,
72        term: <Self::Interner as Interner>::Term,
73    ) -> Option<Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>>;
74
75    fn make_deduplicated_region_constraints(
76        &self,
77    ) -> Vec<(ty::RegionConstraint<Self::Interner>, VisibleForLeakCheck)>;
78
79    fn instantiate_canonical<V>(
80        &self,
81        canonical: ty::Canonical<Self::Interner, V>,
82        values: ty::CanonicalVarValues<Self::Interner>,
83    ) -> V
84    where
85        V: TypeFoldable<Self::Interner>;
86
87    fn instantiate_canonical_var(
88        &self,
89        kind: ty::CanonicalVarKind<Self::Interner>,
90        span: <Self::Interner as Interner>::Span,
91        var_values: &[<Self::Interner as Interner>::GenericArg],
92        universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex,
93    ) -> <Self::Interner as Interner>::GenericArg;
94
95    fn add_item_bounds_for_hidden_type(
96        &self,
97        def_id: <Self::Interner as Interner>::OpaqueTyId,
98        args: <Self::Interner as Interner>::GenericArgs,
99        param_env: <Self::Interner as Interner>::ParamEnv,
100        hidden_ty: <Self::Interner as Interner>::Ty,
101        goals: &mut Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>,
102    );
103
104    fn fetch_eligible_assoc_item(
105        &self,
106        goal_trait_ref: ty::TraitRef<Self::Interner>,
107        trait_assoc_def_id: <Self::Interner as Interner>::TraitAssocTermId,
108        impl_def_id: <Self::Interner as Interner>::ImplId,
109    ) -> FetchEligibleAssocItemResponse<Self::Interner>;
110
111    fn is_transmutable(
112        &self,
113        src: <Self::Interner as Interner>::Ty,
114        dst: <Self::Interner as Interner>::Ty,
115        assume: <Self::Interner as Interner>::Const,
116    ) -> Result<Certainty, NoSolution>;
117
118    /// Obtain canonicalizer state, either by allocating it afresh (the default) or by reusing
119    /// previously allocated state.
120    fn obtain_canonicalizer_state(&self) -> CanonicalizerState<Self::Interner> {
121        Default::default()
122    }
123
124    /// Release canonicalizer state, either by deallocating it (the default) or by clearing it and
125    /// stashing it for later reuse.
126    fn release_canonicalizer_state(&self, _: CanonicalizerState<Self::Interner>) {}
127
128    fn emit_next_solver_overflow_fcw(
129        &self,
130        goal: Goal<Self::Interner, <Self::Interner as Interner>::Predicate>,
131        span: <Self::Interner as Interner>::Span,
132    );
133}