コンテンツにスキップ

11. Lint と制約検証

コンパイラは行番号付きの警告とエラーを返します。すべてのメッセージは自己修正の三つ組、すなわち 何が間違っているか / ターゲットで有効な候補 / 推奨される修正 を持たなければなりません。 評価フレームワーク のループに乗せるためです。

この節がカタログです。安定コマンドが出しうるコードには必ずここに行があり、行の無いコードはこの節の バグであって、カタログの外にあるコードではありません。コードの規則が別の章にある場合、行はコードの 意味を述べ、規則についてはそこへリンクします。コードを手にした読者が探すのは行であり、振る舞いが 定義されているのは章の方だからです。

redstone パイプラインの E_LOGIC_* / W_LOGIC_* はこの約束の外です。到達経路は cairn synth --experimental-logic-synth だけで、その面は丸ごと Internal ティア (互換性) です。文字列について何も保証していない以上、ここに行を置くと存在しない 契約を述べることになります。自身の規則が言及するものは レッドストーンと論理 が名指し ます。

コード 意味
E_DUPLICATE_SIZE ヘッダに size= が 2 つ以上ある。
E_DUPLICATE_SLOT theme 本体が同じスロットを 2 回宣言している。
E_DUPLICATE_ARG 1 つの引数リストで key= が繰り返されている。
E_DUPLICATE_ID 同一ボディスコープ内の 2 つのメンバが id= を共有している。
E_DUPLICATE_SELECTOR 1 つの theme 内の 2 つのセレクタ行が、同じメンバを選び同じキーを束縛している。
E_DUPLICATE_ITEM 同じ種別のトップレベル項目 2 つが名前を共有している。
E_DUPLICATE_HEADER 単一値の @directive が 2 回以上宣言されている。

E_DUPLICATE_SELECTOR はセレクタを字面ではなく意味で比較します。属性の順序は関係なく、class= / id= / mat_slot= はラベルテキストとして比較されるので small と "small" は同じ値です。 違う キーを束縛する行は合成されるので報告されません。属性が部分的に重なるだけの行も同様です (マテリアルとテーマ §7.1)。

E_DUPLICATE_ITEM は theme / def / struct / site を 4 つの別々の名前空間として扱うので、 1 つの名前は各種別に 1 回ずつ現れられます。前 3 つでは最初の宣言が解決し、残りは何も束縛しません。同名 の site ブロック 2 つは代わりに site::NAME::PLACE_ID の名前空間を共有してマージされます。 id= が異なる place はすべてビルドされ、衝突するのは id= の重複だけですが、east_of= はブロックをまた いで届きません。

E_DUPLICATE_HEADER の対象は @cairn と @intended_targets です。@requires は除外されます。その 下限はすべての行で最も厳しいものに畳まれるので、2 つ目は制約を追加します (§5.3)。

コード 意味
E_PARSE ソースがパースできない。
E_UNKNOWN_KEYWORD 文キーワードが既知キーワード表にない。
E_UNKNOWN_ARGUMENT そのメンバのキーワードの語彙に無い key=。引数として書かれたものと、メンバ自身の [key=value] の中のものの両方。または struct / def のヘッダが取る size= / class= 以外の key=。
W_IGNORED_ARGUMENT その語彙、または struct / def のヘッダの語彙の中にはあるが、書かれた行でどのパスにも読まれなかった key=。または theme のセレクタ行が束ねる key= で、まだどのパスも読まないもの。
E_MISPLACED_BINDING 信号を発せないキーワードのメンバに付いた -> value の末尾 (§14.2)。
E_MISPLACED_MEMBER キーワードは既知だが、囲んでいるボディに読み手がいない。
E_UNEXPECTED_POSITIONAL 位置引数を読まない行に裸の値がある (§5.1)。
E_UNSUPPORTED_NESTING メンバが、誰も読まないインデントされたボディを持っている。
E_TYPE_MISMATCH_LABEL ラベル型キーの値が識別子でも文字列でもない。
E_TYPE_MISMATCH_SIZE size= の値が WxH リテラルでない。
E_CONNECT_ARITY connect 行の形が FROM.PORT to TO.PORT でない。
E_INVALID_REQUIRES requires の式がバージョン下限になっていない。@requires ヘッダと def / theme の本体行の両方が対象 (§5.3)。
W_INVALID_CAIRN_VERSION @cairn の値が YYYY.M[.PATCH] の言語バージョンになっていない (§5.3)。
W_FUTURE_CAIRN_VERSION @cairn の値が、読んでいるコンパイラより新しい言語バージョンを指している。

E_MISPLACED_MEMBER は struct / def 内の place / connect、あるいは site の行に混ざった ジオメトリキーワードで発火します。該当行で 1 回だけ報告され、その下にインデントされたものも一緒に 落ちます。

E_UNSUPPORTED_NESTING: メンバをグループ化するのは struct / def 内の level y=N だけです。 site のボディはフラットなリストです。落ちたサブツリーごとに、その根で 1 回報告されます。

E_TYPE_MISMATCH_LABEL: ラベル型キーは id= / class= / mat_slot= / use= / theme= です。 use= と theme= では、型の合わない値はリゾルバから見るとキーが無いのと区別できません。このコード は「キーは行にあるが使えない」、E_INCOMPLETE_PLACE は「キーが無い」を意味します。

E_CONNECT_ARITY: connect FROM.PORT to TO.PORT が位置引数を読む唯一の形です。片側の欠落、to キーワードの欠落や別トークンへの置き換え、末尾の余分な位置引数、ドット 1 つの PLACE.PORT 参照で ない端点を対象にします。2 つの端点は独立した修正箇所なので別々に報告されます。

E_INVALID_REQUIRES: 受け付ける形は任意のエディション、version、>=、バージョンラベルで、空白は 任意です。version の前にあるエディションでない語、それ以外の演算子、バージョンの欠落、数字で始まら ないか u32 に収まらない構成要素、- の後に読めるプレリリースタグが無いもの、バージョン後の余分な テキストを対象にします。ターゲットのエディションが DataVersion を持たない整形式のラベルは対象では ありません。それは E_REQUIRES_UNORDERABLE で、構文の問題ではないからです。下限の 2 つの綴り — @requires ヘッダと、def / theme が持てるメンバレベルの requires 行 (§10.4) — は同じ規則で検査されます。どのビルドもインスタンス化しない構成要素も検査対象です。誤りは行そのものにあり、それを読むものが あるかどうかではありません。

W_INVALID_CAIRN_VERSION: 受け付ける形は YYYY.M または YYYY.M.PATCH です。4 桁の年、1 … 12 の月、省略可能なパッチで、いずれの構成要素も 10 進数字だけです。月の先頭のゼロは受け付けられ、値を 変えません。2026.06 と 2026.6 は同じバージョンで、前者は calver.org の YYYY.0M、後者は Cargo の version フィールドが持てる YYYY.M です。構成要素が 2 つでも 3 つでもない値、空または数字で ない構成要素、4 桁でない年、暦に無い月、u32 を超えるパッチ、そしてバージョンの後に続く 2 つ目の 語を対象にします。ヘッダの値は行まるごとなので、@cairn 2026.6 draft はバージョンとそれ以外の何か を書いていることになります。

