blob: 0a307f766ebb2b61eae5ed036029cdfb74ac9784 [file]
use std::fmt::Debug;
use std::ops::Deref;
use rustc_type_ir::solve::{
Certainty, ComputeGoalFastPathOutcome, FetchEligibleAssocItemResponse, Goal, NoSolution,
VisibleForLeakCheck,
};
use rustc_type_ir::{self as ty, CanonicalizerState, InferCtxtLike, Interner, TypeFoldable};
/// `SolverDelegate` is one of the two traits in the `rustc_type_ir` shared abstraction layer
/// between rustc and rust-analyzer abstracting over the [InferCtxt][inferctxt-doc], which had to be
/// split due to coherence reasons:
/// - `SolverDelegate` contains the parts depending on trait-solving logic, to provide functionality
/// in `rustc_trait_selection`, and is implemented by a [simple wrapper over
/// `InferCtxt`][inferctxt-wrapper-doc] there,
/// - [InferCtxtLike] contains the other parts, and is implemented [directly on
/// `InferCtxt`][inferctxtlike-impl-doc].
///
/// More information can also be found in the dedicated chapter in the dev-guide, in [this
/// section][dev-guide].
///
/// [inferctxt-doc]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/struct.InferCtxt.html
/// [inferctxt-wrapper-doc]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_trait_selection/solve/delegate/struct.SolverDelegate.html
/// [inferctxtlike-impl-doc]: https://doc.rust-lang.org/nightly/nightly-rustc/rustc_infer/infer/struct.InferCtxt.html#impl-InferCtxtLike-for-InferCtxt%3C'tcx%3E
/// [dev-guide]: https://rustc-dev-guide.rust-lang.org/solve/sharing-crates-with-rust-analyzer.html#trait-inferctxtlike-and-trait-solverdelegate
pub trait SolverDelegate: Deref<Target = Self::Infcx> + Sized {
type Infcx: InferCtxtLike<Interner = Self::Interner>;
type Interner: Interner;
fn cx(&self) -> Self::Interner {
(**self).cx()
}
fn build_with_canonical<V>(
cx: Self::Interner,
canonical: &ty::CanonicalQueryInput<Self::Interner, V>,
) -> (Self, V, ty::CanonicalVarValues<Self::Interner>)
where
V: TypeFoldable<Self::Interner>;
fn compute_goal_fast_path(
&self,
goal: Goal<Self::Interner, <Self::Interner as Interner>::Predicate>,
span: <Self::Interner as Interner>::Span,
) -> ComputeGoalFastPathOutcome<Self::Interner>;
fn fresh_var_for_kind(
&self,
arg: <Self::Interner as Interner>::GenericArg,
span: <Self::Interner as Interner>::Span,
universe: ty::UniverseIndex,
) -> <Self::Interner as Interner>::GenericArg;
// FIXME: Uplift the leak check into this crate.
fn leak_check(&self, max_input_universe: ty::UniverseIndex) -> Result<(), NoSolution>;
/// Evaluate a const, normalizing the type of the resulting value with `normalize_ty`.
/// Returns `Ok(None)` if the const is too generic, and `Err(_)` only if `normalize_ty`
/// failed.
fn evaluate_const<E: Debug>(
&self,
param_env: <Self::Interner as Interner>::ParamEnv,
alias_const: ty::AliasConst<Self::Interner>,
normalize_ty: impl FnOnce(
ty::Unnormalized<Self::Interner, <Self::Interner as Interner>::Ty>,
) -> Result<<Self::Interner as Interner>::Ty, E>,
) -> Result<Option<<Self::Interner as Interner>::Const>, E>;
// FIXME: This only is here because `wf::obligations` is in `rustc_trait_selection`!
fn well_formed_goals(
&self,
param_env: <Self::Interner as Interner>::ParamEnv,
term: <Self::Interner as Interner>::Term,
) -> Option<Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>>;
fn make_deduplicated_region_constraints(
&self,
) -> Vec<(ty::RegionConstraint<Self::Interner>, VisibleForLeakCheck)>;
fn instantiate_canonical<V>(
&self,
canonical: ty::Canonical<Self::Interner, V>,
values: ty::CanonicalVarValues<Self::Interner>,
) -> V
where
V: TypeFoldable<Self::Interner>;
fn instantiate_canonical_var(
&self,
kind: ty::CanonicalVarKind<Self::Interner>,
span: <Self::Interner as Interner>::Span,
var_values: &[<Self::Interner as Interner>::GenericArg],
universe_map: impl Fn(ty::UniverseIndex) -> ty::UniverseIndex,
) -> <Self::Interner as Interner>::GenericArg;
fn add_item_bounds_for_hidden_type(
&self,
def_id: <Self::Interner as Interner>::OpaqueTyId,
args: <Self::Interner as Interner>::GenericArgs,
param_env: <Self::Interner as Interner>::ParamEnv,
hidden_ty: <Self::Interner as Interner>::Ty,
goals: &mut Vec<Goal<Self::Interner, <Self::Interner as Interner>::Predicate>>,
);
fn fetch_eligible_assoc_item(
&self,
goal_trait_ref: ty::TraitRef<Self::Interner>,
trait_assoc_def_id: <Self::Interner as Interner>::TraitAssocTermId,
impl_def_id: <Self::Interner as Interner>::ImplId,
) -> FetchEligibleAssocItemResponse<Self::Interner>;
fn is_transmutable(
&self,
src: <Self::Interner as Interner>::Ty,
dst: <Self::Interner as Interner>::Ty,
assume: <Self::Interner as Interner>::Const,
) -> Result<Certainty, NoSolution>;
/// Obtain canonicalizer state, either by allocating it afresh (the default) or by reusing
/// previously allocated state.
fn obtain_canonicalizer_state(&self) -> CanonicalizerState<Self::Interner> {
Default::default()
}
/// Release canonicalizer state, either by deallocating it (the default) or by clearing it and
/// stashing it for later reuse.
fn release_canonicalizer_state(&self, _: CanonicalizerState<Self::Interner>) {}
fn emit_next_solver_overflow_fcw(
&self,
goal: Goal<Self::Interner, <Self::Interner as Interner>::Predicate>,
span: <Self::Interner as Interner>::Span,
);
}