-
Notifications
You must be signed in to change notification settings - Fork 13k
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
Draft: Miri/CTFE engine: Unions are not scalar #94411
Conversation
Some changes occured to the CTFE / Miri engine cc @rust-lang/miri |
ty.tuple_fields().iter().all(|field| type_is_scalar(tcx, field)) | ||
} | ||
// FIXME: can these ever have Scalar ABI? | ||
ty::Closure(..) | ty::Generator(..) => false, |
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.
This line is the problem: some closures (and likely generators) can end up with a Scalar
layout, and they can even have niches, which then means validity will call read_scalar
and cause an ICE when we do not treat it as a scalar.
To fix this, we need a way to iterate over the types of all the fields of (all the variants of) a closure/generator. Any suggestion for how to do that? :D I browsed the code for a bit and found nothing.
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.
For closures you'll want https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/sty/struct.ClosureSubsts.html#method.upvar_tys which you get by copying the substs into a new instance of ClosureSubsts. The same helper exists for generators. I guess we should make this less cumbersome to do
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.
What about renaming this function to type_can_be_scalar
and returning true in all cases except unions?
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.
Then we'd still have the bug for (e.g.) closures that capture unions in a way that they still get abi::Scalar
layout.
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 am experimenting with changing the layout to support undef scalars. If perf is happy with it, we can just ask the layout whether the scalars are undef and not do an immediate representation then.
This comment has been minimized.
This comment has been minimized.
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'm not too happy with this approach. Maybe we should add a flag to scalar layout information stating whether it has a union inside? Maybe other backends are interested in whether a scalar can be undef, too?
// FIXME: can these ever have Scalar ABI? | ||
ty::Closure(..) | ty::Generator(..) => false, | ||
// Types that don't have scalar layout to begin with. | ||
ty::Array(..) | ty::Slice(..) | ty::Str | ty::Dynamic(..) | ty::Foreign(..) => { |
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.
Single element arrays can have scalar layout, I think?
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.
Two element arrays can be scalar pair, too, by the same logic, but maybe we don't do 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.
At least currently, arrays always seem to have Aggregate
ABI.
ty.tuple_fields().iter().all(|field| type_is_scalar(tcx, field)) | ||
} | ||
// FIXME: can these ever have Scalar ABI? | ||
ty::Closure(..) | ty::Generator(..) => false, |
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.
For closures you'll want https://doc.rust-lang.org/nightly/nightly-rustc/rustc_middle/ty/sty/struct.ClosureSubsts.html#method.upvar_tys which you get by copying the substs into a new instance of ClosureSubsts. The same helper exists for generators. I guess we should make this less cumbersome to do
45543cc
to
ed7ca44
Compare
I agree looking at the types is somewhat icky, and ideally FWIW, #93670 actually has some overlap with this I think. There, a new attribute was added to And indeed I think LLVM might some day be interested in this distinction -- |
(I cannot reply directly to that comment, WTF GitHub?) I was trying to figure out how to construct a ClosureSubst, but |
The job Click to see the possible cause of the failure (guessed by this bot)
|
I can check on Tuesday, but my approach is basically "check other use sites, do the same thing and document the findings and/or add helpers" |
Closing in favor of #94527. |
…esjardin Let CTFE to handle partially uninitialized unions without marking the entire value as uninitialized. follow up to rust-lang#94411 To fix rust-lang#69488 and by extension fix rust-lang#94371, we should stop treating types like `MaybeUninit<usize>` as something that the `Scalar` type in the interpreter engine can represent. So we add a new field to `abi::Primitive` that records whether the primitive is nested in a union cc `@RalfJung` r? `@ghost`
To fix #69488 and by extension #94371, we should stop treating types like
MaybeUninit<usize>
as something that theScalar
type in the interpreter engine can represent. So we add a new testtype_is_scalar
which checks if a type can be represented as aScalar
.This is a draft since it still ICEs in Miri, but I need help figuring out the best way to avoid that.
r? @oli-obk