0

I'm trying to implement a Rust procedural macro that exports a C-compatible function for a driver I'm writing. Here's my macro:

extern crate proc_macro;
use proc_macro::TokenStream;
use quote::quote;
use syn::{ItemStruct, parse_macro_input};

#[proc_macro_attribute]
pub fn export_driver(_attr: TokenStream, item: TokenStream) -> TokenStream {
    let input = parse_macro_input!(item as ItemStruct);
    let name = &input.ident;
    
    let expanded = quote! {
        #input        
        
        #[no_mangle]
        pub unsafe extern "C" fn init() -> i32 {
            #name::init()                
        }        
    };

    TokenStream::from(expanded)
}

I try to use the macro like this:

#[export_driver] 
struct MyDriver;

But I get the error:

[export_driver]
  | ^^^^^^^^^^^^^^^^ usage of unsafe attribute
  |
  = note: this error originates in the attribute macro `export_driver` (in Nightly builds, run with -Z macro-backtrace for more info)
help: wrap the attribute in `unsafe(...)`
  |
4 | unsafe(#[export_driver])
  | +++++++  

If I try what the compiler suggests, I get another error:

error: expected item, found keyword `unsafe`
 --> my-driver\src\main.rs:4:1
  |
4 | unsafe(#[export_driver])
  | ^^^^^^ expected item

Removing #[no_mangle] suppresses the first error in the original code, but I need to keep the exported function name.

Question: How can I keep #[no_mangle] in the generated function while still applying my macro to a struct?

2
  • 3
    You need to put #[unsafe(no_mangle)]. You can report a bug for the broken suggestion. Commented Sep 30 at 7:58
  • That worked perfectly, awesome! Thanks a lot for the help. Commented Sep 30 at 8:12

1 Answer 1

1

#[no_mangle] is an unsafe attribute, since it may cause Undefined Behavior if the symbol isn't unique in the binary. That means that on edition 2024 and onward, it needs to be spelled #[unsafe(no_mangle)] (the syntax is also accepted on older editions, if the Rust version is at least 1.82.0).

You may want to require the unsafe token in your macro input, since the macro by itself has no way to verify that the soundness requirements hold.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.