Apêndice G - Como é feito o Rust e o "Rust Nightly"

Este apêndice é sobre como o Rust é feito e como isso afeta você como um desenvolvedor Rust. Mencionamos que a saída deste livro foi gerada pelo Rust estável (Stable) na versão 1.21.0, mas todos os exemplos que compilam devem continuar sendo compilados em qualquer versão estável do Rust mais recente. Esta seção explica como garantimos que isso seja verdade!

Estabilidade sem estagnação

Como linguagem, o Rust se preopcupa muito com a estabilidade do seu código. Queremos que o Rust seja uma base sólida sobre a qual você possa construir, e se as coisas estivessem mudando constantemente, isso seria impossível. Ao mesmo tempo, se não pudermos experimentar novos recursos, poderemos descobrir falhas importantes somente após o lançamento, quando não podemos mais mudar as coisas.

Nossa solução para esse problema é o que chamamos de "estabilidade sem estagnação", e somos guiados pelo seguinte princípio: você nunca deve ter medo de atualizar para uma nova versão do Rust. Cada atualização deve ser indolor, mas também deve trazer novos recursos, menos bugs e tempos de compilação mais rápidos.

Tchu, Tchu! Canais de Release e Passeios de Trem

O desenvolvimento do Rust opera em um "train scheduler" (Horário de trem). Isto é, todo o desenvolvimento é feito na branch master do repositório do Rust. As versões seguem um modelo de trem de liberação de software (train model) que têm sido usado pela Cisco IOS e outros projetos de software. Existem três canais de release para o Rust.

  • Nightly
  • Beta
  • Stable (Estável)

A maioria dos desenvolvedores Rust usa principalmente o canal estável (Stable), mas aqueles que desejam usar novos recursos experimentais podem usar o Nightly ou o Beta.

Aqui está um exemplo de como o processo de desenvolvimento e lançamento (release) funciona: vamos supor que a equipe do Rust esteja trabalhando no lançamento do Rust 1.5. Esse lançamento ocorreu em dezembro de 2015, mas nos fornecerá números de versão realistas. Um novo recurso foi adicionado ao Rust: um novo commit é feito na branch master. Todas as noites, uma nova versão Nightly do Rust é produzida. Todo dia é um dia de lançamento e esses lançamentos são criados automaticamente por nossa infraestrutura de lançamento. Assim, com o passar do tempo, nossos lançamentos ficam assim, uma vez por noite:

nightly: * - - * - - *

A cada seis semanas, chega a hora de preparar uma nova release! A branch beta do repositório do Rust é ramificada a partir da branch master usada pelo Nightly. Agora existem duas releases.

nightly: * - - * - - *
                     |
beta:                *

A maioria dos usuários do Rust não usa ativamente as versões beta, mas faz testes com versões beta no sistema de IC (integração contínua) para ajudar o Rust a descobrir possíveis regressões. Enquanto isso, ainda há uma release todas as noites:

nightly: * - - * - - * - - * - - *
                     |
beta:                *

Agora digamos que uma regressão seja encontrada. Ainda bem que tivemos algum tempo para testar a versão beta antes da regressão se tornar uma versão estável! A correção é aplicada à branch master, de modo que todas as noites é corrigida e, em seguida, a correção é portada para a branch beta, e uma nova versão beta é produzida:

nightly: * - - * - - * - - * - - * - - *
                     |
beta:                * - - - - - - - - *

Seis semanas depois da criação da primeira versão beta, é hora de uma versão estável! A branch stable é produzida a partir da branch beta:

nightly: * - - * - - * - - * - - * - - * - * - *
                     |
beta:                * - - - - - - - - *
                                       |
stable:                                *

Viva! Rust 1.5 está feito! No entanto, esquecemos uma coisa: como as seis semanas se passaram, também precisamos de uma nova versão beta da próxima versão do Rust, 1.6. Então, depois que a branch stable é criada a partir da beta, a próxima versão da beta é criada a partir da nightly novamente:

nightly: * - - * - - * - - * - - * - - * - * - *
                     |                         |
beta:                * - - - - - - - - *       *
                                       |
stable:                                *

Isso é chamado de "train model" (modelo de trem) porque a cada seis semanas, uma release "sai da estação", mas ainda precisa percorrer o canal beta antes de chegar como uma release estável.

O Rust é lançando a cada seis semanas, como um relógio. Se você souber a data de um lançamento do Rust, poderá saber a data do próximo: seis semanas depois. Um aspecto interessante de ter lançamentos agendados a cada seis semanas é que o próximo trem estará chegando em breve. Se um recurso falhar em uma versão específica, não há necessidade de se preocupar: outra está acontecendo em pouco tempo! Isso ajuda a reduzir a pressão para ocultar recursos possivelmente "não polidos" perto do prazo de lançamento.

Graças a esse processo, você sempre pode verificar a próxima versão do Rust e verificar por si mesmo que é fácil fazer uma atualização para a mesma: se uma versão beta não funcionar conforme o esperado, você pode reportar à equipe e ter isso corrigido antes do próximo lançamento estável! A quebra de uma versão beta é relativamente rara, mas o rustc ainda é um software, e bugs existem.

Recursos instáveis

Há mais um problema neste modelo de lançamento: recursos instáveis. O Rust usa uma técnica chamada "sinalizadores de recursos" para determinar quais recursos estão ativados em uma determinada release. Se um novo recurso estiver em desenvolvimento ativo, ele pousará na branch master e, logo, no Nightly, mas atrás de um sinalizador de recurso. Se você, como usuário, deseja experimentar o recurso de trabalho em andamento, pode, mas deve estar usando uma versão Nightly do Rust e anotar seu código-fonte com o sinalizador apropriado para ativar.

Se você estiver usando uma versçao beta ou estável do Rust, você não pode usar qualquer sinalizador de recurso. Essa é a chave que nos permite usar de forma prática os novos recursos antes de declará-los estáveis para sempre. Aqueles que desejam optar pelo que há de mais moderno podem fazê-lo, e aqueles que desejam uma experiência sólida podem se manter estáveis sabendo que seu código não será quebrado. Estabilidade sem estagnação.

Este livro contém informações apenas sobre recursos estáveis, pois os recursos em desenvolvimento ainda estão sendo alterados e certamente serão diferentes entre quando este livro foi escrito e quando eles forem ativados em compilações estáveis. Você pode encontrar documentação on-line para recursos do exclusivos do Nightly (nightly-only).

O Rustup e o papel do Rust Nightly

O Rustup facilita a troca entre os diferentes canais de release do Rust, global ou por projeto. Para instalar o Rust Nightly, por exemplo:

$ rustup install nightly

Você pode ver todos os toolchains (versões do Rust e componentes associados) instalados com o rustup também. Veja um exemplo nos computadores de seus autores:

> rustup toolchain list
stable-x86_64-pc-windows-msvc (default)
beta-x86_64-pc-windows-msvc
nightly-x86_64-pc-windows-msvc

Como pode ver, o toolchain estável (Stable) é o padrão. A maioria dos usuários do Rust usa o estável na maioria das vezes. Você pode querer usar o estável na mioria das vezes, mas usará o Nightly em um projeto específico por se preocupar com um recurso de ponta. Para fazer isso, você pode usar rustup override no diretório desse projeto para definir que o toolchain do Nightly deve ser usado quando o rustup for usado nesse diretório.

$ cd ~/projects/needs-nightly
$ rustup override add nightly

Agora, toda que chamar rustc ou cargo dentro de ~/projects/needs-nightly, o rustup irá garantir que você esteja usando o Rust Nightly ao invés do padrão Rust Stable. Isso é útil quando você tem muitos projetos em Rust.

O Processo de RFC e Equipes

Então, como você aprende sobre esses novos recursos? O modelo de desenvolvimento da Rust segue um processo de solicitação de comentários (RFC). Se você deseja uma melhoria no Rust, pode escrever uma proposta, chamada RFC (Request For Comments).

Qualquer um pode escrever RFCs para melhorar o Rust, e as propostas são revisadas e discutidas pela equipe do Rust, que é composta por muitas subequipes de tópicos. Há uma lista completa das equipes no site do Rust, que inclui equipes para cada área do projeto: design de linguagem, implementação do compilador, infraestrutura, documentação e muito mais. A equipe apropriada lê a proposta e os comentários, escreve alguns comentários próprios e, eventualmente, há um consenso para aceitar ou rejeitar o recurso.

Se o recurso for aceito, uma Issue será aberta no repositório do Rust e alguém poderá implementá-lo. A pessoa que a implementa pode muito bem não ser a pessoa que propôs o recurso em primeiro lugar! Quando a implementação está pronta, ela chega à branch master atrás de um sinalizador de recurso, conforme discutimos na seção "Recursos instáveis".

Depois de algum tempo, assim que os desenvolvedores do Rust que usam versões Nightly puderem experimentar o novo recurso, os membros da equipe discutirão o recurso, como ele funciona no Nightly e decidirão se ele deve se tornar parte do Rust estável ou não. Se a decisão for sim, o portão do recurso será removido e o recurso agora será considerado estável! Ele entra no próximo trem para uma nova versão estável do Rust.