O tipo never do Rust, explicado
O tipo never do Rust, escrito !, é o tipo do código que nunca produz um valor. Está estável no Rust 1.100 após dez anos, e muda o recuo de tipos.
5 min de leitura

Em números
- RFC 1216 proposed making ! a real type
- 2015
- crates crater compiled against the stabilization
- 9,024
- of them flagged as regressions
- 3,277
O tipo never do Rust é o tipo de uma expressão que nunca produz um valor. Ele é escrito com um único ponto de exclamação, !. Uma função que sempre entra em pânico, roda para sempre ou sai cedo tem esse tipo, porque nunca devolve um valor ao código que vem depois dela. Após dez anos como recurso instável, o tipo never agora está estável. O pull request que fez isso foi mesclado em 24 de agosto de 2026, e traz consigo uma quebra de compatibilidade.
Isso importa além de uma curiosidade sobre o compilador. O tipo never decide o que acontece nos becos sem saída do seu código, e a nova regra de recuo pode mudar o que uma função genérica infere. A Rust Reference define ! como um tipo sem valores, que representa computações que nunca terminam.
Como funciona
Um tipo é um conjunto de valores possíveis. O tipo bool tem dois. O tipo never não tem nenhum. A RFC 1216, a proposta de 2015 que começou tudo isso, chama um tipo assim de tipo vazio, "um tipo para o qual não existe nada desse tipo". Nada do tipo ! pode existir enquanto um programa roda, então um valor desse tipo não tem nenhuma representação no nível da máquina.
Esse vazio dá a ! seu único poder especial. Segundo a documentação da biblioteca padrão do Rust, uma expressão do tipo ! pode ser convertida por coerção em qualquer outro tipo. O compilador pode prometer isso com segurança, porque a coerção nunca precisa ser executada. Se o código depois de um panic!() espera uma String, a expressão de pânico se encaixa, já que nenhuma String jamais será necessária ali. É por isso que return, break, continue e panic!() podem todos ficar em uma posição que espera algum outro tipo.
A biblioteca padrão documenta que ! implementa Clone, Copy, Debug, Display, Eq, Hash, Ord, PartialEq, PartialOrd e Error. A mesma documentação nomeia um trait que ele nunca deveria implementar: Default. Default precisa produzir um valor, e ! não pode.
Antes desta estabilização, o Rust stable deixava você escrever ! em um único lugar, como tipo de retorno de uma função, segundo a Reference. Os desenvolvedores que precisavam de um tipo vazio em outro lugar escreviam o seu próprio, geralmente enum Never {}, um padrão que a RFC 1216 descreve. A versão da própria biblioteca padrão é std::convert::Infallible, um enum sem variantes que está na biblioteca desde o Rust 1.34.0. Sua documentação o descreve como o tipo de erro para erros que nunca podem acontecer. Um Result<T, Infallible> diz ao leitor que o resultado é sempre Ok.
O que mudou e quando
Três coisas chegaram juntas no pull request 155499, segundo o PR. Primeiro, ! está estável como tipo completo, que é o que a RFC 1216 pediu em 2015. Segundo, Infallible passa a ser um alias de tipo para !, então os dois nomes agora significam o mesmo tipo. Terceiro, e essa é a parte que quebra, o recuo de tipos agora resolve para ! em toda edição do Rust.
O recuo é a regra para um caso limite. Às vezes o compilador chega a um ponto onde uma expressão diverge e nada ao redor fixa um tipo. Historicamente ele escolhia ali o tipo unit (), a tupla vazia. Na edição 2024 e posteriores, a documentação da biblioteca padrão já descreve o recuo como ! em vez disso. O PR de estabilização torna isso a regra em todo lugar, incluindo as edições mais antigas.
O projeto Rust mediu a mudança antes de mesclá-la. O PR relata uma execução do crater sobre 9.024 crates. O crater compila uma amostra grande das crates publicadas contra um compilador proposto e relata o que quebra. Ele apontou 3.277 regressões e nenhuma correção. O PR está marcado para o Rust 1.100.0, como a reportagem do Tech AI Wire sobre a estabilização observou quando ele foi mesclado.
Um relato de regressão é instrutivo. Um colaborador apontou que o cargo-semver-checks, uma ferramenta que verifica crates em busca de mudanças incompatíveis de API, reportava a mudança no Infallible como uma quebra. A discussão do PR chama isso de falso positivo. Como disse o colaborador JonathanBrouwer, "O tipo ainda está lá, ele só passou de um pub enum para um pub type."
| Marco | Quando | O que aconteceu |
|---|---|---|
| RFC 1216 | 19 de julho de 2015 | Propôs promover ! a tipo completo |
| Issue de acompanhamento 35121 | 29 de julho de 2016 | Aberta para acompanhar a RFC; o PR 35162 foi a primeira implementação |
| PR 65355 | Rust 1.41.0 | Primeira estabilização, revertida no PR 67224 após regressões |
| Edição Rust 2024 | Edição 2024 | Recuo alterado para ! primeiro dentro da nova edição |
| PR 155499 | 24 de agosto de 2026 | ! estável, recuo universal, Infallible virou alias |
Por que levou dez anos
A issue de acompanhamento conta a história do atraso. A issue 35121 foi aberta em 29 de julho de 2016. Uma primeira estabilização foi lançada no Rust 1.41.0 e depois retirada, porque crates reais quebraram. A issue registra o gatilho: uma conversão de Error a partir de Infallible parou de compilar, registrada como a issue 66757. O autor do PR final escreve no seu blog que houve cinco tentativas fracassadas no total. Este último esforço levou mais de dois anos.
A saída foi fazer por etapas. A issue de acompanhamento expõe um plano em três fases. Mudar o recuo para ! somente dentro da edição 2024. Estabilizar essa edição. Depois, uma vez que o ecossistema tivesse absorvido a nova regra, tornar universais as quebras de compatibilidade e definir Infallible igual a !. O PR de agosto de 2026 é essa fase final. A outra grande mudança do compilador do Rust neste ano, o resolvedor de traits de nova geração, passa primeiro pelo nightly com a mesma cautela, com estabilização prevista para depois.
O que isso significa para os desenvolvedores
Verifique o código genérico no nightly antes de o Rust 1.100.0 chegar ao stable. A mudança de recuo importa onde um parâmetro de tipo só é fixado por uma expressão que entra em pânico ou sai cedo. Nesses pontos o compilador costumava escolher () para você e agora escolhe !. A maior parte do código não vai notar. O código que dependia da escolha antiga pode falhar ao compilar, ou escolher uma implementação de trait diferente. Os 3.277 casos apontados pelo crater mostram que isso não é hipotético.
Procure Infallible com grep. Se sua crate implementa um trait tanto para Infallible quanto para !, essas duas implementações agora colidem, porque nomeiam um único tipo. A documentação do Infallible também observa que tipos de ponteiro de função como fn() -> ! e fn() -> Infallible podiam carregar implementações de trait diferentes. Esses agora também coincidem. Uma biblioteca que expõe Infallible na sua API pública não quebra seus usuários, diga o que disser uma ferramenta de semver. O tipo ainda está lá sob os dois nomes.
Use ! de propósito daqui em diante. Uma função que só pode ter sucesso pode retornar Result<T, !>, que a RFC 1216 lista como caso de uso motivador, e quem a chama pode fazer match apenas no braço Ok. Um handler que nunca retorna pode ser passado a código genérico que espera um Fn() -> T, outro caso de uso da RFC, sem um tipo invólucro. Abandone o enum Never {} caseiro assim que a sua versão mínima do Rust suportada permitir.
Dez anos é muito tempo para um tipo de um caractere só. A primeira tentativa revertida, a implantação que passou primeiro por uma edição e o número do crater explicam a maior parte. Eles também são o motivo de esta ser uma mudança para a qual você pode se preparar no nightly hoje, antes de ela chegar ao stable.
Fontes
- Never type - The Rust Reference - The Rust Reference
- Primitive type ! - Rust standard library documentation - Rust standard library docs
- RFC 1216: Promote ! to a type - Rust RFCs
- stabilize never type (PR #155499) - GitHub - rust-lang/rust
- Tracking issue for RFC 1216 (promoting ! to a type) - GitHub - rust-lang/rust
- Enum std::convert::Infallible - Rust standard library documentation - Rust standard library docs
Artigos relacionados

Rust estabiliza o tipo never após dez anos e cinco tentativas
O tipo never está estável e o Infallible passa a ser um alias dele. O problema é uma quebra no recuo de tipos, que o crater apontou em 3.277 crates.

Rust ativa seu resolvedor de traits de nova geração nas builds nightly
O novo resolvedor de traits do Rust agora é o padrão no nightly: a maior mudança do compilador desde a 1.0, quatro anos de trabalho e estabilização prevista para os próximos meses.

Reescrita do mold em Rust quer ser o linker padrão do Linux
O mold faz a ligação 4,9 vezes mais rápido que o LLVM lld. Seu autor o está reescrevendo em Rust e quer que as distribuições o instalem como /usr/bin/ld.