---
title: "E0502: Empréstimo Mutável e Imutável no Rust"
url: "https://rustlang.com.br/erros/e0502-emprestimo-mutavel-imutavel/"
markdown_url: "https://rustlang.com.br/erros/e0502-emprestimo-mutavel-imutavel.MD"
description: "Como resolver o erro E0502 do Rust: não é possível emprestar como mutável enquanto também emprestado como imutável. Veja explicação e soluções práticas."
date: "2026-02-23"
author: "Equipe Rust Brasil"
---

# E0502: Empréstimo Mutável e Imutável no Rust

Como resolver o erro E0502 do Rust: não é possível emprestar como mutável enquanto também emprestado como imutável. Veja explicação e soluções práticas.


# E0502: Empréstimo Mutável e Imutável Simultâneo

O erro **E0502** ocorre quando você tenta criar um empréstimo mutável (`&mut`) enquanto já existe um empréstimo imutável (`&`) ativo para o mesmo dado. Este é um dos pilares de segurança do Rust: **você pode ter múltiplas referências imutáveis OU uma única referência mutável, mas nunca ambos ao mesmo tempo.**

## A Mensagem de Erro

```
error[E0502]: cannot borrow `dados` as mutable because it is also borrowed as immutable
 --> src/main.rs:5:5
  |
3 |     let referencia = &dados;
  |                      ------ immutable borrow occurs here
4 |
5 |     dados.push(4);
  |     ^^^^^^^^^^^^^ mutable borrow occurs here
6 |
7 |     println!("{:?}", referencia);
  |                      ---------- immutable borrow later used here
```

## O Que Significa

O Rust aplica a regra de **exclusão mútua de referências** para prevenir **data races** (condições de corrida) em tempo de compilação. A lógica é simples:

- Se alguém está **lendo** um dado (referência imutável `&`), ninguém pode **modificar** esse dado ao mesmo tempo.
- Se alguém está **modificando** um dado (referência mutável `&mut`), ninguém mais pode ler nem modificar.

Sem essa regra, seria possível que uma referência imutável "visse" um dado sendo modificado por baixo dos panos, causando comportamento indefinido — algo que nunca acontece em Rust seguro.

O compilador verifica os **tempos de vida** (lifetimes) das referências. Um empréstimo imutável permanece ativo desde sua criação até seu **último uso**. Se durante esse período você tenta criar um empréstimo mutável, o compilador rejeita o código.

## Código com Erro

```rust
fn main() {
    let mut numeros = vec![1, 2, 3];

    // Cria referência imutável
    let primeiro = &numeros[0];

    // ERRO: tenta modificar enquanto `primeiro` ainda é válido
    numeros.push(4);

    // `primeiro` é usado aqui, mantendo o empréstimo imutável ativo
    println!("Primeiro: {}", primeiro);
}
```

Outro exemplo comum com iteração:

```rust
fn main() {
    let mut lista = vec![1, 2, 3, 4, 5];

    // O `for` cria um empréstimo imutável de `lista`
    for item in &lista {
        if *item == 3 {
            // ERRO: não pode modificar `lista` enquanto itera sobre ela
            lista.push(10);
        }
    }
}
```

## Como Resolver

### Solução 1: Reorganizar o Uso das Referências

Graças ao **Non-Lexical Lifetimes (NLL)**, o Rust moderno encerra o empréstimo no último ponto de uso, não no final do escopo. Basta usar a referência imutável antes de criar a mutável:

```rust
fn main() {
    let mut numeros = vec![1, 2, 3];

    // Usa a referência imutável ANTES de modificar
    let primeiro = &numeros[0];
    println!("Primeiro: {}", primeiro);
    // `primeiro` não é mais usado — empréstimo imutável encerrado

    // Agora pode modificar livremente
    numeros.push(4);
    println!("{:?}", numeros);
}
```

### Solução 2: Usar Escopos Separados

Quando a reorganização simples não é possível, use blocos para limitar o tempo de vida das referências:

```rust
fn main() {
    let mut numeros = vec![1, 2, 3];

    {
        let referencia = &numeros;
        println!("Números: {:?}", referencia);
    } // `referencia` sai de escopo aqui

    // Agora livre para modificar
    numeros.push(4);
}
```

### Solução 3: Coletar Antes, Modificar Depois

Para o caso de modificação durante iteração, colete as mudanças necessárias e aplique-as depois:

```rust
fn main() {
    let mut lista = vec![1, 2, 3, 4, 5];

    // Primeiro, descubra o que precisa mudar
    let precisa_adicionar: Vec<i32> = lista
        .iter()
        .filter(|&&x| x == 3)
        .map(|_| 10)
        .collect();

    // Depois, aplique as mudanças
    lista.extend(precisa_adicionar);
    println!("{:?}", lista); // [1, 2, 3, 4, 5, 10]
}
```

Ou use `retain`, `drain`, ou índices quando precisar modificar durante iteração:

```rust
fn main() {
    let mut lista = vec![1, 2, 3, 4, 5];

    // Remove elementos usando retain (não precisa de empréstimo separado)
    lista.retain(|&x| x != 3);
    println!("{:?}", lista); // [1, 2, 4, 5]
}
```

## Por Que Isso Importa

O exemplo do `Vec::push` é especialmente relevante: quando um `Vec` cresce além de sua capacidade, ele realoca a memória. Se existisse uma referência imutável apontando para o endereço antigo, ela se tornaria um **dangling pointer** — apontando para memória liberada. O Rust previne isso em tempo de compilação.

## Veja Também

- [E0499: Dois Empréstimos Mutáveis](/erros/e0499-emprestimo-mutavel-duplo/)
- [E0382: Uso de Valor Após Move](/erros/e0382-uso-apos-move/)
- [Tutorial de Ownership e Borrowing](/tutoriais/ownership-borrowing/)
- [Cheatsheet Rust](/cheatsheet/)
- [Documentação oficial: E0502](https://doc.rust-lang.org/error_codes/E0502.html)