@requires より意図的に厳しくしてあります。あちらは Mojang の名前空間にある Minecraft のラベルを 読み、順序が付けばよいだけなので、構成要素は数字で 始まれば よく、プレリリースタグもラベルです。 @cairn は Cairn 自身のバージョンを指すので、構成要素はすべて数字であり、2026.13 は存在しない月、 1.2 は年ではなく semver です。

W_FUTURE_CAIRN_VERSION は、自分より新しい言語で書かれたファイルについてコンパイラが言える唯一の 有用なことです。このビルドより後に追加されたキーワードや引数は E_UNKNOWN_KEYWORD / E_UNKNOWN_ARGUMENT として報告されるので、それらがその行についてではなくバージョン差についての指摘 かもしれない、と知っているのはヘッダだけです。これが届くのは、後の言語が「今ある形の中に」足したもの です。まったく新しい構文形式 — ディレクティブ、トップレベル項目 — は E_PARSE であり、パースは すべての check パスに先行するので (§11.3)、バージョン差が最も説明になる場面で この指摘は現れ得ません。

その場面では、ヘッダをテキストとして読みます — 先頭の @cairn で照合し、行末まで読む 1 行です — そして E_PARSE が、このファイルは読んでいるビルドより新しい言語を宣言している、という note を 持ちます。2 つ目の指摘ではなく note なのは、パースできないソースが報告する指摘は E_PARSE ひとつ だけ、という決まりをそのまま保つためです。note が付くのはバージョンとして読める値のときだけです。 読めない値は W_INVALID_CAIRN_VERSION の担当であり、無関係なパース失敗の上でそれを繰り返すのは ノイズになります。

1 つのディレクティブが両方のコードを受け取ることはありません。バージョンとして読めない値には、 比較するバージョンが無いからです。

コード 意味
E_UNKNOWN_ID 固定されたターゲットが宣言していない解決済みブロック ID。
E_VERSION_CAP --target がソースの宣言する @requires の下限を下回る (versioning-editions §10.4)。
E_REQUIRES_UNORDERABLE @requires の下限が、ターゲットのエディションの DataVersion 表で位置づけられないバージョンを名指す (versioning-editions §10.4)。
E_INTENDED_TARGET_CAP @intended_targets が名指すバージョンが、同じファイルの宣言する下限をすべて下回る。
W_INTENDED_TARGET_CAP そのうちの一部だけが下回る。
W_INTENDED_TARGET_UNSUPPORTED @intended_targets が、そのエディションのどの --target でもビルドできないバージョンを名指す。
E_INCOMPATIBLE_MATERIAL ブロックステートを付けるジオメトリを持つメンバが、それを保持できないマテリアルに束縛されている。
E_MISSING_MATERIAL ブロックへの唯一の経路が mat_slot= であるメンバが、それを持たずに書かれている。
E_UNRESOLVED_SLOT メンバの mat_slot= が、束縛されたテーマの宣言していないスロットを指している。
E_UNKNOWN_SLOT_TARGET slot NAME -> VALUE の値が、正規トークンでも抽象マテリアルトークンでもない (マテリアルとテーマ)。
E_THEME_SELECTOR_UNMATCHED theme のセレクタ行が、ファイル中のどのメンバにも一致しない。
E_THEME_VARIANT_MISSING 固定されたエディションが、テーマのどのエディション別バリアントも束縛できない。
E_INCOMPLETE_PLACE place 行が id= / use= / theme= のいずれかを欠いている (§9.3)。
E_UNKNOWN_ABSTRACT_TOKEN mat_slot= が、渡されたパックのカタログが宣言していない抽象マテリアルトークンに解決される (マテリアルとテーマ)。
W_ABSTRACT_TOKEN_DEFERRED 同じトークンだが、そもそもカタログが渡されておらず、照合する相手がいない。
W_STATE_LITERAL_UNCHECKED 正準トークンのステートリテラル (@oak_log[axis=x]) が書かれたまま使われた。E_STATE_DOMAIN が実装されるまで、そのプロパティと値をターゲットに照らして検査するものがない (バージョンとエディション)。
W_NO_THEME_BOUND スコープにテーマが束縛されていないので、その中の mat_slot= メンバはすべて空気になる。
W_THEME_VARIANT_REBOUND place theme= があるエディションのバリアントを名指したが、固定されたエディションは別のものを束縛した (バージョンとエディション)。

E_UNKNOWN_ID と E_INCOMPATIBLE_MATERIAL は block-array lowering 段で発生するので、報告するのは lowering を走らせるコマンド — cairn compile、cairn lower、cairn info、 cairn check --edition E --target V — だけです。さらに E_UNKNOWN_ID は固定されたターゲットを必要 とするので、実際に出せるのは cairn compile --target と cairn check --edition E --target V の 2 つです (info と lower はバージョンを固定せずに lowering します)。--target なしの cairn check は lowering を走らせないので、どちらのコードにも到達しません。

W_STATE_LITERAL_UNCHECKED も同じ lowering が出します。テーマのスロットや connect … path= から 読むステートリテラルのそれぞれに付くので、cairn compile、cairn lower、cairn info、 cairn check --edition E --target V がどちらのエディションでも報告します。これは E_STATE_DOMAIN の代わりです。コンパイラが各ブロックのステートの表を持つまで、ブロックにないプロパティやドメイン外 の値はそのまま構造ファイルに書き出されるので、それを黙って済ませないのがこの警告です。

cairn check --target があるのは、CI ジョブが check コマンドをゲートにしつつ、compile が拒否する lowering 段の指摘を見られるようにするためです。ターゲットが宣言していない ID は check を終了コード 0 で通過し、cairn compile を終了コード 1 で止めていました。それを決める情報 — ただ 1 つの (edition, version) の組 — が check のコマンドラインになかったからです。このフラグは コンパイルモデル §4.2 が --target 単独を拒否するのと同じ理由で --edition を必要とし、compile と同じテーブルに対して同じ lowering パスを走らせるので、スコープを 失えば同じ E_PARTIAL_BUILD を出します。行わないのは compile が書くことすべてです。成果物もロック ファイルも作らず、@requires の下限の強制も行いません — ロックはビルドを保証する記録であり、 --target を下限に突き合わせるのはそれを生成するコマンドだけの仕事だからです (E_VERSION_CAP)。 フラグを付けなければ従来どおりの挙動なので、今日通っているソースが落ち始めることはありません (バージョンとエディション §10.4)。

E_INCOMPATIBLE_MATERIAL は現時点では、階段ファミリ外に束縛された傾斜屋根または軒の stair を 意味します (コンパイルモデル §4.3)。

E_THEME_VARIANT_MISSING は --edition 指定時のみ発火し、いくつのスコープが読んでいても 論理テーマごとに 1 回 報告されます。修正すべきは同じ theme ブロックの同じ 1 箇所だからです。 そのテーマを名指しする placement はすべて拒否されます。テーマを宣言しつつ mat_slot= を 1 つも 読まないモジュールは報告されません。ピンの有無でビルド結果が 1 バイトも変わらないからです。

E_THEME_SELECTOR_UNMATCHED は接頭辞に反して警告です。何にも一致しない規則は何も上書きしないので、 どのメンバも規則を消した場合と同じマテリアルのままです。この指摘は「何が作られたか」ではなく書き手の 意図についてのものです。接頭辞はコード文字列の一部であり、それは Stable なので (互換性ティア)、書かれたまま据え置きます。深刻度は先頭の 1 文字ではなく severity フィールドから読んでください。

E_UNKNOWN_SLOT_TARGET は逆の判定でエラーです。何にも束縛されないスロットは、そこを指すすべての mat_slot= を空気に落とすので、スロットが全部打ち間違っているテーマは、要求された大きさの空洞を 終了コード 0 で建ててしまいます。

E_MISSING_MATERIAL と E_UNRESOLVED_SLOT は 1 つの切り分けの両側で、両方を受け取るメンバは ありません。前者はキーが無い場合、後者はキーがあって使えない場合です。修正の仕方が違うので コードも分かれています — place 行における E_INCOMPLETE_PLACE と E_TYPE_MISMATCH_LABEL と 同じ分け方です。

E_MISSING_MATERIAL の対象は、それが無いと何も置かないロールです。floor と walls は適用 テーマのスロットマップ経由でパレットに到達し、既定ブロックを持たないので、mat_slot= の無い ものはボクセルを 1 つも生みません。mat_slot= の無い window は 開口 であり、空気に彫られる ので報告されません。壁に細い狭間を、樹種を選ばずに開けるための書き方です。door は常に彫る側で、 マテリアルをそもそも読みません。 roof / stair / pressure_plate は既定ブロックを塗るので、これも報告されません。発生させる のは cairn check で、lowering の前です。テーマも要りません。1 つもテーマを宣言しない モジュールでも、どのメンバがマテリアルを名指ししていないかは伝えられます。

E_UNRESOLVED_SLOT は メンバごと・束縛テーマごとに高々 1 回 報告されます。def の本体は、 それ自身のスコープとして 1 回、さらにインスタンス化する place ごとに 1 回解決され、そのどれも がテーマを束縛します。あるメンバについて既に報告済みのテーマに対する繰り返しは捨てられます。 2 つの placement が別々のテーマを名指しした場合は 2 つの finding になります。それぞれが自分の 対象テーマを名乗り、修正箇所も別だからです。残った finding がどの解決から出たものかは規定 しません。同じテーマを束縛した 2 つの解決が、同じスロットについて別の判断に達しうるからです。

その差はエディションバリアントによるソフトニングです。--edition の固定が無い場合、選ばれた テーマの姉妹バリアントのいずれかが宣言しているスロットは既知として扱われ、報告されません。 具体的な束縛はエディション依存で、固定によってテーマが 1 つのバリアントに絞られて初めてスコープに 入るからです (バージョンとエディション §10.7)。 place ... theme=NAME が同じように緩められるのは NAME が論理テーマ名のときだけです。 バリアント名を書くことは、そのバリアントのスロットについて訊くことだからです。したがって 2 つの placement が同じテーマを束縛しながら 1 つのスロットについて食い違うことがあります。

どこからも置かれない def も、モジュールが選んだテーマに対して解決されます。したがって def だけで site の無いファイルも、モジュールが選べる論理テーマが 1 つであるかぎり検査されます。 2 つ以上、あるいは 1 つも宣言されていない場合は、def 自身のスコープにテーマが束縛されないため、 その mat_slot= は place がテーマを選ぶまで判定されません。

E_INCOMPLETE_PLACE は欠けているキーをすべて列挙し、その行はビルドから落とされます。

E_UNKNOWN_ABSTRACT_TOKEN と W_ABSTRACT_TOKEN_DEFERRED は、答えられる相手がいたかどうかで分かれ ます。パックが渡されていてそのトークンを宣言していないなら、最も近い既知のトークンへの示唆を添えて ビルドを止めます。パックが渡されていないなら、そもそも問うていないので、セルは警告付きで空気に なります。後者はライブラリ呼び出し側が到達する経路 — LSP のハイライトや、パック無しの cairn check — であり、警告なのはそのためです。そこで拒否すると、パック無しで読まれたソースをすべて拒否すること になります。

W_NO_THEME_BOUND は 1 段上の同じ形です。どのテーマにも解決されない mat_slot= は読むスロット表を 持たないので、そのメンバはボクセルを 1 つも置きません。テーマを束縛せず mat_slot= も読まない モジュールは報告されません。

@intended_targets の 3 つのコードは、ファイルが表明した意図を、そのファイル自身の下限に照らします (versioning-editions §10.4)。そのエディション がビルドできないバージョンは W_INTENDED_TARGET_UNSUPPORTED であって、下限には照らされません。作者が まず動くのは「そのターゲットはここに存在しない」という事実であり、その隣に cap を並べれば、ビルドを止 めているのではない行を編集させることになるからです。残り — そのエディションが ビルドできる バージョ ン — はその中だけで数えます。そのすべてが下限を下回れば E_INTENDED_TARGET_CAP です。ファイルは、自分 が対象だと言っているどのバージョン向けにもビルドできず、そのいずれかを cairn compile --target に渡し た瞬間に E_VERSION_CAP になります。一部 であれば W_INTENDED_TARGET_CAP です。このヘッダはヒント であり (§5.3)、下限より上のバージョンは変わらずビルドできるからです。そも そもビルドできないバージョンはどちらの数にも入りません。リストのどの部分の答えにもならず、数に入れれば 「何もビルドできないファイル」を「半分だけの問題」として報告することになるからです。1 つのヘッダが cap コードと unsupported コードを同時に得ることもあります。名指されたバージョンの誤り方が同じとは限らない からです。

3 つともエディションごとの答えです。下限とターゲットのラベルは、あるエディションの DataVersion 表の 中で順序づけられるからです。cairn check を通すすべてのコマンド — check / info / lower / compile / synth — が 2 つの cap コードを報告し、それぞれが対象としているエディションの表でヘッダを 照らします。--edition が名指す 1 つ、cairn info --editions が挙げるもの、あるいはどれも名指さない 場合は両方です。どちらかのエディションが到達した所見は報告されます。矛盾は、後でどう建てるかに関わらず ファイルの 2 行の間にあるからです。1 つのスパンが持つ cap 所見は 1 つで、2 つのエディションが及ぶ範囲に ついて食い違った場合はエラーの方を報告します。W_INTENDED_TARGET_UNSUPPORTED はスコープにエディション がちょうど 1 つある場合にだけ答えます。Java がビルドできないバージョンは、作者が意図した Bedrock の ターゲットであることが普通にあるので、両方がスコープにあるうちはその問いはまだ立てられていません。

コード 意味
E_INVALID_PLACE_ID place id= が空、または . / : / / / \ / 空白を含む。
E_DUPLICATE_PLACE_ID 同じ site の 2 つの place 行が id= を共有している。
E_OUTPUT_NAME_COLLISION ビルドが書くはずの 2 つの成果物が、大文字小文字を無視して同じファイル名になる。同じ名前の struct と place、2 つの site に置かれた同じ id=、平坦化すると同じ名前になる 2 本の walkway など。
E_INVALID_PLACE_ORIGIN place が origin 以外の at= を持つ、または at= と east_of= / north_of= を併用している (§9.3)。
E_UNRESOLVED_PLACE_REF place use=、east_of= / north_of=、connect の端点が、存在しない place や def を名指している。
E_UNRESOLVED_THEME_REF place theme= が、モジュールの宣言していないテーマを名指している。
W_UNUSED_DEF どの place use= からも参照されていない def。

E_INVALID_PLACE_ID は趣味の問題ではなく往復の問題です。スコープキー site::SITE::PLACE と、そこ から読み戻されるすべての walkway キーは、. と : を区切りとして組み立てられているので、それを 含む id は読み戻せません。id は出力ディレクトリに書かれるファイルの名前でもあり、/ や \ はその名前を パスに変えてしまいます。区切りを含む相対 id はサブディレクトリに落ち、絶対 id は出力ディレクトリそのものを 置き換えます。どちらの区切りもすべてのプラットフォームで拒否するので、id が受け入れられるかどうかは検査する ホストに依存しません。id= は文字列リテラルを受け取るので、値はそのまま通っていました。

E_DUPLICATE_PLACE_ID は両方のスパンを示します。id を参照するものはすべて最初の行を採り、重複した 方は落とされるので、「もう一方」に解決された参照が 2 つ目の指摘になることはありません。

E_OUTPUT_NAME_COLLISION は成果物の名前の付け方から生じます (§9.3.4)。struct はその名前、place は id= だけ、walkway は site とポートで名付けられます。どれも同じ出力ディレクトリに書かれるので、2 つが 1 つのファイルを指すことがあり、両方がビルドされればその片方しか残せません。この検査は lowering の前に 行われます。サイズのない struct と、サイズのない def を使う place は lowering が落とすので数えず、 同じポートの組を結ぶ 2 行の connect は、向きによらず lowering が敷くとおり 1 本の walkway として数えます。 W_STRUCTURE_TOO_LARGE が落とす struct や placement と、探索範囲がルーターの上限を超え W_WALKWAY_BLOCKED が報告して敷かない walkway は数えるので、指摘は 2 つが同じファイルに「書かれるはず」と 述べます。名前は大文字小文字を無視して比べます。 macOS と Windows が既定で使う大文字小文字を区別しないファイルシステムでは Hut と hut は 1 つの ファイルであり、ソースがビルドできるかどうかがビルドするホストに依存するべきではないからです。この指摘は 他の site の指摘と同じく lowering の前に出るので、cairn check は --target なしで報告します。同じ名前を 2 回宣言したものはこのコードではありません。2 つ目の struct hut は E_DUPLICATE_ITEM、同じ site の 2 つ目の id= は E_DUPLICATE_PLACE_ID です。

E_UNRESOLVED_PLACE_REF と E_UNRESOLVED_THEME_REF は、綴りの上限に収まる候補があれば最も近いもの を添えます (did you mean)。どちらもエラーなのは、名前に何かを代入すればソースが 書いていない site を建てることになるからです。

コード 意味
E_UNRESOLVED_PORT connect A.PORT to B.PORT が、参照先の def が公開していないポートを名指している。
E_AMBIGUOUS_PORT そのポート id が、参照先の def の複数のメンバに一致する。
E_MISSING_PATH_MATERIAL connect 行に path= が無く、walkway を敷くマテリアルがない。
W_DUPLICATE_WALKWAY 同じ site の先行する行が既に敷いた (from, to) の組を、connect が繰り返している。
W_INVALID_WALKWAY_IDENT connect の site / place / port 識別子が __ を含む、または place / port 識別子が _ で始まるか終わる。
W_DEFERRED_CONNECT connect の対象の place 自身が拒否されており、繋ぐものがない。
W_WALKWAY_BLOCKED フォールバック経路のセルが既存の構造物と重なり、落とされた。

E_UNRESOLVED_PORT は place.port のうちポート側だけを指します。place 側は E_UNRESOLVED_PLACE_REF です。E_AMBIGUOUS_PORT は lowering では最初の一致を採り、衝突の方を報告 します。修理は書き手の代わりに選ぶことではなく、衝突しているメンバのどちらかを改名することだから です。

E_MISSING_PATH_MATERIAL は、他の「マテリアルが無い」系が警告なのに対してエラーです。空気に落ちた walkway は、ソース上では繋がって見える 2 棟を世界では繋がないまま残し、そのことを report の中で言う ものが何もありません。

W_INVALID_WALKWAY_IDENT は E_INVALID_PLACE_ID のうち . / : に関する往復の規則を、別の区切りに 適用したものです。 __ は walkway のスコープキーの from と to を繋ぐので、片側の b__c ともう片側の c__home2 が 同じ文字列に符号化されます。この区切りに接する _ も同じように区切りに溶け込みます。 a.p_ to b.p と a.p to _b.p はどちらも a.p___b.p に符号化され、_ という名前の port は、 分け直すと port が空になるキーを残します。区切りに接するのは from 側 port の末尾と to 側 place の 先頭だけです。connect はどちら向きにも書けるので、どの place の先頭もどの port の末尾も区切りに 接し得ます。残りの四つの端、つまり place の末尾と port の先頭は、どちら向きに書いても . の隣にあり 溶け込みませんが、規則を「place と port の識別子は _ で始まることも終わることもできない」という 一文に保つため、これらも拒否します。site は両隣と :: で区切られるため、端の規則から外れます。 行は落とされ、指摘は改名すべき区間を名指します。その行が求めた walkway は失われるので、何も敷かなかった どの行とも同じく、cairn compile は E_PARTIAL_BUILD でビルドを拒否します。

W_DEFERRED_CONNECT は place を拒否したもの — 欠けた行、打ち間違えたキー、失敗した原点セレクタ、 解決できない use= や theme= — に従います。警告なのは、修理を持つ指摘が place 側のものであり、 connect を 2 つ目のエラーとして報告すると、正しい行へ書き手を送ることになるからです。

