Bỏ qua để đến nội dung

Lỗi Rust E0554: #![feature] may not be used on the stable release channel

E0554 nghĩa là: code của bạn bắt đầu bằng một dòng #![feature(...)], và chỉ phiên bản nightly của Rust mới chấp nhận những dòng như vậy. Gần như lúc nào bạn cũng gặp nó từ code chép về: một bài blog, một repo GitHub, một câu trả lời của AI, một câu trả lời cũ trên Stack Overflow. Đoạn code đó được viết cho Rust nightly, còn bạn đang dùng stable, thứ mà rustup cài mặc định. Máy của bạn chẳng có gì sai. Cách sửa thường là xóa một dòng và dùng một cách stable để làm cùng việc đó. (Trang này thuộc loạt bài Giải thích các lỗi trình biên dịch 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
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

Thông báo của trình biên dịch luôn bằng tiếng Anh: “#![feature] may not be used on the stable release channel” nghĩa là “không được dùng #![feature] trên kênh phát hành stable”. Đây là chương trình gây ra lỗi đó (chú thích được giữ bằng tiếng Anh vì nó xuất hiện nguyên văn trong thông báo lỗi):

#![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);
}

Dấu ^^^ gạch dưới toàn bộ dòng đầu tiên, #![feature(iter_map_windows)]. Dòng đó là một lời đề nghị: “hãy bật giúp tôi tính năng chưa hoàn thiện tên là iter_map_windows.” Chỉ trình biên dịch nightly nhận những lời đề nghị như thế. “Stable release channel” (kênh phát hành stable) trong thông báo là Rust bình thường mà bạn cài qua rustup, và nó từ chối.

Hãy để ý thứ mà rustc không phàn nàn: map_windows ở dòng 5. Nó dừng lại ở dòng #![feature] trước. Khi bạn xóa dòng đó, bạn sẽ biết phần còn lại của code có chạy được trên stable hay không.

Bạn cũng gặp lỗi này trên kênh beta. Nếu code có nhiều dòng #![feature], rustc thường chỉ báo dòng đầu tiên, nên hãy kiểm tra đầu file xem còn dòng nào nữa không.

Giống như một tấm thẻ “chỉ dành cho nhân viên”. Bếp thử nghiệm (nightly) cho bạn vào khi có thẻ. Nhà hàng (stable) thì hoàn toàn không chấp nhận loại thẻ này, dù bạn đưa ra lịch sự đến đâu.

Rust hứa rằng code biên dịch được trên stable hôm nay sẽ tiếp tục biên dịch được trên mọi bản stable 1.x sau này. Tính năng chưa hoàn thiện không thể nằm trong lời hứa đó: tên, đối số và hành vi của chúng vẫn có thể thay đổi, hoặc chúng có thể bị bỏ đi. Vì vậy chúng chỉ sống trên nightly, một bản build mới của trình biên dịch được tạo ra mỗi đêm, và bạn bật từng tính năng theo tên bằng #![feature(...)].

Rust stable không chỉ bỏ qua dòng đó: nó dừng lại với một lỗi. Nhờ vậy, bạn không thể xây cả một dự án trên một tính năng chưa hoàn thiện mà không hề hay biết. Khi một tính năng đã xong, nó trở thành một phần của Rust stable và không cần dòng đó nữa.

Vậy khi gặp E0554, chỉ có ba câu hỏi thật sự: có cách stable nào để làm việc này không (cách sửa 1), tính năng đã stable chưa (cách sửa 2), hay bạn thật sự muốn dùng nightly (cách sửa 3)? Xem Stable, beta và nightly.

Cách sửa 1: Bỏ thuộc tính và dùng API stable

Phần tiêu đề “Cách sửa 1: Bỏ thuộc tính và dùng API stable”

Gần như lần nào cũng nên chọn cách này. Xóa dòng #![feature] và biên dịch lại. Nếu giờ bạn gặp E0658 (use of unstable library feature `iter_map_windows` ), nghĩa là tính năng vẫn chưa hoàn thiện, và bạn cần một cách stable để làm cùng việc đó. Phần lớn các phương thức chưa ổn định là lối tắt cho một việc mà Rust stable đã làm được. Ở đây, .windows(2) trên một slice cho bạn từng cặp phần tử kề nhau:

fn main() {
let temps = [18, 21, 19, 24];
let changes: Vec<i32> = temps.windows(2).map(|w| w[1] - w[0]).collect(); // ✅ stable
println!("{:?}", changes);
for w in temps.windows(2) {
println!("{} -> {}", w[0], w[1]);
}
}

Kết quả:

[3, -2, 5]
18 -> 21
21 -> 19
19 -> 24
▶ Tự chạy thử

Để tìm cách stable, hãy mở phương thức đó trong tài liệu thư viện chuẩn. Mục chưa ổn định có một khung ghi “This is a nightly-only experimental API” (đây là API thử nghiệm chỉ có trên nightly), và tên tính năng trong dòng #![feature] của bạn thường trùng với một trang trong The Unstable Book (tiếng Anh). Xem Slice và Iterator.

Cách sửa 2: Kiểm tra xem tính năng giờ đã stable chưa

Phần tiêu đề “Cách sửa 2: Kiểm tra xem tính năng giờ đã stable chưa”

