Skip to content

Refactor AliasTy & AliasTerm to use Alias#156538

Open
Jamesbarford wants to merge 3 commits into
rust-lang:mainfrom
Jamesbarford:chore/merge-AliasTy-AliasTerm
Open

Refactor AliasTy & AliasTerm to use Alias#156538
Jamesbarford wants to merge 3 commits into
rust-lang:mainfrom
Jamesbarford:chore/merge-AliasTy-AliasTerm

Conversation

@Jamesbarford

Copy link
Copy Markdown
Contributor

Refactors AliasTy & AliasTerm to use Alias. To move around errors I had to manually implement Lift, TypeVisitable and TypeFoldable

Part of #156181

r? @lcnr

@rustbot rustbot added S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver) labels May 13, 2026
@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@Jamesbarford Jamesbarford force-pushed the chore/merge-AliasTy-AliasTerm branch from a630681 to 89cd50d Compare May 13, 2026 12:56
@lcnr

lcnr commented May 13, 2026

Copy link
Copy Markdown
Contributor

can you say more about the errors you had to work around? this feels odd to me and something we should fix in the derives instead of requiring manual impls here imo

Comment thread compiler/rustc_type_ir/src/ty_kind.rs Outdated
)]
pub struct AliasTy<I: Interner> {
/// The parameters of the associated or opaque type.
pub struct Alias<I: Interner, K> {

@lcnr lcnr May 13, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can you move Alias and AliasTerm in a separate rustc_type_ir/ty/alias module?

View changes since the review

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

667b095 👍, Only moved Alias & AliasTerm, not AliasTy

Comment thread compiler/rustc_type_ir/src/predicate.rs Outdated
@Jamesbarford

Jamesbarford commented May 13, 2026

Copy link
Copy Markdown
Contributor Author

Edit: I've been experimenting and think I've expanded Lift_Generic to be able to handle more use cases so I've collapsed my original message as it is a wall of text. But does contextualise what Lift_Generic can now do for us.

Original Message

I've whittled it down to only a manual Lift implementation for Alias as below.

(comments omitted for brevity)

#[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> {
    pub args: I::GenericArgs,

    pub kind: K,

