-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Make core::mem::MaybeUninit::zeroed a const fn #54832
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
0b6a44c
255f723
b18f946
fde2e91
e5eb54c
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 | ||
---|---|---|---|---|
|
@@ -1039,6 +1039,19 @@ impl<T> MaybeUninit<T> { | |||
/// Note that dropping a `MaybeUninit` will never call `T`'s drop code. | ||||
/// It is your responsibility to make sure `T` gets dropped if it got initialized. | ||||
#[unstable(feature = "maybe_uninit", issue = "53491")] | ||||
#[rustc_const_unstable(feature = "const_maybe_uninit_zeroed")] | ||||
#[cfg(not(stage0))] | ||||
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. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not make 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'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:
I don't understand why this even works as-is. Trying to make 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. 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 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. 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. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Could this be related to what #54715 fixes? 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. No, I think I found it. The fix is to add rust/src/librustc/ty/constness.rs Line 43 in 567557f
|
||||
} | ||||
u | ||||
} | ||||
|
||||
#[unstable(feature = "maybe_uninit", issue = "53491")] | ||||
#[cfg(stage0)] | ||||
/// Ceci n'est pas la documentation | ||||
pub fn zeroed() -> MaybeUninit<T> { | ||||
let mut u = MaybeUninit::<T>::uninitialized(); | ||||
unsafe { | ||||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -157,6 +157,23 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> | |
let dest = self.force_allocation(dest)?; | ||
self.copy_op(args[0], dest.into())?; | ||
} | ||
"write_bytes" => { | ||
let ptr = self.read_value(args[0])?; | ||
let mplace = self.ref_to_mplace(ptr)?; | ||
let val = self.read_scalar(args[1])?.to_u8()?; | ||
let count = self.read_scalar(args[2])?.to_usize(&self.memory)?; | ||
if mplace.layout.is_zst() || count == 0 { | ||
return Ok(true); | ||
} | ||
if let Some(byte_count) = mplace.layout.size.checked_mul(count, &self.memory) { | ||
self.memory.write_repeat(mplace.ptr, val, byte_count)?; | ||
} else { | ||
return err!(Intrinsic( | ||
format!("Overflowing computing `count * size_of::<T>()` ({} * {}) in {}", | ||
count, mplace.layout.size.bytes(), intrinsic_name), | ||
)); | ||
} | ||
} | ||
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. 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 |
||
|
||
_ => return Ok(false), | ||
} | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -858,6 +858,19 @@ impl<'a, 'tcx> Visitor<'tcx> for Qualifier<'a, 'tcx, 'tcx> { | |
} | ||
} | ||
} | ||
"write_bytes" => { | ||
if self.tcx.sess.features_untracked().const_write_bytes { | ||
is_const_fn = true; | ||
} else if self.mode != Mode::Fn { | ||
// Using write_bytes in a const expression requires the feature | ||
// gate. | ||
emit_feature_err( | ||
&self.tcx.sess.parse_sess, "const_write_bytes", | ||
self.span, GateIssue::Language, | ||
&format!("The use of std::ptr::write_bytes() \ | ||
is gated in {}s", self.mode)); | ||
} | ||
} | ||
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. Why does this logic look different than the one for |
||
|
||
name if name.starts_with("simd_shuffle") => { | ||
is_shuffle = true; | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,26 @@ | ||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
#![feature(maybe_uninit, const_maybe_uninit_zeroed)] | ||
|
||
use std::mem; | ||
|
||
fn main() { | ||
const UNIT: mem::MaybeUninit<()> = mem::MaybeUninit::zeroed(); | ||
let bytes: [u8; 0] = unsafe { mem::transmute(UNIT) }; | ||
assert_eq!(bytes, [0u8; 0]); | ||
|
||
const STRING: mem::MaybeUninit<String> = mem::MaybeUninit::zeroed(); | ||
let bytes: [u8; mem::size_of::<String>()] = unsafe { mem::transmute(STRING) }; | ||
assert_eq!(bytes, [0u8; mem::size_of::<String>()]); | ||
|
||
const U8: mem::MaybeUninit<u8> = mem::MaybeUninit::zeroed(); | ||
let bytes: [u8; 1] = unsafe { mem::transmute(U8) }; | ||
assert_eq!(bytes, [0u8; 1]); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT | ||
// file at the top-level directory of this distribution and at | ||
// http://rust-lang.org/COPYRIGHT. | ||
// | ||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or | ||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license | ||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your | ||
// option. This file may not be copied, modified, or distributed | ||
// except according to those terms. | ||
|
||
#![feature(const_fn, const_let)] | ||
|
||
fn main() {} | ||
|
||
const unsafe fn foo(u: *mut u32) { | ||
std::ptr::write_bytes(u, 0u8, 1); | ||
//~^ ERROR The use of std::ptr::write_bytes() is gated in constant functions (see issue #53491) | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
error[E0658]: The use of std::ptr::write_bytes() is gated in constant functions (see issue #53491) | ||
--> $DIR/feature-gate-const_write_bytes.rs:16:5 | ||
| | ||
LL | std::ptr::write_bytes(u, 0u8, 1); | ||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | ||
| | ||
= help: add #![feature(const_write_bytes)] to the crate attributes to enable | ||
|
||
error: aborting due to previous error | ||
|
||
For more information about this error, try `rustc --explain E0658`. |
Uh oh!
There was an error while loading. Please reload this page.