diff --git a/CHANGELOG.md b/CHANGELOG.md index ba6df671e..c66941b8a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -23,6 +23,9 @@ - Deprecated `BootServices::locate_protocol` and marked it `unsafe`. Use `BootServices::get_handle_for_protocol` and `BootServices::open_protocol` instead. +- Use of the unstable `try_trait_v2` rustc feature (allowing `?` to be + used with `Status`) has been placed behind an optional + `unstable_try_trait` feature. This feature is enabled by default. ### Fixed diff --git a/Cargo.toml b/Cargo.toml index 03041e94a..f5a631b9c 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -19,10 +19,14 @@ categories = ["embedded", "no-std", "api-bindings"] license = "MPL-2.0" [features] -default = [] +default = ["unstable_try_trait"] alloc = [] exts = [] logger = [] +# If enabled, the unstable `try_trait_v2` feature +# (https://github.com/rust-lang/rust/issues/84277) is used to allow +# using `?` with `Status` values. +unstable_try_trait = [] # Ignore text output errors in logger as a workaround for firmware issues that # were observed on the VirtualBox UEFI implementation (see uefi-rs#121) ignore-logger-errors = [] diff --git a/src/lib.rs b/src/lib.rs index 4283c631c..935dc9bd3 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -23,12 +23,12 @@ //! For example, a PC with no network card might not contain a network driver, //! therefore all the network protocols will be unavailable. -#![feature(try_trait_v2)] #![feature(abi_efiapi)] #![feature(maybe_uninit_slice)] #![feature(negative_impls)] #![feature(ptr_metadata)] #![cfg_attr(feature = "exts", feature(vec_into_raw_parts))] +#![cfg_attr(feature = "unstable_try_trait", feature(try_trait_v2))] #![no_std] // Enable some additional warnings and lints. #![warn(clippy::ptr_as_ptr, missing_docs, unused)] diff --git a/src/proto/shim/mod.rs b/src/proto/shim/mod.rs index a7f0bc2d7..c2a52b604 100644 --- a/src/proto/shim/mod.rs +++ b/src/proto/shim/mod.rs @@ -108,14 +108,14 @@ impl ShimLock { .map_err(|_| Error::from(Status::BAD_BUFFER_SIZE))?; let mut context = MaybeUninit::::uninit(); - (self.context)(ptr, size, context.as_mut_ptr())?; + Result::from((self.context)(ptr, size, context.as_mut_ptr()))?; (self.hash)( ptr, size, context.as_mut_ptr(), &mut hashes.sha256, &mut hashes.sha1, - )?; - Ok(()) + ) + .into() } } diff --git a/src/result/status.rs b/src/result/status.rs index 45391e9c7..87a7f61e4 100644 --- a/src/result/status.rs +++ b/src/result/status.rs @@ -1,9 +1,11 @@ use super::{Error, Result}; +use core::fmt::Debug; +#[cfg(feature = "unstable_try_trait")] use core::{ convert::Infallible, + num::NonZeroUsize, ops::{ControlFlow, FromResidual, Try}, }; -use core::{fmt::Debug, num::NonZeroUsize}; /// Bit indicating that an UEFI status code is an error const ERROR_BIT: usize = 1 << (core::mem::size_of::() * 8 - 1); @@ -172,8 +174,10 @@ impl From for Result<(), ()> { } } +#[cfg(feature = "unstable_try_trait")] pub struct StatusResidual(NonZeroUsize); +#[cfg(feature = "unstable_try_trait")] impl Try for Status { type Output = (); type Residual = StatusResidual; @@ -190,18 +194,21 @@ impl Try for Status { } } +#[cfg(feature = "unstable_try_trait")] impl FromResidual for Status { fn from_residual(r: StatusResidual) -> Self { Status(r.0.into()) } } +#[cfg(feature = "unstable_try_trait")] impl FromResidual for Result { fn from_residual(r: StatusResidual) -> Self { Err(Status(r.0.into()).into()) } } +#[cfg(feature = "unstable_try_trait")] impl FromResidual> for Status { fn from_residual(r: core::result::Result) -> Self { match r { diff --git a/xtask/src/cargo.rs b/xtask/src/cargo.rs index 58f751459..1c10e8cf5 100644 --- a/xtask/src/cargo.rs +++ b/xtask/src/cargo.rs @@ -48,6 +48,7 @@ pub enum Feature { Alloc, Exts, Logger, + UnstableTryTrait, Ci, Qemu, @@ -59,6 +60,7 @@ impl Feature { Self::Alloc => "alloc", Self::Exts => "exts", Self::Logger => "logger", + Self::UnstableTryTrait => "unstable_try_trait", Self::Ci => "uefi-test-runner/ci", Self::Qemu => "uefi-test-runner/qemu", @@ -67,7 +69,12 @@ impl Feature { /// Set of features that enables more code in the root uefi crate. pub fn more_code() -> Vec { - vec![Self::Alloc, Self::Exts, Self::Logger] + vec![ + Self::Alloc, + Self::Exts, + Self::Logger, + Self::UnstableTryTrait, + ] } fn comma_separated_string(features: &[Feature]) -> String { @@ -219,7 +226,7 @@ mod tests { fn test_comma_separated_features() { assert_eq!( Feature::comma_separated_string(&Feature::more_code()), - "alloc,exts,logger" + "alloc,exts,logger,unstable_try_trait" ); }