---
title: "Erro de Invocação de Macro no Rust"
url: "https://rustlang.com.br/erros/macro-invocacao-errada/"
markdown_url: "https://rustlang.com.br/erros/macro-invocacao-errada.MD"
description: "Como resolver erros de invocação de macro no Rust. Aprenda sobre a sintaxe correta, problemas comuns com println!, vec!, macro_rules! e macros procedurais."
date: "2026-02-23"
author: "Equipe Rust Brasil"
---

# Erro de Invocação de Macro no Rust

Como resolver erros de invocação de macro no Rust. Aprenda sobre a sintaxe correta, problemas comuns com println!, vec!, macro_rules! e macros procedurais.


# Erro de Invocação de Macro

Erros de invocação de macro no Rust aparecem quando você chama uma macro com **sintaxe incorreta**, **argumentos errados** ou **esquece o `!`**. As mensagens de erro para macros podem ser menos intuitivas que as de funções normais, pois o compilador reporta o erro no código expandido.

## As Mensagens de Erro

Esquecendo o `!`:

```
error[E0423]: expected function, found macro `println`
 --> src/main.rs:2:5
  |
2 |     println("Olá");
  |     ^^^^^^^ not a function
  |
help: use `!` to invoke the macro
  |
2 |     println!("Olá");
  |            +
```

Argumentos errados em `println!`:

```
error: 1 positional argument in format string, but no arguments were given
 --> src/main.rs:2:20
  |
2 |     println!("Olá, {}!");
  |                    ^^
```

Erro em `vec!`:

```
error: no rules expected the token `=>`
 --> src/main.rs:2:25
  |
2 |     let v = vec![1, 2 => 3];
  |                        ^^ no rules expected this token in macro call
```

Macro personalizada com padrão não reconhecido:

```
error: no rules expected the token `+`
  --> src/main.rs:10:20
   |
1  | macro_rules! calcular {
   | ---------------------- when calling this macro
...
10 |     calcular!(5 + 3);
   |                    ^ no rules expected this token in macro call
```

## O Que Significa

Macros no Rust são **expansões de código** — elas geram código Rust baseado em padrões. Diferente de funções, macros:

1. São invocadas com `!` (ex: `println!`, `vec!`)
2. Podem aceitar **padrões variados** de argumentos
3. São expandidas **antes** da verificação de tipos
4. Cada macro define suas próprias **regras** de aceitação de argumentos

Quando uma invocação não corresponde a nenhum padrão definido pela macro, o compilador reporta "no rules expected this token". Quando faltam argumentos esperados, o erro aparece no formato da string ou no padrão esperado.

## Código com Erro

### Esquecendo o `!`

```rust
fn main() {
    // ERRO: sem `!`, o Rust procura uma função chamada `println`
    println("Olá, mundo!");

    // ERRO: mesmo problema
    let v = vec[1, 2, 3];
}
```

### Argumentos Errados em Macros de Formatação

```rust
fn main() {
    // ERRO: placeholder {} sem argumento correspondente
    println!("Nome: {}, Idade: {}");

    // ERRO: argumento demais
    println!("Nome: {}", "Alice", 30);

    // ERRO: tipo incompatível com formatação
    println!("Valor: {:b}", "texto"); // :b é para inteiros
}
```

### Erro em macro_rules! Personalizada

```rust
macro_rules! saudar {
    ($nome:expr) => {
        println!("Olá, {}!", $nome);
    };
}

fn main() {
    // ERRO: macro espera 1 expressão, recebe 2
    saudar!("Alice", "Bob");

    // ERRO: token inesperado
    saudar!(let x = 5);
}
```

## Como Resolver

### Solução 1: Adicionar o `!` na Invocação

```rust
fn main() {
    println!("Olá, mundo!");     // Com !
    let v = vec![1, 2, 3];      // Com !
    format!("Texto: {}", 42);   // Com !
    assert_eq!(1 + 1, 2);       // Com !
}
```

Macros comuns da biblioteca padrão que precisam de `!`:

| Macro | Uso |
|---|---|
| `println!` / `eprintln!` | Imprimir no stdout/stderr |
| `format!` | Formatar string |
| `vec!` | Criar vetor |
| `assert!` / `assert_eq!` | Asserções |
| `panic!` | Causar panic |
| `todo!` / `unimplemented!` | Marcar código incompleto |
| `dbg!` | Debug rápido |
| `include_str!` / `include_bytes!` | Incluir arquivo |
| `cfg!` | Verificar configuração |
| `matches!` | Pattern matching como expressão |

### Solução 2: Corrigir Formatação de String

```rust
fn main() {
    let nome = "Alice";
    let idade = 30;

    // Placeholders posicionais
    println!("Nome: {}, Idade: {}", nome, idade);

    // Placeholders nomeados
    println!("Nome: {nome}, Idade: {idade}");

    // Formatação específica
    println!("Pi: {:.2}", std::f64::consts::PI);   // 3.14
    println!("Hex: {:#x}", 255);                    // 0xff
    println!("Binário: {:08b}", 42);                // 00101010
    println!("Alinhado: {:>10}", "Rust");           //       Rust
    println!("Debug: {:?}", vec![1, 2, 3]);         // [1, 2, 3]
    println!("Pretty: {:#?}", vec![1, 2, 3]);       // Formatado
}
```

### Solução 3: Corrigir macro_rules! Personalizada

Defina padrões claros para cada variação de uso:

```rust
macro_rules! saudar {
    // Padrão 1: um nome
    ($nome:expr) => {
        println!("Olá, {}!", $nome);
    };
    // Padrão 2: múltiplos nomes
    ($($nome:expr),+ $(,)?) => {
        $(
            println!("Olá, {}!", $nome);
        )+
    };
}

fn main() {
    saudar!("Alice");
    saudar!("Bob", "Carol", "Dave");
}
```

Tipos de fragmentos em `macro_rules!`:

```rust
macro_rules! exemplo {
    ($e:expr) => {};       // Expressão
    ($i:ident) => {};      // Identificador
    ($t:ty) => {};         // Tipo
    ($p:pat) => {};        // Padrão (pattern)
    ($b:block) => {};      // Bloco { ... }
    ($s:stmt) => {};       // Statement
    ($l:literal) => {};    // Literal
    ($tt:tt) => {};        // Token tree (qualquer token)
    ($($r:tt)*) => {};     // Repetição de tokens
}
```

### Solução 4: Corrigir Macros Procedurais (derive)

```rust
// ERRO: derive com atributo errado
#[derive(Debug, Serialze)]  // Typo: "Serialze"
struct Dados {
    campo: String,
}

// CORRETO:
#[derive(Debug, serde::Serialize)]
struct Dados {
    campo: String,
}
```

Certifique-se de que o crate com a macro derive está no `Cargo.toml`:

```toml
[dependencies]
serde = { version = "1", features = ["derive"] }
```

### Solução 5: Debug de Macros com cargo expand

Para ver o código que a macro gera:

```bash
# Instalar cargo-expand
cargo install cargo-expand

# Ver código expandido
cargo expand

# Ver expansão de um módulo específico
cargo expand modulo::submodulo
```

## Dicas para Macros

1. **Sempre use `!`** para invocar macros
2. **Leia a documentação** da macro para saber os padrões aceitos
3. **Use `cargo expand`** para debugar macros complexas
4. **Prefira funções** quando possível — macros são mais difíceis de debugar
5. **Use `dbg!`** para debug rápido — imprime a expressão e seu valor

```rust
fn main() {
    let x = 5;
    let y = dbg!(x * 2) + 1;  // Imprime: [src/main.rs:3] x * 2 = 10
    println!("y = {}", y);     // y = 11
}
```

## Veja Também

- [Clippy: Lints Mais Comuns](/erros/clippy-lints-comuns/)
- [Cargo: Could Not Compile](/erros/cargo-could-not-compile/)
- [E0412: Tipo Não Encontrado](/erros/e0412-tipo-nao-encontrado/)
- [Cheatsheet Rust](/cheatsheet/)
