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:
commit
3db13e22b7
4 changed files with 49 additions and 13 deletions
|
|
@ -764,14 +764,20 @@ fn layout_of_uncached<'tcx>(
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::Alias(..) => {
|
ty::Alias(..) => {
|
||||||
// NOTE(eddyb) `layout_of` query should've normalized these away,
|
// In case we're still in a generic context, aliases might be rigid. E.g.
|
||||||
// if that was possible, so there's no reason to try again here.
|
// if we've got a `T: Trait` where-bound, `T::Assoc` cannot be normalized
|
||||||
let err = if ty.has_param() {
|
// 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)
|
LayoutError::TooGeneric(ty)
|
||||||
} else {
|
} else {
|
||||||
// This is only reachable with unsatisfiable predicates. For example, if we have
|
unreachable!("invalid rigid alias in layout_of after normalization: {ty:?}");
|
||||||
// `u8: Iterator`, then we can't compute the layout of `<u8 as Iterator>::Item`.
|
|
||||||
LayoutError::Unknown(ty)
|
|
||||||
};
|
};
|
||||||
return Err(error(cx, err));
|
return Err(error(cx, err));
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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.'
|
//@ 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 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: '
|
//@ !hasraw type_layout/trait.MyTrait.html 'Size: '
|
||||||
pub trait MyTrait {}
|
pub trait MyTrait {}
|
||||||
|
|
||||||
|
|
@ -92,9 +98,3 @@ pub enum Uninhabited {}
|
||||||
//@ hasraw type_layout/struct.Uninhabited2.html 'Size: '
|
//@ hasraw type_layout/struct.Uninhabited2.html 'Size: '
|
||||||
//@ hasraw - '8 bytes (<a href="{{channel}}/reference/glossary.html#uninhabited">uninhabited</a>)'
|
//@ hasraw - '8 bytes (<a href="{{channel}}/reference/glossary.html#uninhabited">uninhabited</a>)'
|
||||||
pub struct Uninhabited2(std::convert::Infallible, u64);
|
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;
|
|
||||||
|
|
|
||||||
30
tests/ui/layout/rigid-alias-no-params.rs
Normal file
30
tests/ui/layout/rigid-alias-no-params.rs
Normal 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();
|
||||||
|
}
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
//@ build-pass
|
//@ build-pass
|
||||||
|
|
||||||
// A regression test for #149081. The environment of `size` and `align`
|
// 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.
|
// result in normalization failures and ICE during MIR optimizations.
|
||||||
//
|
//
|
||||||
// This will no longer be an issue once #149283 is implemented.
|
// This will no longer be an issue once #149283 is implemented.
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue