about summary refs log tree commit diff
path: root/compiler/rustc_middle/src/ty/context.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_middle/src/ty/context.rs')
-rw-r--r--compiler/rustc_middle/src/ty/context.rs363
1 files changed, 323 insertions, 40 deletions
diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs
index 828cd761c19..2663dca7460 100644
--- a/compiler/rustc_middle/src/ty/context.rs
+++ b/compiler/rustc_middle/src/ty/context.rs
@@ -90,46 +90,65 @@ use std::ops::{Bound, Deref};
 impl<'tcx> Interner for TyCtxt<'tcx> {
     type DefId = DefId;
     type LocalDefId = LocalDefId;
-    type AdtDef = ty::AdtDef<'tcx>;
-
     type GenericArgs = ty::GenericArgsRef<'tcx>;
+
     type GenericArgsSlice = &'tcx [ty::GenericArg<'tcx>];
     type GenericArg = ty::GenericArg<'tcx>;
     type Term = ty::Term<'tcx>;
-
     type BoundVarKinds = &'tcx List<ty::BoundVariableKind>;
-    type BoundVarKind = ty::BoundVariableKind;
 
-    type CanonicalVars = CanonicalVarInfos<'tcx>;
+    type BoundVarKind = ty::BoundVariableKind;
     type PredefinedOpaques = solve::PredefinedOpaques<'tcx>;
+
+    fn mk_predefined_opaques_in_body(
+        self,
+        data: PredefinedOpaquesData<Self>,
+    ) -> Self::PredefinedOpaques {
+        self.mk_predefined_opaques_in_body(data)
+    }
     type DefiningOpaqueTypes = &'tcx ty::List<LocalDefId>;
-    type ExternalConstraints = ExternalConstraints<'tcx>;
     type CanonicalGoalEvaluationStepRef =
         &'tcx solve::inspect::CanonicalGoalEvaluationStep<TyCtxt<'tcx>>;
+    type CanonicalVars = CanonicalVarInfos<'tcx>;
+    fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars {
+        self.mk_canonical_var_infos(infos)
+    }
 
+    type ExternalConstraints = ExternalConstraints<'tcx>;
+    fn mk_external_constraints(
+        self,
+        data: ExternalConstraintsData<Self>,
+    ) -> ExternalConstraints<'tcx> {
+        self.mk_external_constraints(data)
+    }
+    type DepNodeIndex = DepNodeIndex;
+    fn with_cached_task<T>(self, task: impl FnOnce() -> T) -> (T, DepNodeIndex) {
+        self.dep_graph.with_anon_task(self, crate::dep_graph::dep_kinds::TraitSelect, task)
+    }
     type Ty = Ty<'tcx>;
     type Tys = &'tcx List<Ty<'tcx>>;
+
     type FnInputTys = &'tcx [Ty<'tcx>];
     type ParamTy = ParamTy;
     type BoundTy = ty::BoundTy;
-    type PlaceholderTy = ty::PlaceholderType;
 
+    type PlaceholderTy = ty::PlaceholderType;
     type ErrorGuaranteed = ErrorGuaranteed;
     type BoundExistentialPredicates = &'tcx List<PolyExistentialPredicate<'tcx>>;
-    type AllocId = crate::mir::interpret::AllocId;
 
+    type AllocId = crate::mir::interpret::AllocId;
     type Pat = Pattern<'tcx>;
     type Safety = hir::Safety;
     type Abi = abi::Abi;
-
     type Const = ty::Const<'tcx>;
     type PlaceholderConst = ty::PlaceholderConst;
+
     type ParamConst = ty::ParamConst;
     type BoundConst = ty::BoundVar;
     type ValueConst = ty::ValTree<'tcx>;
     type ExprConst = ty::Expr<'tcx>;
-
     type Region = Region<'tcx>;
+
     type EarlyParamRegion = ty::EarlyParamRegion;
     type LateParamRegion = ty::LateParamRegion;
     type BoundRegion = ty::BoundRegion;
@@ -137,15 +156,12 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
 
     type ParamEnv = ty::ParamEnv<'tcx>;
     type Predicate = Predicate<'tcx>;
+
     type Clause = Clause<'tcx>;
     type Clauses = ty::Clauses<'tcx>;
 
