---
title: "Clippy: Lints Mais Comuns e Como Resolver"
url: "https://rustlang.com.br/erros/clippy-lints-comuns/"
markdown_url: "https://rustlang.com.br/erros/clippy-lints-comuns.MD"
description: "Guia dos lints mais comuns do Clippy no Rust: needless_return, redundant_clone, unused_imports, manual_map e outros. Aprenda a escrever código Rust mais idiomático."
date: "2026-02-23"
author: "Equipe Rust Brasil"
---

# Clippy: Lints Mais Comuns e Como Resolver

Guia dos lints mais comuns do Clippy no Rust: needless_return, redundant_clone, unused_imports, manual_map e outros. Aprenda a escrever código Rust mais idiomático.


# Clippy: Lints Mais Comuns e Como Resolver

O **Clippy** é a ferramenta oficial de linting do Rust, com mais de 700 lints que ajudam a escrever código mais idiomático, performático e correto. Este guia cobre os lints mais frequentes que desenvolvedores encontram no dia a dia.

## Como Usar o Clippy

```bash
# Executar clippy
cargo clippy

# Corrigir automaticamente (quando possível)
cargo clippy --fix

# Tratar warnings como erros (útil em CI)
cargo clippy -- -D warnings

# Todos os lints, incluindo pedantic
cargo clippy -- -W clippy::pedantic
```

## Os Lints Mais Comuns

### 1. `clippy::needless_return` — Return Desnecessário

O Rust é uma linguagem baseada em expressões. A última expressão de uma função é seu valor de retorno — `return` explícito é desnecessário.

```rust
// AVISO: needless return
fn somar(a: i32, b: i32) -> i32 {
    return a + b;
}

// CORRETO: expressão final sem return nem ;
fn somar(a: i32, b: i32) -> i32 {
    a + b
}
```

Com condicionais:

```rust
// AVISO
fn classificar(n: i32) -> &'static str {
    if n > 0 {
        return "positivo";
    } else {
        return "não-positivo";
    }
}

// CORRETO
fn classificar(n: i32) -> &'static str {
    if n > 0 {
        "positivo"
    } else {
        "não-positivo"
    }
}
```

### 2. `clippy::redundant_clone` — Clone Desnecessário

Clone é usado quando não é necessário, pois o valor não será mais usado depois.

```rust
// AVISO: clone redundante
fn processar(nome: String) {
    let copia = nome.clone();
    println!("{}", copia);
    // `nome` nunca mais é usado — clone era desnecessário
}

// CORRETO: usar o valor diretamente
fn processar(nome: String) {
    println!("{}", nome);
}
```

### 3. `clippy::unused_imports` — Imports Não Utilizados

```rust
// AVISO: imports não utilizados
use std::collections::HashMap;
use std::io::Read;

fn main() {
    // Nenhum dos imports é usado
    println!("Olá");
}

// CORRETO: remova os imports não utilizados
fn main() {
    println!("Olá");
}
```

### 4. `clippy::manual_map` — Map Manual em Option

```rust
// AVISO: manual implementation of `Option::map`
fn dobrar(valor: Option<i32>) -> Option<i32> {
    match valor {
        Some(v) => Some(v * 2),
        None => None,
    }
}

// CORRETO: use .map()
fn dobrar(valor: Option<i32>) -> Option<i32> {
    valor.map(|v| v * 2)
}
```

### 5. `clippy::single_match` — Match com Apenas Um Padrão

```rust
// AVISO: use if let em vez de match com um padrão
fn verificar(valor: Option<i32>) {
    match valor {
        Some(v) => println!("{}", v),
        _ => {},
    }
}

// CORRETO: if let
fn verificar(valor: Option<i32>) {
    if let Some(v) = valor {
        println!("{}", v);
    }
}
```

### 6. `clippy::iter_cloned_collect` — Iterador com Clone Desnecessário

```rust
// AVISO
fn copiar_lista(lista: &[String]) -> Vec<String> {
    lista.iter().map(|s| s.clone()).collect()
}

// CORRETO: use .cloned() ou .to_vec()
fn copiar_lista(lista: &[String]) -> Vec<String> {
    lista.to_vec()
}
```

### 7. `clippy::len_zero` — Comparação com len() == 0