Chọn cách này khi code đã hơi cũ. Nhiều tính năng từng cần #![feature] giờ đã là một phần của Rust stable, và khi đó dòng này đơn giản là không cần nữa. rustc nói cho bạn biết điều đó bằng một cảnh báo ngay dưới lỗi:

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
| ^^^^^^^^^^^^^^^

Cảnh báo nói rằng tính năng slice_as_chunks đã stable từ 1.88.0 và không cần thuộc tính để bật nữa. Chương trình bị lỗi:

// Copied from an older tutorial
#![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);
}
}

Xóa dòng #![feature] (và dòng chú thích phía trên nó), phần còn lại chạy mà không phải sửa gì:

fn main() {
let pixels = [255, 0, 0, 0, 128, 255];
let (rgb, _rest) = pixels.as_chunks::<3>(); // ✅ stable từ Rust 1.88
for [r, g, b] in rgb {
println!("r={} g={} b={}", r, g, b);
}
}

Kết quả:

r=255 g=0 b=0
r=0 g=128 b=255
▶ Tự chạy thử

Với tính năng của ngôn ngữ, rustc còn nói thẳng hơn nữa và thêm help: remove the attribute (hãy xóa thuộc tính) dưới lỗi, cộng với một dòng như the feature `async_closure` has been stable since `1.85.0` and no longer requires an attribute to enable.

Không có cảnh báo nào, nhưng bạn ngờ rằng tính năng đã stable? Có thể bản Rust của bạn đơn giản là cũ hơn phiên bản mà tính năng đó trở thành stable. Kiểm tra và cập nhật:

Terminal window
rustc --version
rustup update

Nếu sau đó rustc --version vẫn hiện phiên bản cũ, có lẽ dự án có một file rust-toolchain.toml ghim nó lại. Xem Cố định toolchain cho từng dự án.

Hãy chọn cách này sau cùng, khi không có cách stable nào và bạn chấp nhận rằng code có thể hỏng với một bản nightly sau này. Những lý do chính đáng thường gặp: bạn đang thử một tính năng mới, viết một thử nghiệm nhỏ, hoặc dự án bạn đóng góp vốn đã dùng nightly. Cài nightly bên cạnh stable và dùng nó cho một lệnh:

Terminal window
rustup toolchain install nightly
cargo +nightly run

Hoặc cho cả dự án dùng nightly bằng một file rust-toolchain.toml đặt cạnh Cargo.toml. Khi đó cargo run trơn sẽ chọn nightly trong thư mục đó, và stable ở mọi nơi khác:

[toolchain]
channel = "nightly"

Với một dự án mà người khác cũng build, hãy ghim một ngày cụ thể, như channel = "nightly-2026-10-01", để ai cũng dùng cùng một trình biên dịch. Trên Rust Playground, hãy chọn Nightly trong menu toolchain.

Bạn có thể gặp lời khuyên đặt RUSTC_BOOTSTRAP=1 để stable chấp nhận #![feature]. Công tắc đó tồn tại để build chính trình biên dịch Rust. Dùng nó cho bạn mọi rủi ro của nightly trong khi giả vờ đang dùng stable, nên đừng làm vậy.

Benchmark với #[bench]. Các hướng dẫn cũ viết benchmark như thế này, và #![feature(test)] vẫn chỉ có trên 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
| ^^^^^^^^^^^^^^^^^
//! Price helpers.
//! Benchmark written the old way, for nightly Rust.
#![feature(test)] // ❌ built-in benchmarks are nightly-only
extern 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]));
}

Cách sửa: dùng một crate benchmark chạy được trên stable, như criterion hoặc divan, và chạy cargo bench. Chỉ xóa dòng #![feature] là chưa đủ ở đây: khi đó extern crate test; sẽ gây ra E0658 (use of unstable library feature `test` ). Xem Hiệu năng.

Một dependency cần nightly. Nếu dòng --> chỉ vào một crate nằm trong ~/.cargo/registry/ thay vì src/ của bạn, thì đó là một crate bạn phụ thuộc vào có dùng #![feature]. Cách sửa: xem README của crate đó; thường thì một phiên bản mới hơn chạy được trên stable (ví dụ, web framework Rocket cần nightly cho tới bản 0.4, còn bản 0.5 chạy trên stable). Nếu không, hãy chọn crate khác. Xem Cargo và crate.

Code chép về có #![feature(let_chains)]. Let chain (if let Some(x) = a && x > 0) đã stable từ Rust 1.88, nhưng chỉ trong edition 2024. Cách sửa: xóa dòng đó (cách sửa 2) và đặt edition = "2024" trong Cargo.toml. Nếu không, bạn sẽ gặp let chains are only allowed in Rust 2024 or later.

Kiểm tra nhanh

1. Bạn dán một đoạn code bắt đầu bằng #![feature(try_blocks)] và gặp E0554. Điều đó có nghĩa là gì?

2. Dưới lỗi, rustc cảnh báo rằng tính năng đã stable từ 1.88.0. Bạn nên làm gì?

3. Bạn thật sự muốn dùng nightly cho một thử nghiệm. Cách gọn gàng nhất là gì?

Điểm: 0 / 3