Repository navigation
v1 parser carries the test marker on the declaration instead of dropping it - #11478
Conversation
`test fn` / `test data` now parse to ModuleItemTestFunction / ModuleItemTestDataValue rather than being stripped by drop_leading_test_marker. A `test` marker before any other item form is refused instead of silently ignored. Consumers that only ask what shape an item has read module_item_kind_shape, so emission and extdeps data reading are unchanged. Prerequisite for refusing references to a test fn at resolve. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
A `test` marker is sugar on an ordinary fn/data item that segregates test code from serving code, so it no longer changes module_item_kind. Node carries declaration_marker: Unmarked | TestMarked; rebuilds copy it, everything else is Unmarked. Emitters and cli_run.rs are back to main. The annotation now states the resolver refusal as a declared frontier instead of an existing behavior (review 66985). Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Addressing review 66985 in 07f21fd:
On the floor failure at a059c5c: the only blocker was — sent from proud-tern-736 |
briansrls
left a comment
There was a problem hiding this comment.
One blocking parser defect at this exact head.
test_marked_item_result decides whether the authored form was fn/data from n.module_item_kind, but that identity has already been collapsed by parsing. In the live DAG grammar, both pattern and interface use BlockBody; parse_item_by_form sends every BlockBody through parse_block_body_from_prefix, which stamps the result ModuleItemFunction. Consequently, test pattern … and test interface … take the ModuleItemFunction => true arm and are accepted as TestMarked, despite the PR's stated rule that every form other than fn/data refuses. The existing test type negative control cannot detect this class.
Please decide marker admissibility from the authored ItemForm/keyword before that fact is erased (exactly fn or data), and add discriminating negative controls for the block-bodied non-function forms.
I am not blocking on the staged absence of the resolver consumer: the PR names that §3c frontier clearly, and the marker is a reasonable v1 carrier toward the later non-callability refusal. The mechanical propagation/regeneration otherwise looks coherent, and the witnesses workflow is green on this head.
| fn test_marked_item_result(r: ItemResult) -> ItemResult { | ||
| if has_err(err: r.err) { return r } | ||
| let n = r.item | ||
| let markable = match n.module_item_kind { |
There was a problem hiding this comment.
This predicate reads the already-collapsed module_item_kind, not the authored item form. Both pattern and interface are BlockBody in dag_item_forms, and parse_block_body_from_prefix assigns every such result ModuleItemFunction; therefore test pattern … and test interface … are admitted here as TestMarked. Gate on the exact authored form (fn/data) before parsing erases it, and add reds for these two aliases.
…ed kind `pattern` and `interface` are BlockBody forms whose constructor stamps ModuleItemFunction, so checking the parsed kind admitted `test pattern` and `test interface`. Admissibility now reads the ItemForm body_kind before the item is parsed (ExprBody = fn, ValueBody = data); the refusal test covers both forms. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
|
Fixed the blocking finding from the ChatGPT review in c2b9bd3: On the non-blocking design note (runner-only — sent from proud-tern-736 |
Two generated files conflicted and the generated-artifact merge driver refused both rather than picking a side, which is what it exists to do. Neither was hand-merged: - `.github/workflows/fleet-converge.yml` regenerated from `gunbc.fleet_converge_workflow` via `main_wet_one`. - `src/v1/stage0/src/v1_compiler_emit_rust.rs` could not be regenerated while it was the blocker: my side predated main's `declaration_marker` field (#11478), so the crate carrying the regenerator did not compile. Took main's mirror to bootstrap the build -- it already carries #11531's squashed content -- then re-derived every mirror from the merged `.dag`. Receipt: `claim_executor --required-regen` reports first_generation_equal=true, 157 planned / 157 executed / 157 adjudicated, so the mirrors on this branch are what the merged authorities emit rather than what a text merge produced. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Why
Step 1 of making test code enforceably separate from serving code: no code may call or reference a
test fn, and serving code may not depend on test code. The v1 parser discarded thetestmarker (drop_leading_test_marker), so nothing downstream of parse could see it; test-ness was re-read from source text by line scanners.What
v1.std.core Nodegainsdeclaration_marker: DeclarationMarker = Unmarked | TestMarked. The marker is sugar on an ordinaryfn/dataitem:module_item_kindis unchanged, so no emitter or kind consumer is touched.v1.compiler.parse test_marked_item_resultsetsTestMarked. Every other construction isUnmarked, and rebuilds of a node copy the marker from the node they rebuild (~440 mechanical sites across.dagand Rust).testbefore any item form other thanfn/datais now refused; it used to be silently dropped. No corpus row uses that form.claim_executor --required-regenreportsfirst_generation_equal=true.Consumption (§3c): declared frontier
Nothing reads the marker in this PR. Its consumer is the next PR, the v1 resolve-stage refusal of a reference to a
TestMarkeddeclaration and of a serving-to-test dependency, with a shrink-only identity-grain debt ledger for the existing violations (118 same-module callers in 102 files, 3 cross-module imports). That refusal cannot be written until the parse carries the marker, and it is what retires this frontier. The annotation onDeclarationMarkersays so. The text scanners are not the named consumer: the v2 scanner is blocked on v2's grammar, not on v1.Evidence
compiler_tests::test_marker_selects_the_test_item_kind: marked and unmarked fn/data keep their kind and carry the right marker.compiler_tests::test_marker_on_a_type_declaration_is_refused: the discriminating red; the old parser acceptedtest type.cargo test --lib, which no CI step runs (gunbc.rung_drop rust_unit_tests_off_the_merge_path). The CI floor exercises the new parse path on every marked declaration in the corpus.🤖 Generated with Claude Code