Unnamed repository; edit this file 'description' to name the repository.
Diffstat (limited to 'crates/hir-ty/src/next_solver/infer/context.rs')
-rw-r--r--crates/hir-ty/src/next_solver/infer/context.rs333
1 files changed, 333 insertions, 0 deletions
diff --git a/crates/hir-ty/src/next_solver/infer/context.rs b/crates/hir-ty/src/next_solver/infer/context.rs
new file mode 100644
index 0000000000..397986e2ed
--- /dev/null
+++ b/crates/hir-ty/src/next_solver/infer/context.rs
@@ -0,0 +1,333 @@
+//! Definition of `InferCtxtLike` from the librarified type layer.
+
+use rustc_type_ir::{
+ ConstVid, FloatVarValue, FloatVid, GenericArgKind, InferConst, InferTy, IntVarValue, IntVid,
+ RegionVid, TyVid, TypeFoldable, TypingMode, UniverseIndex,
+ inherent::{Const as _, IntoKind, Ty as _},
+ relate::combine::PredicateEmittingRelation,
+};
+
+use crate::next_solver::{
+ Binder, Const, ConstKind, DbInterner, ErrorGuaranteed, GenericArgs, OpaqueTypeKey, Region,
+ SolverDefId, Span, Ty, TyKind,
+ infer::opaque_types::{OpaqueHiddenType, table::OpaqueTypeStorageEntries},
+};
+
+use super::{BoundRegionConversionTime, InferCtxt, relate::RelateResult};
+
+impl<'db> rustc_type_ir::InferCtxtLike for InferCtxt<'db> {
+ type Interner = DbInterner<'db>;
+
+ fn cx(&self) -> DbInterner<'db> {
+ self.interner
+ }
+
+ fn next_trait_solver(&self) -> bool {
+ true
+ }
+
+ fn typing_mode(&self) -> TypingMode<DbInterner<'db>> {
+ self.typing_mode()
+ }
+
+ fn universe(&self) -> UniverseIndex {
+ self.universe()
+ }
+
+ fn create_next_universe(&self) -> UniverseIndex {
+ self.create_next_universe()
+ }
+
+ fn universe_of_ty(&self, vid: TyVid) -> Option<UniverseIndex> {
+ self.probe_ty_var(vid).err()
+ }
+
+ fn universe_of_lt(&self, lt: RegionVid) -> Option<UniverseIndex> {
+ self.inner.borrow_mut().unwrap_region_constraints().probe_value(lt).err()
+ }
+
+ fn universe_of_ct(&self, ct: ConstVid) -> Option<UniverseIndex> {
+ self.probe_const_var(ct).err()
+ }
+
+ fn root_ty_var(&self, var: TyVid) -> TyVid {
+ self.root_var(var)
+ }
+
+ fn root_const_var(&self, var: ConstVid) -> ConstVid {
+ self.root_const_var(var)
+ }
+
+ fn opportunistic_resolve_ty_var(&self, vid: TyVid) -> Ty<'db> {
+ match self.probe_ty_var(vid) {
+ Ok(ty) => ty,
+ Err(_) => Ty::new_var(self.interner, self.root_var(vid)),
+ }
+ }
+
+ fn opportunistic_resolve_int_var(&self, vid: IntVid) -> Ty<'db> {
+ self.opportunistic_resolve_int_var(vid)
+ }
+
+ fn opportunistic_resolve_float_var(&self, vid: FloatVid) -> Ty<'db> {
+ self.opportunistic_resolve_float_var(vid)
+ }
+
+ fn opportunistic_resolve_ct_var(&self, vid: ConstVid) -> Const<'db> {
+ match self.probe_const_var(vid) {
+ Ok(ct) => ct,
+ Err(_) => Const::new_var(self.interner, self.root_const_var(vid)),
+ }
+ }
+
+ fn opportunistic_resolve_lt_var(&self, vid: RegionVid) -> Region<'db> {
+ self.inner
+ .borrow_mut()
+ .unwrap_region_constraints()
+ .opportunistic_resolve_var(self.interner, vid)
+ }
+
+ fn is_changed_arg(&self, arg: <Self::Interner as rustc_type_ir::Interner>::GenericArg) -> bool {
+ match arg.kind() {
+ GenericArgKind::Lifetime(_) => {
+ // Lifetimes should not change affect trait selection.
+ false
+ }
+ GenericArgKind::Type(ty) => {
+ if let TyKind::Infer(infer_ty) = ty.kind() {
+ match infer_ty {
+ InferTy::TyVar(vid) => {
+ !self.probe_ty_var(vid).is_err_and(|_| self.root_var(vid) == vid)
+ }
+ InferTy::IntVar(vid) => {
+ let mut inner = self.inner.borrow_mut();
+ !matches!(
+ inner.int_unification_table().probe_value(vid),
+ IntVarValue::Unknown
+ if inner.int_unification_table().find(vid) == vid
+ )
+ }
+ InferTy::FloatVar(vid) => {
+ let mut inner = self.inner.borrow_mut();
+ !matches!(
+ inner.float_unification_table().probe_value(vid),
+ FloatVarValue::Unknown
+ if inner.float_unification_table().find(vid) == vid
+ )
+ }
+ InferTy::FreshTy(_) | InferTy::FreshIntTy(_) | InferTy::FreshFloatTy(_) => {
+ true
+ }
+ }
+ } else {
+ true
+ }
+ }
+ GenericArgKind::Const(ct) => {
+ if let ConstKind::Infer(infer_ct) = ct.kind() {
+ match infer_ct {
+ InferConst::Var(vid) => !self
+ .probe_const_var(vid)
+ .is_err_and(|_| self.root_const_var(vid) == vid),
+ InferConst::Fresh(_) => true,
+ }
+ } else {
+ true
+ }
+ }
+ }
+ }
+
+ fn next_ty_infer(&self) -> Ty<'db> {
+ self.next_ty_var()
+ }
+
+ fn next_region_infer(&self) -> <Self::Interner as rustc_type_ir::Interner>::Region {
+ self.next_region_var()
+ }
+
+ fn next_const_infer(&self) -> Const<'db> {
+ self.next_const_var()
+ }
+
+ fn fresh_args_for_item(&self, def_id: SolverDefId) -> GenericArgs<'db> {
+ self.fresh_args_for_item(def_id)
+ }
+
+ fn instantiate_binder_with_infer<T: TypeFoldable<DbInterner<'db>> + Clone>(
+ &self,
+ value: Binder<'db, T>,
+ ) -> T {
+ self.instantiate_binder_with_fresh_vars(BoundRegionConversionTime::HigherRankedType, value)
+ }
+
+ fn enter_forall<T: TypeFoldable<DbInterner<'db>> + Clone, U>(
+ &self,
+ value: Binder<'db, T>,
+ f: impl FnOnce(T) -> U,
+ ) -> U {
+ self.enter_forall(value, f)
+ }
+
+ fn equate_ty_vids_raw(&self, a: rustc_type_ir::TyVid, b: rustc_type_ir::TyVid) {
+ self.inner.borrow_mut().type_variables().equate(a, b);
+ }
+
+ fn equate_int_vids_raw(&self, a: rustc_type_ir::IntVid, b: rustc_type_ir::IntVid) {
+ self.inner.borrow_mut().int_unification_table().union(a, b);
+ }
+
+ fn equate_float_vids_raw(&self, a: rustc_type_ir::FloatVid, b: rustc_type_ir::FloatVid) {
+ self.inner.borrow_mut().float_unification_table().union(a, b);
+ }
+
+ fn equate_const_vids_raw(&self, a: rustc_type_ir::ConstVid, b: rustc_type_ir::ConstVid) {
+ self.inner.borrow_mut().const_unification_table().union(a, b);
+ }
+
+ fn instantiate_ty_var_raw<R: PredicateEmittingRelation<Self>>(
+ &self,
+ relation: &mut R,
+ target_is_expected: bool,
+ target_vid: rustc_type_ir::TyVid,
+ instantiation_variance: rustc_type_ir::Variance,
+ source_ty: Ty<'db>,
+ ) -> RelateResult<'db, ()> {
+ self.instantiate_ty_var(
+ relation,
+ target_is_expected,
+ target_vid,
+ instantiation_variance,
+ source_ty,
+ )
+ }
+
+ fn instantiate_int_var_raw(
+ &self,
+ vid: rustc_type_ir::IntVid,
+ value: rustc_type_ir::IntVarValue,
+ ) {
+ self.inner.borrow_mut().int_unification_table().union_value(vid, value);
+ }
+
+ fn instantiate_float_var_raw(
+ &self,
+ vid: rustc_type_ir::FloatVid,
+ value: rustc_type_ir::FloatVarValue,
+ ) {
+ self.inner.borrow_mut().float_unification_table().union_value(vid, value);
+ }
+
+ fn instantiate_const_var_raw<R: PredicateEmittingRelation<Self>>(
+ &self,
+ relation: &mut R,
+ target_is_expected: bool,
+ target_vid: rustc_type_ir::ConstVid,
+ source_ct: Const<'db>,
+ ) -> RelateResult<'db, ()> {
+ self.instantiate_const_var(relation, target_is_expected, target_vid, source_ct)
+ }
+
+ fn set_tainted_by_errors(&self, e: ErrorGuaranteed) {
+ self.set_tainted_by_errors(e)
+ }
+
+ fn shallow_resolve(&self, ty: Ty<'db>) -> Ty<'db> {
+ self.shallow_resolve(ty)
+ }
+ fn shallow_resolve_const(&self, ct: Const<'db>) -> Const<'db> {
+ self.shallow_resolve_const(ct)
+ }
+
+ fn resolve_vars_if_possible<T>(&self, value: T) -> T
+ where
+ T: TypeFoldable<DbInterner<'db>>,
+ {
+ self.resolve_vars_if_possible(value)
+ }
+
+ fn probe<T>(&self, probe: impl FnOnce() -> T) -> T {
+ self.probe(|_| probe())
+ }
+
+ fn sub_regions(&self, sub: Region<'db>, sup: Region<'db>, _span: Span) {
+ self.inner.borrow_mut().unwrap_region_constraints().make_subregion(sub, sup);
+ }
+
+ fn equate_regions(&self, a: Region<'db>, b: Region<'db>, _span: Span) {
+ self.inner.borrow_mut().unwrap_region_constraints().make_eqregion(a, b);
+ }
+
+ fn register_ty_outlives(&self, _ty: Ty<'db>, _r: Region<'db>, _span: Span) {
+ // self.register_type_outlives_constraint(ty, r, &ObligationCause::dummy());
+ }
+
+ type OpaqueTypeStorageEntries = OpaqueTypeStorageEntries;
+
+ fn opaque_types_storage_num_entries(&self) -> OpaqueTypeStorageEntries {
+ self.inner.borrow_mut().opaque_types().num_entries()
+ }
+ fn clone_opaque_types_lookup_table(&self) -> Vec<(OpaqueTypeKey<'db>, Ty<'db>)> {
+ self.inner.borrow_mut().opaque_types().iter_lookup_table().map(|(k, h)| (k, h.ty)).collect()
+ }
+ fn clone_duplicate_opaque_types(&self) -> Vec<(OpaqueTypeKey<'db>, Ty<'db>)> {
+ self.inner
+ .borrow_mut()
+ .opaque_types()
+ .iter_duplicate_entries()
+ .map(|(k, h)| (k, h.ty))
+ .collect()
+ }
+ fn clone_opaque_types_added_since(
+ &self,
+ prev_entries: OpaqueTypeStorageEntries,
+ ) -> Vec<(OpaqueTypeKey<'db>, Ty<'db>)> {
+ self.inner
+ .borrow_mut()
+ .opaque_types()
+ .opaque_types_added_since(prev_entries)
+ .map(|(k, h)| (k, h.ty))
+ .collect()
+ }
+
+ fn register_hidden_type_in_storage(
+ &self,
+ opaque_type_key: OpaqueTypeKey<'db>,
+ hidden_ty: Ty<'db>,
+ _span: Span,
+ ) -> Option<Ty<'db>> {
+ self.register_hidden_type_in_storage(opaque_type_key, OpaqueHiddenType { ty: hidden_ty })
+ }
+ fn add_duplicate_opaque_type(
+ &self,
+ opaque_type_key: OpaqueTypeKey<'db>,
+ hidden_ty: Ty<'db>,
+ _span: Span,
+ ) {
+ self.inner
+ .borrow_mut()
+ .opaque_types()
+ .add_duplicate(opaque_type_key, OpaqueHiddenType { ty: hidden_ty })
+ }
+
+ fn reset_opaque_types(&self) {
+ let _ = self.take_opaque_types();
+ }
+
+ fn sub_unification_table_root_var(&self, var: rustc_type_ir::TyVid) -> rustc_type_ir::TyVid {
+ self.sub_unification_table_root_var(var)
+ }
+
+ fn sub_unify_ty_vids_raw(&self, a: rustc_type_ir::TyVid, b: rustc_type_ir::TyVid) {
+ self.sub_unify_ty_vids_raw(a, b);
+ }
+
+ fn opaques_with_sub_unified_hidden_type(
+ &self,
+ _ty: TyVid,
+ ) -> Vec<rustc_type_ir::AliasTy<Self::Interner>> {
+ // FIXME: I guess we are okay without this for now since currently r-a lacks of
+ // detailed checks over opaque types. Might need to implement this in future.
+ vec![]
+ }
+}