-    type DepNodeIndex = DepNodeIndex;
-    fn with_cached_task<T>(self, task: impl FnOnce() -> T) -> (T, DepNodeIndex) {
-        self.dep_graph.with_anon_task(self, crate::dep_graph::dep_kinds::TraitSelect, task)
-    }
-
     type EvaluationCache = &'tcx solve::EvaluationCache<'tcx>;
+
     fn evaluation_cache(self, mode: SolverMode) -> &'tcx solve::EvaluationCache<'tcx> {
         match mode {
             SolverMode::Normal => &self.new_solver_evaluation_cache,
@@ -157,17 +173,6 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
         self.expand_abstract_consts(t)
     }
 
-    fn mk_external_constraints(
-        self,
-        data: ExternalConstraintsData<Self>,
-    ) -> ExternalConstraints<'tcx> {
-        self.mk_external_constraints(data)
-    }
-
-    fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars {
-        self.mk_canonical_var_infos(infos)
-    }
-
     type GenericsOf = &'tcx ty::Generics;
 
     fn generics_of(self, def_id: DefId) -> &'tcx ty::Generics {
@@ -184,6 +189,11 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
         self.type_of(def_id)
     }
 
+    type AdtDef = ty::AdtDef<'tcx>;
+    fn adt_def(self, adt_def_id: DefId) -> Self::AdtDef {
+        self.adt_def(adt_def_id)
+    }
+
     fn alias_ty_kind(self, alias: ty::AliasTy<'tcx>) -> ty::AliasTyKind {
         match self.def_kind(alias.def_id) {
             DefKind::AssocTy => {
@@ -221,8 +231,8 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
     fn trait_ref_and_own_args_for_alias(
         self,
         def_id: DefId,
-        args: Self::GenericArgs,
-    ) -> (rustc_type_ir::TraitRef<Self>, Self::GenericArgsSlice) {
+        args: ty::GenericArgsRef<'tcx>,
+    ) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) {
         assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::AssocConst);
         let trait_def_id = self.parent(def_id);
         assert_matches!(self.def_kind(trait_def_id), DefKind::Trait);
@@ -233,18 +243,22 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
         )
     }
 
-    fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs {
+    fn mk_args(self, args: &[Self::GenericArg]) -> ty::GenericArgsRef<'tcx> {
         self.mk_args(args)
     }
 
     fn mk_args_from_iter<I, T>(self, args: I) -> T::Output
     where
         I: Iterator<Item = T>,
-        T: CollectAndApply<Self::GenericArg, Self::GenericArgs>,
+        T: CollectAndApply<Self::GenericArg, ty::GenericArgsRef<'tcx>>,
     {
         self.mk_args_from_iter(args)
     }
 
+    fn check_args_compatible(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) -> bool {
+        self.check_args_compatible(def_id, args)
+    }
+
     fn check_and_mk_args(
         self,
         def_id: DefId,
@@ -263,7 +277,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
     fn mk_type_list_from_iter<I, T>(self, args: I) -> T::Output
     where
         I: Iterator<Item = T>,
-        T: CollectAndApply<Self::Ty, Self::Tys>,
+        T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
     {
         self.mk_type_list_from_iter(args)
     }
@@ -312,6 +326,24 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
         self.item_bounds(def_id).map_bound(IntoIterator::into_iter)
     }
 
+    fn predicates_of(
+        self,
+        def_id: DefId,
+    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
+        ty::EarlyBinder::bind(
+            self.predicates_of(def_id).instantiate_identity(self).predicates.into_iter(),
+        )
+    }
+
+    fn own_predicates_of(
+        self,
+        def_id: DefId,
+    ) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
+        ty::EarlyBinder::bind(
+            self.predicates_of(def_id).instantiate_own_identity().map(|(clause, _)| clause),
+        )
+    }
+
     fn super_predicates_of(
         self,
         def_id: DefId,
@@ -326,15 +358,11 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
     }
 
     fn require_lang_item(self, lang_item: TraitSolverLangItem) -> DefId {
-        self.require_lang_item(
-            match lang_item {
-                TraitSolverLangItem::Future => hir::LangItem::Future,
-                TraitSolverLangItem::FutureOutput => hir::LangItem::FutureOutput,
-                TraitSolverLangItem::AsyncFnKindHelper => hir::LangItem::AsyncFnKindHelper,
-                TraitSolverLangItem::AsyncFnKindUpvars => hir::LangItem::AsyncFnKindUpvars,
-            },
-            None,
-        )
+        self.require_lang_item(trait_lang_item_to_lang_item(lang_item), None)
+    }
+
+    fn is_lang_item(self, def_id: DefId, lang_item: TraitSolverLangItem) -> bool {
+        self.is_lang_item(def_id, trait_lang_item_to_lang_item(lang_item))
     }
 
     fn associated_type_def_ids(self, def_id: DefId) -> impl IntoIterator<Item = DefId> {
@@ -343,6 +371,257 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
             .filter(|assoc_item| matches!(assoc_item.kind, ty::AssocKind::Type))
             .map(|assoc_item| assoc_item.def_id)
     }
+
+    fn args_may_unify_deep(
+        self,
+        obligation_args: ty::GenericArgsRef<'tcx>,
+        impl_args: ty::GenericArgsRef<'tcx>,
+    ) -> bool {
+        ty::fast_reject::DeepRejectCtxt {
+            treat_obligation_params: ty::fast_reject::TreatParams::ForLookup,
+        }
+        .args_may_unify(obligation_args, impl_args)
+    }
+
+    // This implementation is a bit different from `TyCtxt::for_each_relevant_impl`,
+    // since we want to skip over blanket impls for non-rigid aliases, and also we
+    // only want to consider types that *actually* unify with float/int vars.
+    fn for_each_relevant_impl(
+        self,
+        trait_def_id: DefId,
+        self_ty: Ty<'tcx>,
+        mut f: impl FnMut(DefId),
+    ) {
+        let tcx = self;
+        let trait_impls = tcx.trait_impls_of(trait_def_id);
+        let mut consider_impls_for_simplified_type = |simp| {
+            if let Some(impls_for_type) = trait_impls.non_blanket_impls().get(&simp) {
+                for &impl_def_id in impls_for_type {
+                    f(impl_def_id);
+                }
+            }
+        };
+
+        match self_ty.kind() {
+            ty::Bool
+            | ty::Char
+            | ty::Int(_)
+            | ty::Uint(_)
+            | ty::Float(_)
+            | ty::Adt(_, _)
+            | ty::Foreign(_)
+            | ty::Str
+            | ty::Array(_, _)
+            | ty::Pat(_, _)
+            | ty::Slice(_)
+            | ty::RawPtr(_, _)
+            | ty::Ref(_, _, _)
+            | ty::FnDef(_, _)
+            | ty::FnPtr(_)
+            | ty::Dynamic(_, _, _)
+            | ty::Closure(..)
+            | ty::CoroutineClosure(..)
+            | ty::Coroutine(_, _)
+            | ty::Never
+            | ty::Tuple(_) => {
+                let simp = ty::fast_reject::simplify_type(
+                    tcx,
+                    self_ty,
+                    ty::fast_reject::TreatParams::ForLookup,
+                )
+                .unwrap();
+                consider_impls_for_simplified_type(simp);
+            }
+
+            // HACK: For integer and float variables we have to manually look at all impls
+            // which have some integer or float as a self type.
+            ty::Infer(ty::IntVar(_)) => {
+                use ty::IntTy::*;
+                use ty::UintTy::*;
+                // This causes a compiler error if any new integer kinds are added.
+                let (I8 | I16 | I32 | I64 | I128 | Isize): ty::IntTy;
+                let (U8 | U16 | U32 | U64 | U128 | Usize): ty::UintTy;
+                let possible_integers = [
+                    // signed integers
+                    ty::SimplifiedType::Int(I8),
+                    ty::SimplifiedType::Int(I16),
+                    ty::SimplifiedType::Int(I32),
+                    ty::SimplifiedType::Int(I64),
+                    ty::SimplifiedType::Int(I128),
+                    ty::SimplifiedType::Int(Isize),
+                    // unsigned integers
+                    ty::SimplifiedType::Uint(U8),
+                    ty::SimplifiedType::Uint(U16),
+                    ty::SimplifiedType::Uint(U32),
+                    ty::SimplifiedType::Uint(U64),
+                    ty::SimplifiedType::Uint(U128),
+                    ty::SimplifiedType::Uint(Usize),
+                ];
+                for simp in possible_integers {
+                    consider_impls_for_simplified_type(simp);
+                }
+            }
+
+            ty::Infer(ty::FloatVar(_)) => {
+                // This causes a compiler error if any new float kinds are added.
+                let (ty::FloatTy::F16 | ty::FloatTy::F32 | ty::FloatTy::F64 | ty::FloatTy::F128);
+                let possible_floats = [
+                    ty::SimplifiedType::Float(ty::FloatTy::F16),
+                    ty::SimplifiedType::Float(ty::FloatTy::F32),
+                    ty::SimplifiedType::Float(ty::FloatTy::F64),
+                    ty::SimplifiedType::Float(ty::FloatTy::F128),
+                ];
+
+                for simp in possible_floats {
+                    consider_impls_for_simplified_type(simp);
+                }
+            }
+
+            // The only traits applying to aliases and placeholders are blanket impls.
+            //
+            // Impls which apply to an alias after normalization are handled by
+            // `assemble_candidates_after_normalizing_self_ty`.
+            ty::Alias(_, _) | ty::Placeholder(..) | ty::Error(_) => (),
+
+            // FIXME: These should ideally not exist as a self type. It would be nice for
+            // the builtin auto trait impls of coroutines to instead directly recurse
+            // into the witness.
+            ty::CoroutineWitness(..) => (),
+
+            // These variants should not exist as a self type.
+            ty::Infer(ty::TyVar(_) | ty::FreshTy(_) | ty::FreshIntTy(_) | ty::FreshFloatTy(_))
+            | ty::Param(_)
+            | ty::Bound(_, _) => bug!("unexpected self type: {self_ty}"),
+        }
+
+        let trait_impls = tcx.trait_impls_of(trait_def_id);
+        for &impl_def_id in trait_impls.blanket_impls() {
+            f(impl_def_id);
+        }
+    }
+
+    fn has_item_definition(self, def_id: DefId) -> bool {
+        self.defaultness(def_id).has_value()
+    }
+
+    fn impl_is_default(self, impl_def_id: DefId) -> bool {
+        self.defaultness(impl_def_id).is_default()
+    }
+
+    fn impl_trait_ref(self, impl_def_id: DefId) -> ty::EarlyBinder<'tcx, ty::TraitRef<'tcx>> {
+        self.impl_trait_ref(impl_def_id).unwrap()
+    }
+
+    fn impl_polarity(self, impl_def_id: DefId) -> ty::ImplPolarity {
+        self.impl_polarity(impl_def_id)
+    }
+
+    fn trait_is_auto(self, trait_def_id: DefId) -> bool {
+        self.trait_is_auto(trait_def_id)
+    }
+
+    fn trait_is_alias(self, trait_def_id: DefId) -> bool {
+        self.trait_is_alias(trait_def_id)
+    }
+
+    fn trait_is_object_safe(self, trait_def_id: DefId) -> bool {
+        self.is_object_safe(trait_def_id)
+    }
+
+    fn trait_may_be_implemented_via_object(self, trait_def_id: DefId) -> bool {
+        self.trait_def(trait_def_id).implement_via_object
+    }
+
+    fn fn_trait_kind_from_def_id(self, trait_def_id: DefId) -> Option<ty::ClosureKind> {
+        self.fn_trait_kind_from_def_id(trait_def_id)
+    }
+
+    fn async_fn_trait_kind_from_def_id(self, trait_def_id: DefId) -> Option<ty::ClosureKind> {
+        self.async_fn_trait_kind_from_def_id(trait_def_id)
+    }
+
+    fn supertrait_def_ids(self, trait_def_id: DefId) -> impl IntoIterator<Item = DefId> {
+        self.supertrait_def_ids(trait_def_id)
+    }
+
+    fn delay_bug(self, msg: impl ToString) -> ErrorGuaranteed {
+        self.dcx().span_delayed_bug(DUMMY_SP, msg.to_string())
+    }
+
+    fn is_general_coroutine(self, coroutine_def_id: DefId) -> bool {
+        self.is_general_coroutine(coroutine_def_id)
+    }
+
+    fn coroutine_is_async(self, coroutine_def_id: DefId) -> bool {
+        self.coroutine_is_async(coroutine_def_id)
+    }
+
+    fn coroutine_is_gen(self, coroutine_def_id: DefId) -> bool {
+        self.coroutine_is_gen(coroutine_def_id)
+    }
+
+    fn coroutine_is_async_gen(self, coroutine_def_id: DefId) -> bool {
+        self.coroutine_is_async_gen(coroutine_def_id)
+    }
+
+    fn layout_is_pointer_like(self, param_env: ty::ParamEnv<'tcx>, ty: Ty<'tcx>) -> bool {
+        self.layout_of(self.erase_regions(param_env.and(ty)))
+            .is_ok_and(|layout| layout.layout.is_pointer_like(&self.data_layout))
+    }
+
+    type UnsizingParams = &'tcx rustc_index::bit_set::BitSet<u32>;
+    fn unsizing_params_for_adt(self, adt_def_id: DefId) -> Self::UnsizingParams {
+        self.unsizing_params_for_adt(adt_def_id)
+    }
+
+    fn find_const_ty_from_env(
+        self,
+        param_env: ty::ParamEnv<'tcx>,
+        placeholder: Self::PlaceholderConst,
+    ) -> Ty<'tcx> {
+        placeholder.find_const_ty_from_env(param_env)
+    }
+}
+
+fn trait_lang_item_to_lang_item(lang_item: TraitSolverLangItem) -> LangItem {
+    match lang_item {
+        TraitSolverLangItem::AsyncDestruct => LangItem::AsyncDestruct,
+        TraitSolverLangItem::AsyncFnKindHelper => LangItem::AsyncFnKindHelper,
+        TraitSolverLangItem::AsyncFnKindUpvars => LangItem::AsyncFnKindUpvars,
+        TraitSolverLangItem::AsyncFnOnceOutput => LangItem::AsyncFnOnceOutput,
+        TraitSolverLangItem::AsyncIterator => LangItem::AsyncIterator,
+        TraitSolverLangItem::CallOnceFuture => LangItem::CallOnceFuture,
+        TraitSolverLangItem::CallRefFuture => LangItem::CallRefFuture,
+        TraitSolverLangItem::Clone => LangItem::Clone,
+        TraitSolverLangItem::Copy => LangItem::Copy,
+        TraitSolverLangItem::Coroutine => LangItem::Coroutine,
+        TraitSolverLangItem::CoroutineReturn => LangItem::CoroutineReturn,
+        TraitSolverLangItem::CoroutineYield => LangItem::CoroutineYield,
+        TraitSolverLangItem::Destruct => LangItem::Destruct,
+        TraitSolverLangItem::DiscriminantKind => LangItem::DiscriminantKind,
+        TraitSolverLangItem::DynMetadata => LangItem::DynMetadata,
+        TraitSolverLangItem::FnPtrTrait => LangItem::FnPtrTrait,
+        TraitSolverLangItem::FusedIterator => LangItem::FusedIterator,
+        TraitSolverLangItem::Future => LangItem::Future,
+        TraitSolverLangItem::FutureOutput => LangItem::FutureOutput,
+        TraitSolverLangItem::Iterator => LangItem::Iterator,
+        TraitSolverLangItem::Metadata => LangItem::Metadata,
+        TraitSolverLangItem::Option => LangItem::Option,
+        TraitSolverLangItem::PointeeTrait => LangItem::PointeeTrait,
+        TraitSolverLangItem::PointerLike => LangItem::PointerLike,
+        TraitSolverLangItem::Poll => LangItem::Poll,
+        TraitSolverLangItem::Sized => LangItem::Sized,
+        TraitSolverLangItem::TransmuteTrait => LangItem::TransmuteTrait,
+        TraitSolverLangItem::Tuple => LangItem::Tuple,
+        TraitSolverLangItem::Unpin => LangItem::Unpin,
+        TraitSolverLangItem::Unsize => LangItem::Unsize,
+    }
+}
+
+impl<'tcx> rustc_type_ir::inherent::DefId<TyCtxt<'tcx>> for DefId {
+    fn as_local(self) -> Option<LocalDefId> {
+        self.as_local()
+    }
 }
 
 impl<'tcx> rustc_type_ir::inherent::Abi<TyCtxt<'tcx>> for abi::Abi {
@@ -377,6 +656,10 @@ impl<'tcx> rustc_type_ir::inherent::Features<TyCtxt<'tcx>> for &'tcx rustc_featu
     fn coroutine_clone(self) -> bool {
         self.coroutine_clone
     }
+
+    fn associated_const_equality(self) -> bool {
+        self.associated_const_equality
+    }
 }
 
 type InternedSet<'tcx, T> = ShardedHashMap<InternedInSet<'tcx, T>, ()>;