split out AliasTy -> AliasTerm
This commit is contained in:
parent
ecbe3fd550
commit
3bcdf3058e
70 changed files with 715 additions and 414 deletions
|
@ -132,6 +132,7 @@ impl<'tcx> Interner for TyCtxt<'tcx> {
|
|||
type RegionOutlivesPredicate = ty::RegionOutlivesPredicate<'tcx>;
|
||||
type TypeOutlivesPredicate = ty::TypeOutlivesPredicate<'tcx>;
|
||||
type ProjectionPredicate = ty::ProjectionPredicate<'tcx>;
|
||||
type AliasTerm = ty::AliasTerm<'tcx>;
|
||||
type NormalizesTo = ty::NormalizesTo<'tcx>;
|
||||
type SubtypePredicate = ty::SubtypePredicate<'tcx>;
|
||||
type CoercePredicate = ty::CoercePredicate<'tcx>;
|
||||
|
|
|
@ -294,10 +294,10 @@ impl FlagComputation {
|
|||
self.add_ty(b);
|
||||
}
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::Projection(ty::ProjectionPredicate {
|
||||
projection_ty,
|
||||
projection_term,
|
||||
term,
|
||||
})) => {
|
||||
self.add_alias_ty(projection_ty);
|
||||
self.add_alias_term(projection_term);
|
||||
self.add_term(term);
|
||||
}
|
||||
ty::PredicateKind::Clause(ty::ClauseKind::WellFormed(arg)) => {
|
||||
|
@ -313,7 +313,7 @@ impl FlagComputation {
|
|||
}
|
||||
ty::PredicateKind::Ambiguous => {}
|
||||
ty::PredicateKind::NormalizesTo(ty::NormalizesTo { alias, term }) => {
|
||||
self.add_alias_ty(alias);
|
||||
self.add_alias_term(alias);
|
||||
self.add_term(term);
|
||||
}
|
||||
ty::PredicateKind::AliasRelate(t1, t2, _) => {
|
||||
|
@ -410,6 +410,10 @@ impl FlagComputation {
|
|||
self.add_args(alias_ty.args);
|
||||
}
|
||||
|
||||
fn add_alias_term(&mut self, alias_term: ty::AliasTerm<'_>) {
|
||||
self.add_args(alias_term.args);
|
||||
}
|
||||
|
||||
fn add_args(&mut self, args: &[GenericArg<'_>]) {
|
||||
for kind in args {
|
||||
match kind.unpack() {
|
||||
|
|
|
@ -110,11 +110,11 @@ pub use self::region::{
|
|||
};
|
||||
pub use self::rvalue_scopes::RvalueScopes;
|
||||
pub use self::sty::{
|
||||
AliasTy, Article, Binder, BoundTy, BoundTyKind, BoundVariableKind, CanonicalPolyFnSig,
|
||||
ClosureArgs, ClosureArgsParts, CoroutineArgs, CoroutineArgsParts, CoroutineClosureArgs,
|
||||
CoroutineClosureArgsParts, CoroutineClosureSignature, FnSig, GenSig, InlineConstArgs,
|
||||
InlineConstArgsParts, ParamConst, ParamTy, PolyFnSig, TyKind, TypeAndMut, UpvarArgs,
|
||||
VarianceDiagInfo,
|
||||
AliasTerm, AliasTy, Article, Binder, BoundTy, BoundTyKind, BoundVariableKind,
|
||||
CanonicalPolyFnSig, ClosureArgs, ClosureArgsParts, CoroutineArgs, CoroutineArgsParts,
|
||||
CoroutineClosureArgs, CoroutineClosureArgsParts, CoroutineClosureSignature, FnSig, GenSig,
|
||||
InlineConstArgs, InlineConstArgsParts, ParamConst, ParamTy, PolyFnSig, TyKind, TypeAndMut,
|
||||
UpvarArgs, VarianceDiagInfo,
|
||||
};
|
||||
pub use self::trait_def::TraitDef;
|
||||
pub use self::typeck_results::{
|
||||
|
@ -630,14 +630,14 @@ impl<'tcx> Term<'tcx> {
|
|||
}
|
||||
|
||||
/// This function returns the inner `AliasTy` for a `ty::Alias` or `ConstKind::Unevaluated`.
|
||||
pub fn to_alias_ty(&self, tcx: TyCtxt<'tcx>) -> Option<AliasTy<'tcx>> {
|
||||
pub fn to_alias_term(self) -> Option<AliasTerm<'tcx>> {
|
||||
match self.unpack() {
|
||||
TermKind::Ty(ty) => match *ty.kind() {
|
||||
ty::Alias(_kind, alias_ty) => Some(alias_ty),
|
||||
ty::Alias(_kind, alias_ty) => Some(alias_ty.into()),
|
||||
_ => None,
|
||||
},
|
||||
TermKind::Const(ct) => match ct.kind() {
|
||||
ConstKind::Unevaluated(uv) => Some(AliasTy::new(tcx, uv.def, uv.args)),
|
||||
ConstKind::Unevaluated(uv) => Some(uv.into()),
|
||||
_ => None,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -503,7 +503,7 @@ impl<'tcx> PolyProjectionPredicate<'tcx> {
|
|||
/// Returns the `DefId` of the trait of the associated item being projected.
|
||||
#[inline]
|
||||
pub fn trait_def_id(&self, tcx: TyCtxt<'tcx>) -> DefId {
|
||||
self.skip_binder().projection_ty.trait_def_id(tcx)
|
||||
self.skip_binder().projection_term.trait_def_id(tcx)
|
||||
}
|
||||
|
||||
/// Get the [PolyTraitRef] required for this projection to be well formed.
|
||||
|
@ -516,7 +516,7 @@ impl<'tcx> PolyProjectionPredicate<'tcx> {
|
|||
// This is because here `self` has a `Binder` and so does our
|
||||
// return value, so we are preserving the number of binding
|
||||
// levels.
|
||||
self.map_bound(|predicate| predicate.projection_ty.trait_ref(tcx))
|
||||
self.map_bound(|predicate| predicate.projection_term.trait_ref(tcx))
|
||||
}
|
||||
|
||||
pub fn term(&self) -> Binder<'tcx, Term<'tcx>> {
|
||||
|
@ -529,7 +529,7 @@ impl<'tcx> PolyProjectionPredicate<'tcx> {
|
|||
/// associated type, which is in `tcx.associated_item(projection_def_id()).container`.
|
||||
pub fn projection_def_id(&self) -> DefId {
|
||||
// Ok to skip binder since trait `DefId` does not care about regions.
|
||||
self.skip_binder().projection_ty.def_id
|
||||
self.skip_binder().projection_term.def_id
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -1277,7 +1277,7 @@ pub trait PrettyPrinter<'tcx>: Printer<'tcx> + fmt::Write {
|
|||
|
||||
fn pretty_print_inherent_projection(
|
||||
&mut self,
|
||||
alias_ty: ty::AliasTy<'tcx>,
|
||||
alias_ty: ty::AliasTerm<'tcx>,
|
||||
) -> Result<(), PrintError> {
|
||||
let def_key = self.tcx().def_key(alias_ty.def_id);
|
||||
self.path_generic_args(
|
||||
|
@ -3111,7 +3111,7 @@ define_print! {
|
|||
}
|
||||
|
||||
ty::ProjectionPredicate<'tcx> {
|
||||
p!(print(self.projection_ty), " == ");
|
||||
p!(print(self.projection_term), " == ");
|
||||
cx.reset_type_limit();
|
||||
p!(print(self.term))
|
||||
}
|
||||
|
@ -3206,20 +3206,28 @@ define_print_and_forward_display! {
|
|||
}
|
||||
|
||||
ty::AliasTy<'tcx> {
|
||||
if let DefKind::Impl { of_trait: false } = cx.tcx().def_kind(cx.tcx().parent(self.def_id)) {
|
||||
p!(pretty_print_inherent_projection(*self))
|
||||
} else {
|
||||
// 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));
|
||||
}
|
||||
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 => {
|
||||
// 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));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -246,6 +246,34 @@ impl<'tcx> Relate<'tcx> for ty::AliasTy<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Relate<'tcx> for ty::AliasTerm<'tcx> {
|
||||
fn relate<R: TypeRelation<'tcx>>(
|
||||
relation: &mut R,
|
||||
a: ty::AliasTerm<'tcx>,
|
||||
b: ty::AliasTerm<'tcx>,
|
||||
) -> RelateResult<'tcx, ty::AliasTerm<'tcx>> {
|
||||
if a.def_id != b.def_id {
|
||||
Err(TypeError::ProjectionMismatched(expected_found(a.def_id, b.def_id)))
|
||||
} else {
|
||||
let args = match relation.tcx().def_kind(a.def_id) {
|
||||
DefKind::OpaqueTy => relate_args_with_variances(
|
||||
relation,
|
||||
a.def_id,
|
||||
relation.tcx().variances_of(a.def_id),
|
||||
a.args,
|
||||
b.args,
|
||||
false, // do not fetch `type_of(a_def_id)`, as it will cause a cycle
|
||||
)?,
|
||||
DefKind::AssocTy | DefKind::AssocConst | DefKind::TyAlias => {
|
||||
relate_args_invariantly(relation, a.args, b.args)?
|
||||
}
|
||||
def => bug!("unknown alias DefKind: {def:?}"),
|
||||
};
|
||||
Ok(ty::AliasTerm::new(relation.tcx(), a.def_id, args))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> Relate<'tcx> for ty::ExistentialProjection<'tcx> {
|
||||
fn relate<R: TypeRelation<'tcx>>(
|
||||
relation: &mut R,
|
||||
|
|
|
@ -410,7 +410,7 @@ TrivialTypeTraversalImpls! {
|
|||
crate::ty::BoundRegionKind,
|
||||
crate::ty::AssocItem,
|
||||
crate::ty::AssocKind,
|
||||
crate::ty::AliasKind,
|
||||
crate::ty::AliasTyKind,
|
||||
crate::ty::Placeholder<crate::ty::BoundRegion>,
|
||||
crate::ty::Placeholder<crate::ty::BoundTy>,
|
||||
crate::ty::Placeholder<ty::BoundVar>,
|
||||
|
|
|
@ -22,7 +22,7 @@ use rustc_span::symbol::{sym, Symbol};
|
|||
use rustc_span::{Span, DUMMY_SP};
|
||||
use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT};
|
||||
use rustc_target::spec::abi::{self, Abi};
|
||||
use std::assert_matches::debug_assert_matches;
|
||||
use std::assert_matches::{assert_matches, debug_assert_matches};
|
||||
use std::borrow::Cow;
|
||||
use std::iter;
|
||||
use std::ops::{ControlFlow, Deref, Range};
|
||||
|
@ -1105,7 +1105,228 @@ where
|
|||
}
|
||||
}
|
||||
|
||||
/// Represents the projection of an associated type.
|
||||
/// 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 `AliasTy` without using
|
||||
/// [AliasTy::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> {
|
||||
assert_matches!(
|
||||
self.kind(tcx),
|
||||
ty::AliasTermKind::ProjectionTy
|
||||
| ty::AliasTermKind::OpaqueTy
|
||||
| ty::AliasTermKind::WeakTy
|
||||
| ty::AliasTermKind::InherentTy
|
||||
);
|
||||
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::AssocConst | DefKind::AnonConst => ty::AliasTermKind::UnevaluatedConst,
|
||||
kind => bug!("unexpected DefKind in AliasTy: {kind:?}"),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The following methods work only with (trait) associated type 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>]) {
|
||||
debug_assert!(matches!(tcx.def_kind(self.def_id), DefKind::AssocTy | DefKind::AssocConst));
|
||||
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::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<...>`.
|
||||
|
@ -1113,7 +1334,7 @@ where
|
|||
#[derive(Copy, Clone, PartialEq, Eq, Hash, TyEncodable, TyDecodable)]
|
||||
#[derive(HashStable, TypeFoldable, TypeVisitable, Lift)]
|
||||
pub struct AliasTy<'tcx> {
|
||||
/// The parameters of the associated or opaque item.
|
||||
/// 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.
|
||||
|
@ -1142,36 +1363,6 @@ pub struct AliasTy<'tcx> {
|
|||
_use_alias_ty_new_instead: (),
|
||||
}
|
||||
|
||||
impl<'tcx> rustc_type_ir::inherent::AliasTy<TyCtxt<'tcx>> for AliasTy<'tcx> {
|
||||
fn new(
|
||||
interner: TyCtxt<'tcx>,
|
||||
trait_def_id: DefId,
|
||||
args: impl IntoIterator<Item: Into<ty::GenericArg<'tcx>>>,
|
||||
) -> Self {
|
||||
AliasTy::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> AliasTy<'tcx> {
|
||||
pub fn new(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
|
@ -1182,7 +1373,7 @@ impl<'tcx> AliasTy<'tcx> {
|
|||
ty::AliasTy { def_id, args, _use_alias_ty_new_instead: () }
|
||||
}
|
||||
|
||||
pub fn kind(self, tcx: TyCtxt<'tcx>) -> ty::AliasKind {
|
||||
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 } =
|
||||
|
@ -1199,24 +1390,7 @@ impl<'tcx> AliasTy<'tcx> {
|
|||
|
||||
/// Whether this alias type is an opaque.
|
||||
pub fn is_opaque(self, tcx: TyCtxt<'tcx>) -> bool {
|
||||
matches!(self.opt_kind(tcx), Some(ty::Opaque))
|
||||
}
|
||||
|
||||
/// FIXME: rename `AliasTy` to `AliasTerm` and always handle
|
||||
/// constants. This function can then be removed.
|
||||
pub fn opt_kind(self, tcx: TyCtxt<'tcx>) -> Option<ty::AliasKind> {
|
||||
match tcx.def_kind(self.def_id) {
|
||||
DefKind::AssocTy
|
||||
if let DefKind::Impl { of_trait: false } =
|
||||
tcx.def_kind(tcx.parent(self.def_id)) =>
|
||||
{
|
||||
Some(ty::Inherent)
|
||||
}
|
||||
DefKind::AssocTy => Some(ty::Projection),
|
||||
DefKind::OpaqueTy => Some(ty::Opaque),
|
||||
DefKind::TyAlias => Some(ty::Weak),
|
||||
_ => None,
|
||||
}
|
||||
matches!(self.kind(tcx), ty::Opaque)
|
||||
}
|
||||
|
||||
pub fn to_ty(self, tcx: TyCtxt<'tcx>) -> Ty<'tcx> {
|
||||
|
@ -1224,7 +1398,7 @@ impl<'tcx> AliasTy<'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
/// The following methods work only with associated type projections.
|
||||
/// 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)
|
||||
|
@ -1233,10 +1407,7 @@ impl<'tcx> AliasTy<'tcx> {
|
|||
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)))
|
||||
}
|
||||
}
|
||||
|
||||
/// The following methods work only with trait associated type projections.
|
||||
impl<'tcx> AliasTy<'tcx> {
|
||||
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),
|
||||
|
@ -1541,7 +1712,7 @@ impl<'tcx> Ty<'tcx> {
|
|||
#[inline]
|
||||
pub fn new_alias(
|
||||
tcx: TyCtxt<'tcx>,
|
||||
kind: ty::AliasKind,
|
||||
kind: ty::AliasTyKind,
|
||||
alias_ty: ty::AliasTy<'tcx>,
|
||||
) -> Ty<'tcx> {
|
||||
debug_assert_matches!(
|
||||
|
|
|
@ -1086,7 +1086,7 @@ impl<'tcx> TypeFolder<TyCtxt<'tcx>> for OpaqueTypeExpander<'tcx> {
|
|||
{
|
||||
p.kind()
|
||||
.rebind(ty::ProjectionPredicate {
|
||||
projection_ty: projection_pred.projection_ty.fold_with(self),
|
||||
projection_term: projection_pred.projection_term.fold_with(self),
|
||||
// Don't fold the term on the RHS of the projection predicate.
|
||||
// This is because for default trait methods with RPITITs, we
|
||||
// install a `NormalizesTo(Projection(RPITIT) -> Opaque(RPITIT))`
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue