← Todos os Posts

O que o time de Swift da Apple disse no Lab da WWDC26

A Apple publicou o Swift Group Lab da WWDC26 como uma hora de perguntas e respostas sem roteiro, com quatro engenheiros dos times de Swift, Foundation e redes de servidor, e então o lançou sem legendas.1 Nós passamos o vídeo por uma transcrição local para ler o que eles de fato disseram. As sessões polidas dizem o que um recurso faz. O lab é onde a Holly admite que estava errada sobre uma decisão central de concorrência, onde o Corey explica o padrão de limpeza que falha silenciosamente em código cancelado, e onde o painel insiste em repetir um conselho que o marketing nunca vai dar: pare de colecionar recursos da linguagem. A versão franca está aqui.

Uma observação sobre as fontes: a Apple não divulgou nenhuma transcrição oficial do lab. Cada citação abaixo é uma paráfrase de uma transcrição local do vídeo publicado, com marcas de tempo aproximadas. Os participantes são identificados por primeiro nome e time, como a transcrição os apresenta: Holly (time da linguagem Swift, generics e concorrência), Corey (time de redes de servidor do Swift), Tony (Foundation e biblioteca padrão) e Doug (time da linguagem Swift).1

TL;DR

  • A Holly disse que, se o time desenhasse a concorrência do Swift hoje, as funções nonisolated async rodariam no contexto de quem as chama desde o primeiro dia. Ela manteve a crença oposta “por muito tempo” e mudou de ideia diante de evidências do mundo real. O Swift 6.2 tornou o contexto de quem chama o padrão.1
  • A orientação recorrente: torne tipos não Sendable de propósito. O ~Sendable (SE-0518, implementado no Swift 6.4) oferece uma grafia mais limpa, e a Foundation está reanotando tipos que havia marcado como proibidos, com o UserDefaults ganhando uma conformidade Sendable na instância global.21
  • O padrão de limpeza assíncrona do Corey: contextos cancelados pulam silenciosamente a limpeza assíncrona, então audite cada async defer em busca de chamadas await que suspendem e as envolva em um cancellation shield. O SE-0493 (defer async) e o SE-0504 (withTaskCancellationShield) chegam ambos no Swift 6.4.34
  • Franqueza sobre o roadmap: o tipo Disconnected é uma proposta ativa no fórum, as conformidades de tupla estão “quase lá”, mas formalmente de volta em revisão, o UniqueArray foi aceito em princípio, o Subprocess 1.0 está sendo lançado, e o SwiftPM está unificando em torno do Swift Build.5678
  • O tema recorrente do painel: “recursos de linguagem não são itens de coleção”. Faça profiling primeiro, adote a ferramenta específica para a qual o profiler aponta e deixe o resto em paz.1

A decisão de concorrência que a Apple tomaria de outro jeito

Assista: Swift Group Lab (WWDC26)

A retrospectiva de concorrência da Holly começa por volta de 33:42. O lab completo não tem legendas oficiais; a transcrição abaixo é de ASR local.

Um desenvolvedor fez ao painel uma pergunta que as sessões polidas raramente convidam: agora que a concorrência do Swift 6 já está em campo tempo suficiente para acompanhar a adoção, há algo que o time desenharia de forma diferente hoje? A Holly respondeu sem rodeios. Sim, com certeza.

O arrependimento específico está em onde uma função nonisolated async roda. Duas propostas do Swift Evolution moveram esse comportamento em direções opostas. A primeira fez com que funções nonisolated async sempre pulassem para o pool global de threads concorrentes. A posterior, no Swift 6.2, fez com que elas permanecessem no contexto que as chamou, de modo que uma função chamada a partir do main actor permanece no main actor.1 A Holly atribuiu a reviravolta a evidências de quem rodava as flags iniciais de verificação de concorrência em apps e bibliotecas reais: essas pessoas passavam tipos não Sendable de um lado para o outro entre um contexto isolado por actor e essas funções nonisolated async, e o padrão do pool global produzia erros de corrida de dados porque o actor original ainda mantinha esses valores enquanto a função assíncrona rodava em outro lugar.1

Aí vem a parte que não aparece em nenhuma gravação de sessão. “Eu mantive por muito tempo a crença de que rodar no pool global de threads concorrentes era o modelo certo para os benefícios de longo prazo”, disse a Holly, “mas fui convencida com o tempo por problemas em projetos do mundo real” (paráfrase de ASR, ~35:50).1 O Doug enquadrou a decisão original como uma aposta defensável no sistema como um todo: mais concorrência disponível significa mais potencial de paralelismo, o que pode significar melhor desempenho. O custo só apareceu quando as pessoas usaram o modelo de segurança completo, e ele empurrava tipos demais na direção de Sendable, o que o Doug chamou de “não a forma natural de expressar todas essas ideias”.1 O padrão do contexto de quem chama é mais acessível porque se comporta como código não concorrente até você optar explicitamente pelo paralelismo. Se você adotou o Swift 6.2 e se perguntou por que a história da concorrência de repente parecia mais tranquila, a resposta é: as pessoas que a projetaram admitiram que o primeiro padrão era o errado e lançaram a correção.

Torne seus tipos não Sendable de propósito

O conselho mais contraintuitivo do lab vai contra dois anos de hábito de migração. A Holly disse que encontra o tempo todo desenvolvedores perguntando como tornar seus tipos Sendable, e que a pergunta melhor costuma ser a oposta: esse tipo deveria ser não Sendable?1 Para tipos efêmeros usados dentro de um único cálculo, marcá-los explicitamente como não Sendable produz um modelo de dados mais limpo e uma linha mais nítida entre o que você pretende passar através das fronteiras de isolamento e o que não pretende. Também ajuda no desempenho, porque o custo de passar um tipo adiante é algo que você quer evitar pagar em valores intermediários que nunca precisaram viajar.1

O Swift 6.4 dá a essa intenção uma grafia de verdade. O ~Sendable (SE-0518) permite suprimir a conformidade diretamente, do mesmo jeito que o ~Copyable suprime a copiabilidade, em vez de escrever uma conformidade indisponível.2 A Holly fez a distinção com precisão: uma conformidade Sendable indisponível declara o tipo e toda subclasse como definitivamente não enviáveis e propaga isso por toda a hierarquia, ao passo que o ~Sendable é apenas a ausência de uma conformidade, de modo que uma subclasse que não adiciona estado mutável ainda pode incluir sua própria conformidade Sendable.21

Essa flexibilidade é exatamente o que a Foundation precisava. O Tony explicou a terceira categoria da auditoria Sendable original da Foundation: classes em que a superclasse é segura, mas uma subclasse pode não ser. O exemplo dele foi o NSString, que é imutável e enviável, contra o NSMutableString, que é uma subclasse mutável e não enviável.1 Em vez de apressar uma anotação errada, a Foundation marcou as classes ambíguas como não Sendable e esperou. Agora, disse o Tony no lab, o time está usando a anotação do Swift 6.4 para reanotar esses tipos com precisão, e ele espera que o UserDefaults global padrão ganhe uma conformidade Sendable.1 Trate a conformidade do UserDefaults e a reanotação mais ampla da Foundation como atribuídas ao lab: o Tony afirmou ambas no Q&A, e não são recursos que eu consiga confirmar de forma independente a partir de uma proposta publicada. O aviso permanente do painel vale aqui também, vindo do Tony: não recorra a @unchecked Sendable para forçar o modo Swift 6, porque cada anotação unchecked descarta a segurança que o compilador poderia ter provado para você.1

Limpeza assíncrona, feita de um jeito que de fato roda

O Corey é dono da correção mais prática do lab, e é o tipo de bug que você lança sem perceber. A vitória característica da concorrência estruturada é a propagação automática do cancelamento: cancele uma task e tudo o que foi criado a serviço dela também é cancelado, que é o que você quer quando uma view é dispensada ou um cliente se desconecta.1 A armadilha está na limpeza. Você pode ter um arquivo escrito pela metade que precisa ser descarregado para um estado consistente conhecido, ou uma transação de banco de dados para reverter, e essa limpeza é, ela própria, assíncrona. Como o Corey colocou, a maioria do código Swift se recusa a executar em um contexto cancelado porque presume que deve se desfazer o mais rápido possível, então a limpeza assíncrona rodando dentro de uma task cancelada pode silenciosamente deixar de fazer seu trabalho.1

A correção é um cancellation shield, e ele combina diretamente com o defer async. O SE-0493 permite que um bloco defer contenha chamadas await, chegando no Swift 6.4.3 O SE-0504 adiciona o withTaskCancellationShield, também no Swift 6.4, que roda um bloco como se o cancelamento não tivesse sido solicitado, de modo que a limpeza que suspende seja concluída.4 A receita de auditoria do Corey é concreta: olhe cada bloco async defer e pergunte se algum await dentro dele vai de fato suspender. Se for o caso, envolva-o em um cancellation shield.1 Ele chamou os dois de “um ótimo par” e “um golpe duplo realmente bom para deixar seus recursos limpos direitinho”.1 Tipos não Sendable reforçam a mesma disciplina, como o Corey observou, porque um valor que não pode cruzar domínios de concorrência força seu fluxo de controle assíncrono a se manter linear e fácil de raciocinar.1

O conselho mais amplo de concorrência estruturada do Corey arremata a seção. Aposte nela com firmeza, porque é nas saídas de emergência que mora o problema. Evite tasks não estruturadas (Task.detached ou um Task solto) “quase a qualquer custo”, a menos que você esteja deliberadamente enviando trabalho para outro lugar, e nunca no fluxo principal. Faça dos task groups seu padrão, ajuste os ciclos de vida dos objetos ao seu escopo léxico e escreva código assíncrono linear: uma receita de passo A, depois B, depois C, recorrendo ao paralelismo dentro de task groups apenas quando o trabalho realmente se ramifica.1

Franqueza sobre o roadmap

O lab também é onde o painel separa os recursos lançados dos otimistas, e a diferença importa quando você está decidindo sobre o que construir.

A questão de armazenar um valor não Sendable transferido tem uma resposta de verdade a caminho. Hoje você transfere com a palavra-chave sending, e o isolamento baseado em regiões deixa o compilador provar que o dono original liberou o acesso, mas se você precisa armazenar tal valor, só as alternativas inseguras de opt-out funcionam.1 A Holly apontou para o Disconnected, uma proposta ativa no fórum para um tipo que preserva a propriedade de transferência através do armazenamento, para que você possa guardar um valor e repassá-lo depois. Ele está sendo projetado e discutido agora mesmo, não implementado.51

As conformidades de tupla são o exemplo mais nítido do otimismo de engenheiro contra o status formal. Perguntada sobre o que falta para tuplas conformarem condicionalmente a Equatable, Hashable e Comparable, a Holly explicou que é uma evolução dos parameter packs: a linguagem precisa de sintaxe para escrever uma extension sobre uma tupla cujos tipos de elemento são um parameter pack, com uma cláusula where exigindo que cada elemento conforme.1 Ela disse que uma implementação experimental vive no repositório do compilador e está “quase totalmente lá”.1 O registro formal é mais cauteloso. O SE-0283, a proposta original de conformidades de tupla, foi devolvido para revisão e sua implementação de 2020 revertida; a abordagem geral de parameter packs existe hoje apenas atrás de uma flag experimental TupleConformances do compilador.10 Leia o “quase lá” da Holly como a leitura honesta de uma engenheira sobre a implementação, não como um recurso lançado.

Os contêineres de desempenho estão mais adiantados. O UniqueArray, que o Tony mencionou, vem do SE-0527 (“RigidArray e UniqueArray”), agora aceito em princípio, introduzindo um novo módulo Containers na biblioteca padrão; ele já é distribuído em uma forma inicial no swift-collections 1.3.7 O Tony o posicionou como a evolução para um Array cujo tráfego de retain/release por copy-on-write aparece em um trace do Instruments.1 O Subprocess, a API de processos open-source e multiplataforma que o Tony citou como sua favorita, está sendo lançado na versão 1.0 neste ano; o marco 1.0 foi anunciado, com a tag publicada mais recente ainda em 0.5, então ele está sendo lançado, mas não foi lançado ainda.61 Sobre ferramentas, a Holly descreveu a mudança no SwiftPM que os desenvolvedores talvez nem percebam: os builds de pacotes do Xcode e os builds da toolchain open-source agora compartilham uma única implementação, o Swift Build, que está se tornando o backend padrão do sistema de build (padrão no main, com alvo na 6.4).81

Por fim, o caminho de migração com que a Holly começou: o @diagnose, o novo atributo do SE-0522 (“Source-Level Control Over Compiler Warnings”), aceito.9 Ele dá controle dos avisos no nível do código-fonte, de modo que você pode suprimir avisos de depreciação em uma região ou optar por avisos desligados por padrão, como strict memory safety ou strict concurrency, nas áreas que mais importam, o que faz dele uma ferramenta mais granular para uma migração faseada ao Swift 6.1

Orientações de engenheiros, reunidas

O valor do lab está no conselho acumulado de quem põe a mão na massa, que nunca cabe no tempo de uma sessão. Os destaques, com atribuição:

  • Escreva código assíncrono linear. Corey: evite tasks não estruturadas quase a qualquer custo, mantenha cada task como uma receita sequencial e introduza paralelismo apenas dentro de task groups quando o trabalho realmente se ramifica.1
  • Uma receita de migração para o MainActor. Holly: comece pelos tipos folha e trabalhe para fora, ou ative main-actor-by-default para um módulo que deva ser inteiramente main actor e anote as partes descarregadas explicitamente. Marque como nonisolated os métodos que não tocam estado mutável e converta uma static var que nunca é de fato mutada em um let, para que ela possa permanecer nonisolated.1
  • Os custos de conformidade são desiguais. Doug: uma conformidade Equatable ou Hashable não usada mantém seu código de witness no binário, porque um cast as? em tempo de execução para um existencial pode descobri-la, então ela custa tamanho de código; o Sendable é uma etiqueta puramente de tempo de compilação, sem representação em tempo de execução, então uma conformidade Sendable não usada é gratuita.1
  • A combinação de @inlinable com @inline(never). O truque favorito do Corey: o @inlinable expõe o corpo de uma função através das fronteiras de módulo e libera especialização de genéricos e propagação de efeitos, enquanto o @inline(never) impede que um caminho frio e pesado em código (uma cópia de fallback byte a byte) seja inlinado, para que o caminho quente continue rápido. Ele usou o par “três vezes em todo o portfólio de redes do Swift”, para problemas incomuns de desempenho de caminho frio.1
  • Otimize o caminho mais quente, não o projeto. Corey: “Tivemos ótimo sucesso introduzindo spans e alguns unique arrays apenas ao longo do caminho mais quente”, o que entrega quase todos os ganhos de desempenho com uma mudança pequena e amparada pelo compilador. Mantenha os novos tipos de desempenho isolados, para que adotá-los nunca force uma refatoração gigante.1
  • Pare de colecionar recursos. A frase recorrente do painel, de um amigo que o Corey citou: “recursos de linguagem não são itens de coleção”. Você não ganha prêmio por usar todos eles. Faça profiling primeiro, recorra à ferramenta específica para a qual o profiler aponta (tipos não copiáveis, UniqueArray, Span) e gaste o resto das suas horas com correções de bugs e recursos.1

Perguntas frequentes

A Apple realmente publicou o lab de Swift da WWDC26 sem legendas?

Sim. A Apple postou o Swift Group Lab (sessão 8001) como um vídeo sem transcrição ou legendas oficiais no site de desenvolvedores.1 Para citá-lo com precisão, passei a gravação por uma transcrição local, então cada citação neste post é uma paráfrase desse ASR local com marcas de tempo aproximadas, atribuída por primeiro nome e time.1

O que o time de Swift disse que mudaria na concorrência?

A Holly disse que, se a Apple desenhasse a concorrência do Swift hoje, as funções nonisolated async rodariam no contexto de quem as chama desde o início, em vez de pular para o pool global de threads concorrentes. Ela manteve a crença no pool global por muito tempo e mudou de ideia diante de evidências do mundo real, e o Swift 6.2 tornou o comportamento do contexto de quem chama o padrão.1

Devo tornar meus tipos Swift Sendable ou não Sendable?

O conselho do lab é tornar os tipos efêmeros de computação não Sendable de propósito. O Swift 6.4 adiciona a grafia ~Sendable (SE-0518) para isso, distinta de uma conformidade indisponível porque as subclasses ainda podem adicionar Sendable quando não adicionam estado mutável.2 O Tony disse que a Foundation está reanotando suas classes ambíguas com o novo recurso e espera que o UserDefaults global ganhe uma conformidade Sendable, ambos atribuídos ao lab.1

Como garanto que a limpeza assíncrona rode quando uma task é cancelada?

Contextos cancelados fazem a maioria do código Swift pular o trabalho que suspende, então a limpeza assíncrona pode falhar silenciosamente. O padrão do Corey é auditar cada async defer em busca de chamadas await que de fato suspendem e envolvê-las em um cancellation shield. O defer async (SE-0493) e o withTaskCancellationShield (SE-0504) chegam ambos no Swift 6.4.341

As conformidades de tupla vão ser lançadas no Swift?

Ainda não. O SE-0283 foi devolvido para revisão e sua implementação original revertida; a abordagem geral de parameter packs existe apenas atrás de uma flag experimental TupleConformances. A Holly disse no lab que uma implementação experimental no compilador está “quase totalmente lá”, o que reflete otimismo de engenheiro, e não um recurso lançado.1


O lab é o complemento franco aos anúncios: para os recursos lançados em contexto, leia o que há de novo no Swift 2026, e para a mecânica de migração por trás do padrão de contexto de quem chama que a Holly discutiu, veja concorrência do Swift 6.2 na prática. A filosofia do painel de “faça profiling primeiro, adote a ferramenta específica” se estende aos testes em Swift Testing versus XCTest. A cobertura completa da WWDC26 está na Apple Ecosystem Series.

Referências


  1. Apple, WWDC 2026 session 8001, Swift Group Lab. Apple published no official transcript or captions for this lab; all quotes attributed to it are paraphrases from a local transcription of the published video, with approximate timestamps. Source for the concurrency retrospective (Holly, ~33:42), the make-types-non-Sendable guidance, the Foundation re-annotation and UserDefaults Sendable conformance (both lab-attributed to Tony), the async-cleanup and cancellation-shield pattern (Corey), the structured-concurrency and MainActor migration advice (Corey and Holly), the conformance-cost explanation (Doug), the @inlinable plus @inline(never) combo and hottest-path performance guidance (Corey), the Disconnected, tuple-conformance, UniqueArray, Subprocess, SwiftPM, and @diagnose remarks, and the “language features aren’t collectibles” theme. 

  2. Apple / Swift Evolution, SE-0518, ~Sendable for explicitly marking non-Sendable types. Status: Implemented (Swift 6.4). Source for suppressing the Sendable conformance and the distinction from an unavailable conformance. 

  3. Apple / Swift Evolution, SE-0493, Support async calls in defer bodies. Status: Implemented (Swift 6.4). Source for await inside defer blocks. 

  4. Apple / Swift Evolution, SE-0504, Task cancellation shields. Status: Implemented (Swift 6.4). Source for withTaskCancellationShield

  5. Swift Forums, Pitch: Disconnected type for modeling disconnected values. Active forums pitch for safely storing transferred non-Sendable values; not implemented. 

  6. Apple / Swift, Subprocess — cross-platform, open-source process API announced in 2025; version 1.0 announced as releasing this year, with the latest published tag at 0.5. Status per the lab and the project’s published releases. 

  7. Apple / Swift Evolution, SE-0527, RigidArray and UniqueArray. Status: Accepted in Principle; introduces a new standard-library Containers module and ships in an early form in swift-collections 1.3. 

  8. Swift Forums, SwiftPM development update: default build system change. Swift Build is becoming the default SwiftPM build-system backend (default on main, targeting 6.4). 

  9. Apple / Swift Evolution, SE-0522, Source-Level Control Over Compiler Warnings. Status: Accepted. Source for the @diagnose attribute and region-scoped warning control. 

  10. Apple / Swift Evolution, SE-0283, Tuples Conform to Equatable, Comparable, and Hashable. Status: Returned for revision; original implementation reverted. Source for the formal status of tuple conformances against the experimental TupleConformances flag. 

Artigos relacionados

What's New in Swift (2026): The WWDC26 Update

Swift 6.3 and 6.4 from WWDC26: anyAppleOS availability, module selectors, borrow/mutate accessors, the Iterable protocol…

19 min de leitura

O que o time de performance da Apple disse no lab da WWDC26

O time de Power & Performance da Apple respondeu perguntas de desenvolvedores ao vivo na WWDC26. Orientação de campo sob…

14 min de leitura

Loop Engineering: Loops Win Where Verification Is Cheap

Loop engineering, checked against Boris Cherny's full transcripts: every loop he names has cheap verification. That cons…

19 min de leitura