```rust
// AVISO: use is_empty() em vez de len() == 0
fn vazio(lista: &Vec<i32>) -> bool {
    lista.len() == 0
}

// CORRETO
fn vazio(lista: &Vec<i32>) -> bool {
    lista.is_empty()
}
```

### 8. `clippy::needless_borrow` — Empréstimo Desnecessário

```rust
// AVISO: empréstimo desnecessário
fn imprimir(texto: &String) {
    println!("{}", &texto);  // & é desnecessário
}

// CORRETO
fn imprimir(texto: &String) {
    println!("{}", texto);
}

// MELHOR AINDA: use &str em vez de &String
fn imprimir(texto: &str) {
    println!("{}", texto);
}
```

### 9. `clippy::collapsible_if` — If Aninhados que Podem Ser Combinados

```rust
// AVISO
fn verificar(a: bool, b: bool) {
    if a {
        if b {
            println!("ambos verdadeiros");
        }
    }
}

// CORRETO
fn verificar(a: bool, b: bool) {
    if a && b {
        println!("ambos verdadeiros");
    }
}
```

### 10. `clippy::match_like_matches_macro` — Use matches!()

```rust
// AVISO
fn eh_vogal(c: char) -> bool {
    match c {
        'a' | 'e' | 'i' | 'o' | 'u' => true,
        _ => false,
    }
}

// CORRETO
fn eh_vogal(c: char) -> bool {
    matches!(c, 'a' | 'e' | 'i' | 'o' | 'u')
}
```

### 11. `clippy::map_flatten` — Use flat_map

```rust
// AVISO
fn processar(lista: Vec<Vec<i32>>) -> Vec<i32> {
    lista.into_iter().map(|v| v.into_iter()).flatten().collect()
}

// CORRETO
fn processar(lista: Vec<Vec<i32>>) -> Vec<i32> {
    lista.into_iter().flat_map(|v| v.into_iter()).collect()
}
```

### 12. `clippy::expect_fun_call` — Formatação em expect

```rust
let nome = "arquivo.txt";

// AVISO: alocação desnecessária em expect
let conteudo = std::fs::read_to_string(nome)
    .expect(&format!("Falha ao ler {}", nome));

// CORRETO: use unwrap_or_else para lazy evaluation
let conteudo = std::fs::read_to_string(nome)
    .unwrap_or_else(|_| panic!("Falha ao ler {}", nome));
```

## Configurando o Clippy

### No Código (por Item)

```rust
// Permitir um lint específico
#[allow(clippy::needless_return)]
fn funcao() -> i32 {
    return 42;
}

// Negar (tratar como erro)
#[deny(clippy::unwrap_used)]
fn funcao_segura() {
    // unwrap() aqui causaria erro de compilação
}
```

### No Arquivo `clippy.toml`

```toml
# clippy.toml na raiz do projeto
too-many-arguments-threshold = 10
type-complexity-threshold = 500
cognitive-complexity-threshold = 30
```

### No `Cargo.toml` ou `lib.rs`/`main.rs`

```rust
// No topo do arquivo principal
#![warn(clippy::all)]
#![warn(clippy::pedantic)]
#![allow(clippy::module_name_repetitions)]
```

## Níveis de Lints do Clippy

| Categoria | Flag | Descrição |
|---|---|---|
| `clippy::all` | Padrão | Lints mais comuns e consensuais |
| `clippy::pedantic` | Opcional | Lints mais rigorosos |
| `clippy::nursery` | Experimental | Lints em desenvolvimento |
| `clippy::cargo` | Cargo | Problemas no Cargo.toml |
| `clippy::restriction` | Restritivo | Para projetos com regras específicas |

## Dica: CI com Clippy

Adicione ao seu CI (GitHub Actions, etc.):

```yaml
- name: Clippy
  run: cargo clippy -- -D warnings
```

Isso garante que nenhum warning do Clippy entre no código principal.

## Veja Também

- [Erro de Invocação de Macro](/erros/macro-invocacao-errada/)
- [Cargo: Could Not Compile](/erros/cargo-could-not-compile/)
- [E0277: Trait Não Implementado](/erros/e0277-trait-nao-implementado/)
- [Cheatsheet Rust](/cheatsheet/)
- [Lista completa de lints do Clippy](https://rust-lang.github.io/rust-clippy/master/index.html)