    #[derive_where(skip(Debug))]
    #[type_visitable(ignore)]
    #[type_foldable(identity)]
    pub(crate) _use_alias_new_instead: (),
}

I get 2000+ errors of which fall into the following;

error[E0308]: mismatched types
error[E0521]: borrowed data escapes outside of associated function
error[E0521]: borrowed data escapes outside of function
error[E0521]: borrowed data escapes outside of method

A sample of errors being;

error[E0521]: borrowed data escapes outside of method
   --> compiler/rustc_middle/src/ty/trait_def.rs:229:13
    |
181 | impl<'tcx> TyCtxt<'tcx> {
    |      ---- lifetime `'tcx` defined here
...
223 |         self,
    |         ---- `self` is a reference that is only valid in the method body
...
229 |             fast_reject::simplify_type(self, self_ty, TreatParams::InstantiateWithInfer)
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
    |             |
    |             `self` escapes the method body here
    |             argument requires that `'tcx` must outlive `'static`
    |
    = note: requirement occurs because of the type `context::TyCtxt<'_>`, which makes the generic argument `'_` invariant
    = note: the struct `context::TyCtxt<'tcx>` is invariant over the parameter `'tcx`
    = help: see <https://doc.rust-lang.org/nomicon/subtyping.html> for more information about variance
note: due to a current limitation of the type system, this implies a `'static` lifetime
   --> compiler/rustc_middle/src/ty/print/mod.rs:416:15
    |
416 |     T: Copy + for<'a, 'tcx> Lift<TyCtxt<'tcx>, Lifted: Print<FmtPrinter<'a, 'tcx>>>,
    |               ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

...

error[E0308]: mismatched types
   --> compiler/rustc_middle/src/ty/trait_def.rs:229:13
    |
229 |             fast_reject::simplify_type(self, self_ty, TreatParams::InstantiateWithInfer)
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
    |
    = note: expected enum `rustc_type_ir::AliasTyKind<context::TyCtxt<'tcx>>`
               found enum `rustc_type_ir::AliasTyKind<context::TyCtxt<'_>>`
note: the lifetime requirement is introduced here
   --> compiler/rustc_type_ir/src/interner.rs:25:7
    |
 25 |     + IrPrint<ty::AliasTy<Self>>
    |       ^^^^^^^^^^^^^^^^^^^^^^^^^^

error: implementation of `Interner` is not general enough
   --> compiler/rustc_middle/src/ty/trait_def.rs:229:13
    |
229 |             fast_reject::simplify_type(self, self_ty, TreatParams::InstantiateWithInfer)
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `Interner` is not general enough
    |
    = note: `Interner` would have to be implemented for the type `context::TyCtxt<'tcx>`
    = note: ...but `Interner` is actually implemented for the type `context::TyCtxt<'0>`, for some specific lifetime `'0`


...pub struct Placeholder

error[E0308]: mismatched types
   --> compiler/rustc_middle/src/ty/trait_def.rs:229:13
    |
229 |             fast_reject::simplify_type(self, self_ty, TreatParams::InstantiateWithInfer)
    |             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ one type is more general than the other
    |
    = note: expected enum `rustc_type_ir::AliasTermKind<context::TyCtxt<'tcx>>`
               found enum `rustc_type_ir::AliasTermKind<context::TyCtxt<'_>>`
note: the lifetime requirement is introduced here
   --> compiler/rustc_type_ir/src/interner.rs:33:7
    |
 33 |     + IrPrint<ty::NormalizesTo<Self>>
    |       ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

...

error[E0308]: mismatched types
   --> compiler/rustc_middle/src/ty/relate.rs:55:12
    |
 55 | impl<'tcx> Relate<TyCtxt<'tcx>> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> {
    |            ^^^^^^^^^^^^^^^^^^^^ lifetime mismatch
    |
    = note: expected enum `rustc_type_ir::AliasTermKind<context::TyCtxt<'tcx>>`
               found enum `rustc_type_ir::AliasTermKind<context::TyCtxt<'tcx>>`
note: the required lifetime does not necessarily outlive the lifetime `'tcx` as defined here
   --> compiler/rustc_middle/src/ty/relate.rs:55:6
    |
 55 | impl<'tcx> Relate<TyCtxt<'tcx>> for &'tcx ty::List<ty::PolyExistentialPredicate<'tcx>> {
    |      ^^^^
note: the lifetime requirement is introduced here
   --> compiler/rustc_type_ir/src/relate.rs:116:21
    |
116 | pub trait Relate<I: Interner>: TypeFoldable<I> + PartialEq + Copy {
    |                     ^^^^^^^^

And so on... This was similar to pub struct Placeholder<I: Interner, T> where I think the the generic parameter T required manually implementing Lift. Though this is a superficial understanding

@rust-log-analyzer

This comment has been minimized.

@rust-log-analyzer

This comment has been minimized.

@Jamesbarford Jamesbarford force-pushed the chore/merge-AliasTy-AliasTerm branch from 667b095 to b7965ca Compare May 21, 2026 08:30
@rustbot

This comment has been minimized.

@Jamesbarford

Jamesbarford commented May 21, 2026

Copy link
Copy Markdown
Contributor Author

The latest commits expand Lift_Generic to be able to handle:

pub struct Binder<I: Interner, T> {
    //
}

and then

pub struct Binder<I: Interner, T = SomeKind<I>> {
    //
}

e83546d, fbf009a Not sure if these would be best in a separate PR that also clean up binder.rs then this PR can be solely focused on Alias refactoring?

Which I then used to clean up pub struct Binder {} which is out of scope for these changes but was satisfying to remove a FIXME: e2ba945

I can't get Eq to work for Alias, error bellow;

Eq Error
error[E0277]: the trait bound `AliasTyKind<rustc_middle::ty::TyCtxt<'tcx>>: std::cmp::Eq` is not satisfied
   --> compiler/rustc_infer/src/infer/region_constraints/mod.rs:191:11
    |
187 | #[derive(Copy, Clone, PartialEq, Eq, Hash, TypeFoldable, TypeVisitable)]
    |                                  -- in this derive macro expansion
...
191 |     Alias(ty::AliasTy<'tcx>),
    |           ^^^^^^^^^^^^^^^^^ the trait `std::cmp::Eq` is not implemented for `AliasTyKind<rustc_middle::ty::TyCtxt<'tcx>>`
    |
   --> /rustc/ef0fb8a2563200e322fa4419f09f65a63742038c/library/core/src/cmp.rs:364:0
    |
    = note: in this expansion of `#[derive(Eq)]`
help: the trait `std::cmp::Eq` is implemented for `rustc_type_ir::Alias<I, K>`
   --> compiler/rustc_type_ir/src/ty/alias.rs:15:1

edit: Actually we can remove the empty implementation if we make AliasTyKind derive Eq

@rust-bors

This comment has been minimized.

JonathanBrouwer added a commit to JonathanBrouwer/rust that referenced this pull request Jun 4, 2026
…ric-capabilities, r=lcnr

Support generic params in `Lift_Generic`

Handle generic type parameters, including nested occurrences, when deriving `Lift_Generic`.

This lets types like `Binder<I, T>` use `#[derive(Lift_Generic)]` instead of requiring a manual `Lift` impl.

Concretely it can now handle structs as follows;

```rs
// Generic type parameter
struct Binder<I: Interner, T> {
    // body
}

// Nested generic type parameter
pub struct Binder<I: Interner, T = SomeKind<I>> {
    //
}
```

Split off from the `Alias` refactor work; rust-lang#156538

r? @lcnr
rust-timer added a commit that referenced this pull request Jun 4, 2026
Rollup merge of #156956 - Jamesbarford:feat/extend-lift-generic-capabilities, r=lcnr

Support generic params in `Lift_Generic`

Handle generic type parameters, including nested occurrences, when deriving `Lift_Generic`.

This lets types like `Binder<I, T>` use `#[derive(Lift_Generic)]` instead of requiring a manual `Lift` impl.

Concretely it can now handle structs as follows;

```rs
// Generic type parameter
struct Binder<I: Interner, T> {
    // body
}

// Nested generic type parameter
pub struct Binder<I: Interner, T = SomeKind<I>> {
    //
}
```

Split off from the `Alias` refactor work; #156538

r? @lcnr
@Jamesbarford Jamesbarford force-pushed the chore/merge-AliasTy-AliasTerm branch from e2ba945 to c3bdf72 Compare June 5, 2026 08:16
@rustbot

rustbot commented Jun 5, 2026

Copy link
Copy Markdown
Collaborator

This PR was rebased onto a different main commit. Here's a range-diff highlighting what actually changed.

Rebasing is a normal part of keeping PRs up to date, so no action is needed—this note is just to help reviewers.

@Jamesbarford Jamesbarford force-pushed the chore/merge-AliasTy-AliasTerm branch from 71c7efb to bf409af Compare June 5, 2026 08:42
Comment on lines +24 to +36
/// 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,

@lcnr lcnr Jun 8, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested change
/// 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,
pub kind: 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,

personal style preference

View changes since the review

interner.debug_assert_args_compatible(kind.into(), args);
Alias { kind, args, _use_alias_new_instead: () }
}
}

@lcnr lcnr Jun 8, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The 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 { ... }
}

View changes since the review

fn fold_with<F: TypeFolder<I>>(self, folder: &mut F) -> Self {
NormalizesTo { alias: self.alias.fold_with(folder), term: self.term.fold_with(folder) }
}
}

@lcnr lcnr Jun 8, 2026

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

why do the derives not work?

View changes since the review

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

S-waiting-on-review Status: Awaiting review from the assignee but also interested parties. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. WG-trait-system-refactor The Rustc Trait System Refactor Initiative (-Znext-solver)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants