cleanup: drop resolved-issue citations from src comments

Sweep all src/**.zig comments that cite resolved issues (issue NNNN /
fix-NNNN / KB-N): the invariant or mechanism each comment states is
kept; the historical citation is dropped, per the no-conclusion-comments
rule. Pure-history parentheticals are removed outright. References to
the 16 still-open issues (0030, 0041-0056) are untouched, as are test
NAMES carrying regression provenance (matching the sanctioned
"Regression (issue NNNN)" example-header convention).

Also removes the issues/0019-import-non-transitive-c-scope/ fixture dir
— the issue is superseded and its behavior is covered by
examples/0706-modules-import-non-transitive.sx (the .md writeup stays).
issues/0030's repro .sx stays: that issue is an open feature request.

Gate: zig build OK; zig build test 426/426; run_examples 541/0; zero
expected/ snapshot churn.
This commit is contained in:
agra
2026-06-10 16:34:17 +03:00
parent 8b2a6598a9
commit 2b8041a828
40 changed files with 254 additions and 301 deletions

View File

@@ -14,12 +14,12 @@ const TypeResolver = type_resolver.TypeResolver;
/// Declaration-name / type-position diagnostic pass. Two checks, before
/// lowering:
///
/// 1. Unknown-type diagnostic (issue 0064), extracted from `Lowering`
/// 1. Unknown-type diagnostic, extracted from `Lowering`
/// (architecture phase A2.4): an identifier used in a type position that
/// names no declared type, primitive, or in-scope generic type parameter.
/// Main-file decls only — imported / library modules are trusted, matching
/// `checkErrorFlow`.
/// 2. Reserved-type-name binding (issues 0076, 0077): a value binding
/// 2. Reserved-type-name binding: a value binding
/// (local/global `var`, a typed-local, or a parameter) spelled as a
/// reserved/builtin type name. See `isReservedTypeName`. Runs over EVERY
/// compiled module (no main-file filter): such a binding mis-lowers the same
@@ -47,7 +47,7 @@ pub const UnknownTypeChecker = struct {
main_file: ?[]const u8,
pub fn run(self: UnknownTypeChecker, decls: []const *const Node) void {
// Reserved-type-name binding diagnostic (issues 0076, 0077): rejects any
// Reserved-type-name binding diagnostic: rejects any
// parameter name or `var` / `:=` / typed-local binding name spelled as a
// reserved/builtin type name. Runs over EVERY compiled module — imported
// user modules and the stdlib `library/` included — because such a
@@ -57,10 +57,10 @@ pub const UnknownTypeChecker = struct {
// type / scope context — rejection is purely on spelling. The walk
// tracks each module's source file (via the diagnostic list's
// `current_source_file`, saved/restored per node) so an imported-module
// diagnostic renders against that module's text (issue 0077).
// diagnostic renders against that module's text.
for (decls) |decl| self.checkBindingNames(decl);
// Unknown-type diagnostic (issue 0064): main-file decls only; imported
// Unknown-type diagnostic: main-file decls only; imported
// and library modules are trusted, matching `checkErrorFlow`.
var declared = std.StringHashMap(void).init(self.alloc);
defer declared.deinit();
@@ -84,7 +84,7 @@ pub const UnknownTypeChecker = struct {
}
}
/// Reserved-type-name binding walk (issues 0076, 0077). Visits every node
/// Reserved-type-name binding walk. Visits every node
/// reachable from `node` and rejects each *binding name* — `var` / `:=` /
/// typed-local declarations, destructure names, function / lambda / method
/// parameters, `if` / `while` optional bindings, `for` capture + index
@@ -109,7 +109,7 @@ pub const UnknownTypeChecker = struct {
/// main-file-scoped unknown-type walk. A node carrying its own
/// `source_file` (every module's top-level decls do) becomes the emit file
/// for its whole subtree, restored on exit so a sibling in another module
/// isn't rendered against it (issue 0077).
/// isn't rendered against it.
fn checkBindingNames(self: UnknownTypeChecker, node: *const Node) void {
const saved_file = self.diagnostics.current_source_file;
defer self.diagnostics.current_source_file = saved_file;
@@ -222,7 +222,7 @@ pub const UnknownTypeChecker = struct {
// so a binding nested anywhere below is still reached. ──
// A namespaced import (`mod :: #import "..."`) is wrapped here, its
// module decls held inline; descend so an imported module's
// reserved-name binding is rejected too (issue 0077).
// reserved-name binding is rejected too.
.namespace_decl => |nd| {
self.checkDeclName(node, nd.name, nd.is_raw);
for (nd.decls) |d| self.checkBindingNames(d);
@@ -305,7 +305,7 @@ pub const UnknownTypeChecker = struct {
.insert_expr => |ins| self.checkBindingNames(ins.expr),
.spread_expr => |se| self.checkBindingNames(se.operand),
// ── Named type / alias / import declarations: a bare reserved
// spelling as the declared name is rejected (issue 0089). These
// spelling as the declared name is rejected. These
// have no nested binding sites, so only the name is checked. A
// flat `#import`/`#import c` (name == null) binds nothing. ──
.enum_decl => |ed| self.checkDeclName(node, ed.name, ed.is_raw),
@@ -359,7 +359,7 @@ pub const UnknownTypeChecker = struct {
fn checkParamNames(self: UnknownTypeChecker, params: []const ast.Param) void {
for (params) |p| {
// A backtick raw param (`` (`s2: T) ``) or a `#import c` foreign
// param is exempt from the reserved-type-name rule (issue 0089)
// param is exempt from the reserved-type-name rule —
// the exemption is honored inside `checkBindingName` via `p.is_raw`.
self.checkBindingName(p.name, p.name_span, p.is_raw);
if (p.default_expr) |de| self.checkBindingNames(de);
@@ -378,7 +378,7 @@ pub const UnknownTypeChecker = struct {
// Only a const whose VALUE introduces a type (a type decl or
// type-expression alias) declares a type name. A value const
// like `NotAType :: 123` must NOT satisfy the unknown-type
// check (issue 0068).
// check.
if (constValueIntroducesType(cd.value)) out.put(cd.name, {}) catch {};
if (cd.value.data == .fn_decl) self.harvestScopeDecls(cd.value.data.fn_decl.body, out);
},
@@ -443,7 +443,7 @@ pub const UnknownTypeChecker = struct {
.const_decl => |cd| {
// Local type decl (`T :: struct/enum/union/error/alias`) — add
// its name; a local VALUE const (`x :: 5`) does not declare a
// type (issue 0068). Recurse regardless, to harvest nested decls
// type. Recurse regardless, to harvest nested decls
// (e.g. type decls inside a `f :: () { ... }` body).
if (constValueIntroducesType(cd.value)) out.put(cd.name, {}) catch {};
self.harvestScopeDecls(cd.value, out);
@@ -529,7 +529,7 @@ pub const UnknownTypeChecker = struct {
defer type_vals.shrinkRetainingCapacity(save_v);
for (type_params) |tp| in_scope.append(self.alloc, tp) catch {};
// Value params declared `: Type` (no `$`) — using one in a type position
// is the issue-0064 misuse; track them for the tailored hint.
// is the $-prefix-in-cast-position misuse; track them for the tailored hint.
for (params) |p| {
if (p.type_expr.data == .type_expr) {
const cn = p.type_expr.data.type_expr.name;
@@ -653,7 +653,7 @@ pub const UnknownTypeChecker = struct {
}
/// A `cast(T)` target naming a value-`Type` parameter (the otherwise-silent
/// issue-0064 case in cast position) gets the tailored `$T` hint.
/// case in cast position) gets the tailored `$T` hint.
fn checkCastTarget(self: UnknownTypeChecker, arg: *const Node, in_scope: []const ast.StructTypeParam, type_vals: []const []const u8) void {
const name = switch (arg.data) {
.identifier => |id| id.name,
@@ -804,7 +804,7 @@ pub const UnknownTypeChecker = struct {
// type — explicitly NOT the builtin/reserved spelling — so it must
// resolve to a `` `s2 ``-declared type, else a normal "unknown type"
// error. Skip the builtin-name exemption that would otherwise wave a
// bare `s2` through (issue 0089).
// bare `s2` through.
if (!is_raw and isBuiltinTypeName(name)) return;
for (in_scope) |tp| {
if (!std.mem.eql(u8, tp.name, name)) continue;
@@ -838,7 +838,7 @@ pub const UnknownTypeChecker = struct {
}
/// Reject a value binding (local/global `var` or a parameter) spelled as a
/// reserved/builtin type name (issue 0076). The parser turns such a spelling
/// reserved/builtin type name. The parser turns such a spelling
/// into a `.type_expr` rather than an `.identifier` (`parser.zig`, via
/// `name_class.Type.fromName`), so the address-of family in `lower.zig`
/// (`@x`, the autoref `x.method(...)` receiver, a bare `f(x)` at a `*T`
@@ -852,7 +852,7 @@ pub const UnknownTypeChecker = struct {
/// honoring the backtick / `#import c` foreign exemption. This is what keeps
/// the check and the exemption from desyncing — the recurring failure of the
/// earlier attempts, where each site threaded an `if (!is_raw)` guard
/// separately and one was forgotten (issue 0089).
/// separately and one was forgotten.
fn checkBindingName(self: UnknownTypeChecker, name: []const u8, span: ?ast.Span, is_raw: bool) void {
if (is_raw) return;
if (isReservedTypeName(name))
@@ -862,7 +862,7 @@ pub const UnknownTypeChecker = struct {
/// Reserved-name check for a `::` declaration whose own name binds an
/// identifier but carries no dedicated `name_span` field — struct / enum /
/// union / error-set / protocol / foreign-class type decls, ufcs aliases,
/// and namespaced imports (issue 0089). Each such node begins at its name
/// and namespaced imports. Each such node begins at its name
/// token (`createNode(name_start, …)`), so the name's length isolates the
/// caret onto the name — a single source for the span, no separate stored
/// field to drift from `node.span`. `is_raw` is REQUIRED, exactly as in
@@ -908,7 +908,7 @@ fn isBuiltinTypeName(name: []const u8) bool {
/// (`struct`/`enum`/`union`/`error`) or a type-expression alias (`Alias :: u32`,
/// `Ptr :: *u8`, `Cb :: (s32) -> s32`, …). Only these belong in the declared-
/// type-name set; a value const (`NotAType :: 123`) does NOT declare a type and
/// must stay subject to the unknown-type check (issue 0068).
/// must stay subject to the unknown-type check.
///
/// `.identifier` / `.call` aliases (`B :: A`, `Vec3 :: Vec(3, f32)`) are
/// deliberately NOT matched here: the scan registers the type-valued ones into