LLM пишут Rust с семью категориями скрытых ошибок, которые компилятор не ловит
Разработчик полгода использовал Claude, GPT и Cursor как второго разработчика на Rust. Собрал семь типов скрытых ошибок: lifetime laundering, Mutex в async, Dro

Разработчик провел полгода, используя Claude, GPT и Cursor как полноценного второго программиста на Rust в production коде. За этот период он тщательно отслеживал ошибки и собрал впечатляющий список: семь категорий ошибок, которые LLM делают систематически. Самое неприятное — эти ошибки проходят компилятор, unit-тесты и даже статический анализатор clippy. Но при этом они нарушают память или разрушают архитектуру приложения.
Семь типов скрытых ошибок
Вот категории, которые LLM ломают снова и снова: Lifetime laundering — переменные живут дольше, чем позволяет система типов Rust. Это приводит к use-after-free в runtime. Mutex через await — блокировка, которая удерживает lock во время асинхронного ожидания.
Гарантированный deadlock. * Drop в транзакциях — забывают вызвать drop когда нужно закрыть ресурс (закрыть файл, откатить транзакцию). Ресурс утекает.
Unaligned read — разыменование памяти с неправильным выравниванием. Процессор падает на ARM, молча ломается на x86. Async cancellation — неправильная отмена асинхронных операций.
Оставляет подвешенные стейты. * Orphan rule — нарушение правила orphan при имплементации трейтов. Компилирует в одном проекте, ломается при добавлении dependency.
* Массивы на стеке — выделение огромных массивов в stack (вместо heap). Переполнение стека, segfault.
Почему это опасно для production
Вся прелесть Rust в том, что компилятор ловит ошибки на этапе разработки, а не в production. Но эти семь ошибок компилятор пропускает — потому что они не нарушают синтаксис или формальные правила типизации. В результате код собирается без warnings, проходит unit-тесты, прогоняется через clippy и выкатывается на production. Там всё ломается, но уже поздно. Это хуже, чем явная ошибка компилятора, потому что разработчик уверен, что всё в порядке.
Почему LLM это ломают Rust — маргинальный язык в датасете LLM.
Python, JavaScript, Java занимают 70% кода, на котором обучались модели. Rust — может быть 2-3%. При этом Rust требует глубокого понимания ownership, lifetimes и type system, которые LLM понимают поверхностно. Модели видят паттерны и копируют их. Они знают, что «обычно тут пишут так», но не знают почему это работает в Java и ломается в Rust. Поэтому они воспроизводят паттерны неправильно, создавая иллюзию компилирующегося кода.
Rust ломает LLM потому, что это язык, где нужно думать, а не просто
копировать паттерны.
Практические выводы
Разработчик не советует полностью отказываться от LLM, но рекомендует: Не полагаться на LLM для критических участков: криптография, работа с памятью, concurrency Требовать formal code review даже если компилятор не жалуется Использовать Miri — интерпретатор, который ловит undefined behavior во время разработки Изучить Rust достаточно, чтобы либо писать код самому, либо уметь находить баги в LLM-коде ## Что это значит LLM — полезный инструмент, но не замена человеку. В динамических языках они работают хорошо (Python, JavaScript), потому что там меньше правил, которые нужно понимать интуитивно. В Rust нужно либо проверять каждую строку, либо оставлять человека в контуре принятия решений.
Для фреймворков вроде Next.js или Django LLM-помощник — мощный ускоритель. Для Rust в production это скорее черновик для human review, чем полноценный коллега.