toolchain: banner purge + WHY-only comment sweep (rule 8)
selfhost/, cmd/, internal/ join the tree-wide sweep: every section banner dies (91 selfhost + the cmd C-style dividers -> 0); narration and stale contracts deleted (pre-#22 bundler notes, retired single-PT_LOAD and no-archive claims, superseded ABI tables); every ref/harec/qbe cite, task cite, encoding/ELF contract, and rule-10 twin pointer kept; lost lifetime/rationale lines restored where the sweep over-cut (elf_globals ownership, kwtab linear-scan). Comment- only proven: all five wwstage tool binaries byte-identical across the sweep; test-commit, test-byteid (161+1399, 0 pinned-divergent), and test-bootstrap (fixed point + 991-995 byte-id) all exit 0. The read-through banked 66 latent-bug leads (checkpoint).
This commit is contained in:
@@ -1,21 +1,4 @@
|
||||
// selfhost/cmd/wcc/check.ww — minimal port of cmd/wcc/check.c.
|
||||
//
|
||||
// Status: name-resolution + primitive-type seeding only. Full type
|
||||
// inference, conversion rules, tagged-union dispatch typing, return-
|
||||
// type checking, etc. all live in cmd/wcc/check.c (937 lines) and
|
||||
// will land here in subsequent commits.
|
||||
//
|
||||
// What this version does:
|
||||
// 1. Creates a top scope and seeds it with primitive type names so
|
||||
// `i32`, `str`, `*u8` etc. resolve.
|
||||
// 2. Walks the file's top-level decls (use/def/type/fn/let) and
|
||||
// installs Sym entries for each.
|
||||
// 3. Recursively walks fn bodies; for every nkind.N_IDENT used as an
|
||||
// expression or as a type name, looks it up and counts the
|
||||
// resolved vs. unresolved.
|
||||
// 4. Returns a summary the caller (wwdump -r) prints; the test
|
||||
// asserts unresolved == 0 on every selfhost fixture, which is
|
||||
// the floor signal that the frontend can name-resolve real ww.
|
||||
// Port of cmd/wcc/check.c.
|
||||
|
||||
package wcc;
|
||||
|
||||
@@ -91,8 +74,6 @@ fn circularnamed(c: *checker, t: *syntax.tinfo, n: *syntax.node) bool = {
|
||||
os.exit(1);
|
||||
};
|
||||
|
||||
// seedprimitives — install the built-in type names so `i32`, `str`,
|
||||
// etc. can be looked up like ordinary symbols.
|
||||
fn seedprimitives(c: *checker) void = {
|
||||
syntax.scopedefine(c.top, "void", syntax.skind.SK_TYPE, c.tc.tyvoid, nil);
|
||||
syntax.scopedefine(c.top, "bool", syntax.skind.SK_TYPE, c.tc.tybool, nil);
|
||||
@@ -822,8 +803,7 @@ fn resolvewalk(c: *checker, n: *syntax.node) void = {
|
||||
// free identifier.
|
||||
if (n.lhs != nil) { resolvewalk(c, n.lhs); };
|
||||
// A.6.0: branch returns early; stamp here so the post-walk
|
||||
// dispatch below sees N_DOT covered. exprtype N_DOT arm is
|
||||
// added in A.6.1; for now this is a no-op nil return.
|
||||
// dispatch below sees N_DOT covered.
|
||||
let _t: *syntax.node = exprtype(c, n, nil);
|
||||
return;
|
||||
};
|
||||
@@ -957,15 +937,12 @@ fn resolvewalk(c: *checker, n: *syntax.node) void = {
|
||||
};
|
||||
};
|
||||
|
||||
// ---- type-level helpers (AST-level, no resolved tinfo) --------------
|
||||
//
|
||||
// The selfhost check operates on AST type expressions rather than
|
||||
// resolved Type structs. These helpers mirror what cmd/wcc/check.c
|
||||
// does with tinfo, but only on the subset of cases this checker
|
||||
// needs to enforce: tagged-union exhaustiveness, ? subset
|
||||
// propagation, and !-flag semantics.
|
||||
|
||||
// unwrapbang — strip an nkind.N_TBANG wrapper; leaves other nodes alone.
|
||||
fn unwrapbang(n: *syntax.node) *syntax.node = {
|
||||
if (n == nil) { return nil; };
|
||||
if (n.kind == syntax.nkind.N_TBANG) { return n.lhs; };
|
||||
@@ -1050,10 +1027,6 @@ fn aliassym(c: *checker, n: *syntax.node) *syntax.sym = {
|
||||
return s;
|
||||
};
|
||||
|
||||
// resolvealias — if n is an nkind.N_TNAME pointing at a typedecl, return
|
||||
// the typedecl's body (possibly recursively). Pass-through for any
|
||||
// other node. The chain stops once we hit a non-nkind.N_TNAME node or a
|
||||
// name we can't resolve.
|
||||
fn resolvealias(c: *checker, n: *syntax.node) *syntax.node = {
|
||||
let cur: *syntax.node = n;
|
||||
for (cur != nil) {
|
||||
@@ -1274,9 +1247,6 @@ fn scruttype(c: *checker, e: *syntax.node) *syntax.node = {
|
||||
return nil;
|
||||
};
|
||||
|
||||
// mktname — fabricate an nkind.N_TNAME node with str = `nm`. Used by
|
||||
// exprtype to return primitive type nodes for literal
|
||||
// expressions. The arena keeps them around as long as the checker.
|
||||
fn mktname(c: *checker, nm: str) *syntax.node = {
|
||||
let n: *syntax.node = syntax.newnode(syntax.nkind.N_TNAME, "", 0, 0);
|
||||
n.str = nm;
|
||||
@@ -4692,9 +4662,6 @@ fn exprtype(c: *checker, e: *syntax.node, hint: *syntax.node) *syntax.node = {
|
||||
return nil;
|
||||
};
|
||||
|
||||
// isuntypedint / is_str_like / is_bool_like — helpers used
|
||||
// by the assignability check below to allow common AST shapes
|
||||
// through without needing real type inference.
|
||||
fn isuntypedint(t: *syntax.node) bool = {
|
||||
if (t == nil) { return false; };
|
||||
if (t.kind != syntax.nkind.N_TNAME) { return false; };
|
||||
@@ -5386,14 +5353,10 @@ fn isassignable(c: *checker, dst: *syntax.node, src: *syntax.node, confident: *b
|
||||
return true;
|
||||
};
|
||||
|
||||
// ---- match exhaustiveness --------------------------------------------
|
||||
//
|
||||
// For every match arm, verify that every variant of the scrutinee's
|
||||
// tagged-union type is handled by some case (or a default arm
|
||||
// exists). Multi-pattern `case A | B =>` covers all alts.
|
||||
|
||||
// qualleaf — rightmost dotted segment of a (possibly module-qualified)
|
||||
// type name; the whole name when unqualified.
|
||||
fn qualleaf(nm: str) str = {
|
||||
let dotidx: i32 = -1;
|
||||
let i: i32 = 0;
|
||||
@@ -5408,8 +5371,6 @@ fn qualleaf(nm: str) str = {
|
||||
return leaf;
|
||||
};
|
||||
|
||||
// qualmod — module qualifier of a type name (segment before the
|
||||
// rightmost '.'), or `defmod` when unqualified.
|
||||
fn qualmod(nm: str, defmod: str) str = {
|
||||
let dotidx: i32 = -1;
|
||||
let i: i32 = 0;
|
||||
@@ -5646,8 +5607,6 @@ fn checkvariantcovered(c: *checker, n: *syntax.node, v: *syntax.node, unionmod:
|
||||
if (!covered) { errmatchvariant(c, n, v); };
|
||||
};
|
||||
|
||||
// ---- let init / return assignability --------------------------------
|
||||
//
|
||||
// AST-level approximation: when we can infer src's type and dst is
|
||||
// explicitly declared, verify isassignable. We only emit an error
|
||||
// when isassignable says "false with confidence." If we can't tell
|
||||
@@ -6581,8 +6540,6 @@ fn checkretassign(c: *checker, n: *syntax.node) void = {
|
||||
};
|
||||
};
|
||||
|
||||
// ---- is / as validity ------------------------------------------------
|
||||
//
|
||||
// `e is T` and `e as T` require that e's declared type be a tagged
|
||||
// union and that T name one of its variants. Operates on AST type
|
||||
// expressions; falls back silently when we can't determine e's
|
||||
@@ -6670,8 +6627,6 @@ fn checkisas(c: *checker, n: *syntax.node) void = {
|
||||
c.errs += 1;
|
||||
};
|
||||
|
||||
// ---- ? subset propagation --------------------------------------------
|
||||
//
|
||||
// For `expr?`, the operand's error subset must be a subset of the
|
||||
// enclosing fn's return-type variants. Mirrors C check.c. Operand
|
||||
// is nkind.N_TRYPROP or nkind.N_TRYUNW (the F8 cardinality gate covers
|
||||
@@ -6836,9 +6791,6 @@ fn hascvariadic(params: *syntax.node) bool = {
|
||||
return false;
|
||||
};
|
||||
|
||||
// install_param — when entering a fn body, define its params in a
|
||||
// fresh local scope.
|
||||
//
|
||||
// TODO(#11): cstage check.c (post-#32) errors `param '%s' redeclared`
|
||||
// when two params share a name. The fn body's scope IS fresh here
|
||||
// (resolvefnbody opens it before calling us), so guarding scopedefine's
|
||||
|
||||
Reference in New Issue
Block a user