Rollup merge of #151814 - lcnr:silent-layout-error, r=jackh726

layout: handle rigid aliases without params

fixes rust-lang/rust#151791

r? types
This commit is contained in:
Jacob Pratt 2026-02-12 00:41:07 -05:00 committed by GitHub
commit 3db13e22b7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 49 additions and 13 deletions

View file

@ -764,14 +764,20 @@ fn layout_of_uncached<'tcx>(
}
ty::Alias(..) => {
// NOTE(eddyb) `layout_of` query should've normalized these away,
// if that was possible, so there's no reason to try again here.
let err = if ty.has_param() {
// In case we're still in a generic context, aliases might be rigid. E.g.
// if we've got a `T: Trait` where-bound, `T::Assoc` cannot be normalized
// in the current context.
//
// For some builtin traits, generic aliases can be rigid even in an empty environment,
// e.g. `<T as Pointee>::Metadata`.
//
// Due to trivial bounds, this can even be the case if the alias does not reference
// any generic parameters, e.g. a `for<'a> u32: Trait<'a>` where-bound means that
// `<u32 as Trait<'static>>::Assoc` is rigid.
let err = if ty.has_param() || !cx.typing_env.param_env.caller_bounds().is_empty() {
LayoutError::TooGeneric(ty)
} else {
// This is only reachable with unsatisfiable predicates. For example, if we have
// `u8: Iterator`, then we can't compute the layout of `<u8 as Iterator>::Item`.
LayoutError::Unknown(ty)
unreachable!("invalid rigid alias in layout_of after normalization: {ty:?}");
};
return Err(error(cx, err));
}

View file

@ -64,6 +64,12 @@ pub type GenericTypeAlias = (Generic<(u32, ())>, Generic<u32>);
//@ hasraw type_layout/type.Edges.html 'Unable to compute type layout, possibly due to this type having generic parameters. Layout can only be computed for concrete, fully-instantiated types.'
pub type Edges<'a, E> = std::borrow::Cow<'a, [E]>;
pub trait Project { type Assoc; }
// We can't compute layout as the alias stays rigid. A `LayoutError::TooGeneric` is returned.
//@ hasraw type_layout/struct.RigidAlias.html 'Unable to compute type layout, possibly due to this type having generic parameters. Layout can only be computed for concrete, fully-instantiated types.'
//@ !hasraw - 'Size: '
pub struct RigidAlias(<() as Project>::Assoc) where for<'a> (): Project;
//@ !hasraw type_layout/trait.MyTrait.html 'Size: '
pub trait MyTrait {}
@ -92,9 +98,3 @@ pub enum Uninhabited {}
//@ hasraw type_layout/struct.Uninhabited2.html 'Size: '
//@ hasraw - '8 bytes (<a href="{{channel}}/reference/glossary.html#uninhabited">uninhabited</a>)'
pub struct Uninhabited2(std::convert::Infallible, u64);
pub trait Project { type Assoc; }
// We can't compute layout. A `LayoutError::Unknown` is returned.
//@ hasraw type_layout/struct.Unknown.html 'Unable to compute type layout.'
//@ !hasraw - 'Size: '
pub struct Unknown(<() as Project>::Assoc) where for<'a> (): Project;

View file

@ -0,0 +1,30 @@
//@ compile-flags: -O -Cdebug-assertions=on
//@ build-pass
// A regression test for #151791. Computing the layout of
// `<AsOwned as ArchiveWith<'a>>::Archived` fails as the alias
// is still rigid as the where-bound in scope shadows the impl.
//
// This previously caused an incorrect error during MIR optimizations.
struct ArchivedString;
pub trait ArchiveWith<'a> {
type Archived;
}
struct AsOwned;
impl ArchiveWith<'_> for AsOwned {
type Archived = ArchivedString;
}
fn foo<'a>()
where
AsOwned: ArchiveWith<'a>,
{
let _ = unsafe { &*std::ptr::dangling::<<AsOwned as ArchiveWith<'a>>::Archived>() };
}
fn main() {
foo();
}

View file

@ -2,7 +2,7 @@
//@ build-pass
// A regression test for #149081. The environment of `size` and `align`
// currently means that the item bound of`T::Assoc` doesn't hold. This can
// currently means that the item bound of `T::Assoc` doesn't hold. This can
// result in normalization failures and ICE during MIR optimizations.
//
// This will no longer be an issue once #149283 is implemented.