Uplift AliasTy
This commit is contained in:
parent
34582118af
commit
1ad28a6f53
@ -106,6 +106,12 @@ fn into_diag_arg(self) -> DiagArgValue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<I: rustc_type_ir::Interner> IntoDiagArg for rustc_type_ir::UnevaluatedConst<I> {
|
||||||
|
fn into_diag_arg(self) -> rustc_errors::DiagArgValue {
|
||||||
|
format!("{self:?}").into_diag_arg()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
into_diag_arg_for_number!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128, isize, usize);
|
into_diag_arg_for_number!(i8, u8, i16, u16, i32, u32, i64, u64, i128, u128, isize, usize);
|
||||||
|
|
||||||
impl IntoDiagArg for bool {
|
impl IntoDiagArg for bool {
|
||||||
|
@ -7,8 +7,7 @@
|
|||||||
use rustc_hir::def::{DefKind, Res};
|
use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_hir::def_id::LocalDefId;
|
use rustc_hir::def_id::LocalDefId;
|
||||||
use rustc_macros::{HashStable, TyDecodable, TyEncodable};
|
use rustc_macros::{HashStable, TyDecodable, TyEncodable};
|
||||||
use rustc_type_ir::ConstKind as IrConstKind;
|
use rustc_type_ir::{self as ir, TypeFlags, WithCachedTypeInfo};
|
||||||
use rustc_type_ir::{TypeFlags, WithCachedTypeInfo};
|
|
||||||
|
|
||||||
mod int;
|
mod int;
|
||||||
mod kind;
|
mod kind;
|
||||||
@ -20,7 +19,8 @@
|
|||||||
use rustc_span::DUMMY_SP;
|
use rustc_span::DUMMY_SP;
|
||||||
pub use valtree::*;
|
pub use valtree::*;
|
||||||
|
|
||||||
pub type ConstKind<'tcx> = IrConstKind<TyCtxt<'tcx>>;
|
pub type ConstKind<'tcx> = ir::ConstKind<TyCtxt<'tcx>>;
|
||||||
|
pub type UnevaluatedConst<'tcx> = ir::UnevaluatedConst<TyCtxt<'tcx>>;
|
||||||
|
|
||||||
#[cfg(target_pointer_width = "64")]
|
#[cfg(target_pointer_width = "64")]
|
||||||
rustc_data_structures::static_assert_size!(ConstKind<'_>, 32);
|
rustc_data_structures::static_assert_size!(ConstKind<'_>, 32);
|
||||||
@ -184,9 +184,21 @@ fn new_anon_bound(
|
|||||||
Const::new_bound(tcx, debruijn, var, ty)
|
Const::new_bound(tcx, debruijn, var, ty)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn new_unevaluated(
|
||||||
|
interner: TyCtxt<'tcx>,
|
||||||
|
uv: ty::UnevaluatedConst<'tcx>,
|
||||||
|
ty: Ty<'tcx>,
|
||||||
|
) -> Self {
|
||||||
|
Const::new_unevaluated(interner, uv, ty)
|
||||||
|
}
|
||||||
|
|
||||||
fn ty(self) -> Ty<'tcx> {
|
fn ty(self) -> Ty<'tcx> {
|
||||||
self.ty()
|
self.ty()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn into_term(self) -> ty::Term<'tcx> {
|
||||||
|
self.into()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> Const<'tcx> {
|
impl<'tcx> Const<'tcx> {
|
||||||
|
@ -1,30 +1,15 @@
|
|||||||
use super::Const;
|
use super::Const;
|
||||||
use crate::mir;
|
use crate::mir;
|
||||||
use crate::ty::abstract_const::CastKind;
|
use crate::ty::abstract_const::CastKind;
|
||||||
use crate::ty::GenericArgsRef;
|
|
||||||
use crate::ty::{self, visit::TypeVisitableExt as _, List, Ty, TyCtxt};
|
use crate::ty::{self, visit::TypeVisitableExt as _, List, Ty, TyCtxt};
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_macros::{extension, HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
|
||||||
use rustc_macros::{HashStable, TyDecodable, TyEncodable, TypeFoldable, TypeVisitable};
|
|
||||||
|
|
||||||
/// An unevaluated (potentially generic) constant used in the type-system.
|
#[extension(pub(crate) trait UnevaluatedConstEvalExt<'tcx>)]
|
||||||
#[derive(Copy, Clone, Eq, PartialEq, TyEncodable, TyDecodable)]
|
impl<'tcx> ty::UnevaluatedConst<'tcx> {
|
||||||
#[derive(Hash, HashStable, TypeFoldable, TypeVisitable)]
|
|
||||||
pub struct UnevaluatedConst<'tcx> {
|
|
||||||
pub def: DefId,
|
|
||||||
pub args: GenericArgsRef<'tcx>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl rustc_errors::IntoDiagArg for UnevaluatedConst<'_> {
|
|
||||||
fn into_diag_arg(self) -> rustc_errors::DiagArgValue {
|
|
||||||
format!("{self:?}").into_diag_arg()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> UnevaluatedConst<'tcx> {
|
|
||||||
/// FIXME(RalfJung): I cannot explain what this does or why it makes sense, but not doing this
|
/// FIXME(RalfJung): I cannot explain what this does or why it makes sense, but not doing this
|
||||||
/// hurts performance.
|
/// hurts performance.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn prepare_for_eval(
|
fn prepare_for_eval(
|
||||||
self,
|
self,
|
||||||
tcx: TyCtxt<'tcx>,
|
tcx: TyCtxt<'tcx>,
|
||||||
param_env: ty::ParamEnv<'tcx>,
|
param_env: ty::ParamEnv<'tcx>,
|
||||||
@ -55,13 +40,6 @@ pub(crate) fn prepare_for_eval(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> UnevaluatedConst<'tcx> {
|
|
||||||
#[inline]
|
|
||||||
pub fn new(def: DefId, args: GenericArgsRef<'tcx>) -> UnevaluatedConst<'tcx> {
|
|
||||||
UnevaluatedConst { def, args }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
#[derive(Copy, Clone, Eq, PartialEq, Hash)]
|
||||||
#[derive(HashStable, TyEncodable, TyDecodable, TypeVisitable, TypeFoldable)]
|
#[derive(HashStable, TyEncodable, TyDecodable, TypeVisitable, TypeFoldable)]
|
||||||
pub enum Expr<'tcx> {
|
pub enum Expr<'tcx> {
|
||||||
|
@ -76,6 +76,7 @@
|
|||||||
use rustc_type_ir::WithCachedTypeInfo;
|
use rustc_type_ir::WithCachedTypeInfo;
|
||||||
use rustc_type_ir::{CollectAndApply, Interner, TypeFlags};
|
use rustc_type_ir::{CollectAndApply, Interner, TypeFlags};
|
||||||
|
|
||||||
|
use std::assert_matches::assert_matches;
|
||||||
use std::borrow::Borrow;
|
use std::borrow::Borrow;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@ -91,67 +92,124 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||||||
type DefiningOpaqueTypes = &'tcx ty::List<LocalDefId>;
|
type DefiningOpaqueTypes = &'tcx ty::List<LocalDefId>;
|
||||||
type AdtDef = ty::AdtDef<'tcx>;
|
type AdtDef = ty::AdtDef<'tcx>;
|
||||||
type GenericArgs = ty::GenericArgsRef<'tcx>;
|
type GenericArgs = ty::GenericArgsRef<'tcx>;
|
||||||
|
type GenericArgsSlice = &'tcx [ty::GenericArg<'tcx>];
|
||||||
type GenericArg = ty::GenericArg<'tcx>;
|
type GenericArg = ty::GenericArg<'tcx>;
|
||||||
type Term = ty::Term<'tcx>;
|
|
||||||
|
|
||||||
|
type Term = ty::Term<'tcx>;
|
||||||
type Binder<T: TypeVisitable<TyCtxt<'tcx>>> = Binder<'tcx, T>;
|
type Binder<T: TypeVisitable<TyCtxt<'tcx>>> = Binder<'tcx, T>;
|
||||||
type BoundVars = &'tcx List<ty::BoundVariableKind>;
|
type BoundVars = &'tcx List<ty::BoundVariableKind>;
|
||||||
type BoundVar = ty::BoundVariableKind;
|
type BoundVar = ty::BoundVariableKind;
|
||||||
type CanonicalVars = CanonicalVarInfos<'tcx>;
|
|
||||||
|
|
||||||
|
type CanonicalVars = CanonicalVarInfos<'tcx>;
|
||||||
type Ty = Ty<'tcx>;
|
type Ty = Ty<'tcx>;
|
||||||
type Tys = &'tcx List<Ty<'tcx>>;
|
type Tys = &'tcx List<Ty<'tcx>>;
|
||||||
type AliasTy = ty::AliasTy<'tcx>;
|
|
||||||
type ParamTy = ParamTy;
|
type ParamTy = ParamTy;
|
||||||
type BoundTy = ty::BoundTy;
|
type BoundTy = ty::BoundTy;
|
||||||
type PlaceholderTy = ty::PlaceholderType;
|
type PlaceholderTy = ty::PlaceholderType;
|
||||||
type ErrorGuaranteed = ErrorGuaranteed;
|
|
||||||
|
|
||||||
|
type ErrorGuaranteed = ErrorGuaranteed;
|
||||||
type BoundExistentialPredicates = &'tcx List<PolyExistentialPredicate<'tcx>>;
|
type BoundExistentialPredicates = &'tcx List<PolyExistentialPredicate<'tcx>>;
|
||||||
type PolyFnSig = PolyFnSig<'tcx>;
|
type PolyFnSig = PolyFnSig<'tcx>;
|
||||||
type AllocId = crate::mir::interpret::AllocId;
|
type AllocId = crate::mir::interpret::AllocId;
|
||||||
type Pat = Pattern<'tcx>;
|
|
||||||
|
|
||||||
|
type Pat = Pattern<'tcx>;
|
||||||
type Const = ty::Const<'tcx>;
|
type Const = ty::Const<'tcx>;
|
||||||
type AliasConst = ty::UnevaluatedConst<'tcx>;
|
type AliasConst = ty::UnevaluatedConst<'tcx>;
|
||||||
type PlaceholderConst = ty::PlaceholderConst;
|
type PlaceholderConst = ty::PlaceholderConst;
|
||||||
type ParamConst = ty::ParamConst;
|
type ParamConst = ty::ParamConst;
|
||||||
type BoundConst = ty::BoundVar;
|
type BoundConst = ty::BoundVar;
|
||||||
type ValueConst = ty::ValTree<'tcx>;
|
type ValueConst = ty::ValTree<'tcx>;
|
||||||
type ExprConst = ty::Expr<'tcx>;
|
|
||||||
|
|
||||||
|
type ExprConst = ty::Expr<'tcx>;
|
||||||
type Region = Region<'tcx>;
|
type Region = Region<'tcx>;
|
||||||
type EarlyParamRegion = ty::EarlyParamRegion;
|
type EarlyParamRegion = ty::EarlyParamRegion;
|
||||||
type LateParamRegion = ty::LateParamRegion;
|
type LateParamRegion = ty::LateParamRegion;
|
||||||
type BoundRegion = ty::BoundRegion;
|
type BoundRegion = ty::BoundRegion;
|
||||||
type InferRegion = ty::RegionVid;
|
type InferRegion = ty::RegionVid;
|
||||||
type PlaceholderRegion = ty::PlaceholderRegion;
|
|
||||||
|
|
||||||
|
type PlaceholderRegion = ty::PlaceholderRegion;
|
||||||
type Predicate = Predicate<'tcx>;
|
type Predicate = Predicate<'tcx>;
|
||||||
type TraitPredicate = ty::TraitPredicate<'tcx>;
|
type TraitPredicate = ty::TraitPredicate<'tcx>;
|
||||||
type RegionOutlivesPredicate = ty::RegionOutlivesPredicate<'tcx>;
|
type RegionOutlivesPredicate = ty::RegionOutlivesPredicate<'tcx>;
|
||||||
type TypeOutlivesPredicate = ty::TypeOutlivesPredicate<'tcx>;
|
type TypeOutlivesPredicate = ty::TypeOutlivesPredicate<'tcx>;
|
||||||
type ProjectionPredicate = ty::ProjectionPredicate<'tcx>;
|
type ProjectionPredicate = ty::ProjectionPredicate<'tcx>;
|
||||||
type AliasTerm = ty::AliasTerm<'tcx>;
|
|
||||||
type NormalizesTo = ty::NormalizesTo<'tcx>;
|
type NormalizesTo = ty::NormalizesTo<'tcx>;
|
||||||
type SubtypePredicate = ty::SubtypePredicate<'tcx>;
|
type SubtypePredicate = ty::SubtypePredicate<'tcx>;
|
||||||
type CoercePredicate = ty::CoercePredicate<'tcx>;
|
type CoercePredicate = ty::CoercePredicate<'tcx>;
|
||||||
type ClosureKind = ty::ClosureKind;
|
type ClosureKind = ty::ClosureKind;
|
||||||
type Clauses = ty::Clauses<'tcx>;
|
|
||||||
|
|
||||||
|
type Clauses = ty::Clauses<'tcx>;
|
||||||
fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars {
|
fn mk_canonical_var_infos(self, infos: &[ty::CanonicalVarInfo<Self>]) -> Self::CanonicalVars {
|
||||||
self.mk_canonical_var_infos(infos)
|
self.mk_canonical_var_infos(infos)
|
||||||
}
|
}
|
||||||
|
|
||||||
type GenericsOf = &'tcx ty::Generics;
|
type GenericsOf = &'tcx ty::Generics;
|
||||||
|
|
||||||
fn generics_of(self, def_id: DefId) -> &'tcx ty::Generics {
|
fn generics_of(self, def_id: DefId) -> &'tcx ty::Generics {
|
||||||
self.generics_of(def_id)
|
self.generics_of(def_id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn type_of_instantiated(self, def_id: DefId, args: ty::GenericArgsRef<'tcx>) -> Ty<'tcx> {
|
||||||
|
self.type_of(def_id).instantiate(self, args)
|
||||||
|
}
|
||||||
|
|
||||||
|
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::Weak,
|
||||||
|
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::OpaqueTy => ty::AliasTermKind::OpaqueTy,
|
||||||
|
DefKind::TyAlias => ty::AliasTermKind::WeakTy,
|
||||||
|
DefKind::AssocConst => ty::AliasTermKind::ProjectionConst,
|
||||||
|
DefKind::AnonConst => ty::AliasTermKind::UnevaluatedConst,
|
||||||
|
kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn trait_ref_and_own_args_for_alias(
|
||||||
|
self,
|
||||||
|
def_id: Self::DefId,
|
||||||
|
args: Self::GenericArgs,
|
||||||
|
) -> (rustc_type_ir::TraitRef<Self>, Self::GenericArgsSlice) {
|
||||||
|
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);
|
||||||
|
let trait_generics = self.generics_of(trait_def_id);
|
||||||
|
(
|
||||||
|
ty::TraitRef::new(self, trait_def_id, args.truncate_to(self, trait_generics)),
|
||||||
|
&args[trait_generics.count()..],
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs {
|
fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs {
|
||||||
self.mk_args(args)
|
self.mk_args(args)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn mk_args_from_iter(self, args: impl Iterator<Item = Self::GenericArg>) -> Self::GenericArgs {
|
||||||
|
self.mk_args_from_iter(args)
|
||||||
|
}
|
||||||
|
|
||||||
fn check_and_mk_args(
|
fn check_and_mk_args(
|
||||||
self,
|
self,
|
||||||
def_id: DefId,
|
def_id: DefId,
|
||||||
|
@ -96,9 +96,9 @@
|
|||||||
pub use self::parameterized::ParameterizedOverTcx;
|
pub use self::parameterized::ParameterizedOverTcx;
|
||||||
pub use self::pattern::{Pattern, PatternKind};
|
pub use self::pattern::{Pattern, PatternKind};
|
||||||
pub use self::predicate::{
|
pub use self::predicate::{
|
||||||
Clause, ClauseKind, CoercePredicate, ExistentialPredicate, ExistentialPredicateStableCmpExt,
|
AliasTerm, Clause, ClauseKind, CoercePredicate, ExistentialPredicate,
|
||||||
ExistentialProjection, ExistentialTraitRef, NormalizesTo, OutlivesPredicate,
|
ExistentialPredicateStableCmpExt, ExistentialProjection, ExistentialTraitRef, NormalizesTo,
|
||||||
PolyCoercePredicate, PolyExistentialPredicate, PolyExistentialProjection,
|
OutlivesPredicate, PolyCoercePredicate, PolyExistentialPredicate, PolyExistentialProjection,
|
||||||
PolyExistentialTraitRef, PolyProjectionPredicate, PolyRegionOutlivesPredicate,
|
PolyExistentialTraitRef, PolyProjectionPredicate, PolyRegionOutlivesPredicate,
|
||||||
PolySubtypePredicate, PolyTraitPredicate, PolyTraitRef, PolyTypeOutlivesPredicate, Predicate,
|
PolySubtypePredicate, PolyTraitPredicate, PolyTraitRef, PolyTypeOutlivesPredicate, Predicate,
|
||||||
PredicateKind, ProjectionPredicate, RegionOutlivesPredicate, SubtypePredicate, ToPolyTraitRef,
|
PredicateKind, ProjectionPredicate, RegionOutlivesPredicate, SubtypePredicate, ToPolyTraitRef,
|
||||||
@ -110,11 +110,11 @@
|
|||||||
};
|
};
|
||||||
pub use self::rvalue_scopes::RvalueScopes;
|
pub use self::rvalue_scopes::RvalueScopes;
|
||||||
pub use self::sty::{
|
pub use self::sty::{
|
||||||
AliasTerm, AliasTy, Article, Binder, BoundTy, BoundTyKind, BoundVariableKind,
|
AliasTy, Article, Binder, BoundTy, BoundTyKind, BoundVariableKind, CanonicalPolyFnSig,
|
||||||
CanonicalPolyFnSig, ClosureArgs, ClosureArgsParts, CoroutineArgs, CoroutineArgsParts,
|
ClosureArgs, ClosureArgsParts, CoroutineArgs, CoroutineArgsParts, CoroutineClosureArgs,
|
||||||
CoroutineClosureArgs, CoroutineClosureArgsParts, CoroutineClosureSignature, FnSig, GenSig,
|
CoroutineClosureArgsParts, CoroutineClosureSignature, FnSig, GenSig, InlineConstArgs,
|
||||||
InlineConstArgs, InlineConstArgsParts, ParamConst, ParamTy, PolyFnSig, TyKind, TypeAndMut,
|
InlineConstArgsParts, ParamConst, ParamTy, PolyFnSig, TyKind, TypeAndMut, UpvarArgs,
|
||||||
UpvarArgs, VarianceDiagInfo,
|
VarianceDiagInfo,
|
||||||
};
|
};
|
||||||
pub use self::trait_def::TraitDef;
|
pub use self::trait_def::TraitDef;
|
||||||
pub use self::typeck_results::{
|
pub use self::typeck_results::{
|
||||||
|
@ -13,6 +13,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
pub type TraitRef<'tcx> = ir::TraitRef<TyCtxt<'tcx>>;
|
pub type TraitRef<'tcx> = ir::TraitRef<TyCtxt<'tcx>>;
|
||||||
|
pub type AliasTerm<'tcx> = ir::AliasTerm<TyCtxt<'tcx>>;
|
||||||
pub type ProjectionPredicate<'tcx> = ir::ProjectionPredicate<TyCtxt<'tcx>>;
|
pub type ProjectionPredicate<'tcx> = ir::ProjectionPredicate<TyCtxt<'tcx>>;
|
||||||
pub type ExistentialPredicate<'tcx> = ir::ExistentialPredicate<TyCtxt<'tcx>>;
|
pub type ExistentialPredicate<'tcx> = ir::ExistentialPredicate<TyCtxt<'tcx>>;
|
||||||
pub type ExistentialTraitRef<'tcx> = ir::ExistentialTraitRef<TyCtxt<'tcx>>;
|
pub type ExistentialTraitRef<'tcx> = ir::ExistentialTraitRef<TyCtxt<'tcx>>;
|
||||||
|
@ -3038,6 +3038,33 @@ macro_rules! define_print_and_forward_display {
|
|||||||
p!(write("<{} as {}>", self.self_ty(), self.print_only_trait_path()))
|
p!(write("<{} as {}>", self.self_ty(), self.print_only_trait_path()))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ty::AliasTy<'tcx> {
|
||||||
|
let alias_term: ty::AliasTerm<'tcx> = (*self).into();
|
||||||
|
p!(print(alias_term))
|
||||||
|
}
|
||||||
|
|
||||||
|
ty::AliasTerm<'tcx> {
|
||||||
|
match self.kind(cx.tcx()) {
|
||||||
|
ty::AliasTermKind::InherentTy => p!(pretty_print_inherent_projection(*self)),
|
||||||
|
ty::AliasTermKind::ProjectionTy
|
||||||
|
| ty::AliasTermKind::WeakTy
|
||||||
|
| ty::AliasTermKind::OpaqueTy
|
||||||
|
| ty::AliasTermKind::UnevaluatedConst
|
||||||
|
| ty::AliasTermKind::ProjectionConst => {
|
||||||
|
// If we're printing verbosely, or don't want to invoke queries
|
||||||
|
// (`is_impl_trait_in_trait`), then fall back to printing the def path.
|
||||||
|
// This is likely what you want if you're debugging the compiler anyways.
|
||||||
|
if !(cx.should_print_verbose() || with_reduced_queries())
|
||||||
|
&& cx.tcx().is_impl_trait_in_trait(self.def_id)
|
||||||
|
{
|
||||||
|
return cx.pretty_print_opaque_impl_type(self.def_id, self.args);
|
||||||
|
} else {
|
||||||
|
p!(print_def_path(self.def_id, self.args));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
ty::TraitPredicate<'tcx> {
|
ty::TraitPredicate<'tcx> {
|
||||||
p!(print(self.trait_ref.self_ty()), ": ");
|
p!(print(self.trait_ref.self_ty()), ": ");
|
||||||
p!(pretty_print_bound_constness(self.trait_ref));
|
p!(pretty_print_bound_constness(self.trait_ref));
|
||||||
@ -3205,33 +3232,6 @@ macro_rules! define_print_and_forward_display {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::AliasTy<'tcx> {
|
|
||||||
let alias_term: ty::AliasTerm<'tcx> = (*self).into();
|
|
||||||
p!(print(alias_term))
|
|
||||||
}
|
|
||||||
|
|
||||||
ty::AliasTerm<'tcx> {
|
|
||||||
match self.kind(cx.tcx()) {
|
|
||||||
ty::AliasTermKind::InherentTy => p!(pretty_print_inherent_projection(*self)),
|
|
||||||
ty::AliasTermKind::ProjectionTy
|
|
||||||
| ty::AliasTermKind::WeakTy
|
|
||||||
| ty::AliasTermKind::OpaqueTy
|
|
||||||
| ty::AliasTermKind::UnevaluatedConst
|
|
||||||
| ty::AliasTermKind::ProjectionConst => {
|
|
||||||
// If we're printing verbosely, or don't want to invoke queries
|
|
||||||
// (`is_impl_trait_in_trait`), then fall back to printing the def path.
|
|
||||||
// This is likely what you want if you're debugging the compiler anyways.
|
|
||||||
if !(cx.should_print_verbose() || with_reduced_queries())
|
|
||||||
&& cx.tcx().is_impl_trait_in_trait(self.def_id)
|
|
||||||
{
|
|
||||||
return cx.pretty_print_opaque_impl_type(self.def_id, self.args);
|
|
||||||
} else {
|
|
||||||
p!(print_def_path(self.def_id, self.args));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
ty::Predicate<'tcx> {
|
ty::Predicate<'tcx> {
|
||||||
p!(print(self.kind()))
|
p!(print(self.kind()))
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable};
|
use crate::ty::fold::{FallibleTypeFolder, TypeFoldable, TypeSuperFoldable};
|
||||||
use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer};
|
use crate::ty::print::{with_no_trimmed_paths, FmtPrinter, Printer};
|
||||||
use crate::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
|
use crate::ty::visit::{TypeSuperVisitable, TypeVisitable, TypeVisitor};
|
||||||
use crate::ty::{self, AliasTy, InferConst, Lift, Term, TermKind, Ty, TyCtxt};
|
use crate::ty::{self, InferConst, Lift, Term, TermKind, Ty, TyCtxt};
|
||||||
use rustc_ast_ir::try_visit;
|
use rustc_ast_ir::try_visit;
|
||||||
use rustc_ast_ir::visit::VisitorResult;
|
use rustc_ast_ir::visit::VisitorResult;
|
||||||
use rustc_hir::def::Namespace;
|
use rustc_hir::def::Namespace;
|
||||||
@ -164,23 +164,6 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> fmt::Debug for AliasTy<'tcx> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
WithInfcx::with_no_infcx(self).fmt(f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for AliasTy<'tcx> {
|
|
||||||
fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>(
|
|
||||||
this: WithInfcx<'_, Infcx, &Self>,
|
|
||||||
f: &mut core::fmt::Formatter<'_>,
|
|
||||||
) -> core::fmt::Result {
|
|
||||||
f.debug_struct("AliasTy")
|
|
||||||
.field("args", &this.map(|data| data.args))
|
|
||||||
.field("def_id", &this.data.def_id)
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for Pattern<'tcx> {
|
impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for Pattern<'tcx> {
|
||||||
fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>(
|
fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>(
|
||||||
this: WithInfcx<'_, Infcx, &Self>,
|
this: WithInfcx<'_, Infcx, &Self>,
|
||||||
@ -230,23 +213,6 @@ fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'tcx> fmt::Debug for ty::UnevaluatedConst<'tcx> {
|
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
||||||
WithInfcx::with_no_infcx(self).fmt(f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for ty::UnevaluatedConst<'tcx> {
|
|
||||||
fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>(
|
|
||||||
this: WithInfcx<'_, Infcx, &Self>,
|
|
||||||
f: &mut core::fmt::Formatter<'_>,
|
|
||||||
) -> core::fmt::Result {
|
|
||||||
f.debug_struct("UnevaluatedConst")
|
|
||||||
.field("def", &this.data.def)
|
|
||||||
.field("args", &this.wrap(this.data.args))
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> fmt::Debug for ty::Const<'tcx> {
|
impl<'tcx> fmt::Debug for ty::Const<'tcx> {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
WithInfcx::with_no_infcx(self).fmt(f)
|
WithInfcx::with_no_infcx(self).fmt(f)
|
||||||
|
@ -28,20 +28,17 @@
|
|||||||
use std::ops::{ControlFlow, Deref, Range};
|
use std::ops::{ControlFlow, Deref, Range};
|
||||||
use ty::util::IntTypeExt;
|
use ty::util::IntTypeExt;
|
||||||
|
|
||||||
use rustc_type_ir::BoundVar;
|
|
||||||
use rustc_type_ir::CollectAndApply;
|
|
||||||
use rustc_type_ir::DynKind;
|
|
||||||
use rustc_type_ir::TyKind as IrTyKind;
|
|
||||||
use rustc_type_ir::TyKind::*;
|
use rustc_type_ir::TyKind::*;
|
||||||
use rustc_type_ir::TypeAndMut as IrTypeAndMut;
|
use rustc_type_ir::{self as ir, BoundVar, CollectAndApply, DynKind};
|
||||||
|
|
||||||
use super::fold::FnMutDelegate;
|
use super::fold::FnMutDelegate;
|
||||||
use super::GenericParamDefKind;
|
use super::GenericParamDefKind;
|
||||||
|
|
||||||
// Re-export and re-parameterize some `I = TyCtxt<'tcx>` types here
|
// Re-export and re-parameterize some `I = TyCtxt<'tcx>` types here
|
||||||
#[rustc_diagnostic_item = "TyKind"]
|
#[rustc_diagnostic_item = "TyKind"]
|
||||||
pub type TyKind<'tcx> = IrTyKind<TyCtxt<'tcx>>;
|
pub type TyKind<'tcx> = ir::TyKind<TyCtxt<'tcx>>;
|
||||||
pub type TypeAndMut<'tcx> = IrTypeAndMut<TyCtxt<'tcx>>;
|
pub type TypeAndMut<'tcx> = ir::TypeAndMut<TyCtxt<'tcx>>;
|
||||||
|
pub type AliasTy<'tcx> = ir::AliasTy<TyCtxt<'tcx>>;
|
||||||
|
|
||||||
pub trait Article {
|
pub trait Article {
|
||||||
fn article(&self) -> &'static str;
|
fn article(&self) -> &'static str;
|
||||||
@ -1105,371 +1102,6 @@ fn into_diag_arg(self) -> DiagArgValue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Represents the unprojected term of a projection goal.
|
|
||||||
///
|
|
||||||
/// * For a projection, this would be `<Ty as Trait<...>>::N<...>`.
|
|
||||||
/// * For an inherent projection, this would be `Ty::N<...>`.
|
|
||||||
/// * For an opaque type, there is no explicit syntax.
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
|
|
||||||
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
|
|
||||||
pub struct AliasTerm<'tcx> {
|
|
||||||
/// The parameters of the associated or opaque item.
|
|
||||||
///
|
|
||||||
/// For a projection, these are the generic parameters for the trait and the
|
|
||||||
/// GAT parameters, if there are any.
|
|
||||||
///
|
|
||||||
/// For an inherent projection, they consist of the self type and the GAT parameters,
|
|
||||||
/// if there are any.
|
|
||||||
///
|
|
||||||
/// For RPIT the generic parameters are for the generics of the function,
|
|
||||||
/// while for TAIT it is used for the generic parameters of the alias.
|
|
||||||
pub args: GenericArgsRef<'tcx>,
|
|
||||||
|
|
||||||
/// The `DefId` of the `TraitItem` or `ImplItem` for the associated type `N` depending on whether
|
|
||||||
/// this is a projection or an inherent projection or the `DefId` of the `OpaqueType` item if
|
|
||||||
/// this is an opaque.
|
|
||||||
///
|
|
||||||
/// During codegen, `tcx.type_of(def_id)` can be used to get the type of the
|
|
||||||
/// underlying type if the type is an opaque.
|
|
||||||
///
|
|
||||||
/// Note that if this is an associated type, this is not the `DefId` of the
|
|
||||||
/// `TraitRef` containing this associated type, which is in `tcx.associated_item(def_id).container`,
|
|
||||||
/// aka. `tcx.parent(def_id)`.
|
|
||||||
pub def_id: DefId,
|
|
||||||
|
|
||||||
/// This field exists to prevent the creation of `AliasTerm` without using
|
|
||||||
/// [AliasTerm::new].
|
|
||||||
_use_alias_term_new_instead: (),
|
|
||||||
}
|
|
||||||
|
|
||||||
// FIXME: Remove these when we uplift `AliasTerm`
|
|
||||||
use crate::ty::{DebugWithInfcx, InferCtxtLike, WithInfcx};
|
|
||||||
impl<'tcx> std::fmt::Debug for AliasTerm<'tcx> {
|
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
|
||||||
WithInfcx::with_no_infcx(self).fmt(f)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
impl<'tcx> DebugWithInfcx<TyCtxt<'tcx>> for AliasTerm<'tcx> {
|
|
||||||
fn fmt<Infcx: InferCtxtLike<Interner = TyCtxt<'tcx>>>(
|
|
||||||
this: WithInfcx<'_, Infcx, &Self>,
|
|
||||||
f: &mut std::fmt::Formatter<'_>,
|
|
||||||
) -> std::fmt::Result {
|
|
||||||
f.debug_struct("AliasTerm")
|
|
||||||
.field("args", &this.map(|data| data.args))
|
|
||||||
.field("def_id", &this.data.def_id)
|
|
||||||
.finish()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> rustc_type_ir::inherent::AliasTerm<TyCtxt<'tcx>> for AliasTerm<'tcx> {
|
|
||||||
fn new(
|
|
||||||
interner: TyCtxt<'tcx>,
|
|
||||||
trait_def_id: DefId,
|
|
||||||
args: impl IntoIterator<Item: Into<ty::GenericArg<'tcx>>>,
|
|
||||||
) -> Self {
|
|
||||||
AliasTerm::new(interner, trait_def_id, args)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn def_id(self) -> DefId {
|
|
||||||
self.def_id
|
|
||||||
}
|
|
||||||
|
|
||||||
fn args(self) -> ty::GenericArgsRef<'tcx> {
|
|
||||||
self.args
|
|
||||||
}
|
|
||||||
|
|
||||||
fn trait_def_id(self, interner: TyCtxt<'tcx>) -> DefId {
|
|
||||||
self.trait_def_id(interner)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn self_ty(self) -> Ty<'tcx> {
|
|
||||||
self.self_ty()
|
|
||||||
}
|
|
||||||
|
|
||||||
fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self {
|
|
||||||
self.with_self_ty(tcx, self_ty)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> AliasTerm<'tcx> {
|
|
||||||
pub fn new(
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
def_id: DefId,
|
|
||||||
args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
|
|
||||||
) -> AliasTerm<'tcx> {
|
|
||||||
let args = tcx.check_and_mk_args(def_id, args);
|
|
||||||
AliasTerm { def_id, args, _use_alias_term_new_instead: () }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn expect_ty(self, tcx: TyCtxt<'tcx>) -> AliasTy<'tcx> {
|
|
||||||
match self.kind(tcx) {
|
|
||||||
ty::AliasTermKind::ProjectionTy
|
|
||||||
| ty::AliasTermKind::InherentTy
|
|
||||||
| ty::AliasTermKind::OpaqueTy
|
|
||||||
| ty::AliasTermKind::WeakTy => {}
|
|
||||||
ty::AliasTermKind::UnevaluatedConst | ty::AliasTermKind::ProjectionConst => {
|
|
||||||
bug!("Cannot turn `UnevaluatedConst` into `AliasTy`")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
ty::AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn kind(self, tcx: TyCtxt<'tcx>) -> ty::AliasTermKind {
|
|
||||||
match tcx.def_kind(self.def_id) {
|
|
||||||
DefKind::AssocTy => {
|
|
||||||
if let DefKind::Impl { of_trait: false } = tcx.def_kind(tcx.parent(self.def_id)) {
|
|
||||||
ty::AliasTermKind::InherentTy
|
|
||||||
} else {
|
|
||||||
ty::AliasTermKind::ProjectionTy
|
|
||||||
}
|
|
||||||
}
|
|
||||||
DefKind::OpaqueTy => ty::AliasTermKind::OpaqueTy,
|
|
||||||
DefKind::TyAlias => ty::AliasTermKind::WeakTy,
|
|
||||||
DefKind::AnonConst => ty::AliasTermKind::UnevaluatedConst,
|
|
||||||
DefKind::AssocConst => ty::AliasTermKind::ProjectionConst,
|
|
||||||
kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The following methods work only with (trait) associated item projections.
|
|
||||||
impl<'tcx> AliasTerm<'tcx> {
|
|
||||||
pub fn self_ty(self) -> Ty<'tcx> {
|
|
||||||
self.args.type_at(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self {
|
|
||||||
AliasTerm::new(
|
|
||||||
tcx,
|
|
||||||
self.def_id,
|
|
||||||
[self_ty.into()].into_iter().chain(self.args.iter().skip(1)),
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn trait_def_id(self, tcx: TyCtxt<'tcx>) -> DefId {
|
|
||||||
match tcx.def_kind(self.def_id) {
|
|
||||||
DefKind::AssocTy | DefKind::AssocConst => tcx.parent(self.def_id),
|
|
||||||
kind => bug!("expected a projection AliasTy; found {kind:?}"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Extracts the underlying trait reference from this projection.
|
|
||||||
/// For example, if this is a projection of `<T as Iterator>::Item`,
|
|
||||||
/// then this function would return a `T: Iterator` trait reference.
|
|
||||||
///
|
|
||||||
/// NOTE: This will drop the args for generic associated types
|
|
||||||
/// consider calling [Self::trait_ref_and_own_args] to get those
|
|
||||||
/// as well.
|
|
||||||
pub fn trait_ref(self, tcx: TyCtxt<'tcx>) -> ty::TraitRef<'tcx> {
|
|
||||||
let def_id = self.trait_def_id(tcx);
|
|
||||||
ty::TraitRef::new(tcx, def_id, self.args.truncate_to(tcx, tcx.generics_of(def_id)))
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Extracts the underlying trait reference and own args from this projection.
|
|
||||||
/// For example, if this is a projection of `<T as StreamingIterator>::Item<'a>`,
|
|
||||||
/// then this function would return a `T: StreamingIterator` trait reference and `['a]` as the own args
|
|
||||||
pub fn trait_ref_and_own_args(
|
|
||||||
self,
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) {
|
|
||||||
let trait_def_id = self.trait_def_id(tcx);
|
|
||||||
let trait_generics = tcx.generics_of(trait_def_id);
|
|
||||||
(
|
|
||||||
ty::TraitRef::new(tcx, trait_def_id, self.args.truncate_to(tcx, trait_generics)),
|
|
||||||
&self.args[trait_generics.count()..],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn to_term(self, tcx: TyCtxt<'tcx>) -> ty::Term<'tcx> {
|
|
||||||
match self.kind(tcx) {
|
|
||||||
ty::AliasTermKind::ProjectionTy => Ty::new_alias(
|
|
||||||
tcx,
|
|
||||||
ty::Projection,
|
|
||||||
AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
|
|
||||||
)
|
|
||||||
.into(),
|
|
||||||
ty::AliasTermKind::InherentTy => Ty::new_alias(
|
|
||||||
tcx,
|
|
||||||
ty::Inherent,
|
|
||||||
AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
|
|
||||||
)
|
|
||||||
.into(),
|
|
||||||
ty::AliasTermKind::OpaqueTy => Ty::new_alias(
|
|
||||||
tcx,
|
|
||||||
ty::Opaque,
|
|
||||||
AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
|
|
||||||
)
|
|
||||||
.into(),
|
|
||||||
ty::AliasTermKind::WeakTy => Ty::new_alias(
|
|
||||||
tcx,
|
|
||||||
ty::Weak,
|
|
||||||
AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
|
|
||||||
)
|
|
||||||
.into(),
|
|
||||||
ty::AliasTermKind::UnevaluatedConst | ty::AliasTermKind::ProjectionConst => {
|
|
||||||
ty::Const::new_unevaluated(
|
|
||||||
tcx,
|
|
||||||
ty::UnevaluatedConst::new(self.def_id, self.args),
|
|
||||||
tcx.type_of(self.def_id).instantiate(tcx, self.args),
|
|
||||||
)
|
|
||||||
.into()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> From<AliasTy<'tcx>> for AliasTerm<'tcx> {
|
|
||||||
fn from(ty: AliasTy<'tcx>) -> Self {
|
|
||||||
AliasTerm { args: ty.args, def_id: ty.def_id, _use_alias_term_new_instead: () }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> From<ty::UnevaluatedConst<'tcx>> for AliasTerm<'tcx> {
|
|
||||||
fn from(ct: ty::UnevaluatedConst<'tcx>) -> Self {
|
|
||||||
AliasTerm { args: ct.args, def_id: ct.def, _use_alias_term_new_instead: () }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Represents the projection of an associated, opaque, or lazy-type-alias type.
|
|
||||||
///
|
|
||||||
/// * For a projection, this would be `<Ty as Trait<...>>::N<...>`.
|
|
||||||
/// * For an inherent projection, this would be `Ty::N<...>`.
|
|
||||||
/// * For an opaque type, there is no explicit syntax.
|
|
||||||
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
|
|
||||||
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
|
|
||||||
pub struct AliasTy<'tcx> {
|
|
||||||
/// The parameters of the associated or opaque type.
|
|
||||||
///
|
|
||||||
/// For a projection, these are the generic parameters for the trait and the
|
|
||||||
/// GAT parameters, if there are any.
|
|
||||||
///
|
|
||||||
/// For an inherent projection, they consist of the self type and the GAT parameters,
|
|
||||||
/// if there are any.
|
|
||||||
///
|
|
||||||
/// For RPIT the generic parameters are for the generics of the function,
|
|
||||||
/// while for TAIT it is used for the generic parameters of the alias.
|
|
||||||
pub args: GenericArgsRef<'tcx>,
|
|
||||||
|
|
||||||
/// The `DefId` of the `TraitItem` or `ImplItem` for the associated type `N` depending on whether
|
|
||||||
/// this is a projection or an inherent projection or the `DefId` of the `OpaqueType` item if
|
|
||||||
/// this is an opaque.
|
|
||||||
///
|
|
||||||
/// During codegen, `tcx.type_of(def_id)` can be used to get the type of the
|
|
||||||
/// underlying type if the type is an opaque.
|
|
||||||
///
|
|
||||||
/// Note that if this is an associated type, this is not the `DefId` of the
|
|
||||||
/// `TraitRef` containing this associated type, which is in `tcx.associated_item(def_id).container`,
|
|
||||||
/// aka. `tcx.parent(def_id)`.
|
|
||||||
pub def_id: DefId,
|
|
||||||
|
|
||||||
/// This field exists to prevent the creation of `AliasT` without using
|
|
||||||
/// [AliasTy::new].
|
|
||||||
_use_alias_ty_new_instead: (),
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'tcx> AliasTy<'tcx> {
|
|
||||||
pub fn new(
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
def_id: DefId,
|
|
||||||
args: impl IntoIterator<Item: Into<GenericArg<'tcx>>>,
|
|
||||||
) -> ty::AliasTy<'tcx> {
|
|
||||||
let args = tcx.check_and_mk_args(def_id, args);
|
|
||||||
ty::AliasTy { def_id, args, _use_alias_ty_new_instead: () }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn kind(self, tcx: TyCtxt<'tcx>) -> ty::AliasTyKind {
|
|
||||||
match tcx.def_kind(self.def_id) {
|
|
||||||
DefKind::AssocTy
|
|
||||||
if let DefKind::Impl { of_trait: false } =
|
|
||||||
tcx.def_kind(tcx.parent(self.def_id)) =>
|
|
||||||
{
|
|
||||||
ty::Inherent
|
|
||||||
}
|
|
||||||
DefKind::AssocTy => ty::Projection,
|
|
||||||
DefKind::OpaqueTy => ty::Opaque,
|
|
||||||
DefKind::TyAlias => ty::Weak,
|
|
||||||
kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Whether this alias type is an opaque.
|
|
||||||
pub fn is_opaque(self, tcx: TyCtxt<'tcx>) -> bool {
|
|
||||||
matches!(self.kind(tcx), ty::Opaque)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
|
|
||||||
Ty::new_alias(tcx, self.kind(tcx), self)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The following methods work only with (trait) associated type projections.
|
|
||||||
impl<'tcx> AliasTy<'tcx> {
|
|
||||||
pub fn self_ty(self) -> Ty<'tcx> {
|
|
||||||
self.args.type_at(0)
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn with_self_ty(self, tcx: TyCtxt<'tcx>, self_ty: Ty<'tcx>) -> Self {
|
|
||||||
AliasTy::new(tcx, self.def_id, [self_ty.into()].into_iter().chain(self.args.iter().skip(1)))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn trait_def_id(self, tcx: TyCtxt<'tcx>) -> DefId {
|
|
||||||
match tcx.def_kind(self.def_id) {
|
|
||||||
DefKind::AssocTy | DefKind::AssocConst => tcx.parent(self.def_id),
|
|
||||||
kind => bug!("expected a projection AliasTy; found {kind:?}"),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Extracts the underlying trait reference and own args from this projection.
|
|
||||||
/// For example, if this is a projection of `<T as StreamingIterator>::Item<'a>`,
|
|
||||||
/// then this function would return a `T: StreamingIterator` trait reference and `['a]` as the own args
|
|
||||||
pub fn trait_ref_and_own_args(
|
|
||||||
self,
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
) -> (ty::TraitRef<'tcx>, &'tcx [ty::GenericArg<'tcx>]) {
|
|
||||||
let trait_def_id = self.trait_def_id(tcx);
|
|
||||||
let trait_generics = tcx.generics_of(trait_def_id);
|
|
||||||
(
|
|
||||||
ty::TraitRef::new(tcx, trait_def_id, self.args.truncate_to(tcx, trait_generics)),
|
|
||||||
&self.args[trait_generics.count()..],
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Extracts the underlying trait reference from this projection.
|
|
||||||
/// For example, if this is a projection of `<T as Iterator>::Item`,
|
|
||||||
/// then this function would return a `T: Iterator` trait reference.
|
|
||||||
///
|
|
||||||
/// WARNING: This will drop the args for generic associated types
|
|
||||||
/// consider calling [Self::trait_ref_and_own_args] to get those
|
|
||||||
/// as well.
|
|
||||||
pub fn trait_ref(self, tcx: TyCtxt<'tcx>) -> ty::TraitRef<'tcx> {
|
|
||||||
let def_id = self.trait_def_id(tcx);
|
|
||||||
ty::TraitRef::new(tcx, def_id, self.args.truncate_to(tcx, tcx.generics_of(def_id)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The following methods work only with inherent associated type projections.
|
|
||||||
impl<'tcx> AliasTy<'tcx> {
|
|
||||||
/// Transform the generic parameters to have the given `impl` args as the base and the GAT args on top of that.
|
|
||||||
///
|
|
||||||
/// Does the following transformation:
|
|
||||||
///
|
|
||||||
/// ```text
|
|
||||||
/// [Self, P_0...P_m] -> [I_0...I_n, P_0...P_m]
|
|
||||||
///
|
|
||||||
/// I_i impl args
|
|
||||||
/// P_j GAT args
|
|
||||||
/// ```
|
|
||||||
pub fn rebase_inherent_args_onto_impl(
|
|
||||||
self,
|
|
||||||
impl_args: ty::GenericArgsRef<'tcx>,
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
) -> ty::GenericArgsRef<'tcx> {
|
|
||||||
debug_assert_eq!(self.kind(tcx), ty::Inherent);
|
|
||||||
|
|
||||||
tcx.mk_args_from_iter(impl_args.into_iter().chain(self.args.into_iter().skip(1)))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable)]
|
#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable)]
|
||||||
pub struct GenSig<'tcx> {
|
pub struct GenSig<'tcx> {
|
||||||
pub resume_ty: Ty<'tcx>,
|
pub resume_ty: Ty<'tcx>,
|
||||||
@ -2020,6 +1652,18 @@ impl<'tcx> rustc_type_ir::inherent::Ty<TyCtxt<'tcx>> for Ty<'tcx> {
|
|||||||
fn new_anon_bound(tcx: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self {
|
fn new_anon_bound(tcx: TyCtxt<'tcx>, debruijn: ty::DebruijnIndex, var: ty::BoundVar) -> Self {
|
||||||
Ty::new_bound(tcx, debruijn, ty::BoundTy { var, kind: ty::BoundTyKind::Anon })
|
Ty::new_bound(tcx, debruijn, ty::BoundTy { var, kind: ty::BoundTyKind::Anon })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn new_alias(
|
||||||
|
interner: TyCtxt<'tcx>,
|
||||||
|
kind: ty::AliasTyKind,
|
||||||
|
alias_ty: ty::AliasTy<'tcx>,
|
||||||
|
) -> Self {
|
||||||
|
Ty::new_alias(interner, kind, alias_ty)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn into_term(self) -> ty::Term<'tcx> {
|
||||||
|
self.into()
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Type utilities
|
/// Type utilities
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
|
use rustc_macros::{HashStable_NoContext, TyDecodable, TyEncodable};
|
||||||
|
use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use crate::{DebruijnIndex, DebugWithInfcx, InferCtxtLike, Interner, WithInfcx};
|
use crate::{DebruijnIndex, DebugWithInfcx, InferCtxtLike, Interner, WithInfcx};
|
||||||
@ -86,6 +87,46 @@ fn fmt<Infcx: InferCtxtLike<Interner = I>>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// An unevaluated (potentially generic) constant used in the type-system.
|
||||||
|
#[derive(derivative::Derivative)]
|
||||||
|
#[derivative(
|
||||||
|
Clone(bound = ""),
|
||||||
|
Copy(bound = ""),
|
||||||
|
Hash(bound = ""),
|
||||||
|
PartialEq(bound = ""),
|
||||||
|
Eq(bound = "")
|
||||||
|
)]
|
||||||
|
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||||
|
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
|
||||||
|
pub struct UnevaluatedConst<I: Interner> {
|
||||||
|
pub def: I::DefId,
|
||||||
|
pub args: I::GenericArgs,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: Interner> UnevaluatedConst<I> {
|
||||||
|
#[inline]
|
||||||
|
pub fn new(def: I::DefId, args: I::GenericArgs) -> UnevaluatedConst<I> {
|
||||||
|
UnevaluatedConst { def, args }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: Interner> fmt::Debug for UnevaluatedConst<I> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
WithInfcx::with_no_infcx(self).fmt(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<I: Interner> DebugWithInfcx<I> for UnevaluatedConst<I> {
|
||||||
|
fn fmt<Infcx: InferCtxtLike<Interner = I>>(
|
||||||
|
this: WithInfcx<'_, Infcx, &Self>,
|
||||||
|
f: &mut core::fmt::Formatter<'_>,
|
||||||
|
) -> core::fmt::Result {
|
||||||
|
f.debug_struct("UnevaluatedConst")
|
||||||
|
.field("def", &this.data.def)
|
||||||
|
.field("args", &this.wrap(this.data.args))
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
rustc_index::newtype_index! {
|
rustc_index::newtype_index! {
|
||||||
/// A **`const`** **v**ariable **ID**.
|
/// A **`const`** **v**ariable **ID**.
|
||||||
#[encodable]
|
#[encodable]
|
||||||
|
@ -5,7 +5,8 @@
|
|||||||
use crate::fold::TypeSuperFoldable;
|
use crate::fold::TypeSuperFoldable;
|
||||||
use crate::visit::{Flags, TypeSuperVisitable};
|
use crate::visit::{Flags, TypeSuperVisitable};
|
||||||
use crate::{
|
use crate::{
|
||||||
BoundVar, ConstKind, DebruijnIndex, DebugWithInfcx, Interner, RegionKind, TyKind, UniverseIndex,
|
AliasTy, AliasTyKind, BoundVar, ConstKind, DebruijnIndex, DebugWithInfcx, Interner, RegionKind,
|
||||||
|
TyKind, UnevaluatedConst, UniverseIndex,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait Ty<I: Interner<Ty = Self>>:
|
pub trait Ty<I: Interner<Ty = Self>>:
|
||||||
@ -20,6 +21,10 @@ pub trait Ty<I: Interner<Ty = Self>>:
|
|||||||
+ Flags
|
+ Flags
|
||||||
{
|
{
|
||||||
fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar) -> Self;
|
fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar) -> Self;
|
||||||
|
|
||||||
|
fn new_alias(interner: I, kind: AliasTyKind, alias_ty: AliasTy<I>) -> Self;
|
||||||
|
|
||||||
|
fn into_term(self) -> I::Term;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait Region<I: Interner<Region = Self>>:
|
pub trait Region<I: Interner<Region = Self>>:
|
||||||
@ -43,7 +48,11 @@ pub trait Const<I: Interner<Const = Self>>:
|
|||||||
{
|
{
|
||||||
fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar, ty: I::Ty) -> Self;
|
fn new_anon_bound(interner: I, debruijn: DebruijnIndex, var: BoundVar, ty: I::Ty) -> Self;
|
||||||
|
|
||||||
|
fn new_unevaluated(interner: I, uv: UnevaluatedConst<I>, ty: I::Ty) -> Self;
|
||||||
|
|
||||||
fn ty(self) -> I::Ty;
|
fn ty(self) -> I::Ty;
|
||||||
|
|
||||||
|
fn into_term(self) -> I::Term;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait GenericsOf<I: Interner<GenericsOf = Self>> {
|
pub trait GenericsOf<I: Interner<GenericsOf = Self>> {
|
||||||
@ -89,21 +98,3 @@ pub trait BoundVars<I: Interner> {
|
|||||||
|
|
||||||
fn has_no_bound_vars(&self) -> bool;
|
fn has_no_bound_vars(&self) -> bool;
|
||||||
}
|
}
|
||||||
|
|
||||||
pub trait AliasTerm<I: Interner>: Copy + DebugWithInfcx<I> + Hash + Eq + Sized {
|
|
||||||
fn new(
|
|
||||||
interner: I,
|
|
||||||
trait_def_id: I::DefId,
|
|
||||||
args: impl IntoIterator<Item: Into<I::GenericArg>>,
|
|
||||||
) -> Self;
|
|
||||||
|
|
||||||
fn def_id(self) -> I::DefId;
|
|
||||||
|
|
||||||
fn args(self) -> I::GenericArgs;
|
|
||||||
|
|
||||||
fn trait_def_id(self, interner: I) -> I::DefId;
|
|
||||||
|
|
||||||
fn self_ty(self) -> I::Ty;
|
|
||||||
|
|
||||||
fn with_self_ty(self, tcx: I, self_ty: I::Ty) -> Self;
|
|
||||||
}
|
|
||||||
|
@ -6,13 +6,16 @@
|
|||||||
use crate::ir_print::IrPrint;
|
use crate::ir_print::IrPrint;
|
||||||
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
|
use crate::visit::{Flags, TypeSuperVisitable, TypeVisitable};
|
||||||
use crate::{
|
use crate::{
|
||||||
CanonicalVarInfo, CoercePredicate, DebugWithInfcx, ExistentialProjection, ExistentialTraitRef,
|
AliasTerm, AliasTermKind, AliasTy, AliasTyKind, CanonicalVarInfo, CoercePredicate,
|
||||||
NormalizesTo, ProjectionPredicate, SubtypePredicate, TraitPredicate, TraitRef,
|
DebugWithInfcx, ExistentialProjection, ExistentialTraitRef, NormalizesTo, ProjectionPredicate,
|
||||||
|
SubtypePredicate, TraitPredicate, TraitRef,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait Interner:
|
pub trait Interner:
|
||||||
Sized
|
Sized
|
||||||
+ Copy
|
+ Copy
|
||||||
|
+ IrPrint<AliasTy<Self>>
|
||||||
|
+ IrPrint<AliasTerm<Self>>
|
||||||
+ IrPrint<TraitRef<Self>>
|
+ IrPrint<TraitRef<Self>>
|
||||||
+ IrPrint<TraitPredicate<Self>>
|
+ IrPrint<TraitPredicate<Self>>
|
||||||
+ IrPrint<ExistentialTraitRef<Self>>
|
+ IrPrint<ExistentialTraitRef<Self>>
|
||||||
@ -27,6 +30,7 @@ pub trait Interner:
|
|||||||
type AdtDef: Copy + Debug + Hash + Eq;
|
type AdtDef: Copy + Debug + Hash + Eq;
|
||||||
|
|
||||||
type GenericArgs: GenericArgs<Self>;
|
type GenericArgs: GenericArgs<Self>;
|
||||||
|
type GenericArgsSlice: Copy + Debug + Hash + Eq;
|
||||||
type GenericArg: Copy + DebugWithInfcx<Self> + Hash + Eq;
|
type GenericArg: Copy + DebugWithInfcx<Self> + Hash + Eq;
|
||||||
type Term: Copy + Debug + Hash + Eq;
|
type Term: Copy + Debug + Hash + Eq;
|
||||||
|
|
||||||
@ -39,7 +43,6 @@ pub trait Interner:
|
|||||||
// Kinds of tys
|
// Kinds of tys
|
||||||
type Ty: Ty<Self>;
|
type Ty: Ty<Self>;
|
||||||
type Tys: Copy + Debug + Hash + Eq + IntoIterator<Item = Self::Ty>;
|
type Tys: Copy + Debug + Hash + Eq + IntoIterator<Item = Self::Ty>;
|
||||||
type AliasTy: Copy + DebugWithInfcx<Self> + Hash + Eq + Sized;
|
|
||||||
type ParamTy: Copy + Debug + Hash + Eq;
|
type ParamTy: Copy + Debug + Hash + Eq;
|
||||||
type BoundTy: Copy + Debug + Hash + Eq;
|
type BoundTy: Copy + Debug + Hash + Eq;
|
||||||
type PlaceholderTy: PlaceholderLike;
|
type PlaceholderTy: PlaceholderLike;
|
||||||
@ -74,7 +77,6 @@ pub trait Interner:
|
|||||||
type RegionOutlivesPredicate: Copy + Debug + Hash + Eq;
|
type RegionOutlivesPredicate: Copy + Debug + Hash + Eq;
|
||||||
type TypeOutlivesPredicate: Copy + Debug + Hash + Eq;
|
type TypeOutlivesPredicate: Copy + Debug + Hash + Eq;
|
||||||
type ProjectionPredicate: Copy + Debug + Hash + Eq;
|
type ProjectionPredicate: Copy + Debug + Hash + Eq;
|
||||||
type AliasTerm: AliasTerm<Self>;
|
|
||||||
type NormalizesTo: Copy + Debug + Hash + Eq;
|
type NormalizesTo: Copy + Debug + Hash + Eq;
|
||||||
type SubtypePredicate: Copy + Debug + Hash + Eq;
|
type SubtypePredicate: Copy + Debug + Hash + Eq;
|
||||||
type CoercePredicate: Copy + Debug + Hash + Eq;
|
type CoercePredicate: Copy + Debug + Hash + Eq;
|
||||||
@ -86,8 +88,23 @@ pub trait Interner:
|
|||||||
type GenericsOf: GenericsOf<Self>;
|
type GenericsOf: GenericsOf<Self>;
|
||||||
fn generics_of(self, def_id: Self::DefId) -> Self::GenericsOf;
|
fn generics_of(self, def_id: Self::DefId) -> Self::GenericsOf;
|
||||||
|
|
||||||
|
// FIXME: Remove after uplifting `EarlyBinder`
|
||||||
|
fn type_of_instantiated(self, def_id: Self::DefId, args: Self::GenericArgs) -> Self::Ty;
|
||||||
|
|
||||||
|
fn alias_ty_kind(self, alias: AliasTy<Self>) -> AliasTyKind;
|
||||||
|
|
||||||
|
fn alias_term_kind(self, alias: AliasTerm<Self>) -> AliasTermKind;
|
||||||
|
|
||||||
|
fn trait_ref_and_own_args_for_alias(
|
||||||
|
self,
|
||||||
|
def_id: Self::DefId,
|
||||||
|
args: Self::GenericArgs,
|
||||||
|
) -> (TraitRef<Self>, Self::GenericArgsSlice);
|
||||||
|
|
||||||
fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs;
|
fn mk_args(self, args: &[Self::GenericArg]) -> Self::GenericArgs;
|
||||||
|
|
||||||
|
fn mk_args_from_iter(self, args: impl Iterator<Item = Self::GenericArg>) -> Self::GenericArgs;
|
||||||
|
|
||||||
fn check_and_mk_args(
|
fn check_and_mk_args(
|
||||||
self,
|
self,
|
||||||
def_id: Self::DefId,
|
def_id: Self::DefId,
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
CoercePredicate, ExistentialProjection, ExistentialTraitRef, Interner, NormalizesTo,
|
AliasTerm, AliasTy, CoercePredicate, ExistentialProjection, ExistentialTraitRef, Interner,
|
||||||
ProjectionPredicate, SubtypePredicate, TraitPredicate, TraitRef,
|
NormalizesTo, ProjectionPredicate, SubtypePredicate, TraitPredicate, TraitRef,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait IrPrint<T> {
|
pub trait IrPrint<T> {
|
||||||
@ -43,6 +43,8 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|||||||
NormalizesTo,
|
NormalizesTo,
|
||||||
SubtypePredicate,
|
SubtypePredicate,
|
||||||
CoercePredicate,
|
CoercePredicate,
|
||||||
|
AliasTy,
|
||||||
|
AliasTerm,
|
||||||
);
|
);
|
||||||
|
|
||||||
define_debug_via_print!(TraitRef, ExistentialTraitRef, ExistentialProjection);
|
define_debug_via_print!(TraitRef, ExistentialTraitRef, ExistentialProjection);
|
||||||
|
@ -6,7 +6,9 @@
|
|||||||
|
|
||||||
use crate::inherent::*;
|
use crate::inherent::*;
|
||||||
use crate::visit::TypeVisitableExt as _;
|
use crate::visit::TypeVisitableExt as _;
|
||||||
use crate::{DebugWithInfcx, Interner};
|
use crate::{
|
||||||
|
AliasTy, AliasTyKind, DebugWithInfcx, InferCtxtLike, Interner, UnevaluatedConst, WithInfcx,
|
||||||
|
};
|
||||||
|
|
||||||
/// A complete reference to a trait. These take numerous guises in syntax,
|
/// A complete reference to a trait. These take numerous guises in syntax,
|
||||||
/// but perhaps the most recognizable form is in a where-clause:
|
/// but perhaps the most recognizable form is in a where-clause:
|
||||||
@ -272,20 +274,20 @@ impl<I: Interner> ExistentialProjection<I> {
|
|||||||
/// For example, if this is a projection of `exists T. <T as Iterator>::Item == X`,
|
/// For example, if this is a projection of `exists T. <T as Iterator>::Item == X`,
|
||||||
/// then this function would return an `exists T. T: Iterator` existential trait
|
/// then this function would return an `exists T. T: Iterator` existential trait
|
||||||
/// reference.
|
/// reference.
|
||||||
pub fn trait_ref(&self, tcx: I) -> ExistentialTraitRef<I> {
|
pub fn trait_ref(&self, interner: I) -> ExistentialTraitRef<I> {
|
||||||
let def_id = tcx.parent(self.def_id);
|
let def_id = interner.parent(self.def_id);
|
||||||
let args_count = tcx.generics_of(def_id).count() - 1;
|
let args_count = interner.generics_of(def_id).count() - 1;
|
||||||
let args = tcx.mk_args(&self.args[..args_count]);
|
let args = interner.mk_args(&self.args[..args_count]);
|
||||||
ExistentialTraitRef { def_id, args }
|
ExistentialTraitRef { def_id, args }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_self_ty(&self, tcx: I, self_ty: I::Ty) -> ProjectionPredicate<I> {
|
pub fn with_self_ty(&self, interner: I, self_ty: I::Ty) -> ProjectionPredicate<I> {
|
||||||
// otherwise the escaping regions would be captured by the binders
|
// otherwise the escaping regions would be captured by the binders
|
||||||
debug_assert!(!self_ty.has_escaping_bound_vars());
|
debug_assert!(!self_ty.has_escaping_bound_vars());
|
||||||
|
|
||||||
ProjectionPredicate {
|
ProjectionPredicate {
|
||||||
projection_term: I::AliasTerm::new(
|
projection_term: AliasTerm::new(
|
||||||
tcx,
|
interner,
|
||||||
self.def_id,
|
self.def_id,
|
||||||
[self_ty.into()].into_iter().chain(self.args),
|
[self_ty.into()].into_iter().chain(self.args),
|
||||||
),
|
),
|
||||||
@ -293,13 +295,13 @@ pub fn with_self_ty(&self, tcx: I, self_ty: I::Ty) -> ProjectionPredicate<I> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn erase_self_ty(tcx: I, projection_predicate: ProjectionPredicate<I>) -> Self {
|
pub fn erase_self_ty(interner: I, projection_predicate: ProjectionPredicate<I>) -> Self {
|
||||||
// Assert there is a Self.
|
// Assert there is a Self.
|
||||||
projection_predicate.projection_term.args().type_at(0);
|
projection_predicate.projection_term.args.type_at(0);
|
||||||
|
|
||||||
Self {
|
Self {
|
||||||
def_id: projection_predicate.projection_term.def_id(),
|
def_id: projection_predicate.projection_term.def_id,
|
||||||
args: tcx.mk_args(&projection_predicate.projection_term.args()[1..]),
|
args: interner.mk_args(&projection_predicate.projection_term.args[1..]),
|
||||||
term: projection_predicate.term,
|
term: projection_predicate.term,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -339,6 +341,190 @@ pub fn descr(self) -> &'static str {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Represents the unprojected term of a projection goal.
|
||||||
|
///
|
||||||
|
/// * For a projection, this would be `<Ty as Trait<...>>::N<...>`.
|
||||||
|
/// * For an inherent projection, this would be `Ty::N<...>`.
|
||||||
|
/// * For an opaque type, there is no explicit syntax.
|
||||||
|
#[derive(derivative::Derivative)]
|
||||||
|
#[derivative(
|
||||||
|
Clone(bound = ""),
|
||||||
|
Copy(bound = ""),
|
||||||
|
Hash(bound = ""),
|
||||||
|
PartialEq(bound = ""),
|
||||||
|
Eq(bound = "")
|
||||||
|
)]
|
||||||
|
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||||
|
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
|
||||||
|
pub struct AliasTerm<I: Interner> {
|
||||||
|
/// The parameters of the associated or opaque item.
|
||||||
|
///
|
||||||
|
/// For a projection, these are the generic parameters for the trait and the
|
||||||
|
/// GAT parameters, if there are any.
|
||||||
|
///
|
||||||
|
/// For an inherent projection, they consist of the self type and the GAT parameters,
|
||||||
|
/// if there are any.
|
||||||
|
///
|
||||||
|
/// For RPIT the generic parameters are for the generics of the function,
|
||||||
|
/// while for TAIT it is used for the generic parameters of the alias.
|
||||||
|
pub args: I::GenericArgs,
|
||||||
|
|
||||||
|
/// The `DefId` of the `TraitItem` or `ImplItem` for the associated type `N` depending on whether
|
||||||
|
/// this is a projection or an inherent projection or the `DefId` of the `OpaqueType` item if
|
||||||
|
/// this is an opaque.
|
||||||
|
///
|
||||||
|
/// During codegen, `interner.type_of(def_id)` can be used to get the type of the
|
||||||
|
/// underlying type if the type is an opaque.
|
||||||
|
///
|
||||||
|
/// Note that if this is an associated type, this is not the `DefId` of the
|
||||||
|
/// `TraitRef` containing this associated type, which is in `interner.associated_item(def_id).container`,
|
||||||
|
/// aka. `interner.parent(def_id)`.
|
||||||
|
pub def_id: I::DefId,
|
||||||
|
|
||||||
|
/// This field exists to prevent the creation of `AliasTerm` without using
|
||||||
|
/// [AliasTerm::new].
|
||||||
|
_use_alias_term_new_instead: (),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: Interner> std::fmt::Debug for AliasTerm<I> {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
WithInfcx::with_no_infcx(self).fmt(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<I: Interner> DebugWithInfcx<I> for AliasTerm<I> {
|
||||||
|
fn fmt<Infcx: InferCtxtLike<Interner = I>>(
|
||||||
|
this: WithInfcx<'_, Infcx, &Self>,
|
||||||
|
f: &mut std::fmt::Formatter<'_>,
|
||||||
|
) -> std::fmt::Result {
|
||||||
|
f.debug_struct("AliasTerm")
|
||||||
|
.field("args", &this.map(|data| data.args))
|
||||||
|
.field("def_id", &this.data.def_id)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: Interner> AliasTerm<I> {
|
||||||
|
pub fn new(
|
||||||
|
interner: I,
|
||||||
|
def_id: I::DefId,
|
||||||
|
args: impl IntoIterator<Item: Into<I::GenericArg>>,
|
||||||
|
) -> AliasTerm<I> {
|
||||||
|
let args = interner.check_and_mk_args(def_id, args);
|
||||||
|
AliasTerm { def_id, args, _use_alias_term_new_instead: () }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn expect_ty(self, interner: I) -> AliasTy<I> {
|
||||||
|
match self.kind(interner) {
|
||||||
|
AliasTermKind::ProjectionTy
|
||||||
|
| AliasTermKind::InherentTy
|
||||||
|
| AliasTermKind::OpaqueTy
|
||||||
|
| AliasTermKind::WeakTy => {}
|
||||||
|
AliasTermKind::UnevaluatedConst | AliasTermKind::ProjectionConst => {
|
||||||
|
panic!("Cannot turn `UnevaluatedConst` into `AliasTy`")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn kind(self, interner: I) -> AliasTermKind {
|
||||||
|
interner.alias_term_kind(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_term(self, interner: I) -> I::Term {
|
||||||
|
match self.kind(interner) {
|
||||||
|
AliasTermKind::ProjectionTy => Ty::new_alias(
|
||||||
|
interner,
|
||||||
|
AliasTyKind::Projection,
|
||||||
|
AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
|
||||||
|
)
|
||||||
|
.into_term(),
|
||||||
|
AliasTermKind::InherentTy => Ty::new_alias(
|
||||||
|
interner,
|
||||||
|
AliasTyKind::Inherent,
|
||||||
|
AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
|
||||||
|
)
|
||||||
|
.into_term(),
|
||||||
|
AliasTermKind::OpaqueTy => Ty::new_alias(
|
||||||
|
interner,
|
||||||
|
AliasTyKind::Opaque,
|
||||||
|
AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
|
||||||
|
)
|
||||||
|
.into_term(),
|
||||||
|
AliasTermKind::WeakTy => Ty::new_alias(
|
||||||
|
interner,
|
||||||
|
AliasTyKind::Weak,
|
||||||
|
AliasTy { def_id: self.def_id, args: self.args, _use_alias_ty_new_instead: () },
|
||||||
|
)
|
||||||
|
.into_term(),
|
||||||
|
AliasTermKind::UnevaluatedConst | AliasTermKind::ProjectionConst => {
|
||||||
|
I::Const::new_unevaluated(
|
||||||
|
interner,
|
||||||
|
UnevaluatedConst::new(self.def_id, self.args),
|
||||||
|
interner.type_of_instantiated(self.def_id, self.args),
|
||||||
|
)
|
||||||
|
.into_term()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The following methods work only with (trait) associated type projections.
|
||||||
|
impl<I: Interner> AliasTerm<I> {
|
||||||
|
pub fn self_ty(self) -> I::Ty {
|
||||||
|
self.args.type_at(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
|
||||||
|
AliasTerm::new(
|
||||||
|
interner,
|
||||||
|
self.def_id,
|
||||||
|
[self_ty.into()].into_iter().chain(self.args.into_iter().skip(1)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn trait_def_id(self, interner: I) -> I::DefId {
|
||||||
|
assert!(
|
||||||
|
matches!(
|
||||||
|
self.kind(interner),
|
||||||
|
AliasTermKind::ProjectionTy | AliasTermKind::ProjectionConst
|
||||||
|
),
|
||||||
|
"expected a projection"
|
||||||
|
);
|
||||||
|
interner.parent(self.def_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extracts the underlying trait reference and own args from this projection.
|
||||||
|
/// For example, if this is a projection of `<T as StreamingIterator>::Item<'a>`,
|
||||||
|
/// then this function would return a `T: StreamingIterator` trait reference and
|
||||||
|
/// `['a]` as the own args.
|
||||||
|
pub fn trait_ref_and_own_args(self, interner: I) -> (TraitRef<I>, I::GenericArgsSlice) {
|
||||||
|
interner.trait_ref_and_own_args_for_alias(self.def_id, self.args)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extracts the underlying trait reference from this projection.
|
||||||
|
/// For example, if this is a projection of `<T as Iterator>::Item`,
|
||||||
|
/// then this function would return a `T: Iterator` trait reference.
|
||||||
|
///
|
||||||
|
/// WARNING: This will drop the args for generic associated types
|
||||||
|
/// consider calling [Self::trait_ref_and_own_args] to get those
|
||||||
|
/// as well.
|
||||||
|
pub fn trait_ref(self, interner: I) -> TraitRef<I> {
|
||||||
|
self.trait_ref_and_own_args(interner).0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: Interner> From<AliasTy<I>> for AliasTerm<I> {
|
||||||
|
fn from(ty: AliasTy<I>) -> Self {
|
||||||
|
AliasTerm { args: ty.args, def_id: ty.def_id, _use_alias_term_new_instead: () }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: Interner> From<UnevaluatedConst<I>> for AliasTerm<I> {
|
||||||
|
fn from(ct: UnevaluatedConst<I>) -> Self {
|
||||||
|
AliasTerm { args: ct.args, def_id: ct.def, _use_alias_term_new_instead: () }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// This kind of predicate has no *direct* correspondent in the
|
/// This kind of predicate has no *direct* correspondent in the
|
||||||
/// syntax, but it roughly corresponds to the syntactic forms:
|
/// syntax, but it roughly corresponds to the syntactic forms:
|
||||||
///
|
///
|
||||||
@ -362,7 +548,7 @@ pub fn descr(self) -> &'static str {
|
|||||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||||
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
|
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
|
||||||
pub struct ProjectionPredicate<I: Interner> {
|
pub struct ProjectionPredicate<I: Interner> {
|
||||||
pub projection_term: I::AliasTerm,
|
pub projection_term: AliasTerm<I>,
|
||||||
pub term: I::Term,
|
pub term: I::Term,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -371,16 +557,16 @@ pub fn self_ty(self) -> I::Ty {
|
|||||||
self.projection_term.self_ty()
|
self.projection_term.self_ty()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_self_ty(self, tcx: I, self_ty: I::Ty) -> ProjectionPredicate<I> {
|
pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> ProjectionPredicate<I> {
|
||||||
Self { projection_term: self.projection_term.with_self_ty(tcx, self_ty), ..self }
|
Self { projection_term: self.projection_term.with_self_ty(interner, self_ty), ..self }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn trait_def_id(self, tcx: I) -> I::DefId {
|
pub fn trait_def_id(self, interner: I) -> I::DefId {
|
||||||
self.projection_term.trait_def_id(tcx)
|
self.projection_term.trait_def_id(interner)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn def_id(self) -> I::DefId {
|
pub fn def_id(self) -> I::DefId {
|
||||||
self.projection_term.def_id()
|
self.projection_term.def_id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -403,7 +589,7 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|||||||
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||||
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
|
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
|
||||||
pub struct NormalizesTo<I: Interner> {
|
pub struct NormalizesTo<I: Interner> {
|
||||||
pub alias: I::AliasTerm,
|
pub alias: AliasTerm<I>,
|
||||||
pub term: I::Term,
|
pub term: I::Term,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -412,16 +598,16 @@ pub fn self_ty(self) -> I::Ty {
|
|||||||
self.alias.self_ty()
|
self.alias.self_ty()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn with_self_ty(self, tcx: I, self_ty: I::Ty) -> NormalizesTo<I> {
|
pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> NormalizesTo<I> {
|
||||||
Self { alias: self.alias.with_self_ty(tcx, self_ty), ..self }
|
Self { alias: self.alias.with_self_ty(interner, self_ty), ..self }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn trait_def_id(self, tcx: I) -> I::DefId {
|
pub fn trait_def_id(self, interner: I) -> I::DefId {
|
||||||
self.alias.trait_def_id(tcx)
|
self.alias.trait_def_id(interner)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn def_id(self) -> I::DefId {
|
pub fn def_id(self) -> I::DefId {
|
||||||
self.alias.def_id()
|
self.alias.def_id
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,11 +4,11 @@
|
|||||||
use rustc_data_structures::unify::{EqUnifyValue, UnifyKey};
|
use rustc_data_structures::unify::{EqUnifyValue, UnifyKey};
|
||||||
#[cfg(feature = "nightly")]
|
#[cfg(feature = "nightly")]
|
||||||
use rustc_macros::{Decodable, Encodable, HashStable_NoContext, TyDecodable, TyEncodable};
|
use rustc_macros::{Decodable, Encodable, HashStable_NoContext, TyDecodable, TyEncodable};
|
||||||
use rustc_type_ir_macros::{TypeFoldable_Generic, TypeVisitable_Generic};
|
use rustc_type_ir_macros::{Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic};
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
|
|
||||||
use crate::Interner;
|
use crate::inherent::*;
|
||||||
use crate::{DebruijnIndex, DebugWithInfcx, InferCtxtLike, WithInfcx};
|
use crate::{DebruijnIndex, DebugWithInfcx, InferCtxtLike, Interner, TraitRef, WithInfcx};
|
||||||
|
|
||||||
use self::TyKind::*;
|
use self::TyKind::*;
|
||||||
|
|
||||||
@ -88,7 +88,7 @@ pub enum TyKind<I: Interner> {
|
|||||||
/// for `struct List<T>` and the args `[i32]`.
|
/// for `struct List<T>` and the args `[i32]`.
|
||||||
///
|
///
|
||||||
/// Note that generic parameters in fields only get lazily instantiated
|
/// Note that generic parameters in fields only get lazily instantiated
|
||||||
/// by using something like `adt_def.all_fields().map(|field| field.ty(tcx, args))`.
|
/// by using something like `adt_def.all_fields().map(|field| field.ty(interner, args))`.
|
||||||
Adt(I::AdtDef, I::GenericArgs),
|
Adt(I::AdtDef, I::GenericArgs),
|
||||||
|
|
||||||
/// An unsized FFI type that is opaque to Rust. Written as `extern type T`.
|
/// An unsized FFI type that is opaque to Rust. Written as `extern type T`.
|
||||||
@ -201,7 +201,7 @@ pub enum TyKind<I: Interner> {
|
|||||||
/// A projection, opaque type, weak type alias, or inherent associated type.
|
/// A projection, opaque type, weak type alias, or inherent associated type.
|
||||||
/// All of these types are represented as pairs of def-id and args, and can
|
/// All of these types are represented as pairs of def-id and args, and can
|
||||||
/// be normalized, so they are grouped conceptually.
|
/// be normalized, so they are grouped conceptually.
|
||||||
Alias(AliasTyKind, I::AliasTy),
|
Alias(AliasTyKind, AliasTy<I>),
|
||||||
|
|
||||||
/// A type parameter; for example, `T` in `fn f<T>(x: T) {}`.
|
/// A type parameter; for example, `T` in `fn f<T>(x: T) {}`.
|
||||||
Param(I::ParamTy),
|
Param(I::ParamTy),
|
||||||
@ -422,6 +422,154 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Represents the projection of an associated, opaque, or lazy-type-alias type.
|
||||||
|
///
|
||||||
|
/// * For a projection, this would be `<Ty as Trait<...>>::N<...>`.
|
||||||
|
/// * For an inherent projection, this would be `Ty::N<...>`.
|
||||||
|
/// * For an opaque type, there is no explicit syntax.
|
||||||
|
#[derive(derivative::Derivative)]
|
||||||
|
#[derivative(
|
||||||
|
Clone(bound = ""),
|
||||||
|
Copy(bound = ""),
|
||||||
|
Hash(bound = ""),
|
||||||
|
PartialEq(bound = ""),
|
||||||
|
Eq(bound = "")
|
||||||
|
)]
|
||||||
|
#[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic)]
|
||||||
|
#[cfg_attr(feature = "nightly", derive(TyDecodable, TyEncodable, HashStable_NoContext))]
|
||||||
|
pub struct AliasTy<I: Interner> {
|
||||||
|
/// The parameters of the associated or opaque type.
|
||||||
|
///
|
||||||
|
/// For a projection, these are the generic parameters for the trait and the
|
||||||
|
/// GAT parameters, if there are any.
|
||||||
|
///
|
||||||
|
/// For an inherent projection, they consist of the self type and the GAT parameters,
|
||||||
|
/// if there are any.
|
||||||
|
///
|
||||||
|
/// For RPIT the generic parameters are for the generics of the function,
|
||||||
|
/// while for TAIT it is used for the generic parameters of the alias.
|
||||||
|
pub args: I::GenericArgs,
|
||||||
|
|
||||||
|
/// The `DefId` of the `TraitItem` or `ImplItem` for the associated type `N` depending on whether
|
||||||
|
/// this is a projection or an inherent projection or the `DefId` of the `OpaqueType` item if
|
||||||
|
/// this is an opaque.
|
||||||
|
///
|
||||||
|
/// During codegen, `interner.type_of(def_id)` can be used to get the type of the
|
||||||
|
/// underlying type if the type is an opaque.
|
||||||
|
///
|
||||||
|
/// Note that if this is an associated type, this is not the `DefId` of the
|
||||||
|
/// `TraitRef` containing this associated type, which is in `interner.associated_item(def_id).container`,
|
||||||
|
/// aka. `interner.parent(def_id)`.
|
||||||
|
pub def_id: I::DefId,
|
||||||
|
|
||||||
|
/// This field exists to prevent the creation of `AliasTy` without using
|
||||||
|
/// [AliasTy::new].
|
||||||
|
pub(crate) _use_alias_ty_new_instead: (),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: Interner> AliasTy<I> {
|
||||||
|
pub fn new(
|
||||||
|
interner: I,
|
||||||
|
def_id: I::DefId,
|
||||||
|
args: impl IntoIterator<Item: Into<I::GenericArg>>,
|
||||||
|
) -> AliasTy<I> {
|
||||||
|
let args = interner.check_and_mk_args(def_id, args);
|
||||||
|
AliasTy { def_id, args, _use_alias_ty_new_instead: () }
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn kind(self, interner: I) -> AliasTyKind {
|
||||||
|
interner.alias_ty_kind(self)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Whether this alias type is an opaque.
|
||||||
|
pub fn is_opaque(self, interner: I) -> bool {
|
||||||
|
matches!(self.kind(interner), AliasTyKind::Opaque)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn to_ty(self, interner: I) -> I::Ty {
|
||||||
|
Ty::new_alias(interner, self.kind(interner), self)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The following methods work only with (trait) associated type projections.
|
||||||
|
impl<I: Interner> AliasTy<I> {
|
||||||
|
pub fn self_ty(self) -> I::Ty {
|
||||||
|
self.args.type_at(0)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn with_self_ty(self, interner: I, self_ty: I::Ty) -> Self {
|
||||||
|
AliasTy::new(
|
||||||
|
interner,
|
||||||
|
self.def_id,
|
||||||
|
[self_ty.into()].into_iter().chain(self.args.into_iter().skip(1)),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn trait_def_id(self, interner: I) -> I::DefId {
|
||||||
|
assert_eq!(self.kind(interner), AliasTyKind::Projection, "expected a projection");
|
||||||
|
interner.parent(self.def_id)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extracts the underlying trait reference and own args from this projection.
|
||||||
|
/// For example, if this is a projection of `<T as StreamingIterator>::Item<'a>`,
|
||||||
|
/// then this function would return a `T: StreamingIterator` trait reference and
|
||||||
|
/// `['a]` as the own args.
|
||||||
|
pub fn trait_ref_and_own_args(self, interner: I) -> (TraitRef<I>, I::GenericArgsSlice) {
|
||||||
|
debug_assert_eq!(self.kind(interner), AliasTyKind::Projection);
|
||||||
|
interner.trait_ref_and_own_args_for_alias(self.def_id, self.args)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Extracts the underlying trait reference from this projection.
|
||||||
|
/// For example, if this is a projection of `<T as Iterator>::Item`,
|
||||||
|
/// then this function would return a `T: Iterator` trait reference.
|
||||||
|
///
|
||||||
|
/// WARNING: This will drop the args for generic associated types
|
||||||
|
/// consider calling [Self::trait_ref_and_own_args] to get those
|
||||||
|
/// as well.
|
||||||
|
pub fn trait_ref(self, interner: I) -> TraitRef<I> {
|
||||||
|
self.trait_ref_and_own_args(interner).0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// The following methods work only with inherent associated type projections.
|
||||||
|
impl<I: Interner> AliasTy<I> {
|
||||||
|
/// Transform the generic parameters to have the given `impl` args as the base and the GAT args on top of that.
|
||||||
|
///
|
||||||
|
/// Does the following transformation:
|
||||||
|
///
|
||||||
|
/// ```text
|
||||||
|
/// [Self, P_0...P_m] -> [I_0...I_n, P_0...P_m]
|
||||||
|
///
|
||||||
|
/// I_i impl args
|
||||||
|
/// P_j GAT args
|
||||||
|
/// ```
|
||||||
|
pub fn rebase_inherent_args_onto_impl(
|
||||||
|
self,
|
||||||
|
impl_args: I::GenericArgs,
|
||||||
|
interner: I,
|
||||||
|
) -> I::GenericArgs {
|
||||||
|
debug_assert_eq!(self.kind(interner), AliasTyKind::Inherent);
|
||||||
|
interner.mk_args_from_iter(impl_args.into_iter().chain(self.args.into_iter().skip(1)))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<I: Interner> fmt::Debug for AliasTy<I> {
|
||||||
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
|
WithInfcx::with_no_infcx(self).fmt(f)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
impl<I: Interner> DebugWithInfcx<I> for AliasTy<I> {
|
||||||
|
fn fmt<Infcx: InferCtxtLike<Interner = I>>(
|
||||||
|
this: WithInfcx<'_, Infcx, &Self>,
|
||||||
|
f: &mut core::fmt::Formatter<'_>,
|
||||||
|
) -> core::fmt::Result {
|
||||||
|
f.debug_struct("AliasTy")
|
||||||
|
.field("args", &this.map(|data| data.args))
|
||||||
|
.field("def_id", &this.data.def_id)
|
||||||
|
.finish()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash)]
|
||||||
#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))]
|
#[cfg_attr(feature = "nightly", derive(Encodable, Decodable, HashStable_NoContext))]
|
||||||
pub enum IntTy {
|
pub enum IntTy {
|
||||||
|
Loading…
Reference in New Issue
Block a user