Pular para o conteúdo

Erros do compilador Rust explicados

Apareceu um erro vermelho do compilador Rust e você não sabe bem o que ele quer? Você está no lugar certo. Todo mundo que programa em Rust vê esses erros, muitas vezes por dia. A boa notícia: são poucos os que aparecem de novo e de novo e, depois que você os conhece, eles deixam de assustar.

Cada página abaixo trata de um código de erro: mostra a mensagem real, explica em palavras simples e traz correções que você pode rodar no navegador.

Erro O que o compilador diz Em palavras simples
E0382 borrow of moved value Você entregou um valor e depois tentou usá-lo de novo
E0502 cannot borrow as mutable because it is also borrowed as immutable Você está alterando algo enquanto alguém ainda está lendo
E0499 cannot borrow as mutable more than once at a time Dois lugares querem alterar a mesma coisa ao mesmo tempo
E0308 mismatched types Você passou um tipo onde se esperava outro
E0277 the trait bound is not satisfied Um tipo não sabe fazer algo que você pediu (imprimir, comparar, somar…)
E0106 missing lifetime specifier O Rust não consegue saber por quanto tempo uma referência retornada continua válida
E0425 cannot find value in this scope Um nome está escrito errado ou é usado fora do bloco onde existe
E0599 no method named … found O método não existe nesse tipo, ou o trait dele não foi importado
E0384 cannot assign twice to immutable variable Você alterou uma variável que não foi declarada com mut
E0596 cannot borrow as mutable, as it is not declared as mutable Você tentou alterar algo por meio de uma variável ou referência que não é mut
E0597 borrowed value does not live long enough Uma referência ainda está em uso depois que o valor para o qual ela aponta já sumiu
E0515 cannot return reference to local variable Você retornou uma referência para algo que é descartado quando a função termina
E0373 closure may outlive the current function, but it borrows … Uma closure (muitas vezes uma thread) pega emprestada uma variável local que pode sumir antes de ela rodar
E0369 binary operation == cannot be applied to type … Seu tipo (ainda) não aceita ==, <, + e companhia
E0432 unresolved import Uma linha use aponta para um crate, módulo ou item que não foi encontrado
E0433 cannot find type … in this scope (older: failed to resolve) Um caminho como HashMap::new() usa um nome que não foi importado ou não existe
E0424 self value is a keyword only available in methods with a self parameter Você usou self numa função que não recebe self
E0061 this function takes N arguments but M arguments were supplied Você passou argumentos demais ou de menos (o Rust não tem argumentos opcionais)
E0594 cannot assign to p.hp, as p is not declared as mutable Você alterou um campo ou um valor atrás de & sem acesso mut
E0004 non-exhaustive patterns: X not covered Seu match não trata todos os valores possíveis
E0507 cannot move out of x which is behind a shared reference Você tentou tomar posse de algo que só tinha pegado emprestado
E0603 function x is private Você usou uma função, struct ou módulo que não é pub
E0716 temporary value dropped while borrowed Você guardou uma referência para um valor que é jogado fora no fim da linha
E0463 can’t find crate for x Um crate (ou a biblioteca padrão de um target) não está instalado
E0368 binary assignment operation += cannot be applied to type … Seu tipo não aceita +=, -= e companhia
E0057 this function takes N arguments but M were supplied (note: closure defined here) Você chamou uma closure com argumentos demais ou de menos
E0282 type annotations needed O Rust não consegue descobrir um tipo sozinho, então você precisa dizer qual é
E0609 no field x on type T O nome do campo está errado, ou o valor está embrulhado (por exemplo, num Option)
E0593 closure is expected to take a single 2-tuple as argument, but it takes 2 distinct arguments Uma closure recebe argumentos separados onde se espera uma tupla (ou outra quantidade)
E0631 type mismatch in closure arguments O tipo do parâmetro de uma closure não combina com o que ela recebe (muitas vezes i32 contra &i32)
E0005 refutable pattern in local binding let Some(x) = … pode falhar, então um let simples não aceita
E0615 attempted to take value of method len on type String Você escreveu s.len em vez de s.len()
E0610 {integer} is a primitive type and therefore doesn’t have fields Você usou .campo num número, bool ou char
E0560 struct User has no field named nmae Ao criar uma struct, você usou um nome de campo que ela não tem
E0616 field balance of struct Account is private Você leu, de fora do módulo, um campo que não é pub
E0451 field x of struct Y is private Você criou uma struct com a sintaxe literal, mas alguns campos dela são privados
E0624 method x is private Você chamou um método ou uma função associada que não é pub
E0283 type annotations needed (cannot infer type … multiple impls satisfy this bound) Vários tipos serviriam (por exemplo, em .collect() ou .sum()), então você precisa escolher um
E0284 type annotations needed: cannot satisfy <_ as FromStr>::Err == _ "42".parse() não sabe para qual tipo converter
E0790 cannot call associated function on trait without specifying the corresponding impl type Você escreveu Default::default() ou Trait::new() sem dizer qual é o tipo
E0559 variant Shape::Circle has no field named r Ao criar uma variante de enum, você usou um nome de campo que ela não tem
E0063 missing field email in initializer of User Você criou uma struct, mas deixou um ou mais campos de fora
E0689 can’t call method pow on ambiguous numeric type {integer} 2.pow(10) ou 2.0.sqrt() precisa de um tipo numérico concreto, como i32 ou f64
E0034 multiple applicable items in scope Dois traits dão ao seu tipo um método com o mesmo nome, e o Rust não consegue escolher um
E0412 cannot find type X in this scope (Rust 1.93+ prints E0425) O nome de um tipo está escrito errado, não foi importado ou não foi declarado
E0428 the name area is defined multiple times Dois itens têm o mesmo nome; o Rust não tem sobrecarga de funções
E0026 variant Shape::Circle does not have a field named r Um pattern cita um campo que a struct ou a variante não tem
E0027 pattern does not mention fields id, paid Um pattern de struct deixa campos de fora; acrescente-os ou termine com ..
E0533 expected unit struct, unit variant or constant, found struct variant Shape::Circle Uma variante com campos (ou uma função) foi usada onde se espera um nome simples; acrescente { .. }
E0592 duplicate definitions with name reset Dois blocos impl definem um método com o mesmo nome
E0255 the name Error is defined multiple times Um import com use tem o mesmo nome de um tipo ou função seu
E0252 the name Result is defined multiple times Duas linhas use trazem o mesmo nome; renomeie uma com as
E0411 cannot find type Self in this scope Você usou Self fora de um impl ou de um trait
E0405 cannot find trait Display in this scope O nome de um trait está escrito errado ou não foi importado (por exemplo, use std::fmt::Display;)
E0532 expected unit struct, unit variant or constant, found tuple variant Shape::Circle Um pattern cita uma variante de tupla (ou uma struct) sem os ( ), ou põe ( ) onde não cabem
E0164 expected tuple struct or tuple variant, found struct variant Shape::Circle Um pattern usa ( ) numa variante de struct ou num item associado; use { } ou um guard
E0404 expected trait, found derive macro Debug Você escreveu impl X for ou T: X, mas X é uma struct, um alias ou uma macro derive sem o trait importado
E0401 can’t use generic parameters from outer item Uma fn interna usa o T ou o Self da função de fora; dê a ela os seus próprios genéricos ou use uma closure
E0107 enum takes 2 generic arguments but 1 generic argument was supplied Result<u32>, HashMap<String> e afins: argumentos < > de menos ou demais
E0530 match bindings cannot shadow tuple variants Um nome de variante sozinho, como Circle => (depois de use Shape::*), não pode ser uma variável nova
E0434 can’t capture dynamic environment in a fn item Uma fn interna não enxerga as variáveis locais de fora; use uma closure ou passe os valores como argumento
E0601 main function not found in crate main O binário não tem fn main() (falta, está escrita errado, está dentro de um mod ou o código é, na verdade, uma biblioteca)
E0658 use of unstable library feature iter_intersperse Você usou uma API só do nightly no Rust estável; use a alternativa estável ou atualize o Rust
E0614 type u32 cannot be dereferenced Você escreveu *x, mas x já é um valor comum, e não uma referência
E0435 attempt to use a non-constant value in a constant Um const, o tamanho de um array ou um static usa uma variável let; transforme-a num const ou use um Vec
E0554 #![feature] may not be used on the stable release channel Código copiado que só roda no nightly; remova o atributo e use a API stable, ou use o nightly de propósito

As mensagens de erro do Rust são famosas por ajudar muito, mas trazem bastante informação de uma vez. Veja uma de verdade:

fn main() {
let name = String::from("Ferris");
let greeting = name;
println!("{name}");
}
error[E0382]: borrow of moved value: `name`
--> src/main.rs:4:16
|
2 | let name = String::from("Ferris");
| ---- move occurs because `name` has type `String`, which does not implement the `Copy` trait
3 | let greeting = name;
| ---- value moved here
4 | println!("{name}");
| ^^^^ value borrowed here after move
|
help: consider cloning the value if the performance cost is acceptable
|
3 | let greeting = name.clone();
| ++++++++

Leia nesta ordem:

  1. A primeira linha é o resumo: o código do erro (E0382) e uma descrição de uma linha (aqui, “borrow of moved value” quer dizer “empréstimo de um valor que já foi movido”).
  2. A linha da seta (--> src/main.rs:4:16) mostra o arquivo, a linha e a coluna onde deu problema.
  3. As marcas ^^^^ apontam o lugar exato do erro. As marcas ---- contam a história até ali. Aqui elas dizem: o valor foi criado na linha 2, movido na linha 3 e depois usado na linha 4.
  4. help: é a correção que o compilador sugere, muitas vezes com o código exato a acrescentar (as marcas ++++ mostram os caracteres novos). Nem sempre é a melhor correção, mas é um ótimo ponto de partida.

Comece pelo primeiro erro. Um único engano pode causar uma cadeia de erros seguintes, e corrigir o primeiro muitas vezes faz o resto sumir.

  • Peça mais detalhes ao compilador. Todo código de erro vem com uma explicação mais longa embutida. Rode isto num terminal:

    Terminal window
    rustc --explain E0382

    Você recebe uma descrição curta, um exemplo com o erro e um exemplo corrigido (em inglês).

  • Verifique com frequência. O cargo check encontra erros sem compilar o programa inteiro, então é bem mais rápido que o cargo build. Rodando ele a cada poucas linhas, você encontra um erro por vez, e não vinte. Veja Cargo e crates.

  • Deixe o editor mostrar os erros enquanto você digita. Com a extensão rust-analyzer, os erros aparecem direto no seu código, com o mesmo texto de ajuda. Veja Ferramentas do Rust.

A maioria desses erros existe porque o Rust verifica, antes de o programa rodar, coisas que outras linguagens só descobrem em tempo de execução (ou nunca): usar memória já liberada, duas threads alterando os mesmos dados, uma verificação de null esquecida. Cada erro que você corrige é um bug que nunca vai chegar aos seus usuários.

Por isso muita gente diz: em Rust, a briga acontece na hora de compilar e, depois, o programa simplesmente funciona. As regras por trás dos erros mais comuns estão explicadas em Ownership, Borrowing e Lifetimes.

Teste o que aprendeu

1. Um erro do Rust mostra vários problemas. Qual você deve corrigir primeiro?

2. O que faz o comando rustc --explain E0382?

3. Numa mensagem de erro, o que as marcas ^^^^ mostram?

Pontuação: 0 / 3