コード 意味
W_DEFERRED_MEMBER block-array パスが lowering しないメンバ。そのスコープはそれ抜きで建つ。
W_STRUCT_NO_SIZE struct が size=WxH を宣言していないので、lowering は範囲を導けず飛ばす。
W_DEF_NO_SIZE def での同じ事象。その def を使う place use= がすべて飛ばされる。
W_STRUCTURE_TOO_LARGE スコープの導出範囲が、block-array パスが確保する体積を超えている。
W_PHASE_CONFLICT 同じフェーズの 2 つのメンバが、1 つのボクセルに異なるブロックを書いた (§4.4)。
E_PARTIAL_BUILD 要求されたスコープ、または connect 行が求めた walkway のうち少なくとも 1 つが lowering されず、求められたより少ないものしか作られなかった。

W_STRUCT_NO_SIZE と W_DEF_NO_SIZE は 1 つの規則を、それを担っているものによって分けたものです。 code で絞り込むフィルタが、建たない struct と、実体化されないテンプレートとを区別できます。

W_STRUCTURE_TOO_LARGE は「組み合わせ」で発火します。size=、walls height=、roof overhang=、 level y= はそれぞれ単独で範囲検査されていて、これはその積が届かないところにある場合です。上の 2 つ と同じく、エラーではなく警告です。そのスコープが飛ばされるだけで、ビルドの残りには影響しません。

W_DEFERRED_MEMBER は、モジュールごと失敗させるのではなく、部分的なビルドを見られる状態に保ちます。 スコープの残りは lowering され、指摘は何が欠けているかを名指します。

E_PARTIAL_BUILD はその実行単位版で、この表で唯一のエラーです。上の警告が「スコープはそれ抜きで 建つ」と言うのに対し、こちらは「コマンドが求めたスコープが 1 つも建たなかった」と言います。空気だけ に lowering されたスコープも、何がそれを空にしたかによらず建たなかったスコープです。すべてのメンバ が見送られた、どのテーマもその mat_slot= メンバにブロックを与えなかった、メンバを 1 つも宣言してい ない、のいずれでも同じです。実行ごとに 1 回、失われたスコープの数を名指して報告され、出すのは cairn compile と、同じ lowering パスを走らせる cairn check --edition E --target V です。

W_PHASE_CONFLICT は、拒否ではなく「後勝ち」を報告するものです。コンパイルモデル は同一フェーズ内のローカルな上書きに後勝ちを認めていて、それは書き手がメンバを言い直した場合の話 です。2 つのフットプリントがたまたま交差した場合はそうではありませんが、グリッドは両者を区別できま せん。仕様が定める解決自体は起きます — 指摘は、それがどのボクセルで起きたかを言います。

コード 意味
E_TRUTH_TABLE_EMPTY 行が 1 つも無い、または出力が 0 か 1 の行が 1 つも無い assert truth(...)。
E_TRUTH_TABLE_CONFLICT 2 つの行が同じ入力の組に違う出力を割り当てている。
W_TRUTH_TABLE_DUPLICATE_ROW 2 つの行が同じ入力の組を担当し、かつ矛盾していない。
W_TRUTH_TABLE_PARTIAL 行が割り当てていない入力の組がある。

どちらのコードも後ろの行で報告されます。行は、組を共有する先行のすべての行と比べられるので、 表が拒否されるかどうかは行を書く順序に左右されません。00 -> 1; 01 -> 0 の後の 0- -> 1 は、 前者とは一致していても E_TRUTH_TABLE_CONFLICT です。同じ行では矛盾が重複より優先され、その note は、指摘が名指す組にもう一方の出力を割り当てている最初の行に付きます。それ以外の指摘の note は、指摘が名指す組を割り当てている最初の行に付きます。そのため 1 つの組についての指摘はすべて同じ 行を指します。矛盾する 2 行のどちらを評価器が読むかは規定しません。修復はどちらの行が誤りかを 決めることです。

- があると、見た目の違う行から同じ組に届きます。そのためどちらのコードもパターンではなく組に ついて言います。0- と -1 はどちらも 01 を割り当てます。直し方は形で変わります。先行する行の 内側にある行 — 0- に対する 01 — は削除します。単に交差しているだけの 2 行は狭めます。どちらを 消してもその行だけが割り当てている組を失うからです。先行する行そのものが、さらに前の行と重なる ことで報告されている場合は、代わりにその行を先に片付けるよう求めます。0- -> 1; -0 -> 1; 10 -> 1 では -0 が 0- から離れるよう狭めることを求められており、-0 が 10 を担当しているからと 10 を消すと、それと合わせて 10 がどの行にも割り当てられなくなるからです。

出力の - だけは、矛盾でも重複でもありません。その行は自分の担当する組を制約しないと述べている ので、具体的な出力が矛盾する相手もなく、一致する相手もありません。この組み合わせは W_TRUTH_TABLE_DUPLICATE_ROW になり、その修復案が非対称性を明示します。2 行のどちらを消すかで、 残る表の意味が変わるからです。行はあるが出力が 0 か 1 のものが 1 つも無い表は何も制約しないので、 E_TRUTH_TABLE_EMPTY がこれも含みます。修復が行を足すことではなく行を直すことなので、文面は 行が無い場合とは変えてあります。

2 つの警告が警告なのは、書かれている行はどれも本物の制約だからです。1 つの表が W_TRUTH_TABLE_DUPLICATE_ROW と W_TRUTH_TABLE_PARTIAL の両方を得ることもあります。繰り返し行も、 先行する行の内側にある行も、表がまだ持っていない組を埋めないためです。交差する 2 行だけは例外で、 そこでは網羅性の指摘を出しません。後ろの行を除いて数えると、表が実際には割り当てている組を 未割り当てとして挙げてしまうからです。

上のコードに加えて、lint は次を見ます。

カテゴリ 検査内容
ジオメトリ AABB 展開。壁の外の窓、空中に浮くドア。
attachment 額縁・絵画・看板・ボタン・レバー・松明が有効な取り付け面にあるか。
entity_aabb エンティティが壁や通路にめり込まないか、ドアの開閉弧を塞がないか、過密でないか。
support 吊りランタン、松明、キャンプファイア、砂利などの重力ブロックの支持条件。
fluid 水源 / 流れ / waterlogged の整合性。
version_caps / parity 状態やエンティティのスキーマがターゲットで使えるか (バージョンとエディション)。
edit_stability intent_state の変更が無関係なメンバの resolved_state に波及しないか。
redstone 宣言された真理値表と時相アサーションに対する tick 単位のシミュレーション。タイミング衝突、QC 依存、配線輻輳 (レッドストーン)。
AABB 干渉 重なった場合は優先マージか拒否。境界ブロックステートの再解決は IR 層の責務。

クローズドな語彙に対して識別子を拒絶する診断には、did you mean `X`? の note が付きます。未知の キーワード、未知の mat_slot= 名、未知の --target バージョンが対象です。

候補を出す条件は、入力長でスケールする Damerau-Levenshtein 距離の閾値内にあることです。閾値は 1〜3 文字なら 1 編集以下、4〜6 文字なら 2、それ以上は 3 です。候補列挙 (expected one of: ...) は常に併 せて出力されます。

