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가 이렇게 하는 이유
섹션 제목: “Rust가 이렇게 하는 이유”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 -> 2121 -> 1919 -> 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=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를 쓸 때요. stable 옆에 nightly를 설치하고, 명령 하나에만 쓰세요.
rustup toolchain install nightlycargo +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 이상에서만 쓸 수 있다)라는 에러가 나요.
관련 에러
섹션 제목: “관련 에러”- E0658: use of unstable feature: 기능이 아직 nightly 전용이라면,
#![feature]줄을 지운 뒤 보통 이 에러가 나요. - 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 const 기능을 찾아 나서게 되는 흔한 이유예요.
- 모든 컴파일러 에러 해설
이해도 점검
섹션 제목: “이해도 점검”이해도 점검
1. #![feature(try_blocks)]로 시작하는 코드를 붙여 넣었더니 E0554가 나요. 무슨 뜻일까요?
2. 에러 아래에서 rustc가 그 기능이 1.88.0부터 안정판이라고 경고해요. 어떻게 해야 할까요?
3. 실험 하나에는 정말 nightly를 쓰고 싶어요. 가장 깔끔한 방법은 무엇일까요?
점수: 0 / 3
더 알아보기
섹션 제목: “더 알아보기”- E0554 — Rust error codes index (영어): 기능 속성은 nightly 채널에서만 쓸 수 있다는 공식 설명이에요.
- 부록 G - 러스트가 만들어지는 과정과 “Nightly 러스트” — The Rust Programming Language 한국어판: 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]에 넣을 수 있는 모든 기능 이름과, 각각의 추적 이슈(tracking issue) 링크가 있어요.