콘텐츠로 이동

Rust 에러 E0554: #![feature] may not be used on the stable release channel (stable에서 쓸 수 없는 feature)

E0554는 코드가 #![feature(...)] 줄로 시작하는데, 그런 줄은 nightly 버전의 Rust만 받아 준다는 뜻이에요. 거의 언제나 어딘가에서 복사한 코드에서 생겨요. 블로그 글, GitHub 저장소, AI 답변, 오래된 Stack Overflow 답변 같은 곳이요. 그 코드는 nightly Rust용으로 쓰였는데, 나는 rustup이 기본으로 설치하는 stable(안정판)을 쓰고 있는 거예요. 내 설치에는 아무 문제가 없어요. 보통은 줄 하나를 지우고, 같은 일을 하는 안정판 방법을 쓰면 해결돼요. 이 페이지는 Rust 컴파일러 에러 해설의 일부예요.

error[E0554]: `#![feature]` may not be used on the stable release channel
--> src/main.rs:1:1
|
1 | #![feature(iter_map_windows)] // ❌ nightly Rust용으로 쓰인 코드에서 복사했어요
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

이 에러를 내는 프로그램은 다음과 같아요.

#![feature(iter_map_windows)] // ❌ 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”(안정판 릴리스 채널)은 rustup으로 받는 평범한 Rust이고, 이 요청을 거절해요.

rustc가 무엇에 대해서는 불평하지 않는지도 보세요. 5번째 줄의 map_windows요. rustc는 #![feature] 줄에서 먼저 멈춰요. 그 줄을 지우고 나서야 나머지 코드가 stable에서 돌아가는지 알 수 있어요.

beta 채널에서도 같은 에러가 나요. 코드에 #![feature] 줄이 여러 개 있으면 rustc는 보통 첫 번째 것만 알려 주니까, 파일 맨 위에 더 있는지 확인하세요.

“직원 전용” 출입증과 비슷해요. 시험 주방(nightly)은 그 출입증으로 들여보내 줘요. 레스토랑(stable)은 아무리 정중하게 보여 줘도 그런 출입증을 아예 받지 않아요.

Rust는 오늘 stable에서 컴파일되는 코드가 앞으로 나올 모든 stable 1.x 릴리스에서도 계속 컴파일된다고 약속해요. 아직 완성되지 않은 기능은 이 약속에 포함될 수 없어요. 이름도, 인자도, 동작도 아직 바뀔 수 있고, 아예 없어질 수도 있으니까요. 그래서 그런 기능은 매일 밤 새로 만들어지는 컴파일러 빌드인 nightly에만 있고, #![feature(...)]로 하나씩 이름을 대서 켜야 해요.

stable Rust는 이 줄을 그냥 무시하지 않고 에러를 내며 멈춰요. 그래야 나도 모르는 사이에 미완성 기능 위에 프로젝트를 쌓는 일이 없어요. 기능이 완성되면 stable Rust의 일부가 되고, 그때부터는 이 줄이 전혀 필요 없어요.

그래서 E0554를 보면 진짜 질문은 세 가지뿐이에요. 안정판으로 같은 일을 하는 방법이 있나요(방법 1)? 그 기능이 이미 안정화됐나요(방법 2)? 정말 nightly를 쓰고 싶나요(방법 3)? stable, beta, nightly를 참고하세요.

방법 1: 속성을 지우고 안정판 API 쓰기

섹션 제목: “방법 1: 속성을 지우고 안정판 API 쓰기”

거의 언제나 이 방법을 고르세요. #![feature] 줄을 지우고 다시 컴파일하세요. 그러고 나서 E0658(use of unstable library feature `iter_map_windows` )이 나오면, 그 기능은 아직 미완성이고 같은 일을 하는 안정판 방법이 필요해요. 불안정한 메서드는 대부분 stable 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 -> 21
21 -> 19
19 -> 24
▶ 직접 실행해 보기

안정판 방법을 찾으려면 표준 라이브러리 문서에서 그 메서드를 열어 보세요. 불안정한 항목에는 “This is a nightly-only experimental API”(nightly 전용 실험적 API)라고 적힌 상자가 있고, #![feature] 줄의 기능 이름은 보통 The Unstable Book(영어)의 한 페이지와 이름이 같아요. 슬라이스와 반복자를 참고하세요.

방법 2: 그 기능이 이제 안정화됐는지 확인하기

섹션 제목: “방법 2: 그 기능이 이제 안정화됐는지 확인하기”