--format json を取るコマンド — check、info、parse、lower — はいずれも、どんな入力に 対しても stdout に JSON ドキュメントをちょうど 1 つ書きます。check のドキュメントは finding の配列なので、パースできないソースはその 配列に E_PARSE が 1 つ入ったものです。info のドキュメントはレポートで、レポートが出せないとき — パース失敗、あるいは error 深刻度の finding があるとき — は代わりに {"diagnostics": [ ... ]} を 書きます。キーと終了コードでレポートと区別できます。どのパスが finding を上げたかはこれを変えま せん。厳密な edition 別 dry-run は、edition 中立のゲートが union で吸収してしまうものを見ており、 そこで上がった拒否も、要求された edition をすべて歩き終えたあとに同じドキュメントを書きます。

ただし、どのパスが finding を上げたかは、ドキュメントが何を載せるかは決めます。これは偶然では なく契約です。edition 中立のパスが拒否した場合、そのパスの警告はエラーと並んでドキュメントの要素に なります。edition 別パスが拒否した場合、ドキュメントはエラーだけを載せます。中立の警告はすでにテキ ストで報告済みであり、edition 別の警告は実行がこれから捨てる行に属するので、その edition を示す note の下で stderr に読めます。レポートが出せる実行における警告は、どちらの形式でも stderr にテキス トで報告されます。

実行レベルの拒否は check の配列の要素にはなりません。出荷されていない --target と、スコープを 失った lowering (E_PARTIAL_BUILD) は、ファイル中のスパンに紐づく指摘ではなくコマンドラインとビルド についての事実なので、どちらの形式でも stderr と終了コードで報告します。compile がそれらに与えて いる形と同じです。配列には実行が到達した指摘がすべて入るので、空の文書ではなく「何が検査されたか」の レポートになります。

これは保留中の問題ではなく決着済みです。check --format json には実行レベルの拒否を機械可読に表す 形がなく、利用者は判定を終了コードから読みます。stderr はどちらの形式でも人間向けの文章です。この 契約の一部ではないので、利用者はそれを解析せず、構造のないテキストとして扱ってください。stderr を 読まなくても分かるのは、実行が指摘によってではなく実行レベルで拒否されたという事実です。終了コード 1 で、配列に "severity": "error" の要素が 1 つもなければ、まさにそれを意味します。報告すべきもの のないソースに対する [] も同じです。なお、ソース自身が error severity の指摘を持つ実行でも拒否は 起こりえます。その場合、配列はほかの error による失敗と同じに読め、実行レベルでも拒否されたことは stderr にしか書かれません。ほかの失敗がこう見えることはありません。パースできないソースは E_PARSE を持つ配列になり、読めないファイルはドキュメントを 1 つも書きません。2 つの拒否のどちら だったか、ビルドが何を失ったかは stderr にしか書かれません。

info の拒否のうち 1 つは同じ種類の実行レベルの拒否です。レジストリパックが拒否するはずだった ブロックステートをパレットが抱えている場合、その edition は portability の行を失います。この拒否は ソース中のスパンに紐づきません。そのようなブロックステートは、作者には直せないパックやコンパイラの 漏れか、ソースで階段に書かれたステートリテラルのどちらかです。後者は Java のドメイン外の facing や half の値 (@oak_stairs[facing=up]) か、facing / half / shape 以外のキーで、 E_STATE_DOMAIN が実装されるまでターゲットに照らして検査されません。拒否は両方を挙げます。ほかの ブロックに書かれたリテラルは、代わりに unsupported として数えられます。どちらの形式でも stderr に テキストで読めます。それでもドキュメントは書かれます — 約束は「入力ごとに 1 ドキュメント」であって 「拒否ごとに 1 要素」ではないからです。この拒否のほかに拒否のない実行は {"diagnostics": []} を 書き、残りは終了コードで伝えます。

parse の成果物は AST、lower の成果物はブロック配列 IR です。ダンプはレポートではないので、失敗 は「穴の空いたダンプ」にはなりません。どちらも info と同じ {"diagnostics": [ ... ]} を書き、 キーと終了コードでダンプと区別できます。lower はパースできないソースに対しても、後段のパスで失敗 したソースに対してもこれを書きます。どちらもダンプするに値する IR を残さないからです。それ以外の --format では、所見は stderr にテキストで読めます。

--format json は所見ごとに 1 オブジェクトを返します。

フィールド 型 備考
code string 安定した E_* / W_* 識別子。gcc スタイル出力と同じ文字列。
severity string "error" または "warning"。
line integer プライマリスパン先頭バイトの 1-based 行番号。
col integer 同先頭バイトの 1-based カラム (Unicode スカラー値)。
end_line integer スパン終端 (排他) の 1-based 行番号。
end_col integer スパン終端 (排他) の 1-based カラム。
primary string 人間向けメッセージ。
notes array [{line?, col?, message}]。空のときは省略。
data object コード固有のペイロード。無いときは省略。

data は kind で判別する開かれたオブジェクトです。primary を解析せず (code, data.kind) で 照合してください。追加は厳密に additive なので、未知の kind は失敗にせず無視します。下表に無い コードは data をまるごと省略します (JSON でも null ではなくキーごと存在しません)。

コード data ペイロード
W_WALKWAY_BLOCKED { "kind": "walkway_blocked", "skipped": <u64> }。フォールバックの L 字経路で既存構造と衝突してスキップされたセル数。
E_DUPLICATE_SELECTOR { "kind": "duplicate_selector", "rebound": ["frame"] }。この行が先行する行から奪う束縛キー。末尾の = は含みません。常に非空。
E_UNKNOWN_ID { "kind": "unknown_id", "id", "registry", "origin", "token"?, "suggestion"?, "aliases"? }。後述。
E_INCOMPATIBLE_MATERIAL { "kind": "incompatible_material", "id", "required", "slot"?, "token"? }。束縛されたマテリアル、ジオメトリが必要とするファミリ、束縛の出どころ。
E_INCOMPLETE_PLACE { "kind": "incomplete_place", "missing": ["id", "use", "theme"] }。行が宣言していないキー。常に非空。
E_INVALID_REQUIRES { "kind": "invalid_requires", "reason", "found" }。reason は not_a_version_requirement / unknown_edition_scope / unsupported_operator / empty_version / component_not_a_number / component_too_large / prerelease_not_a_tag / trailing_tokens のいずれか。失敗が断片を名指ししないとき found は空。
W_INVALID_CAIRN_VERSION { "kind": "invalid_cairn_version", "reason", "found" }。reason は component_count / component_not_a_number / year_not_four_digits / month_out_of_range / patch_too_large / trailing_tokens のいずれか。found はその理由が指す構成要素で、失敗が断片を名指ししないときは空 — component_count と、構成要素そのものが空の値 (2026.) に対する component_not_a_number です。
W_FUTURE_CAIRN_VERSION { "kind": "future_cairn_version", "declared", "compiler" }。どちらも書かれたまま。declared はファイル中の文字列、compiler は報告したビルド。
W_TRUTH_TABLE_PARTIAL { "kind": "truth_table_partial", "inputs": 2, "covered": 1, "missing": ["01","10","11"] }。後述。
@intended_targets の 3 コード { "kind": "intended_targets", "edition", "targets": ["1.20.4"], "floor"? }。所見の対象となるバージョンをソース順に、そして照らしたエディション。floor はそれらを最初に拒否する下限を書かれたまま持ち、下限の話ではない W_INTENDED_TARGET_UNSUPPORTED では省かれる。

