Skip to content

Commit

Permalink
Gate use of unstable try_trait_v2 feature
Browse files Browse the repository at this point in the history
Add a new enabled-by-default `unstable_try_trait` feature to the `uefi`
library to control whether the unstable `try_trait_v2` rustc feature is
enabled.

It seems like there's still a fair amount of discussion around what the
Try API should look like in the tracking issue for try_trait_v2. This
could lead to the API being changed in the nightly compiler, and
breaking uefi-rs compilation (which is particularly annoying when using
a released version rather than the latest git version). Users who want
to avoid that problem can now disable `unstable_try_trait`.

rust-osdev#452
  • Loading branch information
nicholasbishop committed Aug 16, 2022
1 parent bfa88e1 commit 9659a59
Show file tree
Hide file tree
Showing 6 changed files with 28 additions and 7 deletions.
3 changes: 3 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
6 changes: 5 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -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 = []
Expand Down
2 changes: 1 addition & 1 deletion src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand Down
6 changes: 3 additions & 3 deletions src/proto/shim/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -108,14 +108,14 @@ impl ShimLock {
.map_err(|_| Error::from(Status::BAD_BUFFER_SIZE))?;

let mut context = MaybeUninit::<Context>::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()
}
}
9 changes: 8 additions & 1 deletion src/result/status.rs
Original file line number Diff line number Diff line change
@@ -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::<usize>() * 8 - 1);
Expand Down Expand Up @@ -172,8 +174,10 @@ impl From<Status> 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;
Expand All @@ -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<T> FromResidual<StatusResidual> for Result<T, ()> {
fn from_residual(r: StatusResidual) -> Self {
Err(Status(r.0.into()).into())
}
}

#[cfg(feature = "unstable_try_trait")]
impl FromResidual<core::result::Result<Infallible, Error>> for Status {
fn from_residual(r: core::result::Result<Infallible, Error>) -> Self {
match r {
Expand Down
9 changes: 8 additions & 1 deletion xtask/src/cargo.rs
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ pub enum Feature {
Alloc,
Exts,
Logger,
UnstableTryTrait,

Ci,
Qemu,
Expand All @@ -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",
Expand All @@ -67,7 +69,12 @@ impl Feature {

/// Set of features that enables more code in the root uefi crate.
pub fn more_code() -> Vec<Self> {
vec![Self::Alloc, Self::Exts, Self::Logger]
vec![
Self::Alloc,
Self::Exts,
Self::Logger,
Self::UnstableTryTrait,
]
}

fn comma_separated_string(features: &[Feature]) -> String {
Expand Down

0 comments on commit 9659a59

Please sign in to comment.