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