E_UNKNOWN_ID.origin は誰がその ID を選んだかを示します。修復先が違うからです。

origin 意味 修正箇所
authored ソースが ID を直接名指しした。 作者の行。
catalog レジストリパックがトークンを対応付けた。 パックの対応付け。
builtin メンバのデフォルト用の行をパックが持たず、コンパイラ組み込みの ID が使われた。 行を追加すべきパック。

token は catalog と builtin に付随し、authored では省略されます。suggestion はタイポ閾値内 の宣言済み ID が無いときに省略されます。リネームは通常その閾値の外ですが、2 つのフィールドは互いに独立 した規則で埋まるので、置き換え先に近いリネームは両方を持ちます。

aliases がもう半分で、この 2 つは同じ ID に対する別種の主張です。suggestion は文字列距離からの推 測ですが、aliases はレジストリパックの aliases コンポーネントが「2 つの名前は同じブロックだ」と述 べたものです。したがってクイックフィックスは aliases なら無断で適用してよく、suggestion は適用す べきではありません。中身はターゲットがそのブロックに対して宣言する ID すべて (閉じた候補集合であって、 そこからの選択ではありません) をパック自身の順で保持し、パックが 1 つも名指ししないときは省略されます。 表示されるノートは先頭のいくつかを並べて残りを数え、集合全体はペイロードにあります。 バージョンとエディション §10.4 を参照して ください。

E_INCOMPATIBLE_MATERIAL も同じ考えです。slot はメンバが読んだ mat_slot= 名で、束縛が無ければ省 略されます。ドット付きの token (roof.dark_wood) なら、修正すべきはソース行ではなくパックの対応付 けです。required を暗黙にせず名前で持つのは、将来別のファミリが加わったときにコードを増やさずここ の値で表せるようにするためです。

W_TRUTH_TABLE_PARTIAL.missing は集合そのものではなく サンプル です。入力 20 本なら組は 100 万 通りあります。件数は missing.len() ではなく 2^inputs - covered から求めてください。総数ではなく inputs を持つのは、入力リストに文法上の上限が無く 2^130 を収める整数が無いためです。

  • エラー は放置すると意図しない結果になるもの、すなわち概念の不在、未知 ID、ドメイン外の状態です。 サイレント置換と暗黙の削除は禁止です。
  • 警告 はバージョン/エディション間の意味ドリフト、レッドストーン挙動の非保証、そして block-array パスが報告する部分ビルドの劣化です。不完全なのがソースではなくコンパイラ側の場合です。

E_ / W_ の接頭辞は severity ではありません。これは両方向に言えます。多くの W_ コードは部分 ビルドの劣化を表しますが、W_UNUSED_DEF / W_TRUTH_TABLE_PARTIAL と @cairn の 2 コードは劣化では ないまま警告です。そして E_ 接頭辞の 2 つは 名前ではなく上のルールで判定されています。

  • E_UNKNOWN_SLOT_TARGET は エラー です。マテリアルでない値に束縛されたスロットは、参照する メンバをすべて空気に落とすからです。
  • E_THEME_SELECTOR_UNMATCHED は 警告 です。何にもマッチしないルールは何も上書きしません。

E_PARSE は、パースが失敗するあらゆる形 — 未知の文字、奇数インデント、i64 を超える整数、item を 期待した位置のキーワード — をまとめた 1 つのコードで、どれだったかはメッセージが言います。形ごとに コードを分けると、将来増える形のたびにこの表が 1 行増えることになり、しかも分岐したい利用者はいま のところいません。その代わりのコストは、区別するにはメッセージを読む必要があることです。加えてこれ は、どの check パスも上げない唯一のコードでもあります。パースは全パスに先行し、パースできないソース はそのどれにも到達しないので、ビルドが単独で報告する唯一の finding です。

E_MISSING_MATERIAL が エラー なのは、上の 2 つのうち 1 つ目の規則によるものです。メンバは ビルドから落ち、その場所に何も置かれません。これは暗黙の drop であって、部分ビルドの劣化では ありません。不完全なのはマテリアルを名指ししなかったソースの側で、コンパイラの側ではありません。 しかも drop はそのメンバで止まりません。walls が落ちると体積の導出に使う壁の高さが下がるため、 構造そのものが縮み、そこに開けるはずだった door や window も併せて deferred になります。

@cairn の 2 つのコードは、同じルールを逆から読んで 警告 です。このヘッダは provenance で、 どのパスも分岐に使わず、パレットのエントリもここからは来ず、lockfile の cairn_version はファイル ではなくコンパイラを記録します。@cairn banana は @cairn 2026.06 とバイト単位で同じものを建てる ので、結果について意図しないことは何も起きません。失われるのはヘッダ自身の仕事 — 後のコンパイラに 読めること — であり、一言添える価値はあってもファイルを拒否する価値はありません。@requires が同じ 判定でエラーなのは、その下限が入力そのものだからです。cairn info の互換範囲を決め、 cairn compile --target がそれに縛られるので、蒸発した下限は通してはいけないターゲットを通します。

E_UNKNOWN_ARGUMENT は エラー です。理由は 1 段上の E_UNKNOWN_KEYWORD と同じで、キーワードの 語彙に無いキーは何も指しておらず、コンパイラがどう育っても値を読むパスは現れず、メンバは求められた ものを持たずに建つからです。既定値を持つ引数の綴り間違いが最悪で、ビルドは既定値のまま成功し、何も 言いません。

各キーワードの語彙は閉じており、theme のセレクタが名指ししたキーワードの語彙だけを広げます。 theme に window[tags=...] と書けば tags= は window で何かが読むキーになり、それ以外では なりません。逆方向は E_THEME_SELECTOR_UNMATCHED です。セレクタが作れるのは新しい語であって、その キーワードがすでに持つ語から 1 編集の距離にあるものは造語ではなく「2 度書かれた綴り間違い」なので、 候補付きで拒否されます。広げるのは語を認めることだけです。マッチがメンバに渡すのはその行の バインディングで、これは予約されたままです (マテリアルとテーマ)。 したがって、キーワードが定義していてどのパスも読まないキーは、セレクタがそれでマッチしていても まだ届いていないキーのままです。

