기능 게이트 검사
기능 게이트를 추가, 제거, 이름 변경 또는 안정화하는 절차는 기능 게이트를 참고하십시오.
기능 게이트는 nightly 전용 #![feature(...)] 옵트인 없이 불안정한 언어 기능과 라이브러리 기능을 사용하지 못하도록 막습니다. 이 장에서는 기능 게이팅의 구현, 즉 게이트가 어디에서 정의되고, 어떻게 활성화되며, 사용이 어떻게 검증되는지를 설명합니다.
기능 정의
모든 기능 게이트 정의는 rustc_feature 크레이트에 있습니다.
- 불안정 기능은
declare_features!매크로를 통해rustc_feature/src/unstable.rs에 선언됩니다. 이를 통해 기능이 이슈 번호 및 추적 메타데이터와 연결됩니다. - 채택된 기능(안정화된 기능)은
rustc_feature/src/accepted.rs에 나열되어 있습니다. - 제거된 기능(명시적으로 금지된 기능)은
rustc_feature/src/removed.rs에 나열되어 있습니다. - 게이트가 적용된 내장 속성과 cfg는
rustc_feature/src/builtin_attrs.rs에 선언됩니다.
rustc_feature::Features 타입은 크레이트의 활성 기능 집합을 나타냅니다. 컴파일 중에는 enabled, incomplete, internal 같은 헬퍼를 사용하여 상태를 검사합니다.
기능 수집
AST 검증이나 확장 전에 rustc는 크레이트 수준의 #![feature(...)] 속성을 수집하여 활성 Features 집합을 빌드합니다.
- 수집은
rustc_expand/src/config.rs의features에서 이루어집니다. - 각
#![feature]항목은unstable,accepted,removed테이블을 기준으로 분류됩니다.- 제거된 기능은 즉시 오류를 발생시킵니다.
- 수락된(Accepted) 기능은 기록되지만 nightly를 요구하지 않습니다. stable/베타에서는
rustc_ast_passes/src/feature_gate.rs의maybe_stage_features가 nightly가 아님을 알리는 진단을 내보내고 안정화된 기능을 나열하며, “이미 안정화됨” 메시지가 바로 여기에서 나옵니다. - 불안정 기능은 활성화된 것으로 기록됩니다.
- 알 수 없는 기능은 라이브러리 기능으로 취급되어 나중에 검증됩니다.
-Z allow-features=...를 사용하면 허용 목록에 없는 불안정 기능이나 알 수 없는 기능은 모두 거부됩니다.RUSTC_BOOTSTRAP은UnstableFeatures::from_environment에 입력됩니다. 이 변수는 컴파일러를 “nightly“로 취급할지 여부를 제어하여, 부트스트래핑 중에 기능 게이트를 우회하거나 명시적으로 비활성화(-1)할 수 있게 합니다.
파서 게이팅
일부 구문은 파싱 중에 감지되어 게이트가 적용됩니다. 파서는 진단을 일관되게 유지하고 파싱이 끝날 때까지 미루기 위해, 나중에 검사할 스팬을 기록합니다.
rustc_session/src/parse.rs는GatedSpans와gate메서드를 정의합니다.- 파서는 게이트가 필요한 구문(예:
async for,yield, 실험적 패턴)을 만나면rustc_parse/src/parser/*에서 이를 사용합니다.
검사 패스
핵심 로직은 rustc_ast_passes/src/feature_gate.rs에 있으며, 주로 check_crate와 그 AST 방문자에 있습니다.
check_crate
check_crate는 상위 수준의 검증을 수행합니다.
maybe_stage_features: stable/베타에서#![feature]를 거부합니다.check_incompatible_features: 서로 호환되지 않는 기능 조합(rustc_feature::INCOMPATIBLE_FEATURES에 선언됨)이 함께 사용되지 않도록 보장합니다.check_new_solver_banned_features: 차세대 트레이트 솔버용 컴파일러 모드와 호환되지 않는 기능을 금지합니다.check_features_requiring_new_solver: 기존 솔버와 호환되지 않는 기능에는 새 트레이트 솔버를 요구합니다.- 파서가 게이트한 스팬: 파싱 중에 기록된
GatedSpans를 처리합니다(GatedSpans검사 참조).
GatedSpans 검사
check_crate는 sess.psess.gated_spans를 순회합니다.
gate_all!매크로는 기능이 활성화되지 않은 경우 게이트된 각 스팬에 대해 진단을 내보냅니다.- 일부 게이트에는 추가 로직이 있습니다(예:
yield는coroutines또는gen_blocks에 의해 허용될 수 있습니다). - 레거시 게이트(예:
box_patterns,try_blocks)는 하드 오류 대신 향후 비호환성 경고를 내보내는 별도의 경로를 사용할 수 있습니다.
AST 방문자
PostExpansionVisitor는 확장된 AST를 순회하며 확장 이후에 검증하기 더 쉬운 구문 요소를 검사합니다.
- 방문자는 헬퍼 매크로(
gate!,gate_alt!,gate_multi!)를 사용하여 다음을 검사합니다.- 기능이 활성화되어 있습니까?
- (내부 컴파일러 매크로의 경우)
span.allows_unstable이 이를 허용합니까?
- 예로는
trait_alias,decl_macro,extern types, 그리고 다양한impl Trait형태가 있습니다.
속성과 cfg
rustc는 구문 외에도 속성과 cfg 옵션을 게이트합니다.
내장 속성
rustc_ast_passes::check_attribute는BUILTIN_ATTRIBUTE_SET을 기준으로 속성을 검사합니다.- 속성이
AttributeGate::Gated이고 해당 기능이 활성화되지 않은 경우feature_err를 내보냅니다.
cfg 옵션
rustc_attr_parsing/src/attributes/cfg.rs는gate_cfg를 정의하고,rustc_feature::find_gated_cfg를 사용하여 게이트된cfg를 거부합니다.gate_cfg는Span::allows_unstable을 존중하므로,#[allow_internal_unstable]로 표시된 내부 컴파일러 매크로는cfg게이트를 우회할 수 있습니다.- 게이트된 cfg 목록은
rustc_feature/src/builtin_attrs.rs에 정의되어 있습니다.
진단
진단 헬퍼는 rustc_session/src/parse.rs에 있습니다.
feature_err와feature_warn은 표준화된 진단을 내보내며, 가능한 경우 추적 이슈 번호를 첨부합니다.rustc_span/src/lib.rs의Span::allows_unstable은 스팬이#[allow_internal_unstable]로 표시된 매크로에서 비롯되었는지 검사합니다. 이를 통해 내부 매크로는 stable 채널에서도 불안정 기능을 사용할 수 있으며, 사용자 코드에는 게이트가 그대로 적용됩니다.