Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

An outer attribute in Rust is a compiler directive or metadata annotation that applies to the syntax element immediately following it in the Abstract Syntax Tree (AST). Unlike inner attributes (#![...]), which apply to the enclosing scope or module, outer attributes strictly modify, configure, or annotate the specific declaration, statement, or expression they precede.

Syntax

Outer attributes are declared using a hash symbol (#) followed by square brackets ([]). They do not use the bang (!) modifier. The contents of the brackets define the attribute path and optional arguments, conforming to one of three primary syntax forms defined in the Rust Reference:
// Path form
#[attribute_name]

// NameValue form
#[attribute_name = "value"]

// List form
#[attribute_name(arg1, key = "value")]

AST Binding and Placement

Outer attributes must be placed directly before the syntax element they annotate. The Rust parser binds the attribute to the syntax node of the subsequent element. If an outer attribute is placed where no valid syntax node follows (e.g., at the end of a file or block), the compiler will emit a syntax error. They can be attached to distinct syntactic categories in Rust, including:
  • Items: Functions, methods, structs, enums, unions, modules, traits, trait implementations, and type aliases.
  • Item Components: Struct fields, enum variants, and generic parameters.
  • Statements: Variable bindings (let statements) and expression statements.
  • Expressions: Block expressions, match expressions, closures, and loop constructs.
// Outer attribute bound to a struct item
#[repr(C)]
// Outer attribute bound to a generic parameter
struct Payload<#[allow(non_camel_case_types)] T_Type> {
    // Outer attribute bound to a struct field using NameValue syntax
    #[doc = "Internal identifier"]
    internal_id: u32,
    _marker: std::marker::PhantomData<T_Type>,
}

// Outer attribute bound to a function item
#[inline(always)]
fn process_payload(p: Payload<i32>) {
    // Outer attribute bound to a statement
    #[allow(unused_variables)]
    let temp = p.internal_id;

    // Outer attribute bound to a match expression
    #[allow(clippy::match_single_binding)]
    match temp {
        _ => {}
    }

    // Outer attribute bound to a closure expression
    let _closure = #[allow(unused)] || {};
}

Stacking and Evaluation Order

Multiple outer attributes can be applied to a single syntax element by stacking them vertically or placing them sequentially on the same line.
#[derive(Debug)]
#[repr(transparent)]
struct Wrapper(u32);
When stacked, outer attributes are parsed and evaluated from top to bottom. This order is structurally significant when attributes invoke procedural macros (such as attribute macros or derive macros), as the topmost macro will consume the syntax element and all subsequent attributes as its input token stream.
Master Rust with Deep Grasping Methodology!Learn More