코드가 조금 오래됐을 때 이 방법을 고르세요. 예전에는 #![feature]가 필요했던 기능 중 많은 것이 지금은 stable Rust의 일부이고, 그렇다면 이 줄은 더 이상 필요 없어요. rustc가 에러 바로 아래의 경고로 그렇다고 알려 줘요.

error[E0554]: `#![feature]` may not be used on the stable release channel
--> src/main.rs:2:1
|
2 | #![feature(slice_as_chunks)] // ❌ 이제 필요 없어요: 이 기능은 안정화됐어요
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
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)] // ❌ 이제 필요 없어요: 이 기능은 안정화됐어요
| ^^^^^^^^^^^^^^^

경고는 “기능 slice_as_chunks는 1.88.0부터 안정판이라서, 더 이상 켜는 속성이 필요 없다”는 뜻이에요. 문제가 있는 프로그램은 다음과 같아요.

// 오래된 튜토리얼에서 복사한 코드
#![feature(slice_as_chunks)] // ❌ 이제 필요 없어요: 이 기능은 안정화됐어요
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=0
r=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가 그 기능이 안정화된 버전보다 그냥 오래됐을 수도 있어요. 확인하고 업데이트하세요.

Terminal window
rustc --version
rustup update

업데이트한 뒤에도 rustc --version이 여전히 옛 버전을 보여 준다면, 프로젝트에 버전을 고정하는 rust-toolchain.toml 파일이 있을 가능성이 커요. 프로젝트별로 툴체인 고정하기를 참고하세요.

안정판 방법이 없고, 앞으로 나올 nightly에서 코드가 깨질 수 있다는 걸 받아들일 때, 마지막으로 이 방법을 고르세요. 흔한 좋은 이유는 이런 거예요. 새 기능을 직접 써 보고 싶을 때, 작은 실험을 할 때, 또는 기여하려는 프로젝트가 이미 nightly를 쓸 때요. stable 옆에 nightly를 설치하고, 명령 하나에만 쓰세요.

Terminal window
rustup toolchain install nightly
cargo +nightly run

아니면 Cargo.toml 옆에 rust-toolchain.toml 파일을 두어 프로젝트 전체가 nightly를 쓰게 할 수도 있어요. 그러면 그 폴더에서는 그냥 cargo run만 해도 nightly가 쓰이고, 다른 곳에서는 stable이 쓰여요.

[toolchain]
channel = "nightly"

다른 사람도 빌드하는 프로젝트라면 channel = "nightly-2026-10-01"처럼 날짜를 고정하세요. 그래야 모두가 같은 컴파일러를 써요. Rust Playground에서는 툴체인 메뉴에서 Nightly를 고르면 돼요.

stable이 #![feature]를 받아 주게 하려고 RUSTC_BOOTSTRAP=1을 설정하라는 조언을 볼 수도 있어요. 그 스위치는 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)] // ❌ 내장 벤치마크는 nightly 전용이에요
| ^^^^^^^^^^^^^^^^^
//! 가격 계산 도우미.
//! nightly Rust용으로, 옛날 방식으로 쓴 벤치마크.
#![feature(test)] // ❌ 내장 벤치마크는 nightly 전용이에요
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]));
}

해결: criterion이나 divan처럼 stable에서 돌아가는 벤치마크 크레이트를 쓰고 cargo bench를 실행하세요. 여기서는 #![feature] 줄만 지워서는 부족해요. 그러면 extern crate test;가 E0658(use of unstable library feature `test` )을 내요. 성능을 참고하세요.

nightly가 필요한 의존성. --> 줄이 내 src/가 아니라 ~/.cargo/registry/ 아래의 크레이트를 가리킨다면, 내가 의존하는 크레이트가 #![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) Cargo.toml에 edition = "2024"를 설정하세요. 그러지 않으면 let chains are only allowed in Rust 2024 or later(let 체인은 Rust 2024 이상에서만 쓸 수 있다)라는 에러가 나요.

이해도 점검

1. #![feature(try_blocks)]로 시작하는 코드를 붙여 넣었더니 E0554가 나요. 무슨 뜻일까요?

2. 에러 아래에서 rustc가 그 기능이 1.88.0부터 안정판이라고 경고해요. 어떻게 해야 할까요?

3. 실험 하나에는 정말 nightly를 쓰고 싶어요. 가장 깔끔한 방법은 무엇일까요?

점수: 0 / 3