Skip to main content

const_unwrap_9dfd7e7b6ae4d549987171c9f89a823d/
lib.rs

1// Copyright 2022 The Fuchsia Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5//! `const-unwrap` provides macros which can be used to unwrap [`Option`]s and
6//! [`Result`]s in a const context.
7
8#![no_std]
9
10/// Unwraps an [`Option`]'s [`Some`] variant, or panics.
11///
12/// `const_unwrap_option` is a `const fn`, and may be called in a const context.
13/// Note that, if called from a non-const context, `const_unwrap_option` will
14/// execute at runtime, not at compile time.
15// TODO(https://github.com/rust-lang/rust/issues/67441): Once `Option::unwrap`
16// is const-stable, remove this and migrate callers.
17pub const fn const_unwrap_option<T: Copy>(opt: Option<T>) -> T {
18    match opt {
19        Some(x) => x,
20        None => panic!("const_unwrap called on a `None` value"),
21    }
22}
23
24/// Unwraps a [`Result`]'s [`Ok`] variant, or panics.
25///
26/// `const_unwrap_result` is a `const fn`, and may be called in a const context.
27/// Note that, if called from a non-const context, `const_unwrap_result` will
28/// execute at runtime, not at compile time.
29// TODO(https://github.com/rust-lang/rust/issues/67441): Once `Option::unwrap`
30// is const-stable, remove this and migrate callers.
31pub const fn const_unwrap_result<T: Copy, E: Copy + core::fmt::Debug>(opt: Result<T, E>) -> T {
32    // Require `E: Debug` because `Result::unwrap` does, and we don't want to
33    // allow code to use `const_unwrap_result` which can't later be transitioned
34    // to `Result::unwrap` once it's const-stable.
35    //
36    // We can't include the error itself in the panic message because
37    // const-panicking only supports string literals, and does not support
38    // format string arguments. There does not appear to be a tracking issue for
39    // this, but the following links may be relevant:
40    // - https://doc.rust-lang.org/beta/unstable-book/library-features/const-format-args.html
41    // - https://doc.rust-lang.org/std/macro.const_format_args.html
42    match opt {
43        Ok(x) => x,
44        Err(_) => panic!("const_unwrap_result called on err `Err` value"),
45    }
46}
47
48const _UNWRAP_SOME: usize = const_unwrap_option(Some(0));
49const _UNWRAP_OK: usize = const_unwrap_result(Result::<_, bool>::Ok(0));
50
51// The following don't compile. Remove `#[cfg(ignore)]` and compile to verify.
52#[cfg(ignore)]
53mod dont_compile {
54    const _UNWRAP_NONE: usize = const_unwrap_option(None);
55    const _UNWRAP_ERR: usize = const_unwrap_result!(Err(0));
56}