Le 15 juillet 2026, Richard Feldman, créateur du langage Roc, a publié un billet technique annonçant que, en 487 jours, ils avaient réécrit 300 000 lignes de Rust en Zig. Le temps de build incrémental du compilateur est passé de 3,4 secondes à 35 millisecondes — cent fois plus rapide.
Ce n’est pas un cas isolé. Avant cela, le compilateur du langage Gleam avait suivi la même voie : de Rust à Zig. Dans l’autre sens, le runtime Bun achevait début 2026 le mouvement inverse — de Zig à Rust, en seulement 11 jours.
Deux équipes d’exploits compilateurs de premier plan, des choix opposés. Quand les deux camps votent avec du vrai code, on comprend : au fond, c’est une question de balance.

35 millisecondes, ça veut dire quoi ?
3,4 secondes, c’est déjà rapide. J’ai écrit pas mal de projets en Rust, cargo check en deux-trois secondes, rust-analyzer qui ronronne en arrière-plan — avouons-le, on s’y fait. La vitesse de compilation de Rust a fait des bonds en 18 mois : Rust 1.97 a rogné les deux tiers du temps de build incrémental par rapport à 1.85. Feldman lui-même salue cet effort dans son article.
Mais 35 millisecondes, c’est une autre espèce.
35 millisecondes, c’est le temps où, à peine votre doigt a-t-il pressé Ctrl+S — avant même de le relever du clavier — le compilateur vous donne déjà la réponse. C’est la disparition de la boucle de feedback. mlugg, membre de l’équipe Zig, décrivait cette expérience sur Lobsters : chaque build incrémental ne lui prend qu’environ 30 ms, dont à peine 1 ms pour l’éditeur de liens. Car le nouvel éditeur de liens ELF de Zig est conçu pour un lien incrémental à la granularité de la fonction — modifier une fonction, le compilateur génère le nouveau code machine, l’éditeur de liens écrase en place l’ancien code dans le segment .text du fichier de sortie. Pas de syscall, le fichier de sortie étant mmap en mémoire.
Ce “zéro attente” change le rapport du développeur au compilateur. On n’accumule plus un batch de modifications avant de lancer un build ; on peut tâtonner vite entre modification et retour — comme avec un langage interprété, mais compilé. La nouvelle version du compilateur Roc supporte même le hot code loading : un serveur en cours d’exécution bascule automatiquement vers le code modifié sans redémarrer le processus. Standard dans le monde Python, luxe dans celui des langages compilés.
Alors, que “coûte” vraiment la sûreté des types de Rust ?
Si 35 ms est le sucré de Zig, à combien monte la “taxe de sûreté” que prélève Rust ? Décomposons.
Premier poste : le temps de compilation. Le borrow checker de Rust accomplit à la compilation quelque chose d’extrêmement luxueux — il prouve que votre programme n’a ni use-after-free, ni double-free, ni data race. Cette preuve parcourt tout le graphe des relations de référence, d’une complexité croissante en super-linéaire avec la taille du code. La compilation incrémentale de Rust progresse, mais la nature du borrow checker l’empêche d‘“sortir le résultat en un clin d’œil” comme Zig.
Deuxième poste : la liberté architecturale. Le compilateur Roc use massivement d’allocateur de type arena et de layout struct-of-arrays — toutes les structures de données remplacent les pointeurs par des indices 32 bits, scindés en tableaux indépendants par champ. Ce style file à toute allure sur un CPU moderne, et permet un mmap direct sur disque pour une “désérialisation sans parsing” — au second roc check, toutes les structures déjà analysées sautent du disque en mémoire, à la vitesse d’un memcpy.
Mais ce style se heurte quasi inévitablement au borrow checker de Rust. Le mode arena + indices contourne le système d’ownership, ce qui gonfle votre proportion d’unsafe bien au-delà d’un projet Rust typique. L’équipe de Feldman compte environ 1 200 occurrences d’unsafe sur 300 000 lignes de Rust — un ordre de grandeur au-dessus de la densité d’unsafe de rustc lui-même. Quand l’unsafe passe du “coin à auditer” à “la norme omniprésente”, la sérénité que procure le borrow checker s’effrite.
Les bilans des deux camps : les chiffres mentent, et disent vrai
Feldman a fait un travail d’honnêteté : il a compté les bugs de corruption mémoire dans les deux versions du compilateur.
Version Rust : 21. Version Zig : 10.
Au premier abord, Zig gagne. Mais en détail — les 21 bugs de la version Rust sont tous des miscompilation (le compilateur a généré un mauvais code machine), aucun dans la logique propre du compilateur. Le borrow checker a fait son job. Sur les 10 de Zig, 8 sont aussi des miscompilation, les 2 restants des use-after-free — tous deux dans le rendu du nom de fichier des rapports d’erreur, au symptôme : le nom de fichier dans le message d’erreur devenait du charabia.
La conclusion de Feldman, d’une sérénité surprenante : en regardant en arrière sur 18 mois de développement, des centaines de rapports de bug, des centaines de milliers de lignes de code, son sentiment principal est que “peu importe lequel on choisit”. Ces 2 use-after-free, le borrow checker de Rust les bloque, le mode ReleaseSafe de Zig panic au runtime — mais l’impact réel des trois solutions se résume à “deux rapports de bug : certains messages d’erreur n’affichent pas le nom de fichier”.
Cette conclusion fait écho, subtilement, à l’équipe Bun. En repassant de Zig à Rust, Bun soulignait que, pour un projet devant gérer à la fois les valeurs GC de JavaScript et la mémoire manuelle, le use-after-free est “une source abondante de bugs”. Feldman est tout à fait d’accord — avant de préciser que le compilateur Roc n’a pas à interagir avec JavaScript.
La clé n’est pas de savoir qui a tort ou raison. La clé est : le contexte décide de tout.

La fracture communautaire : pas une guerre sainte
L’article a recueilli 175 points et 62 commentaires sur Lobsters, et suscité un vif débat sur Hacker News. Mais le plus notable, c’est que les deux camps disposent d’arguments de terrain, solides et argumentés.
Ralf Jung, membre de l’équipe cœur de Rust, a pointé le problème du chiffre “40 000 occurrences d’unsafe dans rustc” cité par Feldman — ce nombre inclut la bibliothèque standard, les tests et les commentaires ; le vrai rustc en compte bien moins. Il concède toutefois : “je suis tout à fait d’accord que l’unsafe Rust est dur à écrire correctement, c’est une préoccupation majeure pour moi.”
llogiq — auteur du crate compact_arena — a noté que le système de typage par étiquettes de Rust peut distinguer à la compilation les indices de différents arenas, évitant l’erreur “mauvais tableau”. Mais il admet aussi que cette technique échoue quand le nombre d’arenas est inconnu à la compilation.
aapoalas — un utilisateur Rust se disant “fanatique du data-oriented design” — exprime l’état d’esprit typiquement ambivalent : “en tant que fanatique du data-oriented design et utilisateur intensif de Rust, voir un projet frère quitter Rust m’attriste.” Il énumère ensuite ses propres tentatives d’optimisation similaires en Rust, avec une honnêteté teintée de “regret”.
Le côté sain de cette querelle : personne ne traitant l’autre d’imbécile. Personne ne dit “choisir Rust, c’est ignorer la performance” ni “choisir Zig, c’est se moquer de la sûreté”. Tous reconnaissent un vrai compromis — puis tranchent selon le contexte de leur projet.
Un niveau plus profond : comptime vs proc macro
Sous le jeu de chiffres de vitesse se cache une divergence philosophique plus savoureuse : comment faire la méta-programmation à la compilation ?
Le choix de Zig, c’est comptime — vous écrivez du Zig ordinaire, simplement marqué pour exécution à la compilation. C’est comme un interpréteur intégré au compilateur, qui rend génériques, génération de code et manipulation de types aussi naturels qu’écrire du code runtime. Pas de seconde syntaxe, pas de manipulation de token tree, pas de bizarreries de macro hygiénique.
Le choix de Rust, c’est la proc macro — un programme Rust indépendant, exécuté à la compilation, qui reçoit un flux de tokens, le manipule et renvoie un flux de tokens. Extrêmement puissant (en théorie, tout est possible), mais extrêmement lourd. Chaque proc macro est un crate indépendant, dont la compilation prend du temps. Le comptime de Zig est imbriqué dans le même pipeline, sans surcoût notable.
Voilà une raison cachée de la rapidité de Zig : il n’a pas à compiler un système de macros avant de compiler votre code. Méta-programmation et programme partagent le même pipeline. Feldman écrit dans l’article : “I like that Zig has no macros.” — seul, ça ressemble à un râlage, mais en contexte, c’est une esthétique de la soustraction : un mécanisme de moins, une abstraction de moins, une charge de compilation de moins.
Bien sûr, soustraire, c’est perdre. Feldman avoue regretter les traits et les champs privés de Rust. C’est le pouvoir d’expression que Rust a gagné par addition. Choisir Zig, c’est accepter que “simplicité” prime sur “expressivité” — du moins pour les projets dont la vitesse de compilation est vitale.
Mon verdict : la poule et l’œuf, mais vous choisissez l’assiette
Ce n’est pas un billet partisan. Mon sentiment réel après cette analyse : la relation Rust-Zig passe de “lequel est meilleur” à “lequel convient à quoi”.
Si votre projet ressemble à un serveur web ou une base de données — structure de code assez stable, unsafe confiné à quelques points chauds, et vous tenez surtout à la confiance à long terme du borrow checker — Rust reste le choix le plus sûr à ce jour.
Si votre projet ressemble à un compilateur — code à réfactorer et itérer sans cesse, unsafe partout, et la vitesse de compilation dicte votre rythme de pensée — Zig devient une option qu’on ne peut plus ignorer. Car dans ce type de scénario, le coût de la sûreté se tarife différemment.
L’équipe Roc a redéfini le type de sûreté dont elle a besoin. Ses problèmes de mémoire surgissent surtout dans le code machine généré, non dans le compilateur lui-même — or le borrow checker ne couvre pas le premier. Quand le goulot d’étranglement de la sûreté échappe aux garanties du langage, payer en temps de compilation devient discutable.
L’écart entre 35 ms et 3,4 s incarne, en somme, deux philosophies de développement : l’une croit que la machine peut tout prouver à la compilation, l’autre que le développeur sait gérer à la runtime. Ni l’une ni l’autre n’est parfaite — mais au moins, les développeurs ont désormais de vraies options distinctes.
C’est probablement la meilleure nouvelle de la programmation système ces dernières années.
Liens de référence :
- Richard Feldman : How Our Rust-to-Zig Rewrite is Going (15 juillet 2026)
- Discussion Lobsters : How Our Rust-to-Zig Rewrite is Going (175 pts / 62 commentaires)
- Équipe Bun : Why We’re Rewriting Bun from Zig to Rust (2026)
- Journal de dev Zig : Incremental Compilation Demo
- FAQ Gleam : Why Rust for the compiler?