Erro E0432 do Rust: unresolved import (import não resolvido)
O E0432 quer dizer que uma das suas linhas use aponta para algo que o Rust não encontra. Talvez o crate ainda não esteja no Cargo.toml, talvez haja um pequeno erro de digitação no caminho, ou talvez exista um arquivo que o Rust não sabe que é um módulo. Parece assustador, mas quase sempre se resolve com uma linha, e o compilador normalmente diz qual. Para os outros erros desta série, veja Erros do compilador Rust.
A mensagem de erro
Seção intitulada “A mensagem de erro”error[E0432]: unresolved import `rand` --> src/main.rs:1:5 |1 | use rand::random_range; | ^^^^ use of unresolved module or unlinked crate `rand` | = help: if you wanted to use a crate named `rand`, use `cargo add rand` to add it to your `Cargo.toml`Em português: “import não resolvido rand”. O compilador não conhece nenhum módulo nem crate chamado rand e sugere rodar cargo add rand para colocá-lo no Cargo.toml.
Este é o programa que gera o erro, num projeto recém-criado com cargo new e nada em [dependencies]:
use rand::random_range;
fn main() { let roll = random_range(1..=6); println!("You rolled {roll}");}O texto embaixo do ^^^^ muda conforme a causa. Todos estes são E0432, e cada um leva a uma correção diferente abaixo:
| O que o rótulo diz | O que costuma ter dado errado | Correção |
|---|---|---|
use of unresolved module or unlinked crate |
falta o crate no Cargo.toml, ou um arquivo está sem a linha mod |
Correção 1 ou 3 |
could not find `collection` in `std` |
um erro de digitação no meio do caminho | Correção 2 |
no `Hashmap` in `collections` |
um erro de digitação (ou de maiúsculas) no último nome | Correção 2 |
could not find `inventory` in the crate root |
caminho com crate:: para um módulo que não foi declarado |
Correção 3 |
no external crate |
o caminho começa no módulo errado | Correção 4 |
O que significa
Seção intitulada “O que significa”Uma linha use é um atalho. use rand::random_range; diz “daqui em diante, random_range significa a coisa que está em rand::random_range”. Antes de criar esse atalho, o Rust precisa percorrer o caminho uma parte de cada vez: primeiro encontrar rand e depois encontrar random_range dentro dele.
O ^^^^ marca a primeira parte que falhou. Aqui é rand, o primeiro pedaço, então o Rust nem chegou a procurar random_range. A linha help: dá um palpite do motivo: rand é um crate do crates.io, e este projeto não o adicionou.
É como dar a um taxista o endereço “Rua do Porto, 12, Florianópols”. Se o nome da cidade está errado, o motorista nem começa a procurar a rua.
Por que o Rust faz isso
Seção intitulada “Por que o Rust faz isso”O Rust resolve todos os caminhos na compilação, não quando o programa roda. Nada é carregado “só por garantia”. O seu código só enxerga três tipos de coisa: os crates listados no Cargo.toml (mais o std), os módulos que você declarou com mod e os itens dentro deles. Se uma linha use cita algo fora desse conjunto, o Rust para na hora em vez de adivinhar.
Isso é bom. Um import com erro de digitação em Python ou JavaScript muitas vezes só falha quando aquela linha finalmente roda, talvez em produção. Em Rust, o programa nem compila. Isso também quer dizer que um crate que você nunca adicionou não tem como entrar escondido no seu programa.
Desde a edição 2018, um caminho de use começa num destes lugares: o nome de um crate (std, rand), crate (a raiz do seu próprio crate), self (o módulo atual), super (o módulo pai) ou um módulo declarado no módulo atual. A lição de Módulos explica isso em detalhes, e Cargo e crates explica as dependências.
Como corrigir
Seção intitulada “Como corrigir”Correção 1: Adicione o crate com cargo add
Seção intitulada “Correção 1: Adicione o crate com cargo add”Escolha esta quando a primeira parte do caminho é um crate do crates.io, como rand, serde ou regex, e a linha help: fala em cargo add. É a causa mais comum, principalmente quando você copia código de um post de blog. Rode isto na pasta que contém o Cargo.toml:
cargo add randO Cargo encontra a versão mais nova e acrescenta uma linha ao Cargo.toml para você:
[dependencies]rand = "0.10.3"Agora o mesmo código compila. Esta versão imprime uma verificação em vez do número sorteado, para que a saída seja sempre a mesma:
use rand::random_range;
fn main() { let roll = random_range(1..=6); println!("O dado deu entre 1 e 6: {}", (1..=6).contains(&roll));}Saída:
O dado deu entre 1 e 6: trueDuas coisas costumam confundir aqui. Primeiro, nomes de crate com hífen usam sublinhado no código: você roda cargo add tracing-subscriber, mas escreve use tracing_subscriber::.... Segundo, se o crate é uma dependência do seu workspace, ele ainda precisa estar listado no Cargo.toml do pacote que o usa.
Correção 2: Corrija a grafia do caminho
Seção intitulada “Correção 2: Corrija a grafia do caminho”Escolha esta quando o rótulo disser could not find `X` in `Y` (não encontrei X em Y) ou no `X` in `Y` (não há X em Y). Alguma parte no meio ou no fim do caminho está escrita errado. Um clássico:
error[E0432]: unresolved import `std::collection` --> src/main.rs:1:10 |1 | use std::collection::HashMap; | ^^^^^^^^^^ could not find `collection` in `std`O compilador não encontrou collection dentro de std. O módulo se chama collections, com s. Os nomes também diferenciam maiúsculas de minúsculas: use std::collections::Hashmap; falha com no `Hashmap` in `collections`, e o rustc acrescenta help: a similar name exists in the module (existe um nome parecido no módulo) com a grafia certa. O import corrigido:
use std::collections::HashMap;
fn main() { let mut stock: HashMap<&str, u32> = HashMap::new(); stock.insert("apples", 12); println!("{:?}", stock.get("apples"));}Saída:
Some(12)Se você não tem certeza do caminho exato, procure na documentação da biblioteca padrão (em inglês). A página de cada item mostra o caminho completo no topo. Veja HashMaps para saber mais sobre esse tipo.
Correção 3: Declare o módulo com mod
Seção intitulada “Correção 3: Declare o módulo com mod”Escolha esta quando você criou um arquivo novo, digamos src/inventory.rs, e use inventory::... não o encontra. Em Rust, um arquivo não é um módulo até que um arquivo pai o declare. O seu projeto está assim:
src/├── main.rs use inventory::count_items; ← sem `mod inventory;`└── inventory.rs pub fn count_items() -> u32 { 42 }E o rustc diz exatamente o que falta:
error[E0432]: unresolved import `inventory` --> src/main.rs:1:5 |1 | use inventory::count_items; | ^^^^^^^^^ use of unresolved module or unlinked crate `inventory` |help: to make use of source file src/inventory.rs, use `mod inventory` in this file to declare the module |1 + mod inventory; |O help diz: para usar o arquivo src/inventory.rs, declare o módulo com mod inventory neste arquivo. Acrescente mod inventory; no topo de src/main.rs (ou de src/lib.rs, se o módulo fizer parte da sua biblioteca). Escrever use crate::inventory::count_items; não resolve; isso falha com could not find `inventory` in the crate root (não encontrei inventory na raiz do crate), porque o módulo continua sem declaração.
No Playground tudo fica num único arquivo, então aqui o módulo é escrito direto no código com mod inventory { ... }. Funciona exatamente como o arquivo separado:
mod inventory { pub fn count_items() -> u32 { 42 }}
use inventory::count_items;
fn main() { println!("Itens em estoque: {}", count_items());}Saída:
Itens em estoque: 42Declare cada módulo uma vez só, no módulo pai. Os outros arquivos chegam até ele com use crate::inventory::.... Não coloque mod inventory; em todo arquivo que o usa.
Correção 4: Comece o caminho do lugar certo
Seção intitulada “Correção 4: Comece o caminho do lugar certo”Escolha esta quando o import está dentro de um módulo e o item mora em outro módulo do seu próprio crate. Aqui receipt está dentro de shop e quer shop::store_name:
mod shop { pub fn store_name() -> &'static str { "Ferris Fruits" }
pub mod receipt { use store_name; // ❌ procura no lugar errado
pub fn header() -> String { format!("== {} ==", store_name()) } }}error[E0432]: unresolved import `store_name` --> src/main.rs:7:13 |7 | use store_name; // ❌ procura no lugar errado | ^^^^^^^^^^ no external crate `store_name`O compilador diz que não existe nenhum crate externo chamado store_name. Um nome solto no começo de um caminho de use significa “um crate, ou algo declarado aqui mesmo neste módulo”. store_name não é nenhum dos dois, então o Rust procurou um crate com esse nome. Diga a ele por onde começar:
| Prefixo | Começa em | Exemplo |
|---|---|---|
crate:: |
a raiz do seu crate (main.rs ou lib.rs) |
use crate::shop::prices::price_of; |
super:: |
o módulo pai | use super::store_name; |
self:: |
o módulo atual | use self::lines::line; |
Os três num só programa:
mod shop { pub fn store_name() -> &'static str { "Ferris Fruits" }
pub mod prices { pub fn price_of(item: &str) -> u32 { if item == "apple" { 3 } else { 5 } } }
pub mod receipt { use super::store_name; // módulo pai: shop use crate::shop::prices::price_of; // a partir da raiz do crate use self::layout::line; // filho deste módulo
mod layout { pub fn line(item: &str, price: u32) -> String { format!("{item}: {price}") } }
pub fn print(item: &str) { println!("== {} ==", store_name()); println!("{}", line(item, price_of(item))); } }}
fn main() { shop::receipt::print("apple");}Saída:
== Ferris Fruits ==apple: 3use layout::line; também funcionaria aqui, porque layout está declarado no módulo atual; o self:: só deixa isso explícito. Na dúvida, crate:: com o caminho completo sempre funciona de qualquer lugar do seu crate, e o rustc muitas vezes sugere isso: help: a similar path exists (existe um caminho parecido) seguido da versão com crate::.
Onde você costuma ver esse erro
Seção intitulada “Onde você costuma ver esse erro”Código escrito para uma versão mais antiga do crate. Muitos tutoriais usam o rand 0.8. Com o rand 0.10 você recebe:
error[E0432]: unresolved import `rand::thread_rng` --> src/main.rs:1:5 |1 | use rand::thread_rng; | ^^^^^^^^^^^^^^^^ no `thread_rng` in the rootOu seja, não existe thread_rng na raiz do crate. Correção: confira a documentação do crate no docs.rs para a versão que está no seu Cargo.toml. Aqui o novo nome é rand::rng(). Veja Números aleatórios.
Um pacote com main.rs e lib.rs. São dois crates separados. Dentro de main.rs, crate:: significa o binário, então use crate::inventory::count_items; falha com could not find `inventory` in the crate root mesmo que lib.rs tenha pub mod inventory;. Correção: use o nome do pacote, use shop_app::inventory::count_items; (com os hífens trocados por sublinhados).
O item existe, mas é privado. Esse é outro erro, o E0603, não o E0432:
error[E0603]: function `count_items` is private --> src/main.rs:7:16 |7 | use inventory::count_items; | ^^^^^^^^^^^ private functionO compilador encontrou a função, mas avisa que ela é privada. Correção: coloque pub na frente do fn (e na frente de qualquer mod no caminho, já que um módulo privado dá module `prices` is private). Veja Módulos.
Erros relacionados
Seção intitulada “Erros relacionados”- E0433: um caminho dentro do seu código (como
HashMap::new()ourand::rng()) não pode ser resolvido. As causas são as mesmas, mas não numa linhause. - E0425: não foi possível encontrar um valor ou uma função, muitas vezes resolvido pela mesma linha
use. - E0603: o import foi encontrado, mas é privado. Acrescente
pub. - E0463:
can't find crate(crate não encontrado), que aparece comextern crate rand;quando o crate não está noCargo.toml. - Todos os erros do compilador: a lista completa de páginas de erro.
Teste o que aprendeu
Seção intitulada “Teste o que aprendeu”Teste o que aprendeu
1. Você copiou use serde::Serialize; para um projeto novo e recebe um E0432 dizendo que o crate serde não foi resolvido. Qual é a correção?
2. Você criou src/billing.rs, mas use billing::total; no main.rs falha. O que está faltando?
3. Dentro de mod shop { mod receipt { ... } }, como receipt importa uma função definida diretamente em shop?
Pontuação: 0 / 3
Para saber mais
Seção intitulada “Para saber mais”- E0432 — Rust error codes index (em inglês): a explicação oficial, incluindo como os caminhos mudaram no Rust 2018.
- Bringing Paths into Scope with the
useKeyword — The Rust Book (em inglês): como ousefunciona, com pacotes externos e caminhos aninhados. - Paths for Referring to an Item in the Module Tree — The Rust Book (em inglês): caminhos absolutos com
crate::, caminhos relativos esuper. - Separating Modules into Different Files — The Rust Book (em inglês): onde vai o
modquando um módulo mora no próprio arquivo. cargo add— The Cargo Book (em inglês): todas as opções para adicionar dependências, incluindo features.