Search code examples
rustrust-proc-macros

Custom `derive` macro without the actual `Trait` to be derived


Currently, implementing a custom derive macro does not require an actual Trait to exist at all. All it does is to append an arbitrary code block after the annotated item, and apparently to remove the "helper attributes" from it. That is we can do something like the following:

#[proc_macro_derive(FakeTrait)]

pub fn custom_derive(input: TokenStream) -> TokenStream {
    let name = ... // Get the ident name from input
    ....
        quote! {
        impl #name {
            fn custom_function(...) {
                ...
            }
        }
    }.into()   
}

And then we can use this macro on a struct via

#[derive(FakeTrait)]
struct MyStruct {...}

and it will happily work by appending the impl MyStruct to it regardless the existence of FakeTrait.

My question is whether it is an acceptable use-case for derive macros? Are there any downsides and could it happen that it breaks in the future?


Solution

  • It is certainly the most common case that derive macros generate an implementation for a trait with the same name, but that is not enforced. So likely as long as its clear what your macro is doing it'd probably be "acceptable".

    For prior art: the enum_as_inner crate exposes the EnumAsInner derive macro that does not generate any trait implementations and instead generates inherent methods.