Repository navigation
t27core: every name bound as both backends bind it (Closes #8092) - #8129
Merged
Merged
Conversation
P3 slice 3 of epic #5980, name resolution. t27c's typecheck resolves no name (see #8087). An undeclared identifier, a function or type read as a value, a duplicate declaration, a shadow Zig refuses, and a missing field all pass with 0 errors, and gen-c writes C that cc refuses or reads otherwise. The core now refuses them with E_NAME (5): - a name read that is no local, local array or for-capture in scope, no parameter, and no module const, var or array; a field its struct lacks; - a module name, a parameter, or a local in one scope declared twice; a local, parameter or capture that shadows another; a capture that shadows a module name; - C's one namespace and order (see #8088): a local, parameter, capture or field spelled like a const gen-c writes as #define; a call of a function a local shadows; a test or bench whose test_/bench_ C name is taken; a module initializer, type or size naming a const written after it, or a var. An assignment to a for capture is E_UNSOUND (17). for captures are now in the scope table (Sym.ct 2). e9_local_array_out_of_scope becomes e5_local_array_out_of_scope: no name is in scope there. The slice-3 fuzz round found one more coercion hole, fixed here. A local const that the rest of its block assigns is a var in gen-zig, so it is not known at compile time. Fixtures: names_accepts, 35 refusals (33 e5_*, e17_assign_capture, e17_assigned_const_is_runtime), 9 core tests. t27core_ddc.t27 is repinned. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
gHashTag
enabled auto-merge (squash)
October 9, 2026 09:56
4 of 6 tasks
This was referenced Oct 9, 2026
Contributor
This was referenced Oct 9, 2026
Open
gHashTag
pushed a commit
that referenced
this pull request
Oct 9, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #8092
P3 slice 3 of epic #5980 (see #5980): name resolution. t27c's typecheck resolves no name (see #8087). An undeclared identifier, a function or type read as a value, a duplicate declaration, a shadow Zig refuses and a missing field all pass it with 0 errors. gen-c writes C for them that cc refuses or reads otherwise. gen-c's C also has one namespace and one declaration order that t27 does not have (see #8088).
Refuses (E_NAME, 5, unless noted)
forcapture in scope, no parameter, no module const/var/array (undeclared, used before its declaration, out of its block or loop, in a test, bench or module init, as an index)#define(see #8088)test_T/bench_Banother declaration has (see #8088)forcapture (E_UNSOUND, 17)Accepts
Both backends take these:
forcaptures join the scope table (Sym.ct2).e9_local_array_out_of_scopebecomese5_local_array_out_of_scope, because no name is in scope there.The slice's fuzz round found one more coercion hole, fixed here as a follow-up to #8085. A local const that the rest of its block assigns is a var in gen-zig, so it is not known at compile time (
e17_assigned_const_is_runtime).Fixtures
accept/names_accepts.t27, run on gen-c+cc, Zig and t27b.e5_*,e17_assign_capture,e17_assigned_const_is_runtime. gen-c generates every one (typecheck accepts them), so none joinstools/specs_generate_baseline.txt.Lines by file
Nothing generated; no hand-written Rust;
bootstrap/src/compiler.rsuntouched. Master'scheck_budgetandcheck_allexit 0 on this diff's numstat and name-status.Lab evidence
On master 2e90d31 plus this diff, the t27c lab gives:
cargo test --release -p t27c --test core_selfhost: ok;DDC:
t27core_ddc,names_acceptsandcoercion_acceptseach 1 passed;Probes: 68 hand-written programs, each run through typecheck, gen-c+cc and the Zig route, every function called from a test:
n10/n12, which Zig blocks only through gen (Zig): the assert_eq prelude's parameters a and b shadow a spec fn named a or b, so the spec does not compile #7532.Scratch fuzzers on the final core:
if (false), a comptimefalse and ..., a dead store). Every "Zig refuses, core accepts" is t27c gen (Zig): constant folding turns a comparison into 0 or 1, which Zig refuses where a bool is expected #8077 or a literal width (slice 4).Defects filed: #8087 (typecheck), #8088 (gen-c).
🤖 Generated with Claude Code