Ошибка Rust E0554: #![feature] may not be used on the stable release channel
E0554 значит: твой код начинается со строки #![feature(...)], а такие строки принимает только nightly-версия Rust. Почти всегда эта ошибка приходит вместе со скопированным кодом: из статьи, репозитория на GitHub, ответа ИИ или старого ответа на Stack Overflow. Тот код писали для nightly Rust, а у тебя stable — именно его rustup устанавливает по умолчанию. С твоей установкой всё в порядке. Обычно исправление — удалить одну строку и сделать то же самое стабильным способом. (Эта страница входит в раздел Ошибки компилятора Rust с объяснениями.)
Сообщение об ошибке
Заголовок раздела «Сообщение об ошибке»error[E0554]: `#![feature]` may not be used on the stable release channel --> src/main.rs:1:1 |1 | #![feature(iter_map_windows)] // ❌ copied from code written for nightly Rust | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^По-русски: «#![feature] нельзя использовать в стабильном канале выпусков».
Вот программа, которая её вызывает (комментарий // ❌ оставлен на английском, потому что rustc цитирует эту строку; он значит «скопировано из кода, написанного для nightly Rust»):
#![feature(iter_map_windows)] // ❌ copied from code written for nightly Rust
fn main() { let temps = [18, 21, 19, 24]; let changes: Vec<i32> = temps.iter().map_windows(|[a, b]| *b - *a).collect(); println!("{:?}", changes);}Что это значит
Заголовок раздела «Что это значит»^^^ подчёркивает всю первую строку, #![feature(iter_map_windows)]. Эта строка — просьба: «пожалуйста, включи недоделанную возможность под названием iter_map_windows». Такие просьбы принимает только компилятор nightly. «Stable release channel» («стабильный канал выпусков») в сообщении — это обычный Rust, который ставит rustup, и он отказывается.
Обрати внимание, на что rustc не жалуется: на map_windows в строке 5. Он останавливается на строке #![feature] раньше. Только когда ты её удалишь, станет понятно, работает ли остальной код на stable.
Ту же ошибку ты получишь и в канале beta. Если в коде несколько строк #![feature], rustc обычно сообщает только о первой, так что проверь начало файла — там могут быть ещё.
Это как пропуск «только для персонала». На тестовую кухню (nightly) с ним пустят. А ресторан (stable) такие пропуска не принимает вообще, как вежливо его ни показывай.
Почему Rust так делает
Заголовок раздела «Почему Rust так делает»Rust обещает, что код, который компилируется на stable сегодня, будет компилироваться на каждом будущем стабильном выпуске 1.x. Недоделанные возможности не могут входить в это обещание: их имена, аргументы и поведение ещё могут измениться, а сами они могут исчезнуть. Поэтому они живут только в nightly — новой сборке компилятора, которую делают каждую ночь, — и каждую из них включают по имени через #![feature(...)].
Стабильный Rust не просто игнорирует эту строку, а останавливается с ошибкой. Так ты не сможешь незаметно построить проект на недоделанной возможности. Когда возможность готова, она становится частью стабильного Rust, и строка для неё больше не нужна.
Поэтому, увидев E0554, стоит задать себе всего три вопроса: есть ли стабильный способ это сделать (исправление 1), стала ли возможность уже стабильной (исправление 2) и действительно ли тебе нужен nightly (исправление 3)? Подробнее — в разделе Stable, beta и nightly.
Как исправить
Заголовок раздела «Как исправить»Исправление 1: Убери атрибут и используй стабильный API
Заголовок раздела «Исправление 1: Убери атрибут и используй стабильный API»Это нужно почти всегда. Удали строку #![feature] и скомпилируй снова. Если теперь получишь E0658 (use of unstable library feature `iter_map_windows` ), значит, возможность всё ещё не доделана и нужен стабильный способ сделать то же самое. Большинство нестабильных методов — сокращения для того, что стабильный Rust уже умеет. Здесь .windows(2) у среза даёт каждую пару соседей:
fn main() { let temps = [18, 21, 19, 24]; let changes: Vec<i32> = temps.windows(2).map(|w| w[1] - w[0]).collect(); // ✅ стабильно println!("{:?}", changes);
for w in temps.windows(2) { println!("{} -> {}", w[0], w[1]); }}Вывод:
[3, -2, 5]18 -> 2121 -> 1919 -> 24Чтобы найти стабильный способ, открой метод в документации стандартной библиотеки. У нестабильных элементов есть плашка «This is a nightly-only experimental API», а имя возможности из строки #![feature] обычно совпадает со страницей в The Unstable Book (на английском). Подробнее — в уроках Срезы и Итераторы.
Исправление 2: Проверь, не стала ли возможность стабильной
Заголовок раздела «Исправление 2: Проверь, не стала ли возможность стабильной»Выбирай этот вариант, когда код немного старый. Многие возможности, которым когда-то нужен был #![feature], теперь входят в стабильный Rust, и тогда строка просто больше не нужна. rustc сообщает об этом в предупреждении прямо под ошибкой:
error[E0554]: `#![feature]` may not be used on the stable release channel --> src/main.rs:2:1 |2 | #![feature(slice_as_chunks)] // ❌ not needed any more: this feature is stable now | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
warning: the feature `slice_as_chunks` has been stable since 1.88.0 and no longer requires an attribute to enable --> src/main.rs:2:12 |2 | #![feature(slice_as_chunks)] // ❌ not needed any more: this feature is stable now | ^^^^^^^^^^^^^^^Предупреждение говорит: «возможность slice_as_chunks стабильна с версии 1.88.0, и атрибут для её включения больше не нужен». Программа с ошибкой (комментарий // ❌ значит «больше не нужно: эта возможность теперь стабильна»):
// Скопировано из старого учебника#![feature(slice_as_chunks)] // ❌ not needed any more: this feature is stable now
fn main() { let pixels = [255, 0, 0, 0, 128, 255]; let (rgb, _rest) = pixels.as_chunks::<3>(); for [r, g, b] in rgb { println!("r={} g={} b={}", r, g, b); }}Удали строку #![feature] (и комментарий над ней), и остальное заработает без изменений:
fn main() { let pixels = [255, 0, 0, 0, 128, 255]; let (rgb, _rest) = pixels.as_chunks::<3>(); // ✅ стабильно с Rust 1.88 for [r, g, b] in rgb { println!("r={} g={} b={}", r, g, b); }}Вывод:
r=255 g=0 b=0r=0 g=128 b=255Для возможностей языка rustc ещё прямолинейнее: под ошибкой он добавляет help: remove the attribute («удали атрибут») и строку вроде the feature `async_closure` has been stable since `1.85.0` and no longer requires an attribute to enable.
Предупреждения нет, но ты подозреваешь, что возможность стабильна? Возможно, твой Rust просто старше версии, в которой она стала стабильной. Проверь и обнови:
rustc --versionrustup updateЕсли после этого rustc --version всё ещё показывает старую версию, скорее всего, в проекте есть файл rust-toolchain.toml, который её закрепляет. Подробнее — в разделе Закрепляем тулчейн для проекта.
Исправление 3: Используй nightly осознанно
Заголовок раздела «Исправление 3: Используй nightly осознанно»Выбирай этот вариант в последнюю очередь — когда стабильного способа нет и ты согласен, что код может сломаться на будущем nightly. Типичные хорошие причины: ты пробуешь новую возможность, пишешь небольшой эксперимент или проект, в который ты вносишь вклад, уже использует nightly. Установи nightly рядом со stable и используй его для одной команды:
rustup toolchain install nightlycargo +nightly runИли переведи на nightly весь проект с помощью файла rust-toolchain.toml рядом с Cargo.toml. Тогда обычный cargo run в этой папке выберет nightly, а везде остальном — stable:
[toolchain]channel = "nightly"Если проект собирают и другие люди, закрепи дату, например channel = "nightly-2026-10-01", чтобы у всех был один и тот же компилятор. В Rust Playground выбери Nightly в меню тулчейна.
Тебе может попасться совет выставить RUSTC_BOOTSTRAP=1, чтобы stable принимал #![feature]. Этот переключатель существует для сборки самого компилятора Rust. С ним ты получаешь все риски nightly, делая вид, что сидишь на stable, — так что не надо.
Где это обычно встречается
Заголовок раздела «Где это обычно встречается»Бенчмарки с #[bench]. Старые руководства пишут бенчмарки так, а #![feature(test)] до сих пор работает только в nightly:
error[E0554]: `#![feature]` may not be used on the stable release channel --> src/main.rs:3:1 |3 | #![feature(test)] // ❌ built-in benchmarks are nightly-only | ^^^^^^^^^^^^^^^^^//! Помощники для цен.//! Бенчмарк написан по-старому, для nightly Rust.#![feature(test)] // ❌ built-in benchmarks are nightly-onlyextern crate test;
fn total(prices: &[u32]) -> u32 { prices.iter().sum()}
#[bench]fn bench_total(b: &mut test::Bencher) { let prices: Vec<u32> = (1..1000).collect(); b.iter(|| total(&prices));}
fn main() { println!("{}", total(&[3, 4, 5]));}Комментарий // ❌ значит «встроенные бенчмарки — только для nightly». Исправление: используй крейт для бенчмарков, который работает на stable, например criterion или divan, и запускай cargo bench. Удалить только строку #![feature] здесь недостаточно: тогда extern crate test; даст E0658 (use of unstable library feature `test` ). Подробнее — в уроке Производительность.
Зависимость, которой нужен nightly. Если строка --> указывает в крейт внутри ~/.cargo/registry/, а не в твой src/, значит, #![feature] использует крейт, от которого ты зависишь. Исправление: загляни в README крейта; часто более новая версия работает на stable (например, веб-фреймворку Rocket до версии 0.4 нужен был nightly, а 0.5 работает на stable). Иначе выбери другой крейт. Подробнее — в уроке Cargo и крейты.
Скопированный код с #![feature(let_chains)]. Цепочки let (if let Some(x) = a && x > 0) стали стабильными в Rust 1.88, но только в редакции 2024. Исправление: удали строку (исправление 2) и укажи edition = "2024" в Cargo.toml. Без этого получишь let chains are only allowed in Rust 2024 or later.
Связанные ошибки
Заголовок раздела «Связанные ошибки»- E0658: use of unstable feature: что ты обычно получаешь после удаления строки
#![feature], если возможность всё ещё только для nightly. - E0599: no method found: если ты убрал строку, а метода на самом деле нет или он из крейта, который ты не добавил.
- E0463: can’t find crate: если перейдёшь на
criterionилиdivanи забудешь добавить их вCargo.toml. - E0435: attempt to use a non-constant value in a constant: частая причина, по которой вообще начинают искать константные возможности nightly.
- Все ошибки компилятора с объяснениями
Проверь себя
Заголовок раздела «Проверь себя»Проверь себя
1. Ты вставляешь код, который начинается с #![feature(try_blocks)], и получаешь E0554. Что это значит?
2. Под ошибкой rustc предупреждает, что возможность стабильна с версии 1.88.0. Что делать?
3. Тебе действительно нужен nightly для одного эксперимента. Какой способ самый чистый?
Результат: 0 / 3
Что почитать
Заголовок раздела «Что почитать»- E0554 — Rust error codes index (на английском): официальное объяснение — атрибуты возможностей разрешены только в канале nightly.
- Как создаётся Rust и «Nightly Rust» — книга «Язык программирования Rust» (перевод на русский): каналы stable, beta и nightly и путь возможности от nightly до stable.
- Channels — The rustup book (на английском): установка nightly и работа с ним рядом со stable.
- The toolchain file — The rustup book (на английском): как
rust-toolchain.tomlвыбирает компилятор для одного проекта, включая закреплённую дату nightly. - The Unstable Book (на английском): все имена возможностей, которые можно указать в
#![feature], со ссылками на задачи, где их отслеживают.