Skip to content

Commit e68c0c7

Browse files
committed
Merge branch '0.4' into master
* 0.4: 0.4.11 TEST: Update tests for new MaybeUninit usage FEAT: Use stable MaybeUninit when we can (feature detected)
2 parents 76e8954 + 9792502 commit e68c0c7

File tree

7 files changed

+74
-13
lines changed

7 files changed

+74
-13
lines changed

.travis.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ matrix:
1414
- rust: stable
1515
env:
1616
- FEATURES='array-sizes-33-128 array-sizes-129-255'
17+
- ARRAYVECTEST_ENSURE_MAYBEUNINIT=1
1718
- rust: beta
1819
- rust: nightly
1920
env:
@@ -29,6 +30,7 @@ matrix:
2930
- rust: nightly
3031
env:
3132
- FEATURES='array-sizes-33-128 array-sizes-129-255'
33+
- ARRAYVECTEST_ENSURE_MAYBEUNINIT=1
3234
branches:
3335
only:
3436
- master

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "arrayvec"
3-
version = "0.4.10"
3+
version = "0.4.11"
44
authors = ["bluss"]
55
license = "MIT/Apache-2.0"
66

README.rst

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,13 @@ __ https://docs.rs/arrayvec
2222
Recent Changes (arrayvec)
2323
-------------------------
2424

25+
- 0.4.11
26+
27+
- In Rust 1.36 or later, use newly stable MaybeUninit. This extends the
28+
soundness work introduced in 0.4.9, we are finally able to use this in
29+
stable. We use feature detection (build script) to enable this at build
30+
time.
31+
2532
- 0.4.10
2633

2734
- Use ``repr(C)`` in the ``union`` version that was introduced in 0.4.9, to

build.rs

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,17 +11,28 @@ fn main() {
1111
}
1212

1313
fn detect_maybe_uninit() {
14+
let has_stable_maybe_uninit = probe(&stable_maybe_uninit());
15+
if has_stable_maybe_uninit {
16+
println!("cargo:rustc-cfg=has_stable_maybe_uninit");
17+
return;
18+
}
1419
let has_unstable_union_with_md = probe(&maybe_uninit_code(true));
1520
if has_unstable_union_with_md {
1621
println!("cargo:rustc-cfg=has_manually_drop_in_union");
1722
println!("cargo:rustc-cfg=has_union_feature");
18-
return;
1923
}
24+
}
2025

21-
let has_stable_union_with_md = probe(&maybe_uninit_code(false));
22-
if has_stable_union_with_md {
23-
println!("cargo:rustc-cfg=has_manually_drop_in_union");
24-
}
26+
// To guard against changes in this currently unstable feature, use
27+
// a detection tests instead of a Rustc version and/or date test.
28+
fn stable_maybe_uninit() -> String {
29+
let code = "
30+
#![allow(warnings)]
31+
use std::mem::MaybeUninit;
32+
33+
fn main() { }
34+
";
35+
code.to_string()
2536
}
2637

2738
// To guard against changes in this currently unstable feature, use

src/lib.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,9 +50,12 @@ use std::fmt;
5050
use std::io;
5151

5252

53-
#[cfg(has_manually_drop_in_union)]
53+
#[cfg(has_stable_maybe_uninit)]
54+
#[path="maybe_uninit_stable.rs"]
5455
mod maybe_uninit;
55-
#[cfg(not(has_manually_drop_in_union))]
56+
#[cfg(all(not(has_stable_maybe_uninit), has_manually_drop_in_union))]
57+
mod maybe_uninit;
58+
#[cfg(all(not(has_stable_maybe_uninit), not(has_manually_drop_in_union)))]
5659
#[path="maybe_uninit_nodrop.rs"]
5760
mod maybe_uninit;
5861

src/maybe_uninit_stable.rs

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
2+
3+
use array::Array;
4+
use std::mem::MaybeUninit as StdMaybeUninit;
5+
6+
pub struct MaybeUninit<T> {
7+
inner: StdMaybeUninit<T>,
8+
}
9+
10+
impl<T> MaybeUninit<T> {
11+
/// Create a new MaybeUninit with uninitialized interior
12+
pub unsafe fn uninitialized() -> Self {
13+
MaybeUninit { inner: StdMaybeUninit::uninit() }
14+
}
15+
16+
/// Create a new MaybeUninit from the value `v`.
17+
pub fn from(v: T) -> Self {
18+
MaybeUninit { inner: StdMaybeUninit::new(v) }
19+
}
20+
21+
// Raw pointer casts written so that we don't reference or access the
22+
// uninitialized interior value
23+
24+
/// Return a raw pointer to the start of the interior array
25+
pub fn ptr(&self) -> *const T::Item
26+
where T: Array
27+
{
28+
// std MaybeUninit creates a &self.value reference here which is
29+
// not guaranteed to be sound in our case - we will partially
30+
// initialize the value, not always wholly.
31+
self.inner.as_ptr() as *const T::Item
32+
}
33+
34+
/// Return a mut raw pointer to the start of the interior array
35+
pub fn ptr_mut(&mut self) -> *mut T::Item
36+
where T: Array
37+
{
38+
self.inner.as_mut_ptr() as *mut T::Item
39+
}
40+
}

tests/tests.rs

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -635,10 +635,8 @@ fn test_sizes_129_255() {
635635

636636

637637
#[test]
638-
fn test_nightly_uses_maybe_uninit() {
639-
if option_env!("ARRAYVECTEST_ENSURE_UNION").map(|s| !s.is_empty()).unwrap_or(false) {
640-
assert!(cfg!(has_manually_drop_in_union));
641-
type ByteArray = ArrayVec<[u8; 4]>;
642-
assert!(mem::size_of::<ByteArray>() == 5);
638+
fn test_newish_stable_uses_maybe_uninit() {
639+
if option_env!("ARRAYVECTEST_ENSURE_MAYBEUNINIT").map(|s| !s.is_empty()).unwrap_or(false) {
640+
assert!(cfg!(has_stable_maybe_uninit));
643641
}
644642
}

0 commit comments

Comments
 (0)