blob: 7580cc65d530a99d061ae116735128c3c86039ec [file] [log] [blame] [edit]
//! Implementation of [`rustc_type_ir::Interner`] for [`TyCtxt`].
use std::fmt;
use rustc_abi::ExternAbi;
use rustc_data_structures::debug_assert_matches;
use rustc_errors::ErrorGuaranteed;
use rustc_hir::def::{CtorKind, CtorOf, DefKind};
use rustc_hir::def_id::{DefId, LocalDefId};
use rustc_hir::lang_items::LangItem;
use rustc_hir::{self as hir};
use rustc_span::{DUMMY_SP, Span, Symbol};
use rustc_type_ir::lang_items::{SolverAdtLangItem, SolverLangItem, SolverTraitLangItem};
use rustc_type_ir::{CollectAndApply, Interner, TypeFoldable, search_graph};
use crate::dep_graph::DepNodeIndex;
use crate::infer::canonical::CanonicalVarKinds;
use crate::query::IntoQueryParam;
use crate::traits::cache::WithDepNode;
use crate::traits::solve::{
self, CanonicalInput, ExternalConstraints, ExternalConstraintsData, QueryResult, inspect,
};
use crate::ty::{
self, Clause, Const, List, ParamTy, Pattern, PolyExistentialPredicate, Predicate, Region, Ty,
TyCtxt,
};
#[allow(rustc::usage_of_ty_tykind)]
impl<'tcx> Interner for TyCtxt<'tcx> {
fn next_trait_solver_globally(self) -> bool {
self.next_trait_solver_globally()
}
type DefId = DefId;
type LocalDefId = LocalDefId;
type TraitId = DefId;
type ForeignId = DefId;
type FunctionId = DefId;
type ClosureId = DefId;
type CoroutineClosureId = DefId;
type CoroutineId = DefId;
type AdtId = DefId;
type ImplId = DefId;
type UnevaluatedConstId = DefId;
type Span = Span;
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<'tcx>>;
type PredefinedOpaques = solve::PredefinedOpaques<'tcx>;
fn mk_predefined_opaques_in_body(
self,
data: &[(ty::OpaqueTypeKey<'tcx>, Ty<'tcx>)],
) -> Self::PredefinedOpaques {
self.mk_predefined_opaques_in_body(data)
}
type LocalDefIds = &'tcx ty::List<LocalDefId>;
type CanonicalVarKinds = CanonicalVarKinds<'tcx>;
fn mk_canonical_var_kinds(
self,
kinds: &[ty::CanonicalVarKind<Self>],
) -> Self::CanonicalVarKinds {
self.mk_canonical_var_kinds(kinds)
}
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 Symbol = Symbol;
type ErrorGuaranteed = ErrorGuaranteed;
type BoundExistentialPredicates = &'tcx List<PolyExistentialPredicate<'tcx>>;
type AllocId = crate::mir::interpret::AllocId;
type Pat = Pattern<'tcx>;
type PatList = &'tcx List<Pattern<'tcx>>;
type Safety = hir::Safety;
type Abi = ExternAbi;
type Const = ty::Const<'tcx>;
type ParamConst = ty::ParamConst;
type ValueConst = ty::Value<'tcx>;
type ExprConst = ty::Expr<'tcx>;
type ValTree = ty::ValTree<'tcx>;
type ScalarInt = ty::ScalarInt;
type Region = Region<'tcx>;
type EarlyParamRegion = ty::EarlyParamRegion;
type LateParamRegion = ty::LateParamRegion;
type RegionAssumptions = &'tcx ty::List<ty::ArgOutlivesPredicate<'tcx>>;
type ParamEnv = ty::ParamEnv<'tcx>;
type Predicate = Predicate<'tcx>;
type Clause = Clause<'tcx>;
type Clauses = ty::Clauses<'tcx>;
type Tracked<T: fmt::Debug + Clone> = WithDepNode<T>;
fn mk_tracked<T: fmt::Debug + Clone>(
self,
data: T,
dep_node: DepNodeIndex,
) -> Self::Tracked<T> {
WithDepNode::new(dep_node, data)
}
fn get_tracked<T: fmt::Debug + Clone>(self, tracked: &Self::Tracked<T>) -> T {
tracked.get(self)
}
fn with_global_cache<R>(self, f: impl FnOnce(&mut search_graph::GlobalCache<Self>) -> R) -> R {
f(&mut *self.new_solver_evaluation_cache.lock())
}
fn canonical_param_env_cache_get_or_insert<R>(
self,
param_env: ty::ParamEnv<'tcx>,
f: impl FnOnce() -> ty::CanonicalParamEnvCacheEntry<Self>,
from_entry: impl FnOnce(&ty::CanonicalParamEnvCacheEntry<Self>) -> R,
) -> R {
let mut cache = self.new_solver_canonical_param_env_cache.lock();
let entry = cache.entry(param_env).or_insert_with(f);
from_entry(entry)
}
fn assert_evaluation_is_concurrent(&self) {
// Turns out, the assumption for this function isn't perfect.
// See trait-system-refactor-initiative#234.
}
fn expand_abstract_consts<T: TypeFoldable<TyCtxt<'tcx>>>(self, t: T) -> T {
self.expand_abstract_consts(t)
}
type GenericsOf = &'tcx ty::Generics;
fn generics_of(self, def_id: DefId) -> &'tcx ty::Generics {
self.generics_of(def_id)
}
type VariancesOf = &'tcx [ty::Variance];
fn variances_of(self, def_id: DefId) -> Self::VariancesOf {
self.variances_of(def_id)
}
fn opt_alias_variances(
self,
kind: impl Into<ty::AliasTermKind>,
def_id: DefId,
) -> Option<&'tcx [ty::Variance]> {
self.opt_alias_variances(kind, def_id)
}
fn type_of(self, def_id: DefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
self.type_of(def_id)
}
fn type_of_opaque_hir_typeck(self, def_id: LocalDefId) -> ty::EarlyBinder<'tcx, Ty<'tcx>> {
self.type_of_opaque_hir_typeck(def_id)
}
fn const_of_item(self, def_id: DefId) -> ty::EarlyBinder<'tcx, Const<'tcx>> {
self.const_of_item(def_id)
}
fn anon_const_kind(self, def_id: DefId) -> ty::AnonConstKind {
self.anon_const_kind(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 => {
if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id))
{
ty::Inherent
} else {
ty::Projection
}
}
DefKind::OpaqueTy => ty::Opaque,
DefKind::TyAlias => ty::Free,
kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
}
}
fn alias_term_kind(self, alias: ty::AliasTerm<'tcx>) -> ty::AliasTermKind {
match self.def_kind(alias.def_id) {
DefKind::AssocTy => {
if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id))
{
ty::AliasTermKind::InherentTy
} else {
ty::AliasTermKind::ProjectionTy
}
}
DefKind::AssocConst => {
if let DefKind::Impl { of_trait: false } = self.def_kind(self.parent(alias.def_id))
{
ty::AliasTermKind::InherentConst
} else {
ty::AliasTermKind::ProjectionConst
}
}
DefKind::OpaqueTy => ty::AliasTermKind::OpaqueTy,
DefKind::TyAlias => ty::AliasTermKind::FreeTy,
DefKind::Const => ty::AliasTermKind::FreeConst,
DefKind::AnonConst | DefKind::Ctor(_, CtorKind::Const) => {
ty::AliasTermKind::UnevaluatedConst
}
kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
}
}
fn trait_ref_and_own_args_for_alias(
self,
def_id: DefId,
args: ty::GenericArgsRef<'tcx>,
) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) {
debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::AssocConst);
let trait_def_id = self.parent(def_id);
debug_assert_matches!(self.def_kind(trait_def_id), DefKind::Trait);
let trait_ref = ty::TraitRef::from_assoc(self, trait_def_id, args);
(trait_ref, &args[trait_ref.args.len()..])
}
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, 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 debug_assert_args_compatible(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) {
self.debug_assert_args_compatible(def_id, args);
}
/// Assert that the args from an `ExistentialTraitRef` or `ExistentialProjection`
/// are compatible with the `DefId`. Since we're missing a `Self` type, stick on
/// a dummy self type and forward to `debug_assert_args_compatible`.
fn debug_assert_existential_args_compatible(
self,
def_id: Self::DefId,
args: Self::GenericArgs,
) {
// FIXME: We could perhaps add a `skip: usize` to `debug_assert_args_compatible`
// to avoid needing to reintern the set of args...
if cfg!(debug_assertions) {
self.debug_assert_args_compatible(
def_id,
self.mk_args_from_iter(
[self.types.trait_object_dummy_self.into()].into_iter().chain(args.iter()),
),
);
}
}
fn mk_type_list_from_iter<I, T>(self, args: I) -> T::Output
where
I: Iterator<Item = T>,
T: CollectAndApply<Ty<'tcx>, &'tcx List<Ty<'tcx>>>,
{
self.mk_type_list_from_iter(args)
}
fn parent(self, def_id: DefId) -> DefId {
self.parent(def_id)
}
fn recursion_limit(self) -> usize {
self.recursion_limit().0
}
type Features = &'tcx rustc_feature::Features;
fn features(self) -> Self::Features {
self.features()
}
fn coroutine_hidden_types(
self,
def_id: DefId,
) -> ty::EarlyBinder<'tcx, ty::Binder<'tcx, ty::CoroutineWitnessTypes<TyCtxt<'tcx>>>> {
self.coroutine_hidden_types(def_id)
}
fn fn_sig(self, def_id: DefId) -> ty::EarlyBinder<'tcx, ty::PolyFnSig<'tcx>> {
self.fn_sig(def_id)
}
fn coroutine_movability(self, def_id: DefId) -> rustc_ast::Movability {
self.coroutine_movability(def_id)
}
fn coroutine_for_closure(self, def_id: DefId) -> DefId {
self.coroutine_for_closure(def_id)
}
fn generics_require_sized_self(self, def_id: DefId) -> bool {
self.generics_require_sized_self(def_id)
}
fn item_bounds(
self,
def_id: DefId,
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
self.item_bounds(def_id).map_bound(IntoIterator::into_iter)
}
fn item_self_bounds(
self,
def_id: DefId,
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
self.item_self_bounds(def_id).map_bound(IntoIterator::into_iter)
}
fn item_non_self_bounds(
self,
def_id: DefId,
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
self.item_non_self_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 explicit_super_predicates_of(
self,
def_id: DefId,
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> {
self.explicit_super_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied())
}
fn explicit_implied_predicates_of(
self,
def_id: DefId,
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = (ty::Clause<'tcx>, Span)>> {
self.explicit_implied_predicates_of(def_id).map_bound(|preds| preds.into_iter().copied())
}
fn impl_super_outlives(
self,
impl_def_id: DefId,
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Clause<'tcx>>> {
self.impl_super_outlives(impl_def_id)
}
fn impl_is_const(self, def_id: DefId) -> bool {
debug_assert_matches!(self.def_kind(def_id), DefKind::Impl { of_trait: true });
self.is_conditionally_const(def_id)
}
fn fn_is_const(self, def_id: DefId) -> bool {
debug_assert_matches!(
self.def_kind(def_id),
DefKind::Fn | DefKind::AssocFn | DefKind::Ctor(CtorOf::Struct, CtorKind::Fn)
);
self.is_conditionally_const(def_id)
}
fn alias_has_const_conditions(self, def_id: DefId) -> bool {
debug_assert_matches!(self.def_kind(def_id), DefKind::AssocTy | DefKind::OpaqueTy);
self.is_conditionally_const(def_id)
}
fn const_conditions(
self,
def_id: DefId,
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
ty::EarlyBinder::bind(
self.const_conditions(def_id).instantiate_identity(self).into_iter().map(|(c, _)| c),
)
}
fn explicit_implied_const_bounds(
self,
def_id: DefId,
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = ty::Binder<'tcx, ty::TraitRef<'tcx>>>> {
ty::EarlyBinder::bind(
self.explicit_implied_const_bounds(def_id).iter_identity_copied().map(|(c, _)| c),
)
}
fn impl_self_is_guaranteed_unsized(self, impl_def_id: DefId) -> bool {
self.impl_self_is_guaranteed_unsized(impl_def_id)
}
fn has_target_features(self, def_id: DefId) -> bool {
!self.codegen_fn_attrs(def_id).target_features.is_empty()
}
fn require_lang_item(self, lang_item: SolverLangItem) -> DefId {
self.require_lang_item(solver_lang_item_to_lang_item(lang_item), DUMMY_SP)
}
fn require_trait_lang_item(self, lang_item: SolverTraitLangItem) -> DefId {
self.require_lang_item(solver_trait_lang_item_to_lang_item(lang_item), DUMMY_SP)
}
fn require_adt_lang_item(self, lang_item: SolverAdtLangItem) -> DefId {
self.require_lang_item(solver_adt_lang_item_to_lang_item(lang_item), DUMMY_SP)
}
fn is_lang_item(self, def_id: DefId, lang_item: SolverLangItem) -> bool {
self.is_lang_item(def_id, solver_lang_item_to_lang_item(lang_item))
}
fn is_trait_lang_item(self, def_id: DefId, lang_item: SolverTraitLangItem) -> bool {
self.is_lang_item(def_id, solver_trait_lang_item_to_lang_item(lang_item))
}
fn is_adt_lang_item(self, def_id: DefId, lang_item: SolverAdtLangItem) -> bool {
self.is_lang_item(def_id, solver_adt_lang_item_to_lang_item(lang_item))
}
fn is_default_trait(self, def_id: DefId) -> bool {
self.is_default_trait(def_id)
}
fn is_sizedness_trait(self, def_id: DefId) -> bool {
self.is_sizedness_trait(def_id)
}
fn as_lang_item(self, def_id: DefId) -> Option<SolverLangItem> {
lang_item_to_solver_lang_item(self.lang_items().from_def_id(def_id)?)
}
fn as_trait_lang_item(self, def_id: DefId) -> Option<SolverTraitLangItem> {
lang_item_to_solver_trait_lang_item(self.lang_items().from_def_id(def_id)?)
}
fn as_adt_lang_item(self, def_id: DefId) -> Option<SolverAdtLangItem> {
lang_item_to_solver_adt_lang_item(self.lang_items().from_def_id(def_id)?)
}
fn associated_type_def_ids(self, def_id: DefId) -> impl IntoIterator<Item = DefId> {
self.associated_items(def_id)
.in_definition_order()
.filter(|assoc_item| assoc_item.is_type())
.map(|assoc_item| assoc_item.def_id)
}
// 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(_)
| ty::UnsafeBinder(_) => {
if let Some(simp) = ty::fast_reject::simplify_type(
tcx,
self_ty,
ty::fast_reject::TreatParams::AsRigid,
) {
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}"),
}
#[allow(rustc::usage_of_type_ir_traits)]
self.for_each_blanket_impl(trait_def_id, f)
}
fn for_each_blanket_impl(self, trait_def_id: DefId, mut f: impl FnMut(DefId)) {
let trait_impls = self.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_specializes(self, impl_def_id: Self::DefId, victim_def_id: Self::DefId) -> bool {
self.specializes((impl_def_id, victim_def_id))
}
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)
}
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_coinductive(self, trait_def_id: DefId) -> bool {
self.trait_is_coinductive(trait_def_id)
}
fn trait_is_alias(self, trait_def_id: DefId) -> bool {
self.trait_is_alias(trait_def_id)
}
fn trait_is_dyn_compatible(self, trait_def_id: DefId) -> bool {
self.is_dyn_compatible(trait_def_id)
}
fn trait_is_fundamental(self, def_id: DefId) -> bool {
self.trait_def(def_id).is_fundamental
}
fn trait_is_unsafe(self, trait_def_id: Self::DefId) -> bool {
self.trait_def(trait_def_id).safety.is_unsafe()
}
fn is_impl_trait_in_trait(self, def_id: DefId) -> bool {
self.is_impl_trait_in_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)
}
type UnsizingParams = &'tcx rustc_index::bit_set::DenseBitSet<u32>;
fn unsizing_params_for_adt(self, adt_def_id: DefId) -> Self::UnsizingParams {
self.unsizing_params_for_adt(adt_def_id)
}
fn anonymize_bound_vars<T: TypeFoldable<TyCtxt<'tcx>>>(
self,
binder: ty::Binder<'tcx, T>,
) -> ty::Binder<'tcx, T> {
self.anonymize_bound_vars(binder)
}
fn opaque_types_defined_by(self, defining_anchor: LocalDefId) -> Self::LocalDefIds {
self.opaque_types_defined_by(defining_anchor)
}
fn opaque_types_and_coroutines_defined_by(
self,
defining_anchor: Self::LocalDefId,
) -> Self::LocalDefIds {
let coroutines_defined_by = self
.nested_bodies_within(defining_anchor)
.iter()
.filter(|def_id| self.is_coroutine(def_id.to_def_id()));
self.mk_local_def_ids_from_iter(
self.opaque_types_defined_by(defining_anchor).iter().chain(coroutines_defined_by),
)
}
type Probe = &'tcx inspect::Probe<TyCtxt<'tcx>>;
fn mk_probe(self, probe: inspect::Probe<Self>) -> &'tcx inspect::Probe<TyCtxt<'tcx>> {
self.arena.alloc(probe)
}
fn evaluate_root_goal_for_proof_tree_raw(
self,
canonical_goal: CanonicalInput<'tcx>,
) -> (QueryResult<'tcx>, &'tcx inspect::Probe<TyCtxt<'tcx>>) {
self.evaluate_root_goal_for_proof_tree_raw(canonical_goal)
}
fn item_name(self, id: DefId) -> Symbol {
let id = id.into_query_param();
self.opt_item_name(id).unwrap_or_else(|| {
bug!("item_name: no name for {:?}", self.def_path(id));
})
}
}
/// Defines trivial conversion functions between the main [`LangItem`] enum,
/// and some other lang-item enum that is a subset of it.
macro_rules! bidirectional_lang_item_map {
(
$solver_ty:ident, fn $to_solver:ident, fn $from_solver:ident;
$($name:ident),+ $(,)?
) => {
fn $from_solver(lang_item: $solver_ty) -> LangItem {
match lang_item {
$($solver_ty::$name => LangItem::$name,)+
}
}
fn $to_solver(lang_item: LangItem) -> Option<$solver_ty> {
Some(match lang_item {
$(LangItem::$name => $solver_ty::$name,)+
_ => return None,
})
}
}
}
bidirectional_lang_item_map! {
SolverLangItem, fn lang_item_to_solver_lang_item, fn solver_lang_item_to_lang_item;
// tidy-alphabetical-start
AsyncFnKindUpvars,
AsyncFnOnceOutput,
CallOnceFuture,
CallRefFuture,
CoroutineReturn,
CoroutineYield,
DynMetadata,
FutureOutput,
Metadata,
// tidy-alphabetical-end
}
bidirectional_lang_item_map! {
SolverAdtLangItem, fn lang_item_to_solver_adt_lang_item, fn solver_adt_lang_item_to_lang_item;
// tidy-alphabetical-start
Option,
Poll,
// tidy-alphabetical-end
}
bidirectional_lang_item_map! {
SolverTraitLangItem, fn lang_item_to_solver_trait_lang_item, fn solver_trait_lang_item_to_lang_item;
// tidy-alphabetical-start
AsyncFn,
AsyncFnKindHelper,
AsyncFnMut,
AsyncFnOnce,
AsyncFnOnceOutput,
AsyncIterator,
BikeshedGuaranteedNoDrop,
Clone,
Copy,
Coroutine,
Destruct,
DiscriminantKind,
Drop,
Fn,
FnMut,
FnOnce,
FnPtrTrait,
FusedIterator,
Future,
Iterator,
MetaSized,
PointeeSized,
PointeeTrait,
Sized,
TransmuteTrait,
TrivialClone,
Tuple,
Unpin,
Unsize,
// tidy-alphabetical-end
}