Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

기능 게이트 검사

기능 게이트를 추가, 제거, 이름 변경 또는 안정화하는 절차는 기능 게이트를 참고하십시오.

기능 게이트는 nightly 전용 #![feature(...)] 옵트인 없이 불안정한 언어 기능과 라이브러리 기능을 사용하지 못하도록 막습니다. 이 장에서는 기능 게이팅의 구현, 즉 게이트가 어디에서 정의되고, 어떻게 활성화되며, 사용이 어떻게 검증되는지를 설명합니다.

기능 정의

모든 기능 게이트 정의는 rustc_feature 크레이트에 있습니다.

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_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!)를 사용하여 다음을 검사합니다.
    1. 기능이 활성화되어 있습니까?
    2. (내부 컴파일러 매크로의 경우) 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_session/src/parse.rs에 있습니다.

  • feature_err와 feature_warn은 표준화된 진단을 내보내며, 가능한 경우 추적 이슈 번호를 첨부합니다.
  • rustc_span/src/lib.rs의 Span::allows_unstable은 스팬이 #[allow_internal_unstable]로 표시된 매크로에서 비롯되었는지 검사합니다. 이를 통해 내부 매크로는 stable 채널에서도 불안정 기능을 사용할 수 있으며, 사용자 코드에는 게이트가 그대로 적용됩니다.