Uplift the new trait solver
This commit is contained in:
parent
baf94bddf0
commit
532149eb88
36 changed files with 2014 additions and 1457 deletions
|
@ -205,6 +205,14 @@ impl<'tcx> rustc_type_ir::inherent::AdtDef<TyCtxt<'tcx>> for AdtDef<'tcx> {
|
|||
self.did()
|
||||
}
|
||||
|
||||
fn is_struct(self) -> bool {
|
||||
self.is_struct()
|
||||
}
|
||||
|
||||
fn struct_tail_ty(self, interner: TyCtxt<'tcx>) -> Option<ty::EarlyBinder<'tcx, Ty<'tcx>>> {
|
||||
Some(interner.type_of(self.non_enum_variant().tail_opt()?.did))
|
||||
}
|
||||
|
||||
fn is_phantom_data(self) -> bool {
|
||||
self.is_phantom_data()
|
||||
}
|
||||
|
@ -212,7 +220,7 @@ impl<'tcx> rustc_type_ir::inherent::AdtDef<TyCtxt<'tcx>> for AdtDef<'tcx> {
|
|||
fn all_field_tys(
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
) -> ty::EarlyBinder<'tcx, impl Iterator<Item = Ty<'tcx>>> {
|
||||
) -> ty::EarlyBinder<'tcx, impl IntoIterator<Item = Ty<'tcx>>> {
|
||||
ty::EarlyBinder::bind(
|
||||
self.all_fields().map(move |field| tcx.type_of(field.did).skip_binder()),
|
||||
)
|
||||
|
|
|
@ -16,8 +16,8 @@ mod valtree;
|
|||
|
||||
pub use int::*;
|
||||
pub use kind::*;
|
||||
use rustc_span::Span;
|
||||
use rustc_span::DUMMY_SP;
|
||||
use rustc_span::{ErrorGuaranteed, Span};
|
||||
pub use valtree::*;
|
||||
|
||||
pub type ConstKind<'tcx> = ir::ConstKind<TyCtxt<'tcx>>;
|
||||
|
@ -176,6 +176,10 @@ impl<'tcx> rustc_type_ir::inherent::Const<TyCtxt<'tcx>> for Const<'tcx> {
|
|||
fn new_expr(interner: TyCtxt<'tcx>, expr: ty::Expr<'tcx>) -> Self {
|
||||
Const::new_expr(interner, expr)
|
||||
}
|
||||
|
||||
fn new_error(interner: TyCtxt<'tcx>, guar: ErrorGuaranteed) -> Self {
|
||||
Const::new_error(interner, guar)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Const<'tcx> {
|
||||
|
|
|
@ -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>, ()>;
|
||||
|
|
|
@ -44,10 +44,23 @@ pub struct GenericArg<'tcx> {
|
|||
impl<'tcx> rustc_type_ir::inherent::GenericArg<TyCtxt<'tcx>> for GenericArg<'tcx> {}
|
||||
|
||||
impl<'tcx> rustc_type_ir::inherent::GenericArgs<TyCtxt<'tcx>> for ty::GenericArgsRef<'tcx> {
|
||||
fn rebase_onto(
|
||||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
source_ancestor: DefId,
|
||||
target_args: GenericArgsRef<'tcx>,
|
||||
) -> GenericArgsRef<'tcx> {
|
||||
self.rebase_onto(tcx, source_ancestor, target_args)
|
||||
}
|
||||
|
||||
fn type_at(self, i: usize) -> Ty<'tcx> {
|
||||
self.type_at(i)
|
||||
}
|
||||
|
||||
fn region_at(self, i: usize) -> ty::Region<'tcx> {
|
||||
self.region_at(i)
|
||||
}
|
||||
|
||||
fn identity_for_item(tcx: TyCtxt<'tcx>, def_id: DefId) -> ty::GenericArgsRef<'tcx> {
|
||||
GenericArgs::identity_for_item(tcx, def_id)
|
||||
}
|
||||
|
@ -281,6 +294,7 @@ impl<'tcx> GenericArg<'tcx> {
|
|||
pub fn is_non_region_infer(self) -> bool {
|
||||
match self.unpack() {
|
||||
GenericArgKind::Lifetime(_) => false,
|
||||
// FIXME: This shouldn't return numerical/float.
|
||||
GenericArgKind::Type(ty) => ty.is_ty_or_numeric_infer(),
|
||||
GenericArgKind::Const(ct) => ct.is_ct_infer(),
|
||||
}
|
||||
|
|
|
@ -392,6 +392,10 @@ impl<'tcx> GenericPredicates<'tcx> {
|
|||
EarlyBinder::bind(self.predicates).iter_instantiated_copied(tcx, args)
|
||||
}
|
||||
|
||||
pub fn instantiate_own_identity(&self) -> impl Iterator<Item = (Clause<'tcx>, Span)> {
|
||||
EarlyBinder::bind(self.predicates).instantiate_identity_iter_copied()
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self, tcx))]
|
||||
fn instantiate_into(
|
||||
&self,
|
||||
|
|
|
@ -990,6 +990,16 @@ pub struct ParamEnv<'tcx> {
|
|||
packed: CopyTaggedPtr<Clauses<'tcx>, ParamTag, true>,
|
||||
}
|
||||
|
||||
impl<'tcx> rustc_type_ir::inherent::ParamEnv<TyCtxt<'tcx>> for ParamEnv<'tcx> {
|
||||
fn reveal(self) -> Reveal {
|
||||
self.reveal()
|
||||
}
|
||||
|
||||
fn caller_bounds(self) -> impl IntoIterator<Item = ty::Clause<'tcx>> {
|
||||
self.caller_bounds()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Copy, Clone)]
|
||||
struct ParamTag {
|
||||
reveal: traits::Reveal,
|
||||
|
|
|
@ -175,6 +175,14 @@ pub struct Clause<'tcx>(
|
|||
|
||||
impl<'tcx> rustc_type_ir::inherent::Clause<TyCtxt<'tcx>> for Clause<'tcx> {}
|
||||
|
||||
impl<'tcx> rustc_type_ir::inherent::IntoKind for Clause<'tcx> {
|
||||
type Kind = ty::Binder<'tcx, ClauseKind<'tcx>>;
|
||||
|
||||
fn kind(self) -> Self::Kind {
|
||||
self.kind()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Clause<'tcx> {
|
||||
pub fn as_predicate(self) -> Predicate<'tcx> {
|
||||
Predicate(self.0)
|
||||
|
@ -251,6 +259,28 @@ impl<'tcx> ExistentialPredicate<'tcx> {
|
|||
|
||||
pub type PolyExistentialPredicate<'tcx> = ty::Binder<'tcx, ExistentialPredicate<'tcx>>;
|
||||
|
||||
impl<'tcx> rustc_type_ir::inherent::BoundExistentialPredicates<TyCtxt<'tcx>>
|
||||
for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>>
|
||||
{
|
||||
fn principal_def_id(self) -> Option<DefId> {
|
||||
self.principal_def_id()
|
||||
}
|
||||
|
||||
fn principal(self) -> Option<ty::PolyExistentialTraitRef<'tcx>> {
|
||||
self.principal()
|
||||
}
|
||||
|
||||
fn auto_traits(self) -> impl IntoIterator<Item = DefId> {
|
||||
self.auto_traits()
|
||||
}
|
||||
|
||||
fn projection_bounds(
|
||||
self,
|
||||
) -> impl IntoIterator<Item = ty::Binder<'tcx, ExistentialProjection<'tcx>>> {
|
||||
self.projection_bounds()
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ty::List<ty::PolyExistentialPredicate<'tcx>> {
|
||||
/// Returns the "principal `DefId`" of this set of existential predicates.
|
||||
///
|
||||
|
@ -481,12 +511,6 @@ impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TraitRef<'tcx>> for Predicate<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TraitRef<'tcx>> for TraitPredicate<'tcx> {
|
||||
fn upcast_from(from: TraitRef<'tcx>, _tcx: TyCtxt<'tcx>) -> Self {
|
||||
TraitPredicate { trait_ref: from, polarity: PredicatePolarity::Positive }
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> UpcastFrom<TyCtxt<'tcx>, TraitRef<'tcx>> for Clause<'tcx> {
|
||||
fn upcast_from(from: TraitRef<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
|
||||
let p: Predicate<'tcx> = from.upcast(tcx);
|
||||
|
@ -543,6 +567,12 @@ impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PolyTraitPredicate<'tcx>> for Clause<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> UpcastFrom<TyCtxt<'tcx>, RegionOutlivesPredicate<'tcx>> for Predicate<'tcx> {
|
||||
fn upcast_from(from: RegionOutlivesPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
|
||||
ty::Binder::dummy(PredicateKind::Clause(ClauseKind::RegionOutlives(from))).upcast(tcx)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> UpcastFrom<TyCtxt<'tcx>, PolyRegionOutlivesPredicate<'tcx>> for Predicate<'tcx> {
|
||||
fn upcast_from(from: PolyRegionOutlivesPredicate<'tcx>, tcx: TyCtxt<'tcx>) -> Self {
|
||||
from.map_bound(|p| PredicateKind::Clause(ClauseKind::RegionOutlives(p))).upcast(tcx)
|
||||
|
|
|
@ -930,6 +930,22 @@ impl<'tcx> rustc_type_ir::inherent::Ty<TyCtxt<'tcx>> for Ty<'tcx> {
|
|||
fn new_pat(interner: TyCtxt<'tcx>, ty: Self, pat: ty::Pattern<'tcx>) -> Self {
|
||||
Ty::new_pat(interner, ty, pat)
|
||||
}
|
||||
|
||||
fn new_unit(interner: TyCtxt<'tcx>) -> Self {
|
||||
interner.types.unit
|
||||
}
|
||||
|
||||
fn new_usize(interner: TyCtxt<'tcx>) -> Self {
|
||||
interner.types.usize
|
||||
}
|
||||
|
||||
fn discriminant_ty(self, interner: TyCtxt<'tcx>) -> Ty<'tcx> {
|
||||
self.discriminant_ty(interner)
|
||||
}
|
||||
|
||||
fn async_destructor_ty(self, interner: TyCtxt<'tcx>) -> Ty<'tcx> {
|
||||
self.async_destructor_ty(interner)
|
||||
}
|
||||
}
|
||||
|
||||
/// Type utilities
|
||||
|
|
|
@ -565,42 +565,6 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
/// Checks whether each generic argument is simply a unique generic placeholder.
|
||||
///
|
||||
/// This is used in the new solver, which canonicalizes params to placeholders
|
||||
/// for better caching.
|
||||
pub fn uses_unique_placeholders_ignoring_regions(
|
||||
self,
|
||||
args: GenericArgsRef<'tcx>,
|
||||
) -> Result<(), NotUniqueParam<'tcx>> {
|
||||
let mut seen = GrowableBitSet::default();
|
||||
for arg in args {
|
||||
match arg.unpack() {
|
||||
// Ignore regions, since we can't resolve those in a canonicalized
|
||||
// query in the trait solver.
|
||||
GenericArgKind::Lifetime(_) => {}
|
||||
GenericArgKind::Type(t) => match t.kind() {
|
||||
ty::Placeholder(p) => {
|
||||
if !seen.insert(p.bound.var) {
|
||||
return Err(NotUniqueParam::DuplicateParam(t.into()));
|
||||
}
|
||||
}
|
||||
_ => return Err(NotUniqueParam::NotParam(t.into())),
|
||||
},
|
||||
GenericArgKind::Const(c) => match c.kind() {
|
||||
ty::ConstKind::Placeholder(p) => {
|
||||
if !seen.insert(p.bound) {
|
||||
return Err(NotUniqueParam::DuplicateParam(c.into()));
|
||||
}
|
||||
}
|
||||
_ => return Err(NotUniqueParam::NotParam(c.into())),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Returns `true` if `def_id` refers to a closure, coroutine, or coroutine-closure
|
||||
/// (i.e. an async closure). These are all represented by `hir::Closure`, and all
|
||||
/// have the same `DefKind`.
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue