機能ゲートのチェック
機能ゲートを追加、削除、名前変更、または安定化するための手順については、 機能ゲートを参照してください。
機能ゲートは、nightly 限定の #![feature(...)] による明示的な有効化なしに、不安定な言語機能やライブラリ機能が使用されることを防ぎます。
この章では、機能ゲートの実装、つまりゲートがどこで定義され、どのように有効化され、使用がどのように検証されるかを文書化します。
機能の定義
すべての機能ゲート定義は rustc_feature クレートに配置されています。
- 不安定な機能は、
rustc_feature/src/unstable.rsでdeclare_features!マクロを通じて宣言されます。 これにより、機能が issue 番号や追跡メタデータに関連付けられます。 - 受理済み機能(安定化済み)は
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テーブルに照らして分類されます。- 削除済み機能は即座にエラーになります。
- 受理済み機能は記録されますが、nightly は必要ありません。
stable/beta では、
rustc_ast_passes/src/feature_gate.rsのmaybe_stage_featuresが非 nightly の 診断を発行し、安定した機能を列挙します。ここが「すでに安定化済み」 というメッセージの出所です。 - 不安定な機能は有効として記録されます。
- 不明な機能はライブラリ機能として扱われ、後で検証されます。
-Z allow-features=...を指定すると、allowlist に含まれていない不安定な機能または不明な機能は拒否されます。RUSTC_BOOTSTRAPはUnstableFeatures::from_environmentに渡されます。 この変数は、コンパイラを「nightly」として扱うかどうかを制御し、ブートストラップ中に機能ゲートを迂回できるようにするか、または明示的に無効化します(-1)。
パーサーでのゲート
一部の構文は、解析中に検出され、ゲートされます。 パーサーは後続のチェックのために span を記録し、診断の一貫性を保ち、解析後まで遅延させます。
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/beta で#![feature]を拒否します。check_incompatible_features: 互換性のない機能の組み合わせ (rustc_feature::INCOMPATIBLE_FEATURESで宣言)が同時に使用されないようにします。check_new_solver_banned_features: 次期トレイトソルバーのコンパイラモードと互換性のない機能を禁止します。check_features_requiring_new_solver: 古いソルバーと互換性のない機能に対して、新しいトレイトソルバーを要求します。- パーサーでゲートされた span: 解析中に記録された
GatedSpansを処理します (GatedSpansのチェックを参照)。
GatedSpans のチェック
check_crate は sess.psess.gated_spans を反復処理します。
gate_all!マクロは、機能が有効でない場合、ゲートされた各 span について診断を発行します。- 一部のゲートには追加のロジックがあります(例:
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_MAPと照合して検査します。- 属性が
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は標準化された診断を発行し、可能であれば追跡 issue 番号を添付します。rustc_span/src/lib.rsのSpan::allows_unstableは、span が#[allow_internal_unstable]でマークされたマクロに由来するかどうかをチェックします。 これにより、ユーザーコードにはゲートを適用しつつ、内部マクロが stable チャネル上で不安定な機能を使用できるようになります。