-
-
Notifications
You must be signed in to change notification settings - Fork 15k
Refactor AliasTy & AliasTerm to use Alias
#156538
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -8,10 +8,12 @@ use rustc_type_ir_macros::{ | |
| GenericTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic, | ||
| }; | ||
|
|
||
| use crate::fold::{FallibleTypeFolder, TypeFoldable, TypeFolder}; | ||
| use crate::inherent::*; | ||
| use crate::ty::AliasTerm; | ||
| use crate::upcast::{Upcast, UpcastFrom}; | ||
| use crate::visit::TypeVisitableExt as _; | ||
| use crate::{self as ty, AliasTyKind, Interner, UnevaluatedConstKind}; | ||
| use crate::visit::{TypeVisitable, TypeVisitableExt as _, TypeVisitor}; | ||
| use crate::{self as ty, Alias, AliasTyKind, Interner, UnevaluatedConstKind, try_visit}; | ||
|
|
||
| /// `A: 'region` | ||
| #[derive_where(Clone, Hash, PartialEq, Debug; I: Interner, A)] | ||
|
|
@@ -544,7 +546,7 @@ impl<I: Interner> ty::Binder<I, ExistentialProjection<I>> { | |
| } | ||
|
|
||
| #[derive_where(Clone, Copy, PartialEq, Eq, Hash, Debug; I: Interner)] | ||
| #[derive(Lift_Generic, GenericTypeVisitable)] | ||
| #[derive(TypeVisitable_Generic, TypeFoldable_Generic, Lift_Generic, GenericTypeVisitable)] | ||
| #[cfg_attr( | ||
| feature = "nightly", | ||
| derive(Encodable_NoContext, Decodable_NoContext, StableHash_NoContext) | ||
|
|
@@ -661,49 +663,14 @@ impl<I: Interner> From<ty::UnevaluatedConstKind<I>> for AliasTermKind<I> { | |
| } | ||
| } | ||
|
|
||
| /// 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_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner)] | ||
| #[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] | ||
| #[cfg_attr( | ||
| feature = "nightly", | ||
| derive(Decodable_NoContext, Encodable_NoContext, StableHash_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, | ||
|
|
||
| #[type_foldable(identity)] | ||
| #[type_visitable(ignore)] | ||
| pub kind: AliasTermKind<I>, | ||
|
|
||
| /// This field exists to prevent the creation of `AliasTerm` without using [`AliasTerm::new_from_args`]. | ||
| #[derive_where(skip(Debug))] | ||
| _use_alias_term_new_instead: (), | ||
| } | ||
|
|
||
| impl<I: Interner> Eq for AliasTerm<I> {} | ||
|
|
||
| impl<I: Interner> AliasTerm<I> { | ||
| pub fn new_from_args( | ||
| interner: I, | ||
| kind: AliasTermKind<I>, | ||
| args: I::GenericArgs, | ||
| ) -> AliasTerm<I> { | ||
| interner.debug_assert_args_compatible(kind.def_id(), args); | ||
| AliasTerm { kind, args, _use_alias_term_new_instead: () } | ||
| AliasTerm { kind, args, _use_alias_new_instead: () } | ||
| } | ||
|
|
||
| pub fn new( | ||
|
|
@@ -733,7 +700,7 @@ impl<I: Interner> AliasTerm<I> { | |
| panic!("Cannot turn `{}` into `AliasTy`", kind.descr()) | ||
| } | ||
| }; | ||
| ty::AliasTy { kind, args: self.args, _use_alias_ty_new_instead: () } | ||
| ty::AliasTy { kind, args: self.args, _use_alias_new_instead: () } | ||
| } | ||
|
|
||
| pub fn expect_ct(self) -> ty::UnevaluatedConst<I> { | ||
|
|
@@ -884,21 +851,13 @@ impl<I: Interner> AliasTerm<I> { | |
|
|
||
| impl<I: Interner> From<ty::AliasTy<I>> for AliasTerm<I> { | ||
| fn from(ty: ty::AliasTy<I>) -> Self { | ||
| AliasTerm { | ||
| args: ty.args, | ||
| kind: AliasTermKind::from(ty.kind), | ||
| _use_alias_term_new_instead: (), | ||
| } | ||
| AliasTerm { args: ty.args, kind: AliasTermKind::from(ty.kind), _use_alias_new_instead: () } | ||
| } | ||
| } | ||
|
|
||
| impl<I: Interner> From<ty::UnevaluatedConst<I>> for AliasTerm<I> { | ||
| fn from(ty: ty::UnevaluatedConst<I>) -> Self { | ||
| AliasTerm { | ||
| args: ty.args, | ||
| kind: AliasTermKind::from(ty.kind), | ||
| _use_alias_term_new_instead: (), | ||
| } | ||
| AliasTerm { args: ty.args, kind: AliasTermKind::from(ty.kind), _use_alias_new_instead: () } | ||
| } | ||
| } | ||
|
|
||
|
|
@@ -977,18 +936,36 @@ impl<I: Interner> fmt::Debug for ProjectionPredicate<I> { | |
|
|
||
| /// Used by the new solver to normalize an alias. This always expects the `term` to | ||
| /// be an unconstrained inference variable which is used as the output. | ||
| #[derive_where(Clone, Copy, Hash, PartialEq; I: Interner)] | ||
| #[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] | ||
| #[derive_where(Clone, Copy, Hash, Eq, PartialEq; I: Interner, K)] | ||
| #[derive(GenericTypeVisitable, Lift_Generic)] | ||
| #[cfg_attr( | ||
| feature = "nightly", | ||
| derive(Decodable_NoContext, Encodable_NoContext, StableHash_NoContext) | ||
| )] | ||
| pub struct NormalizesTo<I: Interner> { | ||
| pub alias: AliasTerm<I>, | ||
| pub struct NormalizesTo<I: Interner, K = AliasTermKind<I>> { | ||
| pub alias: Alias<I, K>, | ||
| pub term: I::Term, | ||
| } | ||
|
|
||
| impl<I: Interner> Eq for NormalizesTo<I> {} | ||
| impl<I: Interner, K: TypeVisitable<I>> TypeVisitable<I> for NormalizesTo<I, K> { | ||
| fn visit_with<V: TypeVisitor<I>>(&self, visitor: &mut V) -> V::Result { | ||
| try_visit!(self.alias.visit_with(visitor)); | ||
| self.term.visit_with(visitor) | ||
| } | ||
| } | ||
|
|
||
| impl<I: Interner, K: TypeFoldable<I>> TypeFoldable<I> for NormalizesTo<I, K> { | ||
| fn try_fold_with<F: FallibleTypeFolder<I>>(self, folder: &mut F) -> Result<Self, F::Error> { | ||
| Ok(NormalizesTo { | ||
| alias: self.alias.try_fold_with(folder)?, | ||
| term: self.term.try_fold_with(folder)?, | ||
| }) | ||
| } | ||
|
|
||
| fn fold_with<F: TypeFolder<I>>(self, folder: &mut F) -> Self { | ||
| NormalizesTo { alias: self.alias.fold_with(folder), term: self.term.fold_with(folder) } | ||
| } | ||
| } | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. why do the derives not work?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In essence a similar problem that hampered |
||
|
|
||
| impl<I: Interner> NormalizesTo<I> { | ||
| pub fn self_ty(self) -> I::Ty { | ||
|
|
@@ -1008,7 +985,7 @@ impl<I: Interner> NormalizesTo<I> { | |
| } | ||
| } | ||
|
|
||
| impl<I: Interner> fmt::Debug for NormalizesTo<I> { | ||
| impl<I: Interner, K: fmt::Debug> fmt::Debug for NormalizesTo<I, K> { | ||
| fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { | ||
| write!(f, "NormalizesTo({:?}, {:?})", self.alias, self.term) | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||||||||||||||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| @@ -0,0 +1,66 @@ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| use derive_where::derive_where; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| #[cfg(feature = "nightly")] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| use rustc_macros::{Decodable_NoContext, Encodable_NoContext, StableHash_NoContext}; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| use rustc_type_ir_macros::{ | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| GenericTypeVisitable, Lift_Generic, TypeFoldable_Generic, TypeVisitable_Generic, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| }; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| use crate::Interner; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| use crate::predicate::AliasTermKind; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| use crate::ty_kind::AliasTyKind; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// Represents an alias of a type, constant, or other term-like item. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// * 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_where(Clone, Copy, Hash, PartialEq, Debug; I: Interner, K)] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| #[derive(TypeVisitable_Generic, GenericTypeVisitable, TypeFoldable_Generic, Lift_Generic)] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| #[cfg_attr( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| feature = "nightly", | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| derive(Decodable_NoContext, Encodable_NoContext, StableHash_NoContext) | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| )] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| pub struct Alias<I: Interner, K> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// The parameters of the associated, opaque, or constant alias. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// 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, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| pub kind: K, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Comment on lines
+24
to
+36
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Suggested change
personal style preference |
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| /// This field exists to prevent the creation of `Alias` without using the relevant constructor. | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| #[derive_where(skip(Debug))] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| #[type_visitable(ignore)] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| #[type_foldable(identity)] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| #[lift(identity)] | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| pub(crate) _use_alias_new_instead: (), | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| impl<I: Interner, K: PartialEq> Eq for Alias<I, K> {} | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| impl<I: Interner, K: Copy> Alias<I, K> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| pub fn kind(self, _interner: I) -> K { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| self.kind | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| impl<I: Interner> Alias<I, I::UnevaluatedConstId> { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| pub fn new_unevaluated_const_from_args( | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| interner: I, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| kind: I::UnevaluatedConstId, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| args: I::GenericArgs, | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| ) -> Self { | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| interner.debug_assert_args_compatible(kind.into(), args); | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Alias { kind, args, _use_alias_new_instead: () } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| } | ||||||||||||||||||||||||||||||||||||||||||||||||||||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. hmm, could we change this to trait AliasKind<I: Interner>: Copy {
fn assert_args_compatible(self, cx: I, args: I::GenericArgs);
#[inline]
fn debug_assert_args_compatible(self, cx: I, args: I::GenericArgs) {
if cfg!(debug_assertions) { self.assert... }
}
}
impl<I: Interner, K: AliasKind> Alias<I, K> {
pub fn new(
cx: I,
kind: K,
args: I::GenericArgs,
) -> Self {
kind.debug_assert_args_compatible(interner, args);
Alias { kind, args, _use_alias_new_instead: () }
}
pub fn new_from_iter(
cx: I,
kind: K,
args: impl IntoIterator<...>,
) -> Self { ... }
} |
||||||||||||||||||||||||||||||||||||||||||||||||||||
|
|
||||||||||||||||||||||||||||||||||||||||||||||||||||
| pub type AliasTerm<I> = Alias<I, AliasTermKind<I>>; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| pub type AliasTy<I> = Alias<I, AliasTyKind<I>>; | ||||||||||||||||||||||||||||||||||||||||||||||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,3 @@ | ||
| mod alias; | ||
|
|
||
| pub use alias::{Alias, AliasTerm, AliasTy}; |
Uh oh!
There was an error while loading. Please reload this page.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm extremely on board with the style of thing that lcnr said with
there's a lot of places in the code that could hugely benefit from this (e.g. there's a large number of unwraps in #157653 that could be avoided), but this particular case with
normalize_anon_constis a bit gross, and I would prefer keeping this asNormalizesTo<I, K = AliasTermKind<I>>(at least until additional refactorings happen that would e.g. allowevaluate_const_and_instantiate_normalizes_to_termto be more generic)(this is just my code style opinion though, up to you!)
edit: just want to clarify, that PR has a lot of unwraps of the form:
having the Alias have a more specific Kind in all the cases that PR does that style of unwrap (it's so common that projections already have a helper method for it,
expect_projection_def_id) would be super nice, but yeah