> ## 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.

# Rust Function-like Macro

A function-like macro in Rust is a metaprogramming construct invoked using the macro invocation operator (`!`) that accepts a stream of tokens as input and expands into a new stream of tokens at compile time. Unlike standard functions, which operate on evaluated values at runtime, function-like macros operate on Token Streams (or Token Trees) during the parsing phase, before the full Abstract Syntax Tree (AST) is constructed. This enables syntactic abstraction and arbitrary code generation.

Rust provides two distinct mechanisms for defining function-like macros: Declarative Macros and Procedural Macros.

## Declarative Macros (`macro_rules!`)

Declarative macros are defined using the built-in `macro_rules!` construct. They operate via a pattern-matching engine that evaluates the input token stream against a series of defined rules. When a match is found, the macro expands according to the corresponding transcriber block.

**Syntax Visualization:**

```rust theme={"dark"}
#[macro_export]
macro_rules! macro_name {
    ( $metavariable:fragment_specifier ) => {
        // Transcriber (expansion code)
    };
    // Additional rules...
}
```

* **Metavariables:** Prefixed with `$`, these capture matched tokens from the input stream.
* **Fragment Specifiers:** Define the expected syntax node type for the metavariable (e.g., `expr` for expressions, `ident` for identifiers, `ty` for types, `tt` for token trees).
* **Repetitions:** Indicated by syntax like `$( ... ),*`, allowing the macro to accept and expand variable-length lists of tokens.

**Structural Example:**

```rust theme={"dark"}
macro_rules! parse_elements {
    ( $( $val:expr ),* ) => {
        {
            let mut temp_vec = Vec::new();
            $(
                temp_vec.push($val);
            )*
            temp_vec
        }
    };
}
```

## Macro Hygiene

A fundamental feature that distinguishes Rust's declarative macros from C-style text replacement is **macro hygiene**. Declarative macros are partially hygienic. This means that local variables, labels, and other identifiers declared within the macro's transcriber block (such as `temp_vec` in the example above) are resolved in the macro's definition context, not the caller's context. This protects the macro's internal variables from accidentally clashing with variables in the scope where the macro is invoked.

*Note: Hygiene in declarative macros applies primarily to local variables and labels. Items like functions or types are resolved in the call site's context. Procedural macros, by contrast, are unhygienic by default, requiring manual hygiene management using the `Span` API.*

## Scoping and Visibility

Because declarative macros operate differently from standard functions, they do not use the `pub` keyword for visibility. Instead, declarative macros use the `#[macro_export]` attribute to be visible outside their defining module. Applying `#[macro_export]` hoists the macro into the root scope of the crate, making it accessible to external crates. Without this attribute, a declarative macro is only visible within the module where it is defined and its submodules.

## Procedural Function-like Macros

Procedural function-like macros are defined as public functions within a specialized crate type (`proc-macro = true`). They are written in standard Rust and execute as compiler plugins at compile time to transform an input `TokenStream` into an output `TokenStream`.

**Syntax Visualization:**

```rust theme={"dark"}
use proc_macro::TokenStream;

#[proc_macro]
pub fn macro_name(input: TokenStream) -> TokenStream {
    // 1. Parse the input TokenStream (often using the `syn` crate)
    // 2. Manipulate the parsed syntax tree
    // 3. Serialize the modified syntax tree back into a TokenStream (often using `quote`)
    
    TokenStream::new() // Returns an empty TokenStream to satisfy the type signature
}
```

Unlike declarative macros, procedural macros do not rely on declarative pattern matching. Instead, they receive the raw `TokenStream`, allowing for arbitrary programmatic inspection and manipulation before emitting the final `TokenStream`.

## Invocation Syntax

Regardless of whether a function-like macro is declarative or procedural, it is invoked by appending a bang (`!`) to its identifier. The input token stream can be enclosed in parentheses `()`, brackets `[]`, or braces `{}`. The compiler treats these delimiters identically for the purpose of macro expansion, though convention dictates their usage based on the macro's structural output.

```rust theme={"dark"}
// Parentheses (typically used for expression-like expansions)
my_macro!(arg1, arg2);

// Brackets (typically used for array/vector-like expansions)
my_macro![arg1, arg2];

// Braces (typically used for block-like expansions)
// Note: Semicolons are not required after brace invocations when used as either items or statements.
my_macro! {
    arg1, arg2
}
```

## Expansion Mechanics

1. **Lexing:** The compiler converts the source code into a stream of raw tokens.
2. **Token Tree Parsing:** The compiler groups these raw tokens into token trees (`tt`) by matching delimiters (`()`, `[]`, and `{}`).
3. **Invocation Parsing:** The compiler encounters the `!` operator and identifies the macro invocation.
4. **Expansion:** The macro consumes the token stream within its delimiters. For declarative macros, the compiler evaluates the matchers sequentially. For procedural macros, the compiler executes the compiled macro binary, passing the tokens as arguments.
5. **Integration:** The resulting `TokenStream` is parsed and integrated into the AST, replacing the original macro invocation. The expanded code must form valid Rust syntax for the specific context in which it was invoked (e.g., an expression context, an item context, or a statement context).

<div
  style={{ 
display: "flex", 
justifyContent: "space-between", 
alignItems: "center", 
maxWidth: "754px", 
padding: "1rem 0",
marginBottom: "24px"
}}
>
  <span style={{ fontWeight: "bold", fontSize: "1.25rem", color: "var(--tw-prose-headings)", fontFamily: "Inter, ui-sans-serif, system-ui, sans-serif" }}>Tired of Poor Rust Skills? Fix That With Deep Grasping!</span>

  <a
    href="https://syntblaze.com"
    target="_blank"
    style={{ 
  marginLeft: "24px",
  textDecoration: "none", 
  backgroundColor: "#007AFF",
  color: "#ffffff", 
  padding: "6px 16px", 
  borderRadius: "16px",
  fontSize: "0.9rem",
  fontWeight: "600",
  textAlign: "center",
  transition: "background-color 0.2s ease"
}}
  >
    Learn More
  </a>
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/skill-tracking.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=b9b0305c93bb501c9e767b5c76c88835" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/skill-tracking.png" />

  <img src="https://mintcdn.com/syntblazellc/23tyuOzaWS88qFlc/images/nuggets.png?fit=max&auto=format&n=23tyuOzaWS88qFlc&q=85&s=c86c80197299762989e9b882419b2109" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/nuggets.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/bite-sized-exercises.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=a65f9a38c37ff28ab73ed783c53c60e3" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/bite-sized-exercises.png" />
</div>

<div style={{ display: "flex", gap: "12px", flexWrap: "wrap", marginTop: "12px" }}>
  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/mastery-chain.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=748a1763454713e679260fbb95f154a2" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/mastery-chain.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-previews.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=242f61448ff5dd6deaaab2dccc13b507" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-previews.png" />

  <img src="https://mintcdn.com/syntblazellc/-L0ums_2lctDSZ1l/images/element-explanations.png?fit=max&auto=format&n=-L0ums_2lctDSZ1l&q=85&s=cf0fc1c31f9cd0fc26716781be05fbc9" style={{ width: "30%", minWidth: 60 }} width="621" height="1344" data-path="images/element-explanations.png" />
</div>
