1
Fork 0

Uplift the new trait solver

This commit is contained in:
Michael Goulet 2024-06-17 17:59:08 -04:00
parent baf94bddf0
commit 532149eb88
36 changed files with 2014 additions and 1457 deletions

View file

@ -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()),
)

View file

@ -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> {

View file

@ -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>, ()>;

View file

@ -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(),
}

View file

@ -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,

View file

@ -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,

View file

@ -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)

View file

@ -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

View file

@ -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`.