-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Handle more cases in is_normalizable
#13833
base: master
Are you sure you want to change the base?
Handle more cases in is_normalizable
#13833
Conversation
Thank you! |
Consider raw pointers fields as normalizable. This is only used to determine the layout, and the layout of a raw pointer is known, whatever the designated type is. As a side effect, this makes the layout of `Box<T>` known, even inside `T`, and enables recursive types. Would there be a drawback in doing this? I have included the new tests in a separate commit, so that the effect of the change can be seen in the second commit. It can also be seen on the lintcheck diff result. Close #9798.
This is wrong. The size of both references and raw pointers depend on whether the pointee is |
This is what I meant by "known" instead of "constant", because I thought that at this stage the sizedness of the pointee type would be known. I will try to double-check this. |
The sizedness of pointee types is the reason |
@llogiq I haven't checked, but it probably fails because of the missing |
For reference (maybe this helps), a concrete repro that starts ICE-ing with this change (taken from #12550 which also intends to fix the same issue) #![warn(clippy::zero_sized_map_values)]
trait Foo { type Foo; }
struct Bar<T: Foo>(T::Foo);
type Bad<T> = std::collections::HashMap<u32, *const Bar<T>>;
fn main() {} |
Thanks @y21 that will be useful |
@rustbot author Please ping me again when there's something to review. |
By assuming that a recursive type is normalizable within the deeper calls to `is_normalizable_helper()`, more cases can be handled by this function. In order to fix stack overflows, a recursion limit has also been added for recursive generic type instantiations.
cbfa74b
to
bd57421
Compare
is_normalizable
By limiting the recursion and assuming that recursive types are normalizable by default when recursing (which will be fixed when going up if needed), more cases are detected and some ICEs are fixed. @rustbot review Ping @llogiq and also ping @Jarcho as this collides with #12550 (but can serve as a stopgap until |
@llogiq Do you see anything to be changed here? This has fixed all ICE I know of. Also, looking at the two commits separately, you can see that some diagnostics have been improved (which was the initial goal of this PR before I was made aware of the ICE): LL | | Recursive(Box<WithRecursion>),
| | ----------------------------- the second-largest variant contains at least 0 bytes
| | ----------------------------- the second-largest variant contains at least 8 bytes
LL | | }
| |_^ the entire enum is at least 0 bytes
| |_^ the entire enum is at least 520 bytes |
By assuming that a recursive type is normalizable within the deeper calls to
is_normalizable_helper()
, more cases can be handled by this function.In order to fix stack overflows, a recursion limit has also been added for recursive generic type instantiations.
Fix #9798
Fix #10508
Fix #11915
changelog: [
large_enum_variant
]: more precise detection of variants with large size differences