Rollup merge of #42959 - SimonSapin:nonzero-checked, r=sfackler

Make the "main" constructors of NonZero/Shared/Unique return Option

Per discussion in https://github.com/rust-lang/rust/issues/27730#issuecomment-303939441.

This is a breaking change to unstable APIs.

The old behavior is still available under the name `new_unchecked`. Note that only that one can be `const fn`, since `if` is currently not allowed in constant contexts.

In the case of `NonZero` this requires adding a new `is_zero` method to the `Zeroable` trait. I mildly dislike this, but it’s not much worse than having a `Zeroable` trait in the first place. `Zeroable` and `NonZero` are both unstable, this can be reworked later.
This commit is contained in:
Mark Simulacrum 2017-07-26 06:15:01 -06:00 committed by GitHub
commit b5b7266b78
21 changed files with 218 additions and 86 deletions

View file

@ -42,7 +42,7 @@ impl Default for EmbeddedDiscr {
}
#[derive(Default)]
pub struct IndirectNonZero<T: Zeroable> {
pub struct IndirectNonZero<T: Zeroable + One> {
pre: u8,
nested: NestedNonZero<T>,
post: u16,
@ -54,14 +54,20 @@ pub struct NestedNonZero<T: Zeroable> {
post: u16,
}
impl<T: Zeroable+Default> Default for NestedNonZero<T> {
impl<T: Zeroable+One> Default for NestedNonZero<T> {
fn default() -> Self {
unsafe {
NestedNonZero { pre: 0, val: NonZero::new(Default::default()), post: 0 }
}
NestedNonZero { pre: 0, val: NonZero::new(T::one()).unwrap(), post: 0 }
}
}
pub trait One {
fn one() -> Self;
}
impl One for u32 {
fn one() -> Self { 1 }
}
pub fn main() {
let _x: MyOption<NonZero<u32>> = Default::default();
let _y: EmbeddedDiscr = Default::default();