Error E0554 de Rust: #![feature] may not be used on the stable release channel
E0554 significa que tu código empieza con una línea #![feature(...)], y solo la versión nightly de Rust acepta esas líneas. Casi siempre te pasa con código copiado: de un artículo de un blog, de un repositorio de GitHub, de una respuesta de una IA o de una respuesta antigua de Stack Overflow. Ese código se escribió para Rust nightly, y tú estás en stable (estable), que es lo que rustup instala por defecto. Tu instalación está bien. La solución suele ser borrar una línea y hacer lo mismo de una forma estable. Forma parte de la guía de errores del compilador.
El mensaje de error
Sección titulada «El mensaje de error»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] may not be used on the stable release channel” quiere decir “#![feature] no se puede usar en el canal de versiones estables”.
Este es el programa que lo produce:
#![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);}Qué significa
Sección titulada «Qué significa»Los ^^^ subrayan toda la primera línea, #![feature(iter_map_windows)]. Esa línea es una petición: “por favor, activa la funcionalidad sin terminar llamada iter_map_windows”. Solo el compilador nightly acepta estas peticiones. El “stable release channel” del mensaje es el Rust normal que obtienes con rustup, y se niega.
Fíjate en lo que rustc no dice: no se queja de map_windows en la línea 5. Se detiene antes, en la línea #![feature]. Cuando quites esa línea, sabrás si el resto del código funciona en estable.
En el canal beta obtienes el mismo error. Si tu código tiene varias líneas #![feature], rustc suele mostrar solo la primera, así que revisa el principio del archivo por si hay más.
Es como un pase de “solo personal”. La cocina de pruebas (nightly) te deja entrar con él. El restaurante (stable) no acepta esos pases, por muy amablemente que lo enseñes.
Por qué Rust hace esto
Sección titulada «Por qué Rust hace esto»Rust promete que el código que compila hoy en estable seguirá compilando en todas las futuras versiones estables 1.x. Las funcionalidades sin terminar no pueden formar parte de esa promesa: sus nombres, sus argumentos y su comportamiento todavía pueden cambiar, o pueden desaparecer. Por eso solo viven en nightly, una versión nueva del compilador que se genera cada noche, y cada una se activa por su nombre con #![feature(...)].
Rust estable no ignora la línea sin más: se detiene con un error. Así no puedes construir un proyecto sobre una funcionalidad sin terminar sin darte cuenta. Cuando una funcionalidad está terminada, pasa a formar parte de Rust estable y ya no necesita esa línea.
Así que cuando veas E0554, solo hay tres preguntas de verdad: ¿hay una forma estable de hacer esto (Solución 1)?, ¿la funcionalidad ya es estable (Solución 2)?, ¿o de verdad quieres nightly (Solución 3)? Mira Stable, beta y nightly.
Cómo solucionarlo
Sección titulada «Cómo solucionarlo»Solución 1: Quita el atributo y usa la API estable
Sección titulada «Solución 1: Quita el atributo y usa la API estable»Elige esta casi siempre. Borra la línea #![feature] y vuelve a compilar. Si ahora obtienes E0658 (use of unstable library feature `iter_map_windows` , uso de una funcionalidad inestable de la biblioteca), la funcionalidad todavía no está terminada, y necesitas una forma estable de hacer lo mismo. La mayoría de los métodos inestables son atajos para algo que Rust estable ya sabe hacer. Aquí, .windows(2) sobre un slice te da cada pareja de vecinos:
fn main() { let temps = [18, 21, 19, 24]; let changes: Vec<i32> = temps.windows(2).map(|w| w[1] - w[0]).collect(); // ✅ estable println!("{:?}", changes);
for w in temps.windows(2) { println!("{} -> {}", w[0], w[1]); }}Salida:
[3, -2, 5]18 -> 2121 -> 1919 -> 24Para encontrar la forma estable, abre el método en la documentación de la biblioteca estándar. Los elementos inestables tienen un recuadro que dice “This is a nightly-only experimental API” (esta es una API experimental solo de nightly), y el nombre de tu línea #![feature] suele coincidir con una página de The Unstable Book (en inglés). Mira Slices e Iteradores.
Solución 2: Comprueba si la funcionalidad ya es estable
Sección titulada «Solución 2: Comprueba si la funcionalidad ya es estable»Elige esta cuando el código es algo antiguo. Muchas funcionalidades que antes necesitaban #![feature] ahora forman parte de Rust estable, y entonces la línea simplemente ya no hace falta. rustc te lo dice en un aviso (warning) justo debajo del error:
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 | ^^^^^^^^^^^^^^^El aviso dice que la funcionalidad slice_as_chunks es estable desde la versión 1.88.0 y ya no necesita un atributo para activarse. El programa con el error:
// Copiado de un tutorial antiguo#![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); }}Borra la línea #![feature] (y el comentario de encima) y el resto funciona sin cambios:
fn main() { let pixels = [255, 0, 0, 0, 128, 255]; let (rgb, _rest) = pixels.as_chunks::<3>(); // ✅ estable desde Rust 1.88 for [r, g, b] in rgb { println!("r={} g={} b={}", r, g, b); }}Salida:
r=255 g=0 b=0r=0 g=128 b=255Con las funcionalidades del lenguaje, rustc es todavía más directo y añade help: remove the attribute (quita el atributo) debajo del error, además de una línea como the feature `async_closure` has been stable since `1.85.0` and no longer requires an attribute to enable.
¿No hay ningún aviso, pero sospechas que la funcionalidad es estable? Puede que tu Rust sea más antiguo que la versión en la que se estabilizó. Compruébalo y actualiza:
rustc --versionrustup updateSi después rustc --version sigue mostrando una versión antigua, probablemente el proyecto tiene un archivo rust-toolchain.toml que la fija. Mira Fijar una toolchain para un proyecto.
Solución 3: Usa nightly a propósito
Sección titulada «Solución 3: Usa nightly a propósito»Elige esta en último lugar, cuando no hay una forma estable y aceptas que tu código puede romperse con un nightly futuro. Buenas razones típicas: estás probando una funcionalidad nueva, escribes un pequeño experimento o el proyecto en el que colaboras ya usa nightly. Instala nightly junto a stable y úsalo para un solo comando:
rustup toolchain install nightlycargo +nightly runO haz que todo el proyecto use nightly con un archivo rust-toolchain.toml junto a Cargo.toml. Entonces un simple cargo run elige nightly en esa carpeta, y stable en todas las demás:
[toolchain]channel = "nightly"Para un proyecto que también compilan otras personas, fija una fecha, como channel = "nightly-2026-10-01", para que todos usen el mismo compilador. En el Rust Playground, elige Nightly en el menú de toolchain.
Puede que encuentres el consejo de poner RUSTC_BOOTSTRAP=1 para que stable acepte #![feature]. Ese interruptor existe para compilar el propio compilador de Rust. Usarlo te da todos los riesgos de nightly mientras finges estar en estable, así que no lo hagas.
Dónde lo verás normalmente
Sección titulada «Dónde lo verás normalmente»Benchmarks con #[bench]. Las guías antiguas escriben los benchmarks (pruebas de rendimiento) así, y #![feature(test)] sigue siendo solo de 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 | ^^^^^^^^^^^^^^^^^//! Funciones auxiliares para precios.//! Benchmark escrito a la antigua, para Rust nightly.#![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]));}Solución: usa un crate de benchmarks que funcione en estable, como criterion o divan, y ejecuta cargo bench. Aquí no basta con borrar la línea #![feature]: entonces extern crate test; da E0658 (use of unstable library feature `test` ). Mira Rendimiento.
Una dependencia que necesita nightly. Si la línea --> apunta a un crate dentro de ~/.cargo/registry/ en lugar de a tu propio src/, es un crate del que dependes el que usa #![feature]. Solución: mira el README del crate; muchas veces una versión más nueva funciona en estable (por ejemplo, el framework web Rocket necesitaba nightly hasta la 0.4, y la 0.5 funciona en estable). Si no, elige otro crate. Mira Cargo y crates.
Código copiado con #![feature(let_chains)]. Las let chains (if let Some(x) = a && x > 0) se estabilizaron en Rust 1.88, pero solo en la edición 2024. Solución: borra la línea (Solución 2) y pon edition = "2024" en Cargo.toml. Si no, obtienes let chains are only allowed in Rust 2024 or later (las let chains solo se permiten en Rust 2024 o posterior).
Errores relacionados
Sección titulada «Errores relacionados»- E0658: use of unstable feature: lo que normalmente obtienes después de quitar la línea
#![feature], si la funcionalidad sigue siendo solo de nightly. - E0599: no method found: si quitas la línea y el método de verdad no existe, o viene de un crate que no has añadido.
- E0463: can’t find crate: si cambias a
criterionodivany te olvidas de añadirlo aCargo.toml. - E0435: attempt to use a non-constant value in a constant: una razón habitual por la que la gente acaba buscando funcionalidades constantes de nightly.
- Todos los errores del compilador: la lista completa de páginas de errores.
Comprueba lo que aprendiste
Sección titulada «Comprueba lo que aprendiste»Comprueba lo aprendido
1. Pegas un código que empieza con #![feature(try_blocks)] y obtienes E0554. ¿Qué significa?
2. Debajo del error, rustc avisa de que la funcionalidad es estable desde la 1.88.0. ¿Qué deberías hacer?
3. Sí quieres nightly para un experimento. ¿Cuál es la forma más limpia?
Puntuación: 0 / 3
Para leer más
Sección titulada «Para leer más»- E0554 — Rust error codes index (en inglés): la explicación oficial: los atributos de funcionalidades solo se permiten en el canal nightly.
- How Rust is Made and “Nightly Rust” — El libro de Rust (en inglés): los canales stable, beta y nightly, y cómo pasa una funcionalidad de nightly a estable. También existe una traducción al español de la comunidad del libro.
- Channels — The rustup book (en inglés): cómo instalar nightly y usarlo junto a stable.
- The toolchain file — The rustup book (en inglés): cómo
rust-toolchain.tomlelige el compilador para un proyecto, incluida una fecha fija de nightly. - The Unstable Book (en inglés): todos los nombres de funcionalidades que puedes poner en
#![feature], con un enlace a su issue de seguimiento.