Uh oh!
There was an error while loading. Please reload this page.
Make core::mem::MaybeUninit::zeroed a const fn - #54832
Conversation
rust-highfive
commented
Oct 5, 2018
(rust_highfive has picked a reviewer for you, use r? to override) |
oli-obk
left a comment
There was a problem hiding this comment.
I believe miri zero-fills allocations, and that force_allocation is the right way to allocate something in miri, but if either of those assumptions are incorrect please let me know.
While the "byte" representation is zero filled, there's also a layer marking these bytes as "uninitialized". Only after looking at all three layers (bytes, initialized, relocation/pointer) can one make a statement about the value.
Uh oh!
There was an error while loading. Please reload this page.
| self.write_scalar(val, dest)?; | ||
| } | ||
| "init" => { | ||
| self.force_allocation(dest)?; |
There was a problem hiding this comment.
You can just copy the implementation from https://github.com/solson/miri/blob/master/src/intrinsic.rs#L238
Your current implementation is a nop, it literally does nothing ;)
There was a problem hiding this comment.
Dang, that was awfully naive of me ha. Done.
Side question: is there any reason that entire file isn't just copied into here?
oli-obk
commented
Oct 5, 2018
r? @oli-obk |
mjbshaw
commented
Oct 5, 2018
Thank you, @oli-obk, for helping walk me through this one! |
rust-highfive
commented
Oct 5, 2018
The job Click to expand the log.I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
RalfJung
commented
Oct 5, 2018
Uh... I am not a big fan. :/ The plan is to get rid of these horrible intrinsics ( I'd much prefer keeping the original implementation of |
RalfJung
commented
Oct 5, 2018
(Sorry, somehow I managed to submit the same thing twice and close the PR and I have no idea how that happened.) So, to be clear: If you are asking for my opinion, I'll |
rust-highfive
commented
Oct 5, 2018
The job Click to expand the log.I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
mjbshaw
commented
Oct 5, 2018
Dang. I originally wanted to implement this by just transmuting a |
rust-highfive
commented
Oct 5, 2018
The job Click to expand the log.I'm a bot! I can only do what humans tell me to, so if this was not helpful or you have suggestions for improvements, please ping or otherwise contact |
RalfJung
commented
Oct 5, 2018
|
Use this to implement MaybeUninit::zeroed, and make the init intrinsic no longer const
mjbshaw
commented
Oct 5, 2018
Okay, I've added a commit that reverts |
| pub const fn zeroed() -> MaybeUninit<T> { | ||
| let mut u = MaybeUninit::<T>::uninitialized(); | ||
| unsafe { | ||
| (&mut *u.value as *mut T).write_bytes(0u8, 1); |
There was a problem hiding this comment.
Why not make as_mut_ptr a const fn as well and avoid duplicating?
There was a problem hiding this comment.
I've been digging into making that change, but I keep running into issues like this, and now that I think of it, I can't figure out why this even compiles in the first place:
ManuallyDropimplements the deref traits, but those functions aren'tconst.- I only made the intrinsic
write_bytesconst, not thewrite_bytesmethod formut_ptrlang item. This should be using the latter, not the intrinsic. - This requires taking a mutable reference.
I don't understand why this even works as-is. Trying to make as_mut_ptr a const fn reveals all these issues, but manually inlining it here does not...
There was a problem hiding this comment.
O_o, that looks like a hole in the const checks, but I don't even know where to start debugging this. Even if the function isn't checked for min_const_fn, it should definitely fail to build due to the regular const fn checks.
There was a problem hiding this comment.
Yea, in the playground this won't compile: https://play.rust-lang.org/?gist=adce30a361142dcea174aee030ea8a91&version=nightly&mode=debug&edition=2018
There was a problem hiding this comment.
No, I think I found it. is_min_const_fn doesn't check for is_const_fn as a prerequisite.
The fix is to add self.is_const_fn(def_id) && infront of
rust/src/librustc/ty/constness.rs
Line 43 in 567557f
| count, mplace.layout.size.bytes(), intrinsic_name), | ||
| )); | ||
| } | ||
| } |
There was a problem hiding this comment.
Why is this code so different from https://github.com/solson/miri/blob/master/src/intrinsic.rs#L420 ?
Also note that the ZST optimization here is wrong. It is UB to call write_bytes on an unaligned pointer even for a ZST. Your code fails to check for that.
| &format!("The use of std::ptr::write_bytes() \ | ||
| is gated in {}s", self.mode)); | ||
| } | ||
| } |
There was a problem hiding this comment.
Why does this logic look different than the one for transmute above?
RalfJung
commented
Oct 6, 2018
Yes, I'm in favor of this approach. :) Please remove the old commits though, no reason to keep them. |
mjbshaw
commented
Oct 22, 2018
I'm unsure how to proceed here. As best as I can tell, in order to implement this (without a const
Items 1 and 2 are easy, but item 3 seems to be the real blocker. Any advice on how to proceed? |
oli-obk
commented
Oct 23, 2018
is 3. solvable with the |
mjbshaw
commented
Oct 23, 2018
No, |
oli-obk
commented
Oct 26, 2018
hmm... this is a little tricky to solve. The checks are there so we don't end up with a |
TimNN
commented
Nov 6, 2018
Ping from triage! What is the status of this PR? Is it blocked on an external issue? |
oli-obk
commented
Nov 6, 2018
yea, @mjbshaw unfortunately I think we can't really do this right now. We need to figure out how to do mutable references in const fns first. This is going to take a while (both in figuring out and implementing). Once we've done that, don't hesitate to reopen your PR |
First, let me say I have no idea what I'm doing, so this might be completely wrong. @RalfJung (and others), please let me know if this accidentally causes undefined behavior.
I believe miri zero-fills allocations, and that
force_allocationis the right way to allocate something in miri, but if either of those assumptions are incorrect please let me know.I'm happy to add this behind a feature gate (as suggested by @Centril). I didn't here since
MaybeUninitis already unstable and I'm hoping this isn't too controversial.