liveBook · Manning

Inert attribute

As explained in Write Powerful Rust Macros

An inert attribute is an attribute that remains available during processing rather than removing itself during macro expansion.

An inert attribute remains available during attribute processing instead of removing itself. In Rust derive macros, helper attributes are inert: the derive macro reads them to alter generated behavior and output, while the original input still retains them. section 8.1.1

This differs from an attribute macro. Attribute-macro annotations are active and remove themselves during processing, which is useful when the annotated item may disappear or be replaced. Derive macros cannot change their input, so retaining helper attributes is appropriate. section 8.7 section 8.1.1

Renaming a generated builder setter

A derive macro can use an inert helper attribute to customize generated code. Declaring `attributes(rename)` makes `rename` valid, while the macro implementation can generate the `tops_of` setter from the `roots_of` field: `#[derive(Builder)]` `struct Gleipnir {` ` #[rename("tops_of")]` ` roots_of: String,` `}` The test then calls `.tops_of("mountains".to_string())` and verifies that `roots_of` receives the value. Before the attribute is declared, compilation fails with an unknown-attribute error; after declaration, the remaining failure indicates that generation still needs implementation. section 8.1.1

Listing 8.1 Verifying the desired behavior with a test
#[test]
fn should_generate_builder_for_struct_with_one_renamed_property() {
    #[derive(Builder)]
    struct Gleipnir {
        #[rename("tops_of")]       #1
        roots_of: String,
    }

    let gleipnir = Gleipnir::builder()
        .tops_of("mountains".to_string())      #2
        .build();

    assert_eq!(
        gleipnir.roots_of, #3
        "mountains".to_string()
    );                      
}

Inspect the complete test showing an inert `rename` helper attribute driving a generated builder method. section 8.1.1

How Write Powerful Rust Macros covers it

How deep it goes
Explains retention, derive-macro constraints, declaration, expansion inspection, and a failing-to-working rename test.
Examples
Demonstrates `#[rename("tops_of")]` changing a generated builder setter while retaining the original `roots_of` field.
What it assumes
Assumes Rust derive-macro knowledge and teaches why helper attributes must be declared before implementation.
What you can do after
Apply inert helper attributes by declaring them on derive macros and testing their effect on generated code.
How it connects
Connects derive macros, attribute macros, helper attributes, macro expansion, and generated builder methods.

Related concepts

This explainer was generated by Manning's knowledge graph from the text of Write Powerful Rust Macros. The section links point to the parts of the book it draws on.