From 8ddc58573d39ff4e8bf14fd9165554564ebcfed6 Mon Sep 17 00:00:00 2001 From: Nicholas Bishop Date: Sat, 8 Apr 2023 15:09:45 -0400 Subject: [PATCH] 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 --- CHANGELOG.md | 5 +++++ uefi-macros/src/lib.rs | 31 ++++++++++--------------------- uefi/src/proto/mod.rs | 6 ++---- 3 files changed, 17 insertions(+), 25 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a5568ac5a..5700dd9a2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -33,6 +33,11 @@ ## uefi-macros - [Unreleased] +- The `unsafe_protocol` struct no longer makes protocols `!Send` and + `!Sync`. Protocols can only be used while boot services are active, and that's + already a single-threaded environment, so these negative traits do not have + any effect. + ## uefi-services - [Unreleased] ## uefi - 0.20.0 (2023-03-19) diff --git a/uefi-macros/src/lib.rs b/uefi-macros/src/lib.rs index 07b91ecc5..6cc964f31 100644 --- a/uefi-macros/src/lib.rs +++ b/uefi-macros/src/lib.rs @@ -8,7 +8,7 @@ use proc_macro2::{TokenStream as TokenStream2, TokenTree}; use quote::{quote, quote_spanned, ToTokens, TokenStreamExt}; use syn::spanned::Spanned; use syn::{ - parse_macro_input, parse_quote, Error, Fields, FnArg, Ident, ItemFn, ItemStruct, LitStr, Pat, + parse_macro_input, parse_quote, Error, FnArg, Ident, ItemFn, ItemStruct, LitStr, Pat, Visibility, }; @@ -25,11 +25,9 @@ macro_rules! err { /// /// The macro takes one argument, a GUID string. /// -/// The macro can only be applied to a struct, and the struct must have -/// named fields (i.e. not a unit or tuple struct). It implements the +/// The macro can only be applied to a struct. It implements the /// [`Protocol`] trait and the `unsafe` [`Identify`] trait for the -/// struct. It also adds a hidden field that causes the struct to be -/// marked as [`!Send` and `!Sync`][send-and-sync]. +/// struct. /// /// # Safety /// @@ -64,25 +62,16 @@ pub fn unsafe_protocol(args: TokenStream, input: TokenStream) -> TokenStream { let item_struct = parse_macro_input!(input as ItemStruct); let ident = &item_struct.ident; - let struct_attrs = &item_struct.attrs; - let struct_vis = &item_struct.vis; - let struct_fields = if let Fields::Named(struct_fields) = &item_struct.fields { - &struct_fields.named - } else { - return err!(item_struct, "Protocol struct must used named fields").into(); - }; - let struct_generics = &item_struct.generics; let (impl_generics, ty_generics, where_clause) = item_struct.generics.split_for_impl(); quote! { - #(#struct_attrs)* - #struct_vis struct #ident #struct_generics { - // Add a hidden field with `PhantomData` of a raw - // pointer. This has the implicit side effect of making the - // struct !Send and !Sync. - _no_send_or_sync: ::core::marker::PhantomData<*const u8>, - #struct_fields - } + // Disable this lint for now. It doesn't account for the fact that + // currently it doesn't work to `derive(Debug)` on structs that have + // `extern "efiapi" fn` fields, which most protocol structs have. The + // derive _does_ work in current nightly (1.70.0) though, so hopefully + // in a couple Rust releases we can drop this. + #[allow(missing_debug_implementations)] + #item_struct unsafe impl #impl_generics ::uefi::Identify for #ident #ty_generics #where_clause { const GUID: ::uefi::Guid = ::uefi::Guid::from_values( diff --git a/uefi/src/proto/mod.rs b/uefi/src/proto/mod.rs index 92ea20760..71d7530dd 100644 --- a/uefi/src/proto/mod.rs +++ b/uefi/src/proto/mod.rs @@ -14,10 +14,8 @@ use core::ffi::c_void; /// Common trait implemented by all standard UEFI protocols. /// -/// According to the UEFI's specification, protocols are `!Send` (they expect to -/// be run on the bootstrap processor) and `!Sync` (they are not thread-safe). -/// You can derive the `Protocol` trait, add these bounds, and specify the -/// protocol's GUID using the [`unsafe_protocol`] macro. +/// You can derive the `Protocol` trait and specify the protocol's GUID using +/// the [`unsafe_protocol`] macro. /// /// # Example ///