Uplift the new trait solver
This commit is contained in:
parent
baf94bddf0
commit
532149eb88
36 changed files with 2014 additions and 1457 deletions
|
@ -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>, ()>;
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue