about summary refs log tree commit diff
diff options
context:
space:
mode:
authorTrevor Gross <tmgross@umich.edu>2024-10-01 17:11:48 -0400
committerTrevor Gross <tmgross@umich.edu>2024-10-12 17:07:13 -0400
commit19f6c17df486c5f70c1000ecada39c62b9c93550 (patch)
tree326ea966597781d18a42c85e1851eed464cba193
parent6b9676b45431a1e531b9c5f7bd289fc36a312749 (diff)
downloadrust-19f6c17df486c5f70c1000ecada39c62b9c93550.tar.gz
rust-19f6c17df486c5f70c1000ecada39c62b9c93550.zip
Stabilize `const_option`
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: <https://github.com/rust-lang/rust/issues/67441>
-rw-r--r--compiler/rustc_middle/src/lib.rs1
-rw-r--r--compiler/rustc_serialize/src/lib.rs1
-rw-r--r--library/alloc/src/lib.rs1
-rw-r--r--library/core/src/array/ascii.rs1
-rw-r--r--library/core/src/lib.rs1
-rw-r--r--library/core/src/option.rs30
-rw-r--r--library/core/src/ptr/non_null.rs2
-rw-r--r--library/core/src/time.rs1
-rw-r--r--library/core/tests/lib.rs1
-rw-r--r--src/tools/clippy/tests/ui/doc/doc-fixable.fixed2
-rw-r--r--src/tools/clippy/tests/ui/doc/doc-fixable.rs2
-rw-r--r--src/tools/miri/src/lib.rs1
-rw-r--r--tests/ui/consts/const-unwrap.rs10
-rw-r--r--tests/ui/consts/const-unwrap.stderr12
14 files changed, 37 insertions, 29 deletions
diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs
index 70e61df1ab4..e9b73d25ba2 100644
--- a/compiler/rustc_middle/src/lib.rs
+++ b/compiler/rustc_middle/src/lib.rs
@@ -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)]
diff --git a/compiler/rustc_serialize/src/lib.rs b/compiler/rustc_serialize/src/lib.rs
index b7977a848ce..47f72298e22 100644
--- a/compiler/rustc_serialize/src/lib.rs
+++ b/compiler/rustc_serialize/src/lib.rs
@@ -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)]
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index 1d7b7a03454..ec6ffa7a105 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -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(const_vec_string_slice)]
diff --git a/library/core/src/array/ascii.rs b/library/core/src/array/ascii.rs
index 05797b042ee..e2faef855bc 100644
--- a/library/core/src/array/ascii.rs
+++ b/library/core/src/array/ascii.rs
@@ -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();
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 61fe024300e..726aa209fdf 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -131,7 +131,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)]
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index 154e52e288b..84ccb7a1f66 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -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),
@@ -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,
@@ -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,
@@ -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,
@@ -1712,7 +1716,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 take(&mut self) -> Option<T> {
         // FIXME(const-hack) replace `mem::replace` by `mem::take` when the latter is const ready
         mem::replace(self, None)
@@ -1769,8 +1774,9 @@ 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_const_stable(feature = "const_option", since = "CURRENT_RUSTC_VERSION")]
     pub const fn replace(&mut self, value: T) -> Option<T> {
         mem::replace(self, Some(value))
     }
@@ -1878,7 +1884,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,
@@ -1931,7 +1937,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,
@@ -1986,7 +1993,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)),
@@ -2009,7 +2017,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)
 }
@@ -2534,7 +2541,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 {
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index dc1a7c6220e..980d4a3cf6c 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -1211,7 +1211,6 @@ impl<T: ?Sized> NonNull<T> {
     ///
     /// ```
     /// #![feature(const_nonnull_new)]
-    /// #![feature(const_option)]
     /// #![feature(const_pointer_is_aligned)]
     /// use std::ptr::NonNull;
     ///
@@ -1264,7 +1263,6 @@ impl<T: ?Sized> NonNull<T> {
     ///
     /// ```
     /// #![feature(const_pointer_is_aligned)]
-    /// #![feature(const_option)]
     /// #![feature(const_nonnull_new)]
     /// use std::ptr::NonNull;
     ///
diff --git a/library/core/src/time.rs b/library/core/src/time.rs
index a997874dd9c..f7ea7e06e9c 100644
--- a/library/core/src/time.rs
+++ b/library/core/src/time.rs
@@ -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]
diff --git a/library/core/tests/lib.rs b/library/core/tests/lib.rs
index 02777886b45..9e15bb1dd8f 100644
--- a/library/core/tests/lib.rs
+++ b/library/core/tests/lib.rs
@@ -24,7 +24,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)]
diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.fixed b/src/tools/clippy/tests/ui/doc/doc-fixable.fixed
index edfffe8fcfe..355f2bc7736 100644
--- a/src/tools/clippy/tests/ui/doc/doc-fixable.fixed
+++ b/src/tools/clippy/tests/ui/doc/doc-fixable.fixed
@@ -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)
diff --git a/src/tools/clippy/tests/ui/doc/doc-fixable.rs b/src/tools/clippy/tests/ui/doc/doc-fixable.rs
index 3c0f6913e32..9ced2677622 100644
--- a/src/tools/clippy/tests/ui/doc/doc-fixable.rs
+++ b/src/tools/clippy/tests/ui/doc/doc-fixable.rs
@@ -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)
diff --git a/src/tools/miri/src/lib.rs b/src/tools/miri/src/lib.rs
index 330147c8f1c..f089d1e1bcc 100644
--- a/src/tools/miri/src/lib.rs
+++ b/src/tools/miri/src/lib.rs
@@ -1,6 +1,5 @@
 #![feature(rustc_private)]
 #![feature(cell_update)]
-#![feature(const_option)]
 #![feature(float_gamma)]
 #![feature(map_try_insert)]
 #![feature(never_type)]
diff --git a/tests/ui/consts/const-unwrap.rs b/tests/ui/consts/const-unwrap.rs
index bc79c7db2fc..ea0a15af1be 100644
--- a/tests/ui/consts/const-unwrap.rs
+++ b/tests/ui/consts/const-unwrap.rs
@@ -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);
diff --git a/tests/ui/consts/const-unwrap.stderr b/tests/ui/consts/const-unwrap.stderr
index fee22a1d070..aa5dd9a5c36 100644
--- a/tests/ui/consts/const-unwrap.stderr
+++ b/tests/ui/consts/const-unwrap.stderr
@@ -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`.