| 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, | |
| ); | |
| } |