Skip to content

Commit

Permalink
Stabilize const_option
Browse files Browse the repository at this point in the history
This makes the following API stable in const contexts:

    impl<T> Option<T> {
        pub const fn as_mut(&mut self) -> Option<&mut T>;
        pub const fn expect(self, msg: &str) -> T;
        pub const fn unwrap(self) -> T;
        pub const unsafe fn unwrap_unchecked(self) -> T;
        pub const fn take(&mut self) -> Option<T>;
        pub const fn replace(&mut self, value: T) -> Option<T>;
    }

    impl<T> Option<&T> {
        pub const fn copied(self) -> Option<T>
        where T: Copy;
    }

    impl<T> Option<&mut T> {
        pub const fn copied(self) -> Option<T>
        where T: Copy;
    }

    impl<T, E> Option<Result<T, E>> {
        pub const fn transpose(self) -> Result<Option<T>, E>
    }

    impl<T> Option<Option<T>> {
        pub const fn flatten(self) -> Option<T>;
    }

The following functions make use of the unstable
`const_precise_live_drops` feature:

- `expect`
- `unwrap`
- `unwrap_unchecked`
- `transpose`
- `flatten`

Fixes: <rust-lang#67441>
  • Loading branch information
tgross35 committed Oct 1, 2024
1 parent 8dd5cd0 commit 5af32ad
Show file tree
Hide file tree
Showing 14 changed files with 39 additions and 29 deletions.
1 change: 0 additions & 1 deletion compiler/rustc_middle/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,6 @@
#![feature(box_as_ptr)]
#![feature(box_patterns)]
#![feature(closure_track_caller)]
#![feature(const_option)]
#![feature(const_type_name)]
#![feature(core_intrinsics)]
#![feature(coroutines)]
Expand Down
1 change: 0 additions & 1 deletion compiler/rustc_serialize/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
test(attr(allow(unused_variables), deny(warnings)))
)]
#![doc(rust_logo)]
#![feature(const_option)]
#![feature(core_intrinsics)]
#![feature(min_specialization)]
#![feature(never_type)]
Expand Down
1 change: 0 additions & 1 deletion library/alloc/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -112,7 +112,6 @@
#![feature(const_eval_select)]
#![feature(const_heap)]
#![feature(const_maybe_uninit_write)]
#![feature(const_option)]
#![feature(const_pin)]
#![feature(const_size_of_val)]
#![feature(core_intrinsics)]
Expand Down
1 change: 0 additions & 1 deletion library/core/src/array/ascii.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ impl<const N: usize> [u8; N] {
///
/// ```
/// #![feature(ascii_char)]
/// #![feature(const_option)]
///
/// const HEX_DIGITS: [std::ascii::Char; 16] =
/// *b"0123456789abcdef".as_ascii().unwrap();
Expand Down
1 change: 0 additions & 1 deletion library/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,7 +135,6 @@
#![feature(const_maybe_uninit_assume_init)]
#![feature(const_nonnull_new)]
#![feature(const_num_midpoint)]
#![feature(const_option)]
#![feature(const_option_ext)]
#![feature(const_pin)]
#![feature(const_pointer_is_aligned)]
Expand Down
32 changes: 21 additions & 11 deletions library/core/src/option.rs
Original file line number Diff line number Diff line change
Expand Up @@ -723,7 +723,8 @@ impl<T> Option<T> {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_option", issue = "67441")]
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))]
#[rustc_const_stable(feature = "const_option", since = "CURRENT_RUSTC_VERSION")]
pub const fn as_mut(&mut self) -> Option<&mut T> {
match *self {
Some(ref mut x) => Some(x),
Expand Down Expand Up @@ -924,7 +925,8 @@ impl<T> Option<T> {
#[track_caller]
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "option_expect")]
#[rustc_const_unstable(feature = "const_option", issue = "67441")]
#[rustc_allow_const_fn_unstable(const_precise_live_drops)]
#[rustc_const_stable(feature = "const_option", since = "CURRENT_RUSTC_VERSION")]
pub const fn expect(self, msg: &str) -> T {
match self {
Some(val) => val,
Expand Down Expand Up @@ -962,7 +964,8 @@ impl<T> Option<T> {
#[track_caller]
#[stable(feature = "rust1", since = "1.0.0")]
#[cfg_attr(not(test), rustc_diagnostic_item = "option_unwrap")]
#[rustc_const_unstable(feature = "const_option", issue = "67441")]
#[rustc_allow_const_fn_unstable(const_precise_live_drops)]
#[rustc_const_stable(feature = "const_option", since = "CURRENT_RUSTC_VERSION")]
pub const fn unwrap(self) -> T {
match self {
Some(val) => val,
Expand Down Expand Up @@ -1069,7 +1072,8 @@ impl<T> Option<T> {
#[inline]
#[track_caller]
#[stable(feature = "option_result_unwrap_unchecked", since = "1.58.0")]
#[rustc_const_unstable(feature = "const_option", issue = "67441")]
#[rustc_allow_const_fn_unstable(const_precise_live_drops)]
#[rustc_const_stable(feature = "const_option", since = "CURRENT_RUSTC_VERSION")]
pub const unsafe fn unwrap_unchecked(self) -> T {
match self {
Some(val) => val,
Expand Down Expand Up @@ -1712,7 +1716,9 @@ impl<T> Option<T> {
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
#[rustc_const_unstable(feature = "const_option", issue = "67441")]
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))]
#[rustc_allow_const_fn_unstable(const_replace)] // todo: drop if we don't get stable const_replace
#[rustc_const_stable(feature = "const_option", since = "CURRENT_RUSTC_VERSION")]
pub const fn take(&mut self) -> Option<T> {
// FIXME(const-hack) replace `mem::replace` by `mem::take` when the latter is const ready
mem::replace(self, None)
Expand Down Expand Up @@ -1769,8 +1775,10 @@ impl<T> Option<T> {
/// assert_eq!(old, None);
/// ```
#[inline]
#[rustc_const_unstable(feature = "const_option", issue = "67441")]
#[stable(feature = "option_replace", since = "1.31.0")]
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))]
#[rustc_allow_const_fn_unstable(const_replace)] // todo: drop if we don't get stable const_replace
#[rustc_const_stable(feature = "const_option", since = "CURRENT_RUSTC_VERSION")]
pub const fn replace(&mut self, value: T) -> Option<T> {
mem::replace(self, Some(value))
}
Expand Down Expand Up @@ -1878,7 +1886,7 @@ impl<T> Option<&T> {
/// ```
#[must_use = "`self` will be dropped if the result is not used"]
#[stable(feature = "copied", since = "1.35.0")]
#[rustc_const_unstable(feature = "const_option", issue = "67441")]
#[rustc_const_stable(feature = "const_option", since = "CURRENT_RUSTC_VERSION")]
pub const fn copied(self) -> Option<T>
where
T: Copy,
Expand Down Expand Up @@ -1931,7 +1939,8 @@ impl<T> Option<&mut T> {
/// ```
#[must_use = "`self` will be dropped if the result is not used"]
#[stable(feature = "copied", since = "1.35.0")]
#[rustc_const_unstable(feature = "const_option", issue = "67441")]
#[cfg_attr(bootstrap, rustc_allow_const_fn_unstable(const_mut_refs))]
#[rustc_const_stable(feature = "const_option", since = "CURRENT_RUSTC_VERSION")]
pub const fn copied(self) -> Option<T>
where
T: Copy,
Expand Down Expand Up @@ -1986,7 +1995,8 @@ impl<T, E> Option<Result<T, E>> {
/// ```
#[inline]
#[stable(feature = "transpose_result", since = "1.33.0")]
#[rustc_const_unstable(feature = "const_option", issue = "67441")]
#[rustc_allow_const_fn_unstable(const_precise_live_drops)]
#[rustc_const_stable(feature = "const_option", since = "CURRENT_RUSTC_VERSION")]
pub const fn transpose(self) -> Result<Option<T>, E> {
match self {
Some(Ok(x)) => Ok(Some(x)),
Expand All @@ -2009,7 +2019,6 @@ const fn unwrap_failed() -> ! {
#[cfg_attr(feature = "panic_immediate_abort", inline)]
#[cold]
#[track_caller]
#[rustc_const_unstable(feature = "const_option", issue = "67441")]
const fn expect_failed(msg: &str) -> ! {
panic_display(&msg)
}
Expand Down Expand Up @@ -2534,7 +2543,8 @@ impl<T> Option<Option<T>> {
/// ```
#[inline]
#[stable(feature = "option_flattening", since = "1.40.0")]
#[rustc_const_unstable(feature = "const_option", issue = "67441")]
#[rustc_allow_const_fn_unstable(const_precise_live_drops)]
#[rustc_const_stable(feature = "const_option", since = "CURRENT_RUSTC_VERSION")]
pub const fn flatten(self) -> Option<T> {
// FIXME(const-hack): could be written with `and_then`
match self {
Expand Down
2 changes: 0 additions & 2 deletions library/core/src/ptr/non_null.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1210,7 +1210,6 @@ impl<T: ?Sized> NonNull<T> {
///
/// ```
/// #![feature(const_nonnull_new)]
/// #![feature(const_option)]
/// #![feature(const_pointer_is_aligned)]
/// use std::ptr::NonNull;
///
Expand Down Expand Up @@ -1263,7 +1262,6 @@ impl<T: ?Sized> NonNull<T> {
///
/// ```
/// #![feature(const_pointer_is_aligned)]
/// #![feature(const_option)]
/// #![feature(const_nonnull_new)]
/// use std::ptr::NonNull;
///
Expand Down
1 change: 0 additions & 1 deletion library/core/src/time.rs
Original file line number Diff line number Diff line change
Expand Up @@ -626,7 +626,6 @@ impl Duration {
/// ```
#[stable(feature = "duration_abs_diff", since = "1.81.0")]
#[rustc_const_stable(feature = "duration_abs_diff", since = "1.81.0")]
#[rustc_allow_const_fn_unstable(const_option)]
#[must_use = "this returns the result of the operation, \
without modifying the original"]
#[inline]
Expand Down
1 change: 0 additions & 1 deletion library/core/tests/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,6 @@
#![feature(const_ipv6)]
#![feature(const_likely)]
#![feature(const_nonnull_new)]
#![feature(const_option)]
#![feature(const_option_ext)]
#![feature(const_pin)]
#![feature(const_pointer_is_aligned)]
Expand Down
2 changes: 1 addition & 1 deletion src/tools/clippy/tests/ui/doc/doc-fixable.fixed
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#![allow(dead_code, incomplete_features)]
#![warn(clippy::doc_markdown)]
#![feature(custom_inner_attributes, generic_const_exprs, const_option)]
#![feature(custom_inner_attributes, generic_const_exprs)]
#![rustfmt::skip]

/// The `foo_bar` function does _nothing_. See also `foo::bar`. (note the dot there)
Expand Down
2 changes: 1 addition & 1 deletion src/tools/clippy/tests/ui/doc/doc-fixable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
#![allow(dead_code, incomplete_features)]
#![warn(clippy::doc_markdown)]
#![feature(custom_inner_attributes, generic_const_exprs, const_option)]
#![feature(custom_inner_attributes, generic_const_exprs)]
#![rustfmt::skip]

/// The foo_bar function does _nothing_. See also foo::bar. (note the dot there)
Expand Down
1 change: 0 additions & 1 deletion src/tools/miri/src/lib.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
#![feature(rustc_private)]
#![feature(cell_update)]
#![feature(const_option)]
#![feature(float_gamma)]
#![feature(map_try_insert)]
#![feature(never_type)]
Expand Down
10 changes: 7 additions & 3 deletions tests/ui/consts/const-unwrap.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,15 @@
//@ check-fail

#![feature(const_option)]
// Verify that panicking `const_option` methods do the correct thing

const FOO: i32 = Some(42i32).unwrap();

const BAR: i32 = Option::<i32>::None.unwrap();
//~^ERROR: evaluation of constant value failed
//~^ ERROR: evaluation of constant value failed
//~| NOTE: the evaluated program panicked

const BAZ: i32 = Option::<i32>::None.expect("absolutely not!");
//~^ ERROR: evaluation of constant value failed
//~| NOTE: absolutely not!

fn main() {
println!("{}", FOO);
Expand Down
12 changes: 9 additions & 3 deletions tests/ui/consts/const-unwrap.stderr
Original file line number Diff line number Diff line change
@@ -1,9 +1,15 @@
error[E0080]: evaluation of constant value failed
--> $DIR/const-unwrap.rs:7:18
--> $DIR/const-unwrap.rs:6:18
|
LL | const BAR: i32 = Option::<i32>::None.unwrap();
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'called `Option::unwrap()` on a `None` value', $DIR/const-unwrap.rs:7:38
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'called `Option::unwrap()` on a `None` value', $DIR/const-unwrap.rs:6:38

error: aborting due to 1 previous error
error[E0080]: evaluation of constant value failed
--> $DIR/const-unwrap.rs:10:18
|
LL | const BAZ: i32 = Option::<i32>::None.expect("absolutely not!");
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the evaluated program panicked at 'absolutely not!', $DIR/const-unwrap.rs:10:38

error: aborting due to 2 previous errors

For more information about this error, try `rustc --explain E0080`.

0 comments on commit 5af32ad

Please sign in to comment.