FEAT: Use stable MaybeUninit when we can (feature detected)
This commit is contained in:
@@ -11,17 +11,28 @@ fn main() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn detect_maybe_uninit() {
|
fn detect_maybe_uninit() {
|
||||||
|
let has_stable_maybe_uninit = probe(&stable_maybe_uninit());
|
||||||
|
if has_stable_maybe_uninit {
|
||||||
|
println!("cargo:rustc-cfg=has_stable_maybe_uninit");
|
||||||
|
return;
|
||||||
|
}
|
||||||
let has_unstable_union_with_md = probe(&maybe_uninit_code(true));
|
let has_unstable_union_with_md = probe(&maybe_uninit_code(true));
|
||||||
if has_unstable_union_with_md {
|
if has_unstable_union_with_md {
|
||||||
println!("cargo:rustc-cfg=has_manually_drop_in_union");
|
println!("cargo:rustc-cfg=has_manually_drop_in_union");
|
||||||
println!("cargo:rustc-cfg=has_union_feature");
|
println!("cargo:rustc-cfg=has_union_feature");
|
||||||
return;
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let has_stable_union_with_md = probe(&maybe_uninit_code(false));
|
// To guard against changes in this currently unstable feature, use
|
||||||
if has_stable_union_with_md {
|
// a detection tests instead of a Rustc version and/or date test.
|
||||||
println!("cargo:rustc-cfg=has_manually_drop_in_union");
|
fn stable_maybe_uninit() -> String {
|
||||||
}
|
let code = "
|
||||||
|
#![allow(warnings)]
|
||||||
|
use std::mem::MaybeUninit;
|
||||||
|
|
||||||
|
fn main() { }
|
||||||
|
";
|
||||||
|
code.to_string()
|
||||||
}
|
}
|
||||||
|
|
||||||
// To guard against changes in this currently unstable feature, use
|
// To guard against changes in this currently unstable feature, use
|
||||||
|
|||||||
+5
-2
@@ -50,9 +50,12 @@ use std::fmt;
|
|||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
|
|
||||||
#[cfg(has_manually_drop_in_union)]
|
#[cfg(has_stable_maybe_uninit)]
|
||||||
|
#[path="maybe_uninit_stable.rs"]
|
||||||
mod maybe_uninit;
|
mod maybe_uninit;
|
||||||
#[cfg(not(has_manually_drop_in_union))]
|
#[cfg(all(not(has_stable_maybe_uninit), has_manually_drop_in_union))]
|
||||||
|
mod maybe_uninit;
|
||||||
|
#[cfg(all(not(has_stable_maybe_uninit), not(has_manually_drop_in_union)))]
|
||||||
#[path="maybe_uninit_nodrop.rs"]
|
#[path="maybe_uninit_nodrop.rs"]
|
||||||
mod maybe_uninit;
|
mod maybe_uninit;
|
||||||
|
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
|
||||||
|
|
||||||
|
use array::Array;
|
||||||
|
use std::mem::MaybeUninit as StdMaybeUninit;
|
||||||
|
|
||||||
|
pub struct MaybeUninit<T> {
|
||||||
|
inner: StdMaybeUninit<T>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> MaybeUninit<T> {
|
||||||
|
/// Create a new MaybeUninit with uninitialized interior
|
||||||
|
pub unsafe fn uninitialized() -> Self {
|
||||||
|
MaybeUninit { inner: StdMaybeUninit::uninit() }
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Create a new MaybeUninit from the value `v`.
|
||||||
|
pub fn from(v: T) -> Self {
|
||||||
|
MaybeUninit { inner: StdMaybeUninit::new(v) }
|
||||||
|
}
|
||||||
|
|
||||||
|
// Raw pointer casts written so that we don't reference or access the
|
||||||
|
// uninitialized interior value
|
||||||
|
|
||||||
|
/// Return a raw pointer to the start of the interior array
|
||||||
|
pub fn ptr(&self) -> *const T::Item
|
||||||
|
where T: Array
|
||||||
|
{
|
||||||
|
// std MaybeUninit creates a &self.value reference here which is
|
||||||
|
// not guaranteed to be sound in our case - we will partially
|
||||||
|
// initialize the value, not always wholly.
|
||||||
|
self.inner.as_ptr() as *const T::Item
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Return a mut raw pointer to the start of the interior array
|
||||||
|
pub fn ptr_mut(&mut self) -> *mut T::Item
|
||||||
|
where T: Array
|
||||||
|
{
|
||||||
|
self.inner.as_mut_ptr() as *mut T::Item
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user