From fc2c1f8ddc9a460c558741ae44b894faf3967f7c Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Thu, 30 Jul 2020 12:30:56 -0700 Subject: [PATCH 1/2] Make `Option::unwrap` unstably const `Result::unwrap` is not eligible becuase it formats the contents of the `Err` variant. `unwrap_or`, `unwrap_or_else` and friends are not eligible because they drop things or invoke closures. --- library/core/src/lib.rs | 1 + library/core/src/option.rs | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 550e07f9d5710..46a6ec09962bc 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -82,6 +82,7 @@ #![feature(const_fn_union)] #![feature(const_generics)] #![feature(const_option)] +#![feature(const_precise_live_drops)] #![feature(const_ptr_offset)] #![feature(const_ptr_offset_from)] #![feature(const_raw_ptr_comparison)] diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 5932f8e5856a7..3c7211fe040dc 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -380,7 +380,8 @@ impl Option { #[inline] #[track_caller] #[stable(feature = "rust1", since = "1.0.0")] - pub fn unwrap(self) -> T { + #[rustc_const_unstable(feature = "const_option", issue = "67441")] + pub const fn unwrap(self) -> T { match self { Some(val) => val, None => panic!("called `Option::unwrap()` on a `None` value"), From 96c84ac3cbc4f2c81580893dacf263d00306649c Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Thu, 30 Jul 2020 12:32:20 -0700 Subject: [PATCH 2/2] Test `Option::unwrap` in a const context --- src/test/ui/consts/const-unwrap.rs | 14 ++++++++++++++ src/test/ui/consts/const-unwrap.stderr | 20 ++++++++++++++++++++ 2 files changed, 34 insertions(+) create mode 100644 src/test/ui/consts/const-unwrap.rs create mode 100644 src/test/ui/consts/const-unwrap.stderr diff --git a/src/test/ui/consts/const-unwrap.rs b/src/test/ui/consts/const-unwrap.rs new file mode 100644 index 0000000000000..6ed60ed87bf76 --- /dev/null +++ b/src/test/ui/consts/const-unwrap.rs @@ -0,0 +1,14 @@ +// check-fail + +#![feature(const_option)] + +const FOO: i32 = Some(42i32).unwrap(); + +// This causes an error, but it is attributed to the `panic` *inside* `Option::unwrap` (maybe due +// to `track_caller`?). A note points to the originating `const`. +const BAR: i32 = Option::::None.unwrap(); //~ NOTE + +fn main() { + println!("{}", FOO); + println!("{}", BAR); +} diff --git a/src/test/ui/consts/const-unwrap.stderr b/src/test/ui/consts/const-unwrap.stderr new file mode 100644 index 0000000000000..7f2c1f4151097 --- /dev/null +++ b/src/test/ui/consts/const-unwrap.stderr @@ -0,0 +1,20 @@ +error: any use of this value will cause an error + --> $SRC_DIR/core/src/option.rs:LL:COL + | +LL | None => panic!("called `Option::unwrap()` on a `None` value"), + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | the evaluated program panicked at 'called `Option::unwrap()` on a `None` value', $DIR/const-unwrap.rs:9:38 + | inside `std::option::Option::::unwrap` at $SRC_DIR/core/src/macros/mod.rs:LL:COL + | inside `BAR` at $DIR/const-unwrap.rs:9:18 + | + ::: $DIR/const-unwrap.rs:9:1 + | +LL | const BAR: i32 = Option::::None.unwrap(); + | ---------------------------------------------- + | + = note: `#[deny(const_err)]` on by default + = note: this error originates in a macro (in Nightly builds, run with -Z macro-backtrace for more info) + +error: aborting due to previous error +