-
-
Notifications
You must be signed in to change notification settings - Fork 14.5k
layout: handle rigid aliases without params #151814
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
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 |
|---|---|---|
|
|
@@ -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() { | ||
|
Member
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. This seems like a weird fix? Like, just because there were where clauses, doesn't mean they they were even relevant to the alias, right? Like, this would mean that I'm not sure I have a better easy solution in mind. As a heuristic, we could see if there is a bound like
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. I agree, I don't care as the |
||
| 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)); | ||
| } | ||
|
|
||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -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(); | ||
| } |
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.
Before 5dfbf67 (the commit that revealed the bug this fixes) we had this in the middle of borrowck:
Was that
.prove_trait_ref(..., ..., ConstraintCategory::SizedBound)what was "rescuing" this code from having to think about this?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 don't think so, the code broken by his compiled previously and this check could have at most resulted in errors.
The reason this regressed is that we've added new associated constants to the standard library causing us to evaluate things and to check their layout in more places