Skip to content

Commit 8ddc585

Browse files
uefi-macros: Drop !Send and !Sync from unsafe_protocol macro
Protocols can only be used while boot services are active, and that's already a single-threaded environment [1], so these negative traits do not have any effect. (Note that many protocols will still be automatically `!Send`/`!Sync` due to containing raw pointers.) In addition, there's nothing particularly special about protocols; we have lots of structs that are intended for use during boot services and can't be safely shared between threads. There are no threads to worry about in the UEFI environment though, so none of them need to be explictly marked `!Send`/`!Sync`. [1]: https://github.com/rust-lang/rust/blob/4f87a63edcef5c8c06229ff13e0f64f427537378/compiler/rustc_target/src/spec/uefi_msvc_base.rs#L47
1 parent 9777fd4 commit 8ddc585

File tree

3 files changed

+17
-25
lines changed

3 files changed

+17
-25
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@
3333

3434
## uefi-macros - [Unreleased]
3535

36+
- The `unsafe_protocol` struct no longer makes protocols `!Send` and
37+
`!Sync`. Protocols can only be used while boot services are active, and that's
38+
already a single-threaded environment, so these negative traits do not have
39+
any effect.
40+
3641
## uefi-services - [Unreleased]
3742

3843
## uefi - 0.20.0 (2023-03-19)

uefi-macros/src/lib.rs

Lines changed: 10 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use proc_macro2::{TokenStream as TokenStream2, TokenTree};
88
use quote::{quote, quote_spanned, ToTokens, TokenStreamExt};
99
use syn::spanned::Spanned;
1010
use syn::{
11-
parse_macro_input, parse_quote, Error, Fields, FnArg, Ident, ItemFn, ItemStruct, LitStr, Pat,
11+
parse_macro_input, parse_quote, Error, FnArg, Ident, ItemFn, ItemStruct, LitStr, Pat,
1212
Visibility,
1313
};
1414

@@ -25,11 +25,9 @@ macro_rules! err {
2525
///
2626
/// The macro takes one argument, a GUID string.
2727
///
28-
/// The macro can only be applied to a struct, and the struct must have
29-
/// named fields (i.e. not a unit or tuple struct). It implements the
28+
/// The macro can only be applied to a struct. It implements the
3029
/// [`Protocol`] trait and the `unsafe` [`Identify`] trait for the
31-
/// struct. It also adds a hidden field that causes the struct to be
32-
/// marked as [`!Send` and `!Sync`][send-and-sync].
30+
/// struct.
3331
///
3432
/// # Safety
3533
///
@@ -64,25 +62,16 @@ pub fn unsafe_protocol(args: TokenStream, input: TokenStream) -> TokenStream {
6462
let item_struct = parse_macro_input!(input as ItemStruct);
6563

6664
let ident = &item_struct.ident;
67-
let struct_attrs = &item_struct.attrs;
68-
let struct_vis = &item_struct.vis;
69-
let struct_fields = if let Fields::Named(struct_fields) = &item_struct.fields {
70-
&struct_fields.named
71-
} else {
72-
return err!(item_struct, "Protocol struct must used named fields").into();
73-
};
74-
let struct_generics = &item_struct.generics;
7565
let (impl_generics, ty_generics, where_clause) = item_struct.generics.split_for_impl();
7666

7767
quote! {
78-
#(#struct_attrs)*
79-
#struct_vis struct #ident #struct_generics {
80-
// Add a hidden field with `PhantomData` of a raw
81-
// pointer. This has the implicit side effect of making the
82-
// struct !Send and !Sync.
83-
_no_send_or_sync: ::core::marker::PhantomData<*const u8>,
84-
#struct_fields
85-
}
68+
// Disable this lint for now. It doesn't account for the fact that
69+
// currently it doesn't work to `derive(Debug)` on structs that have
70+
// `extern "efiapi" fn` fields, which most protocol structs have. The
71+
// derive _does_ work in current nightly (1.70.0) though, so hopefully
72+
// in a couple Rust releases we can drop this.
73+
#[allow(missing_debug_implementations)]
74+
#item_struct
8675

8776
unsafe impl #impl_generics ::uefi::Identify for #ident #ty_generics #where_clause {
8877
const GUID: ::uefi::Guid = ::uefi::Guid::from_values(

uefi/src/proto/mod.rs

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,8 @@ use core::ffi::c_void;
1414

1515
/// Common trait implemented by all standard UEFI protocols.
1616
///
17-
/// According to the UEFI's specification, protocols are `!Send` (they expect to
18-
/// be run on the bootstrap processor) and `!Sync` (they are not thread-safe).
19-
/// You can derive the `Protocol` trait, add these bounds, and specify the
20-
/// protocol's GUID using the [`unsafe_protocol`] macro.
17+
/// You can derive the `Protocol` trait and specify the protocol's GUID using
18+
/// the [`unsafe_protocol`] macro.
2119
///
2220
/// # Example
2321
///

0 commit comments

Comments
 (0)