メンバ自身の [key=value] も同じ語彙に従います。window[clas=outer] は window clas=outer と同じ 欠陥であり — 書き手が何かに読まれると思っている語を何も読まず、どちらにしても class は失われます — 同じコードと同じ候補を受け取ります。そのセレクタが何を 意味 するかは別の問いで、ここでは決めて いません。メンバのセレクタはそのまま運ばれ、新しい id を束縛しているのか既存のメンバを参照している のかは後段のパスが決めます。この検査にその答えは要りません。どちらに決まろうと、その語は何かに読ま れるか読まれないかのどちらかだからです。なお、メンバ自身の括弧に書いたキーはそのメンバがその属性を 持つ ことにはならないので、それを選ぶ theme の行はどのメンバにも一致しません。

struct / def のヘッダ行は、コンポーネント・編集・複数建築 が定める、それ自身の閉じた語彙に答えます。下げが読む size= と、まだどのパスも読まない class= で す。セレクタが名指すのはメンバのキーワードなので、theme のセレクタがこの語彙を広げることはありませ ん。この 2 つ以外のキーは、メンバの場合と同じ欠陥が 1 行上で起きたもので、候補を添えて拒否されます。 struct s siz=7x7 には size が示されます。同じ綴り誤りが引き起こすサイズ欠落の警告はその誤りを名 指せず、しかも block-array の下げが走るところでしか出ません。cairn check でそれが走るのは --edition と --target の両方を指定したときだけなので、この検査がなければ、素の cairn check は その行について何も言わないことになります。両方が出るときは、エラーが警告より先に出力されます。

W_IGNORED_ARGUMENT は 警告 で、3 つのものを覆います。読めなかった値: 語彙にはあるが値を読 めなかった key= は捨てられ、代わりに既定値が入ります。まだ届いていないキー: 本仕様が定義してい てまだどのパスも読まない key= (今日それに当たるのは window shape= / anchor=、 roof footprint= / bounds=、ヘッダの class= です) は IR まで運ばれて一度も参照されません。コン パイラが知るキーワードの theme セレクタ行で矢印の右にある key=value もすべてこれに当たり、キーや 値が何であってもそのバインディングの位置で報告されます。セレクタのバインディングを下げるパスはまだな いからです (マテリアルとテーマ)。素通りされたキー: 同じ行の別の引 数の書かれ方によってのみ読まれるキーが、その引数を別の書き方で書いたメンバに載っている場合です。境界 はキーワードです。コンパイラが知るキーワード上の仕様定義キーはこの形で報告され、知らない キーワードは E_UNKNOWN_KEYWORD で、その引数は判定されません。3 つともビルドをソースと食い違わ せます。ルールが禁じているのは サイレント な置換であり、3 つとも告知されます。まだ届いていないキー で欠けているのはソースではなくコンパイラの側で、だから拒否ではありません。autofix を提供するかは実装 で定義します。

読めなかった値は、そのメンバがその後建つかどうかに関わらず報告されます。値はメンバがどうなっても誤り なので、それ自体が 1 つの修復であり、同じ行の拒否が直るまで指摘を保留すると、書いた人にコンパイルを 1 回余計に強いるだけです。注記はどちらが起きたかを述べます。建つメンバでは既定値が出力に何をしたか、 建たないメンバではどちらにせよ建たないことと、その理由が隣の拒否であることです。今日の例外は、引数が 読まれる前に落とされるメンバ (持ち上げた level の下の roof) で、値が読まれないので、落とされた ことの指摘の横に報告されません。ほとんどの値はブロック配列の下げでしか読まれないので、--edition / --target の無い cairn check と言語サーバーは、チェックパス自身が読むキーについてしか読めなかった値を報告しません (§11.1)。

素通りされたキーは語彙の第 2 軸です。語彙はキーワードごとに閉じており、さらに 下げ規則を選ぶ引数の 書かれ方ごとに閉じています。roof slope_to= を読むのは kind=shed の規則だけで、他のどの規則も読ま ないので、

roof kind=gable slope_to=front

は向きを無視した屋根を建てます。語彙の外のキーが起こすサイレントな取りこぼしと同じことが、引数 1 段 下で起きているわけです。これが E_UNKNOWN_ARGUMENT のような拒否にならず警告のままなのは、修復先が 決まらないからです。キーはそれを読むキーワード上の実在の語であり、意図されていたのが kind= の方か、 slope_to= が残り物なのかは決められません。メッセージは両方の箇所を示し、どちらも選びません。

この軸の腕は、セレクタが 書かれていないこと でもあり得ます。書かれていないこと自体が 1 つの規則で ある場合です。place gap= がそれで、at= の無い行は別の place からの相対配置で距離を読み、 at=origin は絶対位置に固定され読みません。つまり at=origin gap=5 は同じサイレントな取りこぼしです (§9.3.2)。

セレクタ がどの規則も名指していないとき — 下げ規則が知らない値、または不在の腕を持たない軸で何も 書かれていないとき — ここでは何も報告しません。そのメンバは下がらず W_DEFERRED_MEMBER が修復の全体 を担うので、その規則が読まなかったはずの引数について 2 つ目の指摘を出すのは 1 つの修復に 2 度請求する ことです。この deferral はブロック配列の下げで出るため、--edition / --target の無い cairn check はどちらも報告しません (§11.1)。常に報告されるのは、メンバが建つ側の場合です。規則 を選ぶのでは なく 別のキーを無効化するキーはさらに別の形で、今日は報告されません。repeat=1 のとき の window step= は、規則ではなく個数に対する条件です。

E_MISPLACED_BINDING は、メンバ行の 4 つ目のフィールドに他の 3 つと同じ問いを向けたものです。すなわ ち「この語は何かに読まれるのか」です。-> value の末尾を読むものはただ 1 つ、 §14.2 のセンサ集合だけなので、センサでないメンバに付いた末尾は IR に運ばれて捨てられ、そこで名指された信号は誰も発しません。E_UNKNOWN_ARGUMENT と同じ基準で エラー です。ビルドがソースと食い違い、しかも値をどう直しても修復にならないからです。

ここで問うのはホストだけです。Logic IR 無しで問えるのがホストだけだからです。末尾の値が信号を名指し ているか、その信号が二重に駆動されていないか、誰にも駆動されていないかは redstone パイプラインが答え ます (§14.2)。そしてホストが先に問われるので、発せないメンバに付い た末尾はこのコードを受け、値側の所見は付きません。キーワードが既知キーワード表に無いメンバは E_UNKNOWN_KEYWORD に任されます。本仕様が挙げていて表層がまだ受け付けていないセンサ、たとえば lever -> sig.a にホストが違うと言わないのはそのためです。

ゲーム内制約 (重力ブロック、取り付け条件、流体挙動、許容されない組み合わせ) はカタログ化し、 バージョンごとに管理します (バージョンとエディション)。「額縁はガラスに 掛けられない」のような制約はここに入ります。