IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

  1. #1
    Invité de passage
    Profil pro
    Inscrit en
    Janvier 2003
    Messages
    37
    Détails du profil
    Informations personnelles :
    Localisation : Belgique

    Informations forums :
    Inscription : Janvier 2003
    Messages : 37
    Par défaut Bun passe à la version 1.4 et marque les esprits via une migration controversée de son code de Zig vers Rust
    Bun, la boîte à outils JavaScript sur laquelle tourne Claude Code, est en train d'être portée de Zig vers Rust par des agents IA
    entre expérience prometteuse et signal d'alarme, les développeurs sont partagés

    Racheté par Anthropic en décembre 2025, Bun, le runtime JavaScript ultra-rapide bâti sur Zig, traverse une semaine de remous. Pendant que certains développeurs s'interrogent sur l'avenir du projet dans le giron d'une entreprise d'IA dont le produit phare, Claude Code, accumule les critiques, son créateur Jarred Sumner publie discrètement un guide de portage vers Rust, alimenté par l'IA. Coïncidence malheureuse ou signal fort d'un tournant stratégique ? La communauté ne sait plus quoi penser.

    En décembre 2025, l'annonce du rachat de Bun par Anthropic avait été globalement bien accueillie. La logique semblait imparable : Claude Code est distribué sous forme d'exécutable Bun à des millions d'utilisateurs. Si Bun se casse, Claude Code se casse. Anthropic a donc une incitation directe à maintenir Bun excellent. Pour une communauté qui se demandait comment un projet financé par du capital-risque allait trouver un modèle économique viable, l'adossement à une entreprise valorisée à plusieurs dizaines de milliards de dollars paraissait être une bouée de sauvetage providentielle.

    L'annonce assurait que Bun resterait open source sous licence MIT, que la même équipe continuerait à travailler dessus, et que la feuille de route resterait centrée sur les outils JavaScript haute performance et la compatibilité Node.js. Cinq mois plus tard, ce tableau rassurant commence à se fissurer, non pas parce que Bun lui-même aurait fléchi, mais parce que son nouveau propriétaire donne des signes inquiétants de son rapport au logiciel produit.

    Nom : fast.png
Affichages : 28195
Taille : 243,6 Ko

    Claude Code, le cas d'école de la dégradation

    Il y a un an, Claude Code semblait prodigieux. C'était l'un des premiers outils de codage assisté par IA qui convainquait que les flux de travail des développeurs allaient évoluer de l'autocomplétion vers les agents. Il pouvait lire un projet, effectuer des modifications précises, exécuter des commandes, corriger des erreurs et persévérer. Ce qui avait transformé des sceptiques en évangélistes. Aujourd'hui, le même outil concentre les doléances.

    En avril 2026, les développeurs ont commencé à se plaindre de la qualité de Claude Code, du comportement vis-à-vis des limites d'utilisation, des restrictions imposées aux harnais tiers, d'une facturation opaque et d'une communication trop lente.

    Le 2 avril 2026, un ticket intitulé « Claude Code est inutilisable pour les tâches d'ingénierie complexes avec les mises à jour de février » est ouvert sur le dépôt officiel d'Anthropic. Son auteure : Stella Laurenzo, identifiable via son profil GitHub sous le pseudonyme stellaraccident et un post LinkedIn associé : directrice du groupe IA chez AMD. Le message n'est pas une simple plainte d'utilisatrice frustrée. C'est un rapport d'analyse de plusieurs semaines, produit par Claude lui-même à partir de données de sessions réelles, et qui pointe nommément Anthropic pour une dégradation progressive et non communiquée de son produit phare.

    Laurenzo explique que son équipe est parvenue à cette conclusion en s'appuyant sur des mois de logs issus d'un environnement de travail à haute complexité. Tous les ingénieurs seniors de son équipe ont rapporté des expériences similaires. Le verdict est sans appel : « Claude ne peut plus être considéré comme fiable pour des tâches d'ingénierie complexes. »

    Anthropic a publié un post-mortem technique reconnaissant plusieurs problèmes : un effort de raisonnement par défaut réduit, un bug de session périmée, et une modification de prompt ayant dégradé la qualité de génération de code.

    Puis vint l'affaire OpenClaw. TechCrunch a rapporté qu'Anthropic avait indiqué aux abonnés de Claude Code qu'ils devraient payer un supplément pour utiliser OpenClaw et d'autres harnais tiers. Plus préoccupant encore : le simple fait de mentionner « OpenClaw » dans l'historique git pouvait provoquer un refus de Claude Code ou générer une surfacturation, même dans un dépôt vide lors d'un simple appel à claude -p "hi". Ce type de comportement, où le contexte textuel d'un commit modifie silencieusement la facturation, illustre précisément ce que la communauté désigne par le terme d'enshittification : une dégradation progressive et méthodique de l'expérience utilisateur au profit de mécanismes de monétisation.

    L'effet de contamination craint sur Bun

    C'est dans ce contexte que le développeur William Johnston publie un billet intitulé « I am worried about Bun ». Le raisonnement est simple : Bun est embarqué dans Claude Code. Claude Code semble s'enshittifier. On est donc en droit de s'inquiéter que Bun puisse suivre le même chemin. Non pas parce que Bun est mauvais, il ne l'est pas, ni parce que l'équipe Bun a cessé de s'en soucier, mais parce qu'à mesure que Bun et son équipe s'intègrent davantage dans Anthropic, les mêmes politiques qui ont conduit à la dégradation de Claude Code pourraient s'y appliquer.

    Johnston annonce donc migrer ses projets vers pnpm, tout en précisant qu'il ne recommande pas nécessairement cette démarche à tous : pour les nouveaux projets, pnpm fait sens ; pour les projets existants, mieux vaut rester avec Bun à moins d'avoir une bonne raison d'en partir.

    Sur Hacker News, la discussion divise. Un commentateur, AntonyGarand, apporte un contre-argument structuré : avant l'acquisition, Bun devait de toute façon trouver un modèle de monétisation. Et même si la maison mère adopte des pratiques discutables avec ses autres logiciels, il est exagéré d'en déduire que cela se traduira par une dégradation de Bun. Claude Code est au cœur de la croissance d'Anthropic, là où tout changement peut entraîner des problèmes de facturation ; Bun est un runtime JavaScript qui peut se concentrer sur l'excellence sans peser sur le compte de résultat. La distinction est pertinente : Bun ne génère pas directement de revenus pour Anthropic, ce qui le soustrait pour l'instant aux pressions de monétisation court-termistes.

    Nom : simon.png
Affichages : 2473
Taille : 130,1 Ko

    Le guide de portage Zig → Rust : expérience ou signal ?

    C'est alors que survient un deuxième événement, simultané et hautement symbolique. Le créateur de Bun, Jarred Sumner, a publié un guide de portage Zig-vers-Rust, alimentant les spéculations sur une possible migration du projet en dehors de Zig. Le commit, poussé sur la branche claude/phase-a-port, porte bien la signature d'une démarche pilotée par IA.

    Le document de portage est en réalité un prompt système adressé à un agent IA. La « Phase A » consiste à produire un fichier .rs en miroir du fichier .zig qui capture fidèlement la logique, sans nécessairement compiler. La « Phase B » assure la compilation module par module. Certaines bibliothèques sont explicitement exclues : tokio, rayon, hyper, async-trait. On est dans la génération de code assez contrainte, pas dans le vibe coding débridé, mais la communauté a tout de même tiqué.

    Sur Hacker News, un commentateur a fait remarquer l'ironie de la situation : le fil de discussion sur les inquiétudes autour de Bun mentionnait qu'Anthropic ne ferait pas de « vibe coding expérimental » sur sa propre base de code, or voilà que dans le même temps, on découvre exactement ce type de démarche en cours.

    Sumner lui-même a cherché à tempérer les attentes sur Hacker News : « Nous ne nous sommes pas engagés à réécrire. Il y a une probabilité très élevée que tout ce code soit finalement jeté. Je suis curieux de voir à quoi ressemble une version fonctionnelle, ce qu'elle donne, comment elle performe. »

    Pourquoi abandonner Zig ?

    Les raisons d'une éventuelle migration ne sont pas que cosmétiques. L'équipe Bun a déjà forké Zig, revendiquant une amélioration par quatre des temps de compilation en mode debug grâce à la génération de code parallèle avec LLVM. Ces améliorations ne peuvent pas être reversées en amont vers Zig en raison de sa politique stricte d'interdiction des contributions IA.

    Cette politique est au cœur du désaccord. Selon Loris Cro, membre de la Zig Software Foundation, « la réalité des contributions basées sur les LLM a été principalement négative : augmentation du bruit de fond dû à des pull requests sans valeur remplies d'hallucinations, voire des premières contributions de 10 000 lignes absurdes ». La position de Zig est donc idéologique autant que technique.

    La politique anti-IA de Zig pourrait s'avérer embarrassante pour Anthropic, qui a acquis Bun fin 2025 et l'utilise pour Claude Code. Comment en effet justifier de maintenir un langage hôte dont la gouvernance interdit toute contribution générée par IA, quand votre modèle économique repose précisément sur la vente d'outils de génération de code ? La contradiction est structurelle.

    Un autre facteur milite pour le changement : Andrew Kelley, le créateur de Zig, n'hésite pas à introduire des changements cassants dans le langage, ce qui complique son utilisation pour des projets de production d'envergure. Pour un runtime distribué à des millions de développeurs, la stabilité du langage hôte n'est pas un luxe.

    Le précédent de l'IA comme outil de migration

    Si la migration Zig → Rust se concrétisait, elle s'inscrirait dans une tendance plus large. Cloudflare a réimplémenté la majeure partie de l'API Next.js en une semaine avec l'aide de l'IA, et le projet Ladybird a porté son moteur JavaScript de C++ vers Rust en deux semaines. Ces chantiers auraient été impensables à cette vitesse sans assistance par LLM... et ils ont tenu la route.

    La portée idéologique de la démarche Sumner va plus loin encore. Commentant l'interdiction de l'IA par Zig, il a déclaré sur X qu'il s'attendait à ce que l'open source parte dans la direction opposée : « aucune contribution humaine autorisée ». Les humains discuteront encore des problèmes et des priorités, mais l'acte d'écrire du code, de soumettre des pull requests, de traiter les retours et d'implémenter sera l'affaire des LLM. Une prophétie qui sonne comme un manifeste et qui explique pourquoi le guide de portage Bun est structuré comme un système de prompt plutôt que comme une documentation classique.

    Une semaine révélatrice

    Deux événements en 48 heures : un développeur influent annonce quitter Bun par crainte de son devenir sous Anthropic, et l'équipe Bun révèle une expérimentation de portage par IA vers Rust. Sur Lobste.rs, certains soulignent que le guide PORTING.md fait environ 16 000 tokens et que « l'année dernière, aucun modèle n'aurait suivi de manière utile un tel document de portage ; pratiquement tous les modèles de nouvelle génération ont depuis revendiqué une meilleure capacité à suivre les instructions ». L'expérience serait donc impossible à mener sérieusement il y a douze mois. Ce qui dit beaucoup sur la vitesse à laquelle les LLM changent les pratiques d'ingénierie système.

    La véritable question que soulève cette semaine n'est peut-être pas « Bun survivra-t-il à Anthropic ? » mais plutôt : « à quoi ressemble un logiciel d'infrastructure maintenu, voire réécrit, principalement par des agents IA ? » Bun était jusqu'ici l'un des projets qui répondait le mieux aux critères de qualité artisanale; vitesse brute, fiabilité, expérience développeur soignée. Si ces qualités survivent à une migration par LLM, ce sera la preuve que le vibe coding peut atteindre la qualité de production sur des bases de code critiques. Si elles disparaissent, ce sera un avertissement coûteux.

    Sources : Guide de portage Zig → Rust (GitHub), William Johnston, Loris Cro, zigland

    Et vous ?

    L'acquisition d'un outil d'infrastructure open source par une entreprise d'IA dont c'est l'usage interne constitue-t-elle une garantie de pérennité ou un risque de capture ? Où se situe le point de bascule ?

    Zig a choisi d'interdire les contributions IA pour préserver la qualité de son tracker. Faudra-t-il généraliser ce type de politique dans les projets open source critiques, ou cela condamne-t-il les projets qui l'adoptent à une extinction lente ?

    Si Bun migre vers Rust via des agents IA, et que les benchmarks restent comparables, doit-on considérer cela comme une réussite de l'ingénierie assistée par LLM ou comme un précédent inquiétant pour la lisibilité et la maintenabilité du code à long terme ?

    La déclaration de Jarred Sumner, à savoir « aucune contribution humaine autorisée » dans l'OSS de demain, est-elle une utopie d'efficacité ou la description d'un futur dans lequel les développeurs perdent le contrôle réel de leurs outils ?

    Claude Code se dégrade pendant qu'Anthropic monte en puissance commercialement : est-ce le signe inévitable qu'aucune entreprise ne peut maintenir l'excellence produit en période de croissance exponentielle, ou une défaillance spécifique à la culture d'ingénierie d'Anthropic ?

    Voir aussi :

    La directrice de l'IA d'AMD critique vivement Claude Code d'Anthropic, le jugeant moins performant et moins efficace depuis sa dernière mise à jour : « Je ne peux plus recommander Claude Code à mes clients »

    Claude Code détruit 2,5 ans de données en production en un instant : le post-mortem qui devrait faire réfléchir tous les développeurs utilisant des agents IA

    Anthropic interdit officiellement l'utilisation de l'authentification par abonnement à Claude Code à des fins tierces, y compris OpenClaw. Les développeurs doivent désormais utiliser des clés API à la place

  2. #2
    Communiqués de presse

    Homme Profil pro
    Rédacteur technique
    Inscrit en
    Avril 2025
    Messages
    914
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Paris (Île de France)

    Informations professionnelles :
    Activité : Rédacteur technique

    Informations forums :
    Inscription : Avril 2025
    Messages : 914
    Par défaut La boîte à outils JavaScript Bun fait un choix surprenant : passer de Zig à Rust
    Une pull request contenant une version Rust de Bun de Claude Code d'Anthropic, une boîte à outils et un moteur d'exécution JavaScript initialement écrits en Zig, a été fusionnée dans le dépôt principal de Bun

    Les développeurs du moteur d'exécution JavaScript Bun ont décidé de réécrire en grande partie la plateforme en Rust. Ce faisant, le projet s'éloigne de Zig, le langage de programmation qui a fait la renommée de Bun à l'origine. Ce changement suscite un intérêt particulier, car Bun fait partie d'Anthropic depuis décembre dernier et joue un rôle au sein de Claude Code. La migration a été en grande partie réalisée à l’aide de Claude Code. Cela crée un scénario saisissant dans lequel une plateforme de codage IA contribue à réécrire l’infrastructure sur laquelle elle s’exécute. Dans le même temps, cette opération suscite un débat animé parmi les développeurs.

    Anthropic est une entreprise américaine spécialisée dans l'intelligence artificielle (IA) dont le siège social se trouve à San Francisco. Elle a développé une gamme de grands modèles de langage (LLM) baptisés Claude et se concentre sur la sécurité de l'IA. Anthropic a été fondée en 2021 par d'anciens membres d'OpenAI. Claude Code est un agent IA en ligne de commande conçu pour le codage. Avec l'arrivée de Claude Code, le « vibe coding », une approche de programmation dans laquelle les utilisateurs décrivent les résultats souhaités en langage naturel et laissent un agent IA écrire le code, est devenu de plus en plus populaire. En décembre 2025, Anthropic a racheté Bun afin d'améliorer la rapidité et la stabilité de Claude Code.

    L’annonce du rachat de Bun par Anthropic surprend autant qu’elle intrigue. En un seul mouvement, l’un des laboratoires d’IA les plus avancés au monde absorbe l’un des runtimes JavaScript les plus rapides et les plus prometteurs de ces dernières années. Derrière cette alliance inattendue se cache une stratégie profonde : maîtriser la chaîne complète du développement moderne, de l’exécution applicative à l’orchestration d’agents IA distribués. Ce rapprochement ouvre un nouveau chapitre pour l’écosystème JavaScript, pour l’open source et pour la manière dont l’IA s’intègre dans les architectures Web et DevOps.

    Depuis le début de mai 2026, Bun, le runtime JavaScript ultra-rapide bâti sur Zig, traverse une période de remous. Pendant que certains développeurs s'interrogent sur l'avenir du projet dans le giron d'une entreprise d'IA dont le produit phare, Claude Code, accumule les critiques, son créateur Jarred Sumner a publié discrètement un guide de portage vers Rust, alimenté par l'IA. La communauté a alors émis des inquiétudes autour de Bun, mais Sumner lui-même a cherché à tempérer les attentes : « Nous ne nous sommes pas engagés à réécrire. Il y a une probabilité très élevée que tout ce code soit finalement jeté. Je suis curieux de voir à quoi ressemble une version fonctionnelle, ce qu'elle donne, comment elle performe. »

    Pourtant, un nouveau rapport a récemment révélé que les développeurs du moteur d'exécution JavaScript Bun ont décidé de réécrire en grande partie la plateforme en Rust. Ce faisant, le projet s'éloigne de Zig, le langage de programmation qui a fait la renommée de Bun à l'origine. Ce changement suscite un intérêt particulier, car Bun fait partie d'Anthropic depuis décembre dernier et joue un rôle au sein de Claude Code.

    Ce changement a été révélé par une pull request massive sur GitHub. Elle concerne environ 2 188 fichiers modifiés et près d’un million de lignes de code réécrites. Seules quelques milliers de lignes auraient été supprimées. Cela fait de cette opération l’une des plus importantes conversions de code liées à l’IA à avoir été rendue publique. Selon le fondateur de Bun, Jarred Sumner, l’architecture existante restera en grande partie intacte, mais Rust offre de meilleurs outils pour détecter précocement les problèmes de mémoire et de stabilité.


    Depuis son lancement, Bun est considéré comme l’un des projets logiciels les plus connus s’appuyant fortement sur Zig. Le passage à Rust est donc perçu par de nombreux développeurs comme bien plus qu’un simple choix technique. Un débat émerge au sein de la communauté open source concernant l’influence d’Anthropic sur l’orientation future du projet. Anthropic avait précédemment annoncé avoir acquis Bun dans le cadre de l’infrastructure sous-jacente à Claude Code. Selon l’entreprise spécialisée dans l’IA, cet environnement de développement a atteint un chiffre d’affaires annuel d’environ 1 milliard de dollars en quelques mois.

    La migration a été en grande partie réalisée à l’aide de Claude Code. Cela crée un scénario saisissant dans lequel une plateforme de codage IA contribue à réécrire l’infrastructure sur laquelle elle s’exécute. Dans le même temps, cette opération suscite un débat animé parmi les développeurs. Les critiques soulignent que certains tests ont été modifiés afin que la version Rust les passe avec succès. De plus, des tickets GitHub apparaîtraient avec des erreurs qui ne se produisaient pas dans la version Zig d’origine.

    Selon Sumner, la migration vise avant tout à améliorer la maintenabilité. Les développeurs indiquent que les tests existants sont désormais réussis sur toutes les plateformes prises en charge et que de nombreuses fuites de mémoire et tests instables ont été résolus. Le débat autour de Bun dépasse désormais le simple choix entre Zig et Rust. Les développeurs s'interrogent ouvertement sur la mesure dans laquelle les outils d'IA peuvent migrer et maintenir de manière autonome des logiciels d'infrastructure complexes.

    En conséquence, Bun semble de plus en plus devenir un cas d'étude concret pour le développement logiciel assisté par l'IA au niveau de l'infrastructure. Il est frappant de constater qu'on ignore encore combien de jetons, quelle puissance de calcul et quels coûts de développement ont été nécessaires pour cette migration. C'est précisément cet aspect qui pourrait déterminer si un portage IA à si grande échelle devient également réalisable en dehors des grandes entreprises d'IA.

    Il y a un an, Claude Code semblait prodigieux. Aujourd'hui, le même outil concentre les critiques. Par exemple, en mars, un développeur a confié à Claude Code la gestion d'une migration d'infrastructure Terraform sur AWS. En quelques minutes, l'agent a détruit l'intégralité de son environnement de production — base de données, snapshots compris — faisant disparaître 2,5 ans d'historique de cours. L'incident, rendu public dans un post-mortem exemplaire, soulève une question que l'essor fulgurant du vibe coding ne peut plus esquiver : jusqu'où peut-on déléguer à une IA des opérations irréversibles sur des environnements de production ?

    Source : Bun sur GitHub

    Et vous ?

    Pensez-vous que ce rapport est crédible ou pertinent ?
    Quel est votre avis sur le sujet ?

    Voir aussi :

    La fuite du code source de Claude Code révèle les plans d'Anthropic : un agent persistant, un mode « furtif » pour cacher ses traces dans l'open source, un mécanisme anti-distillation pour la concurrence

    Rust a-t-il atteint son plafond de popularité ? Le langage recule de trois places dans l'index TIOBE d'avril 2026. Son PDG évoque une « courbe d'apprentissage difficile pour les développeurs non experts »

    Krishna Rao, directeur financier d'Anthropic, affirme que l'IA rédige désormais 90 % du code de l'entreprise et qu'elle est désormais capable de gérer la couche d'exécution des tâches intellectuelles
    Publication de communiqués de presse en informatique. Contribuez au club : corrections, suggestions, critiques, ... Contactez le service news et Rédigez des actualités

  3. #3
    Membre Expert Avatar de Uther
    Homme Profil pro
    Tourneur Fraiseur
    Inscrit en
    Avril 2002
    Messages
    4 785
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Pyrénées Orientales (Languedoc Roussillon)

    Informations professionnelles :
    Activité : Tourneur Fraiseur

    Informations forums :
    Inscription : Avril 2002
    Messages : 4 785
    Par défaut
    En conséquence, Bun semble de plus en plus devenir un cas d'étude concret pour le développement logiciel assisté par l'IA au niveau de l'infrastructure. Il est frappant de constater qu'on ignore encore combien de jetons, quelle puissance de calcul et quels coûts de développement ont été nécessaires pour cette migration. C'est précisément cet aspect qui pourrait déterminer si un portage IA à si grande échelle devient également réalisable en dehors des grandes entreprises d'IA.
    C'est en effet un excellent cas d'étude de ce qu'il ne faut pas faire. Claude est un excellent outil, mais ce n'est pas une machine parfaite qui maitrise toutes les subtilités du codage, loin de là. Migrer un million de lignes en une semaine, ça veut dire qu'il n'y a eu quasiment aucune supervision humaine et ça se voit. Le code Rust produit ne respecte pas le principes de base du langage : il y a du code unsafe injustifié un peu partout et une partie est visiblement problématique. Si le but était d'améliorer la sécurité et la maintenabilité, je ne pense pas que ça soit concluant, loin de là.

    A contrario on peut constater un autre cas d'étude : LadyBird a aussi utilisé Claude pour migrer une partie de son code mais de manière plus cadrée : il se sont limités dans un premier temps à une partie du projet de 20 000 lignes, ils ont pris deux semaines, et le tout a été fait sous supervisation humaine. Le résultat est autrement plus convainquant.

    C'est inquiétant que ça soit Anthropic le créateur de Claude qui montre son mauvais usage.

  4. #4
    Chroniqueur Actualités
    Avatar de Patrick Ruiz
    Homme Profil pro
    Redacteur web
    Inscrit en
    Février 2017
    Messages
    2 582
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : Cameroun

    Informations professionnelles :
    Activité : Redacteur web
    Secteur : Communication - Médias

    Informations forums :
    Inscription : Février 2017
    Messages : 2 582
    Par défaut Bun passe à la version 1.4 et marque les esprits via une migration controversée de son code de Zig vers Rust
    Bun, le moteur d’exécution Javascript racheté par Anthropic, passe à la version 1.4 et marque les esprits via une migration controversée de son code de Zig vers Rust, menée à l’aide de Claude Fable

    Bun a fait passer son code de Zig vers Rust pour résoudre des problèmes complexes de gestion de la mémoire, de stabilité et de maintenance, tout en s'appuyant sur un flux de travail piloté par l'IA (notamment via Claude Fable) qui a rendu cette migration massive possible en un temps record. La manœuvre relance le débat sur la comparaison de Rust avec d’autres langages utilisés dans la filière de la programmation système (Zig, C, C++), ainsi que celui de la pertinence du vibe coding dans la filière du développement de logiciels.

    Bun est un moteur d’exécution initialement développé en Zig – un langage de programmation présenté comme un remplaçant potentiel du C. La tête derrière le projet vient d’annoncer le passage complet du code source de Zig vers Rust. Selon Jared Sumner, ce choix a été motivé par la nécessité de la mise à contribution de Rust pour corriger certaines tares de Zig, notamment en matière de gestion des accès à la mémoire.

    Google a opéré une migration similaire de C++ vers Rust pour les mêmes raisons sous-jacentes : l’exploitation des avantages de Rust (en comparaison aux autres langages) en matière de sécurisation des accès à la mémoire. Mais certains acteurs de la filière sont d'avis que le véritable gage de sécurisation de la mémoire réside dans les aptitudes des programmeurs

    Le billet de blog y relatif souligne entre autres des dizaines de bugs de type use-after-free (le noyau réutilise un pan de mémoire qu’il a déjà libéré), double-free (double utilisation de la fonction free() sur la même adresse mémoire) et fuites mémoire dans des modules critiques (node:zlib, node:http2, UDPSocket, crypto.scrypt, TLS…) dus à l’utilisation de Zig comme langage de programmation dans le processus de développement de Bun.

    L’argument central est que Zig, comme le C, ne gère pas la mémoire pour le programmeur, et ne dispose pas de constructeurs/destructeurs. Le nettoyage repose sur le mot-clé explicite defer. Il est manuel et il faut donc penser à l’utiliser, rendant l’erreur humaine quasi inévitable à grande échelle. Google aussi a adopté Rust et rapporte avoir constaté une réduction de 1000 fois des vulnérabilités liées à la sécurité de la mémoire.

    Mais Bjarne Stroustrup est d’avis que ce qu’il est possible d’obtenir du C++ en matière de sécurisation des logiciels dépend entre autres du développeur et notamment de la connaissance des outils que lui offre le langage, de sa maîtrise du compilateur, etc. En gros, le problème en matière de sécurisation de la mémoire se trouve entre la chaise et le clavier et d’avis de Bjarne Stroustrup c’est le programmeur.

    En droite ligne avec cette position, le créateur du C++ propose donc des Profils qui ont pour but de définir des modes de C++ qui imposent des contraintes sur la manière dont le programmeur utilise le langage et la bibliothèque, afin de garantir certaines propriétés de sécurité. Il s'agit principalement de contraintes au moment de la compilation, bien que dans la pratique, certaines vérifications puissent être mises en œuvre à l'aide de fonctionnalités de bibliothèque qui ajoutent une surcharge d'exécution limitée.

    Au lieu d'introduire des constructions de langage entièrement nouvelles, les Profils limitent principalement les fonctionnalités et les utilisations existantes. L'idée est que vous pouvez activer un profil, et tout code qui l'utilise accepte de se conformer aux restrictions. Si vous ne l'activez pas, tout fonctionne comme avant. Il est donc rétrocompatible.

    Jared Sumner a envisagé le C++ pour cette initiative de migration mais a finalement opté pour le Rust et ses avantages en matière de sécurisation de la mémoire.

    Le vibe coding via Claude Fable a joué un rôle prépondérant dans cette migration en permettant de la boucler en quelques jours. De l’autre côté, cette initiative est la preuve que l’expertise humaine reste requise pour obtenir des produits logiciels utilisables et maintenables sur le long terme après mise à contribution de l’IA

    La plus-value de l’utilisation de l’intelligence artificielle qui est en général mise en avant dans le processus du développement de logiciels est le gain de productivité. Le cas de la migration du code source Bun de Zig vers Rust ne fait pas exception étant donné que Jared Sumner rapporte que cette transition a été possible en seulement 11 jours contre une année pour une petite équipe d’ingénieurs lancée sur les 535 496 lignes de code de Zig, selon son estimatif.

    Résultat :

    • le code en Rust produit par l'IA contient plus de 13 000 blocs unsafe, soit une proportion anormalement élevée comparée aux projets écrits par des humains. Par exemple, la gestion de la mémoire de bas niveau et les allocateurs personnalisés s'interfacent directement avec les pointeurs bruts via des constructions non sécurisées (unsafe). Elle gère la provenance des pointeurs et les appels explicites de désallocation par le biais des tables virtuelles (vtables) des allocateurs standard comme on peut le voir dans la section de code suivante :


    Code Rust : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    473
    474
    475
    476
    477
    478
    479
    480
    481
    482
    483
    484
    485
    486
    487
    488
    489
    490
    491
    492
    493
    494
    495
    496
    497
    498
    499
    500
    501
    502
    503
    504
    505
    506
    507
    508
    509
    510
    511
    512
    513
    514
    515
    516
    517
    518
    519
    520
    521
    522
    523
    524
    525
    526
    527
    528
    529
    530
    531
    532
    533
    534
    535
    // bun_alloc is the T0 foundation crate that bun_threading and bun_collections
    // depend on; importing either to satisfy the disallowed-types lint would create
    // a dependency cycle.
    #![allow(clippy::disallowed_types)]
    #![feature(arbitrary_self_types_pointers)]
    #![feature(allocator_api)]
    // `#[thread_local]` (vs the `thread_local!` macro) compiles to a bare
    // `__thread` slot — single `mov reg, fs:[OFFSET]` access, no `LocalKey`
    // `__getit()` wrapper, no lazy-init flag check, no dtor-registration probe.
    // Used for the per-allocation hot-path TLS in `ast_alloc::AST_ALLOC`.
    #![feature(thread_local)]
     
    use core::fmt::Write as _;
    use core::mem::{MaybeUninit, size_of};
    use core::ptr::{NonNull, addr_of_mut};
    use core::sync::atomic::{AtomicU16, AtomicU32, Ordering};
    use std::collections::HashMap;
     
    // ──────────────────────────────────────────────────────────────────────────
    // Re-exports
    // ──────────────────────────────────────────────────────────────────────────
     
    pub use bun_mimalloc_sys::mimalloc;
    pub mod c_thunks;
     
    // ── Allocator vtable ───────────────────────────────────────────────────────
    #[repr(transparent)]
    #[derive(Clone, Copy, PartialEq, Eq)]
    pub struct Alignment(pub u8); // log2 of byte alignment
    impl Alignment {
        #[inline]
        pub(crate) const fn to_byte_units(self) -> usize {
            1usize << self.0
        }
        #[inline]
        pub(crate) const fn from_byte_units(b: usize) -> Self {
            Self(b.trailing_zeros() as u8)
        }
    }
     
    // ── `max_align_t` alignment ────────────────────────────────────────────────
    // The `libc` crate does not expose `max_align_t` on every target Bun ships
    // (missing on Windows MSVC and on FreeBSD aarch64), so those targets carry a
    // local mirror of `max_align_t`. Remaining non-Windows targets keep
    // `libc::max_align_t` (which carries `long double`, align 16 on x86_64/aarch64;
    // the {f64,i64,*const ()} fallback would silently downgrade to 8).
    #[cfg(windows)]
    #[repr(C)]
    struct MaxAlignT {
        _f: f64,
        _i: i64,
        _p: *const (),
    }
    #[cfg(windows)]
    pub(crate) const MAX_ALIGN_T: usize = core::mem::align_of::<MaxAlignT>();
    // On AArch64
    // AAPCS64 `long double` is IEEE binary128, 16-byte aligned. The `libc` crate
    // only defines `max_align_t` for FreeBSD on x86_64, so hardcode the ABI value
    // for the aarch64 port.
    #[cfg(all(target_os = "freebsd", target_arch = "aarch64"))]
    pub(crate) const MAX_ALIGN_T: usize = 16;
    #[cfg(not(any(windows, all(target_os = "freebsd", target_arch = "aarch64"))))]
    pub(crate) const MAX_ALIGN_T: usize = core::mem::align_of::<libc::max_align_t>();
     
    pub struct AllocatorVTable {
        pub alloc: unsafe fn(*mut core::ffi::c_void, usize, Alignment, usize) -> *mut u8,
        pub resize: unsafe fn(*mut core::ffi::c_void, &mut [u8], Alignment, usize, usize) -> bool,
        pub remap: unsafe fn(*mut core::ffi::c_void, &mut [u8], Alignment, usize, usize) -> *mut u8,
        pub free: unsafe fn(*mut core::ffi::c_void, &mut [u8], Alignment, usize),
    }
    impl AllocatorVTable {
        /// `alloc` impl that always fails. For vtables that only ever `free` an
        /// externally-produced buffer (mmap region, plugin-owned memory, refcounted
        /// foreign string) and never allocate or grow it.
        pub(crate) const NO_ALLOC: unsafe fn(
            *mut core::ffi::c_void,
            usize,
            Alignment,
            usize,
        ) -> *mut u8 = |_, _, _, _| core::ptr::null_mut();
        pub(crate) const NO_RESIZE: unsafe fn(
            *mut core::ffi::c_void,
            &mut [u8],
            Alignment,
            usize,
            usize,
        ) -> bool = |_, _, _, _, _| false;
        pub(crate) const NO_REMAP: unsafe fn(
            *mut core::ffi::c_void,
            &mut [u8],
            Alignment,
            usize,
            usize,
        ) -> *mut u8 = |_, _, _, _, _| core::ptr::null_mut();
     
        /// Build a "free-only" vtable: `alloc`/`resize`/`remap` all no-op/fail and
        /// only `free` is meaningful. Each call site still gets its own `static`
        /// (vtable address is an identity tag for `is_instance`).
        pub const fn free_only(
            free: unsafe fn(*mut core::ffi::c_void, &mut [u8], Alignment, usize),
        ) -> Self {
            Self {
                alloc: Self::NO_ALLOC,
                resize: Self::NO_RESIZE,
                remap: Self::NO_REMAP,
                free,
            }
        }
    }
     
    /// Fat allocator handle (ptr + vtable). Distinct from the `Allocator` trait below.
    #[derive(Clone, Copy)]
    pub struct StdAllocator {
        pub ptr: *mut core::ffi::c_void,
        pub vtable: &'static AllocatorVTable,
    }
     
    // SAFETY: `ptr` is an opaque tag/context handle; the vtable is `&'static`.
    // Thread-safety of dispatch is the implementor's concern (mimalloc is
    // thread-safe).
    unsafe impl Send for StdAllocator {}
    // SAFETY: see the `Send` impl directly above.
    unsafe impl Sync for StdAllocator {}
     
    impl Default for StdAllocator {
        /// The mimalloc-backed `c_allocator`.
        #[inline]
        fn default() -> Self {
            basic::C_ALLOCATOR
        }
    }
     
    impl StdAllocator {
        #[inline]
        pub(crate) fn raw_free(&self, buf: &mut [u8], alignment: Alignment, ra: usize) {
            // SAFETY: vtable invariant — `free` callee respects the (ptr, buf, alignment, ra) contract.
            unsafe { (self.vtable.free)(self.ptr, buf, alignment, ra) }
        }
        /// `raw_free` with `ret_addr = 0`, byte-aligned.
        #[inline]
        pub fn free(&self, bytes: &[u8]) {
            if bytes.is_empty() {
                return;
            }
            // SAFETY: `bytes` is reborrowed mutably only for the vtable signature; the
            // callee treats it as opaque.
            let buf =
                unsafe { core::slice::from_raw_parts_mut(bytes.as_ptr().cast_mut(), bytes.len()) };
            self.raw_free(buf, Alignment::from_byte_units(1), 0);
        }
    }
     
    // PORTING.md §Allocators: AST crates thread an `Arena`; non-AST use Vec/Box
    // (global mimalloc). `Arena` is the real per-heap `MimallocArena` — unlike
    // `bumpalo::Bump`, it supports per-allocation free + realloc, so `ArenaVec`
    // no longer leaks on grow.
    pub use mimalloc_arena::MimallocArena;
    pub type Arena = MimallocArena;
    mod baby_vec;
    pub use baby_vec::BabyVec;
    /// Arena-backed `Vec` with `u32` length/capacity.
    /// 24 B (vs 32 B for `Vec<T, &'a MimallocArena>`); the
    /// allocator handle is kept inline for lifetime checking. Growth/free route
    /// through `<&MimallocArena as Allocator>` (= `mi_heap_realloc_aligned` /
    /// `mi_free`); reclaimed on arena `reset`/`Drop`.
    pub type ArenaVec<'a, T> = BabyVec<'a, T>;
    pub use mimalloc_arena::{ArenaString, ArenaVecExt};
     
    /// `bumpalo::collections::Vec::from_iter_in` parity for [`ArenaVec`].
    #[inline]
    pub fn vec_from_iter_in<'a, T, I>(iter: I, arena: &'a MimallocArena) -> ArenaVec<'a, T>
    where
        I: IntoIterator<Item = T>,
    {
        let iter = iter.into_iter();
        let (lo, _) = iter.size_hint();
        let mut v = ArenaVec::with_capacity_in(lo, arena);
        v.extend(iter);
        v
    }
     
    /// Re-tag an [`ArenaVec`]'s allocator handle to `dst` without copying data.
    ///
    /// Sound because `<&MimallocArena as Allocator>` is heap-agnostic on the
    /// existing buffer:
    /// - `deallocate` → `mi_free(ptr)`: looks up the owning heap from the pointer's
    ///   page metadata; works from any thread on any heap's allocation.
    /// - `grow`/`shrink` → `mi_heap_realloc_aligned(dst, ptr, ..)`: returns `ptr`
    ///   in-place if it fits (read-only `mi_usable_size`), else allocs on `dst`,
    ///   `memcpy`s, then `mi_free(ptr)`.
    ///
    /// The original arena is never `mi_heap_malloc`-ed from again via this `Vec`,
    /// so the [`MimallocArena`] single-thread-alloc contract is preserved.
    #[inline]
    pub fn transfer_arena<'a, T>(v: &mut ArenaVec<'a, T>, dst: &'a MimallocArena) {
        v.set_allocator(dst);
    }
     
    /// `bumpalo::format!` parity — `arena_format!(in arena, "...", ..)` →
    /// [`ArenaString`].
    #[macro_export]
    macro_rules! arena_format {
        (in $arena:expr, $($arg:tt)*) => {{
            let mut __s = $crate::ArenaString::new_in($arena);
            ::core::fmt::Write::write_fmt(&mut __s, ::core::format_args!($($arg)*))
                .expect("ArenaString::write_fmt is infallible");
            __s
        }};
    }
     
    /// `bun.use_mimalloc` — false under ASAN, where the global allocator is `std::alloc::System`.
    pub const USE_MIMALLOC: bool = cfg!(not(bun_asan));
     
    // ── Allocator-vtable modules: per-module disposition (PORTING.md §Allocators) ──
    //
    //   MimallocArena            → prefer `bun_alloc::Arena` (= bumpalo::Bump)
    //   MaxHeapAllocator         → debug-only cap (single-allocation arena)
    //   heap_breakdown           → macOS malloc_zone_* per-tag heaps (debug builds)
    //   basic                    → `impl GlobalAlloc for Mimalloc` above is the canonical impl
    //
    //   LinuxMemFdAllocator, MimallocArena (the vtable impl)
    //   import bun_core/sys/runtime/collections and so live in
    //   `bun_runtime::allocators`; callers import from
    //   there directly.
    //
    #[path = "MaxHeapAllocator.rs"]
    pub mod max_heap_allocator;
    pub mod stack_fallback;
     
    /// Raw alloc/free matching the `#[global_allocator]` (`mi_*` normally, libc under ASAN).
    pub mod default_alloc {
        use core::ffi::c_void;
     
        #[inline]
        pub fn malloc(size: usize) -> *mut c_void {
            if cfg!(bun_asan) {
                // SAFETY: `libc::malloc` has no input preconditions; null on failure.
                unsafe { libc::malloc(size) }
            } else {
                crate::mimalloc::mi_malloc(size)
            }
        }
     
        /// # Safety
        /// `ptr` must be null or a live allocation from the default allocator.
        #[inline]
        pub unsafe fn realloc(ptr: *mut c_void, new_size: usize) -> *mut c_void {
            if cfg!(bun_asan) {
                // SAFETY: caller guarantees `ptr` is null or a live libc allocation
                // (the default allocator under ASAN).
                unsafe { libc::realloc(ptr, new_size) }
            } else {
                // SAFETY: caller guarantees `ptr` is null or a live mimalloc allocation.
                unsafe { crate::mimalloc::mi_realloc(ptr, new_size) }
            }
        }
     
        /// # Safety
        /// `ptr` must be null or a live allocation from the default allocator.
        #[inline]
        pub unsafe fn free(ptr: *mut c_void) {
            if cfg!(bun_asan) {
                // SAFETY: caller guarantees `ptr` is null or a live libc allocation
                // (the default allocator under ASAN).
                unsafe { libc::free(ptr) }
            } else {
                // SAFETY: caller guarantees `ptr` is null or a live mimalloc allocation.
                unsafe { crate::mimalloc::mi_free(ptr) }
            }
        }
     
        /// # Safety
        /// `ptr` must be null or a live allocation from the default allocator.
        #[inline]
        pub unsafe fn usable_size(ptr: *const c_void) -> usize {
            if ptr.is_null() {
                return 0;
            }
            // Under `bun_asan` the global allocator is `std::alloc::System`, so the
            // size must come from libc, not mimalloc — and the symbol differs per
            // OS (`malloc_usable_size` on Linux, `malloc_size` on macOS). `bun_asan`
            // is only ever set on Linux or macOS, so the catch-all (non-asan, every
            // `check-all` target including Windows) stays on mimalloc.
            #[cfg(all(bun_asan, target_os = "linux"))]
            return unsafe { libc::malloc_usable_size(ptr.cast_mut()) };
            #[cfg(all(bun_asan, target_os = "macos"))]
            return unsafe { libc::malloc_size(ptr) };
            // SAFETY: caller guarantees `ptr` is a live mimalloc allocation (the
            // non-null check above already handled null).
            #[cfg(not(any(all(bun_asan, target_os = "linux"), all(bun_asan, target_os = "macos"))))]
            return unsafe { crate::mimalloc::mi_usable_size(ptr) };
        }
     
        // The aligned variants are `#[cfg]`-split (not `if cfg!()`) because the
        // posix_memalign/malloc_usable_size symbols don't exist on Windows.
     
        #[cfg(not(bun_asan))]
        #[inline]
        pub(crate) fn malloc_aligned(size: usize, align: usize) -> *mut c_void {
            crate::mimalloc::mi_malloc_auto_align(size, align)
        }
     
        #[cfg(bun_asan)]
        #[inline]
        pub(crate) fn malloc_aligned(size: usize, align: usize) -> *mut c_void {
            if align <= crate::MAX_ALIGN_T {
                return unsafe { libc::malloc(size) };
            }
            let mut p: *mut c_void = core::ptr::null_mut();
            let align = align.max(core::mem::size_of::<*mut c_void>());
            if unsafe { libc::posix_memalign(&mut p, align, size) } != 0 {
                return core::ptr::null_mut();
            }
            p
        }
     
        /// # Safety
        /// `ptr` must be null or a live allocation from the default allocator with the given `align`.
        #[cfg(not(bun_asan))]
        #[inline]
        pub(crate) unsafe fn realloc_aligned(
            ptr: *mut c_void,
            new_size: usize,
            align: usize,
        ) -> *mut c_void {
            // SAFETY: caller guarantees `ptr` is null or a live mimalloc allocation
            // with alignment `align`.
            unsafe { crate::mimalloc::mi_realloc_aligned(ptr, new_size, align) }
        }
     
        /// # Safety
        /// `ptr` must be null or a live allocation from the default allocator with the given `align`.
        #[cfg(bun_asan)]
        #[inline]
        pub(crate) unsafe fn realloc_aligned(
            ptr: *mut c_void,
            new_size: usize,
            align: usize,
        ) -> *mut c_void {
            if align <= crate::MAX_ALIGN_T {
                return unsafe { libc::realloc(ptr, new_size) };
            }
            let new_ptr = malloc_aligned(new_size, align);
            if new_ptr.is_null() {
                return core::ptr::null_mut();
            }
            if !ptr.is_null() {
                unsafe {
                    let copy = usable_size(ptr).min(new_size);
                    core::ptr::copy_nonoverlapping(ptr.cast::<u8>(), new_ptr.cast::<u8>(), copy);
                    libc::free(ptr);
                }
            }
            new_ptr
        }
    }
     
    pub use max_heap_allocator::MaxHeapAllocator;
    pub use stack_fallback::ArenaPtr;
     
    #[path = "MimallocArena.rs"]
    pub mod mimalloc_arena;
     
    pub mod ast_alloc;
    pub use ast_alloc::{AstAlloc, AstBox, AstVec, ast_box};
    mod hashbrown_bridge;
    /// Re-export so `bun_collections` can name the polyfill trait in
    /// `StringHashMap`'s `A` bound without taking its own direct dep on
    /// `allocator-api2`.
    pub use allocator_api2::alloc::Allocator as HashbrownAllocator;
     
    // ── tier-0 local primitives ───────────────────────────────────────────────
    // Real, self-contained helpers used by the BSS containers below. These are the
    // canonical tier-0 definitions, re-exported by higher tiers (`bun_paths::SEP_STR`,
    // `bun_core::strings::trim_right`, `bun_core::strings::trim_right`).
     
    /// `"\\"` on Windows, `"/"` elsewhere.
    /// Canonical tier-0 definition; re-exported by `bun_paths::SEP_STR`.
    pub const SEP_STR: &str = if cfg!(windows) { "\\" } else { "/" };
     
    /// `b'\\'` on Windows, `b'/'` elsewhere.
    /// Canonical tier-0 definition; re-exported by `bun_paths::SEP` / `bun_core::SEP`.
    pub const SEP: u8 = if cfg!(windows) { b'\\' } else { b'/' };
     
    /// Canonical tier-0 definition; re-exported by `bun_core::strings::trim_right`.
    #[inline]
    pub fn trim_right<'a>(s: &'a [u8], chars: &[u8]) -> &'a [u8] {
        let mut end = s.len();
        while end > 0 && chars.contains(&s[end - 1]) {
            end -= 1;
        }
        &s[..end]
    }
     
    /// Canonical tier-0 definition; re-exported by `bun_core::strings::trim_left`.
    #[inline]
    pub fn trim_left<'a>(s: &'a [u8], chars: &[u8]) -> &'a [u8] {
        let mut begin = 0usize;
        while begin < s.len() && chars.contains(&s[begin]) {
            begin += 1;
        }
        &s[begin..]
    }
     
    /// Strip `chars` from both ends.
    /// Canonical tier-0 definition; re-exported by `bun_core::strings::trim`.
    #[inline]
    pub fn trim<'a>(s: &'a [u8], chars: &[u8]) -> &'a [u8] {
        trim_right(trim_left(s, chars), chars)
    }
     
    // ─── ascii-lowercase helpers ──────────────────────────────────────────────
    // Sunk from bun_core::strings so bun_alloc::BSSList::append_lower_case can call
    // them without a dep cycle (bun_core → bun_alloc, not the reverse).
    // `bun_core::strings` re-exports `copy_lowercase` and `ascii_lowercase_buf`.
     
    /// ASCII-lowercase
    /// `in_` into `out` (which must be at least `in_.len()`), returning the
    /// written prefix. Memcpy-runs + per-uppercase-byte fixup; identical output
    /// to a byte-at-a-time `to_ascii_lowercase` zip.
    pub fn copy_lowercase<'a>(in_: &[u8], out: &'a mut [u8]) -> &'a [u8] {
        let mut in_slice = in_;
        // Reshaped for borrowck — track output offset instead of reslicing &mut.
        let mut out_off: usize = 0;
     
        'begin: loop {
            for (i, &c) in in_slice.iter().enumerate() {
                if let b'A'..=b'Z' = c {
                    out[out_off..out_off + i].copy_from_slice(&in_slice[0..i]);
                    out[out_off + i] = c.to_ascii_lowercase();
                    let end = i + 1;
                    in_slice = &in_slice[end..];
                    out_off += end;
                    continue 'begin;
                }
            }
     
            out[out_off..out_off + in_slice.len()].copy_from_slice(in_slice);
            break;
        }
     
        &out[0..in_.len()]
    }
     
    /// Lowercase `input` into a fresh `[u8; N]` stack buffer, returning
    /// `Some((buf, input.len()))` or `None` if `input.len() > N`. The unused tail
    /// of `buf` is zero-filled. Covers the ubiquitous "lowercase a short key into
    /// a stack buffer, then look it up in a length-gated map" pattern.
    #[inline]
    pub fn ascii_lowercase_buf<const N: usize>(input: &[u8]) -> Option<([u8; N], usize)> {
        if input.len() > N {
            return None;
        }
        let mut buf = [0u8; N];
        copy_lowercase(input, &mut buf[..input.len()]);
        Some((buf, input.len()))
    }
     
    /// Wrap a raw allocator pointer in the `Result<NonNull<[u8]>, AllocError>`
    /// shape `core::alloc::Allocator` wants. Null → `Err(AllocError)`. Generic
    /// over the pointee so mimalloc's `*mut c_void` returns pass straight in.
    #[inline(always)]
    pub(crate) fn alloc_result<T>(
        p: *mut T,
        size: usize,
    ) -> core::result::Result<NonNull<[u8]>, core::alloc::AllocError> {
        NonNull::new(p.cast::<u8>())
            .map(|p| NonNull::slice_from_raw_parts(p, size))
            .ok_or(core::alloc::AllocError)
    }
     
    /// Number of bytes the formatted args would produce.
    ///
    /// Drives a discarding `fmt::Write` that only sums `s.len()` — no allocation,
    /// no UTF-8 validation beyond what the formatter already did. Lives here in
    /// T0 so higher tiers (`bun_core::fmt::count` re-exports this) and `bun_alloc`
    /// itself can share the single implementation.
    #[inline]
    pub fn fmt_count(args: core::fmt::Arguments<'_>) -> usize {
        struct Discarding(usize);
        impl core::fmt::Write for Discarding {
            #[inline]
            fn write_str(&mut self, s: &str) -> core::fmt::Result {
                self.0 += s.len();
                Ok(())
            }
        }
        let mut w = Discarding(0);
        // Infallible: our `write_str` never errors.
        let _ = core::fmt::write(&mut w, args);
        w.0
    }
     
    /// `core::fmt::Write` adapter over a borrowed `&mut [u8]` — the engine behind
    /// [`buf_print`] / [`buf_print_len`] (and `bun_core::fmt::buf_print_z`).
    ///
    /// Lives at T0 so `bun_alloc` itself can use it (`BSSStringList::print`); T1
    /// `bun_core::fmt` re-exports it and adds an `io::Write` impl for write-only
    /// sites.
    pub struct SliceCursor<'a> {
        pub buf: &'a mut [u8],
        pub at: usize,
    }
    impl<'a> SliceCursor<'a> {
        #[inline]
        pub fn new(buf: &'a mut [u8]) -> Self {
            Self { buf, at: 0 }
        }
    }
    impl core::fmt::Write for SliceCursor<'_> {
        #[inline]
        fn write_str(&mut self, s: &str) -> core::fmt::Result {
            let bytes = s.as_bytes();
            let end = self.at + bytes.len();
            if end > self.buf.len() {
                return Err(core::fmt::Error);
            }
            self.buf[self.at..end].copy_from_slice(bytes);
            self.at = end;
            Ok(())
        }
    }
     
    /// Render the formatted args into `buf`, returning the written sub-slice.
    /// Fails (`fmt::Error`) when `buf` is too short.
    pub fn buf_print<'a>(
        buf: &'a mut [u8],
        args: core::fmt::Arguments<'_>,
    ) -> core::result::Result<&'a [u8], core::fmt::Error> {
        let mut c = SliceCursor { buf, at: 0 };
        core::fmt::write(&mut c, args)?;
        let len = c.at;
        Ok(&c.buf[..len])
    }
    }
    • l’on note l’apparition dans le code de centaines d'utilisations de static mut et de fonctions de contournement de la mémoire qui violent les garanties de sécurité traditionnelles de Rust. A titre d’illustration, la fonction PathString::init (située dans les sources de gestion de chaînes de caractères de bun_core) a fait l'objet d'audits publics de sécurité après avoir été signalée pour avoir exposé par inadvertance un comportement non sécurisé dans une interface pourtant déclarée comme sûre.
    • certains fichiers générés atteignent près de 10 000 lignes de code et rendent donc la maintenance humaine très ardue.



    Conclusion

    Cette migration du code Bun de Zig vers Rust apparaît désormais comme un excellent cas d'étude de ce qu'il faut éviter en matière d’utilisation de l’intelligence artificielle dans le développement de logiciels. Et pour cause, l’intelligence artificielle reste un outil et non une machine parfaite qui maitrise toutes les subtilités du codage.

    Migrer un tel nombre de lignes de codes en une dizaine de jours est une indication de ce qu’il n’y a quasiment pas eu de supervision humaine. Le code Rust produit ne respecte pas les principes de base du langage : il y a beaucoup de code unsafe injustifié. Si le but était d'améliorer la sécurité et la maintenabilité, il est clair que cette initiative n’a pas été concluante.

    A contrario, LadyBird a aussi utilisé Claude pour migrer une partie de son code mais de manière plus cadrée : ils se sont limités dans un premier temps à une partie du projet de 20 000 lignes. Ils ont pris deux semaines et le tout a été fait sous supervision humaine. Le résultat est autrement plus convainquant :

    • le pipeline en Rust produit des sorties identiques octet par octet par rapport à l'ancien code C++ ;
    • le code converti a passé avec succès plus de 52 000 tests de la suite officielle test262 et plus de 12 000 tests de régression internes de Ladybird sans aucune défaillance ;
    • aucun ralentissement ni régression de performance n'ont été observés sur les benchmarks de JavaScript suivis.

    Source : Notes de version Bun 1.4 (passage de la base de code de Zig à Rust)

    Et vous ?

    Que vous inspire cette initiative de migration (réécriture) de la base de code Bun de Zig à Rust ? Êtes-vous en accord avec la conclusion selon laquelle l'expertise humaine va rester requise pour longtemps dans la filière du développement de logiciels ?
    Partagez-vous les avis des acteurs de la filière selon lesquelles ce type d’exercice ravive des débats sur la supériorité de certains langages sur d’autres alors qu’ils ne devraient pas avoir lieu ?
    Partagez-vous les avis selon lesquels cette initiative sert plutôt les intérêts d'Anthropic en tant qu'opération marketing pour Claude Code/Fable ?
    Contribuez au club : Corrections, suggestions, critiques, ... : Contactez le service news et Rédigez des actualités

Discussions similaires

  1. Réponses: 0
    Dernier message: 03/12/2025, 20h44
  2. [PHP-JS] Probleme de javascript dans un code php
    Par stomerfull dans le forum Langage
    Réponses: 3
    Dernier message: 23/01/2006, 09h33
  3. [Treeview / Javascript] Cherche exemple code source
    Par shaun_the_sheep dans le forum Général JavaScript
    Réponses: 7
    Dernier message: 17/01/2006, 10h41
  4. [PHP-JS] Probleme de javascript dans un code php
    Par stomerfull dans le forum Langage
    Réponses: 20
    Dernier message: 12/01/2006, 13h41
  5. [javascript] générer un code de 6 caractère alphanumérique
    Par LE NEINDRE dans le forum Général JavaScript
    Réponses: 4
    Dernier message: 29/09/2005, 17h03

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo