From 2b8041a828b034bc50f0c58ffadae6a56750ceae Mon Sep 17 00:00:00 2001 From: agra Date: Wed, 10 Jun 2026 16:34:17 +0300 Subject: [PATCH] cleanup: drop resolved-issue citations from src comments MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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. --- .../c_wrapper.sx | 10 --- .../main_bad.sx | 18 ---- .../main_good.sx | 10 --- .../other.sx | 6 -- src/ast.zig | 64 +++++++------- src/backend/llvm/ops.zig | 2 +- src/c_import.zig | 4 +- src/imports.test.zig | 4 +- src/imports.zig | 22 ++--- src/ir/calls.zig | 8 +- src/ir/emit_llvm.test.zig | 6 +- src/ir/emit_llvm.zig | 4 +- src/ir/expr_typer.test.zig | 8 +- src/ir/expr_typer.zig | 4 +- src/ir/generics.zig | 4 +- src/ir/interp.test.zig | 2 +- src/ir/lower.test.zig | 12 +-- src/ir/lower.zig | 28 +++--- src/ir/lower/call.zig | 30 +++---- src/ir/lower/closure.zig | 2 +- src/ir/lower/coerce.zig | 4 +- src/ir/lower/comptime.zig | 12 +-- src/ir/lower/control_flow.zig | 4 +- src/ir/lower/decl.zig | 86 +++++++++---------- src/ir/lower/expr.zig | 16 ++-- src/ir/lower/generic.zig | 8 +- src/ir/lower/nominal.zig | 6 +- src/ir/lower/pack.zig | 6 +- src/ir/lower/stmt.zig | 10 +-- src/ir/program_index.test.zig | 14 +-- src/ir/program_index.zig | 43 +++++----- src/ir/semantic_diagnostics.zig | 38 ++++---- src/ir/type_bridge.zig | 20 ++--- src/ir/type_resolver.zig | 8 +- src/lsp/corpus_sweep.test.zig | 2 +- src/lsp/document.test.zig | 2 +- src/parser.zig | 4 +- src/sema.test.zig | 6 +- src/sema.zig | 12 +-- src/types.zig | 6 +- 40 files changed, 254 insertions(+), 301 deletions(-) delete mode 100644 issues/0019-import-non-transitive-c-scope/c_wrapper.sx delete mode 100644 issues/0019-import-non-transitive-c-scope/main_bad.sx delete mode 100644 issues/0019-import-non-transitive-c-scope/main_good.sx delete mode 100644 issues/0019-import-non-transitive-c-scope/other.sx diff --git a/issues/0019-import-non-transitive-c-scope/c_wrapper.sx b/issues/0019-import-non-transitive-c-scope/c_wrapper.sx deleted file mode 100644 index 2e9a73d..0000000 --- a/issues/0019-import-non-transitive-c-scope/c_wrapper.sx +++ /dev/null @@ -1,10 +0,0 @@ -// This module imports C functions and provides wrappers -#import c { - #include "vendors/test_c/test.h"; - #source "vendors/test_c/test.c"; -}; - -// Wrapper function that calls the C function -wrapped_add :: (a: s32, b: s32) -> s32 { - add_numbers(a, b); -} diff --git a/issues/0019-import-non-transitive-c-scope/main_bad.sx b/issues/0019-import-non-transitive-c-scope/main_bad.sx deleted file mode 100644 index ff8a70e..0000000 --- a/issues/0019-import-non-transitive-c-scope/main_bad.sx +++ /dev/null @@ -1,18 +0,0 @@ -// Test: other.sx calls C functions without importing the C module -// main imports both c_wrapper.sx and other.sx -// other.sx should NOT have access to C functions from c_wrapper -#import "../modules/std.sx"; -#import "c_wrapper.sx"; -#import "other.sx"; - -main :: () -> s32 { - // This works: we import c_wrapper so we have transitive access - result := wrapped_add(10, 20); - print("wrapped_add(10, 20) = {}\n", result); - - // This calls other.sx's function which tries to call add_numbers - // other.sx did NOT import c_wrapper.sx, so this should fail - bad := use_c_directly(); - print("use_c_directly() = {}\n", bad); - 0; -} diff --git a/issues/0019-import-non-transitive-c-scope/main_good.sx b/issues/0019-import-non-transitive-c-scope/main_good.sx deleted file mode 100644 index 89837ab..0000000 --- a/issues/0019-import-non-transitive-c-scope/main_good.sx +++ /dev/null @@ -1,10 +0,0 @@ -// Test: calling wrapper functions works (we import the module) -#import "../modules/std.sx"; -#import "c_wrapper.sx"; - -main :: () -> s32 { - // This should work: calling the sx wrapper - result := wrapped_add(10, 20); - print("wrapped_add(10, 20) = {}\n", result); - 0; -} diff --git a/issues/0019-import-non-transitive-c-scope/other.sx b/issues/0019-import-non-transitive-c-scope/other.sx deleted file mode 100644 index 1cdb627..0000000 --- a/issues/0019-import-non-transitive-c-scope/other.sx +++ /dev/null @@ -1,6 +0,0 @@ -// This file does NOT import c_wrapper.sx -// It should NOT be able to call add_numbers - -use_c_directly :: () -> s32 { - add_numbers(5, 3); -} diff --git a/src/ast.zig b/src/ast.zig index 8a4f287..434cb5b 100644 --- a/src/ast.zig +++ b/src/ast.zig @@ -132,12 +132,12 @@ pub const FnDecl = struct { is_arrow: bool = false, call_conv: CallingConvention = .default, /// Span of the function's name token, for the reserved-type-name decl - /// diagnostic (issue 0089). Synthesized decls (e.g. `#import c` foreign + /// diagnostic. Synthesized decls (e.g. `#import c` foreign /// functions, lowering-time objc/protocol method synthesis) leave it zero. name_span: Span = .{ .start = 0, .end = 0 }, /// True when the function NAME was written as a backtick raw identifier /// (`` `s2 :: … ``) or synthesized by a `#import c` foreign decl. A raw - /// name is exempt from the reserved-type-name binding check (issue 0089). + /// name is exempt from the reserved-type-name binding check. /// Every PARSER fn_decl is built through `parseFnDecl`, whose `name_is_raw` /// is a REQUIRED parameter, so a parser site cannot drop it; the default /// here serves only post-check synthesized decls (which are never raw). @@ -161,7 +161,7 @@ pub const Param = struct { default_expr: ?*Node = null, /// True when the param name was written as a backtick raw identifier /// (`` `s2 ``) or synthesized by a `#import c` foreign decl. A raw name is - /// exempt from the reserved-type-name binding check (issue 0089). + /// exempt from the reserved-type-name binding check. is_raw: bool = false, }; @@ -201,7 +201,7 @@ pub const Identifier = struct { name: []const u8, /// True when written as a backtick raw identifier (`` `s2 ``). Carried so a /// destructure target (`` `s2, b := … ``) can be recognised as raw and - /// exempted from the reserved-type-name binding check (issue 0089). + /// exempted from the reserved-type-name binding check. is_raw: bool = false, }; @@ -293,7 +293,7 @@ pub const IfExpr = struct { binding_name: ?[]const u8 = null, // for `if val := expr { ... }` optional binding binding_span: ?Span = null, // span of `binding_name` (set iff `binding_name` is) /// True when the optional binding was a backtick raw identifier - /// (`` if `s2 := … ``) — exempt from the reserved-type-name check (issue 0089). + /// (`` if `s2 := … ``) — exempt from the reserved-type-name check. binding_is_raw: bool = false, }; @@ -310,7 +310,7 @@ pub const MatchArm = struct { capture: ?[]const u8 = null, // payload binding name: case .variant: (name) { ... } capture_span: ?Span = null, // span of `capture` (set iff `capture` is) /// True when the capture was a backtick raw identifier - /// (`` case .v: (`s2) ``) — exempt from the reserved-type-name check (issue 0089). + /// (`` case .v: (`s2) ``) — exempt from the reserved-type-name check. capture_is_raw: bool = false, }; @@ -319,14 +319,14 @@ pub const ConstDecl = struct { type_annotation: ?*Node, value: *Node, /// Span of the constant's name token, for the reserved-type-name decl - /// diagnostic (issue 0089). NO default: every construction site must set + /// diagnostic. NO default: every construction site must set /// it explicitly, so a struct-body const can't silently fall back to a /// 1:1 caret (the finding-1 bug). name_span: Span, /// True when the constant NAME was written as a backtick raw identifier /// (`` `s2 :: … ``). NO default: required at every site so the reserved- /// name exemption can't be dropped — mirrors `checkBindingName`'s required - /// `is_raw` argument so the parser and the check can't desync (issue 0089). + /// `is_raw` argument so the parser and the check can't desync. is_raw: bool, }; @@ -340,7 +340,7 @@ pub const VarDecl = struct { foreign_name: ?[]const u8 = null, /// True when the binding name was written as a backtick raw identifier /// (`` `s2 := … ``). A raw name is exempt from the reserved-type-name - /// binding check (issue 0089). + /// binding check. is_raw: bool = false, }; @@ -374,7 +374,7 @@ pub const DestructureDecl = struct { name_spans: []const Span, // one per entry in `names`, same order /// One per entry in `names`, same order: true when that target was a /// backtick raw identifier (`` `s2, b := … ``) — exempt from the - /// reserved-type-name binding check (issue 0089). + /// reserved-type-name binding check. name_is_raw: []const bool, value: *Node, }; @@ -388,7 +388,7 @@ pub const EnumDecl = struct { backing_type: ?*Node = null, // optional backing type: enum u8 { ... } /// True when the declared NAME was a backtick raw identifier /// (`` `s2 :: enum { … } ``) — exempt from the reserved-type-name decl - /// check (issue 0089). A bare reserved-name decl still errors. + /// check. A bare reserved-name decl still errors. is_raw: bool = false, }; @@ -397,7 +397,7 @@ pub const UnionDecl = struct { field_names: []const []const u8, field_types: []const *Node, /// True when the declared NAME was a backtick raw identifier — exempt from - /// the reserved-type-name decl check (issue 0089). + /// the reserved-type-name decl check. is_raw: bool = false, }; @@ -407,7 +407,7 @@ pub const ErrorSetDecl = struct { name: []const u8, tag_names: []const []const u8, /// True when the declared NAME was a backtick raw identifier — exempt from - /// the reserved-type-name decl check (issue 0089). + /// the reserved-type-name decl check. is_raw: bool = false, }; @@ -436,7 +436,7 @@ pub const StructDecl = struct { constants: []const *Node = &.{}, // const_decl nodes for struct-level constants /// True when the declared NAME was a backtick raw identifier /// (`` `s2 :: struct { … } ``) — exempt from the reserved-type-name decl - /// check (issue 0089). A bare reserved-name decl still errors. + /// check. A bare reserved-name decl still errors. is_raw: bool = false, }; @@ -467,8 +467,8 @@ pub const TypeExpr = struct { /// True when written as a backtick raw identifier in type position /// (`` `s2 ``). Such a reference is the LITERAL name `s2` used as a type — /// resolution skips the builtin/reserved classifier and looks up a - /// `` `s2 ``-declared type (struct/enum/union/alias), else "unknown type" - /// (issue 0089). A bare `s2` keeps `is_raw = false` and is the int type. + /// `` `s2 ``-declared type (struct/enum/union/alias), else "unknown + /// type". A bare `s2` keeps `is_raw = false` and is the int type. is_raw: bool = false, }; @@ -518,7 +518,7 @@ pub const CatchExpr = struct { binding: ?[]const u8 = null, binding_span: ?Span = null, // span of `binding` (set iff `binding` is) /// True when the binding was a backtick raw identifier - /// (`` x catch `s2 { … } ``) — exempt from the reserved-type-name check (issue 0089). + /// (`` x catch `s2 { … } ``) — exempt from the reserved-type-name check. binding_is_raw: bool = false, body: *Node, is_match_body: bool = false, @@ -531,7 +531,7 @@ pub const OnFailStmt = struct { binding: ?[]const u8 = null, binding_span: ?Span = null, // span of `binding` (set iff `binding` is) /// True when the binding was a backtick raw identifier - /// (`` onfail `s2 { … } ``) — exempt from the reserved-type-name check (issue 0089). + /// (`` onfail `s2 { … } ``) — exempt from the reserved-type-name check. binding_is_raw: bool = false, body: *Node, }; @@ -558,7 +558,7 @@ pub const ImportDecl = struct { name: ?[]const u8, /// True when the namespace NAME was a backtick raw identifier /// (`` `s2 :: #import "…" ``) — exempt from the reserved-type-name decl - /// check (issue 0089). A flat `#import` (name == null) binds nothing. + /// check. A flat `#import` (name == null) binds nothing. is_raw: bool = false, }; @@ -583,7 +583,7 @@ pub const ParameterizedTypeExpr = struct { /// (`` `s2(s64) ``). Such a reference is the LITERAL name `s2` used as a /// parameterized type — resolution skips the builtin parameterized /// classifier (e.g. the `Vector` intrinsic) and instantiates a - /// `` `s2 ``-declared generic template (issue 0089). + /// `` `s2 ``-declared generic template. is_raw: bool = false, }; @@ -638,7 +638,7 @@ pub const WhileExpr = struct { binding_name: ?[]const u8 = null, // for `while val := expr { ... }` optional binding binding_span: ?Span = null, // span of `binding_name` (set iff `binding_name` is) /// True when the optional binding was a backtick raw identifier - /// (`` while `s2 := … ``) — exempt from the reserved-type-name check (issue 0089). + /// (`` while `s2 := … ``) — exempt from the reserved-type-name check. binding_is_raw: bool = false, }; @@ -648,12 +648,12 @@ pub const ForExpr = struct { capture_name: []const u8, capture_span: ?Span = null, // span of `capture_name` (null when omitted, e.g. `for 0..N { }`) /// True when `capture_name` was a backtick raw identifier - /// (`` for xs: (`s2) ``) — exempt from the reserved-type-name check (issue 0089). + /// (`` for xs: (`s2) ``) — exempt from the reserved-type-name check. capture_is_raw: bool = false, index_name: ?[]const u8 = null, index_span: ?Span = null, // span of `index_name` (set iff `index_name` is) /// True when `index_name` was a backtick raw identifier - /// (`` for xs: (x, `s2) ``) — exempt from the reserved-type-name check (issue 0089). + /// (`` for xs: (x, `s2) ``) — exempt from the reserved-type-name check. index_is_raw: bool = false, /// Range form `for start..end (i) { }`: `iterable` is the start, `range_end` /// the (exclusive) end. Null for the iterate-a-collection form @@ -678,7 +678,7 @@ pub const NamespaceDecl = struct { /// subset of `decls` (which also carries the module's transitive flat /// imports). Lowering registers these under their module-qualified name /// (`ns.fn`) so `pkg.fn(...)` resolves to a unique FuncId distinct from a - /// same-named function in another module (issue 0100). + /// same-named function in another module. own_decls: []const *Node = &.{}, /// The resolved path of the module this alias targets — the importing file's /// own path for a `#import c` namespace (its members are synthesized there). @@ -687,7 +687,7 @@ pub const NamespaceDecl = struct { /// edge without re-walking the import graph. target_module_path: []const u8, /// True when the namespace NAME was a backtick raw identifier — exempt - /// from the reserved-type-name decl check (issue 0089). + /// from the reserved-type-name decl check. is_raw: bool = false, }; @@ -700,7 +700,7 @@ pub const LibraryDecl = struct { lib_name: []const u8, name: []const u8, // sx-side constant name /// True when the constant NAME was a backtick raw identifier — exempt from - /// the reserved-type-name decl check (issue 0089). + /// the reserved-type-name decl check. is_raw: bool = false, }; @@ -746,7 +746,7 @@ pub const UfcsAlias = struct { name: []const u8, target: []const u8, /// True when the alias NAME was a backtick raw identifier — exempt from - /// the reserved-type-name decl check (issue 0089). + /// the reserved-type-name decl check. is_raw: bool = false, }; @@ -758,7 +758,7 @@ pub const CImportDecl = struct { name: ?[]const u8 = null, bitcode_paths: []const []const u8 = &.{}, // populated during import resolution /// True when the namespace NAME was a backtick raw identifier — exempt - /// from the reserved-type-name decl check (issue 0089). + /// from the reserved-type-name decl check. is_raw: bool = false, }; @@ -768,7 +768,7 @@ pub const ProtocolMethodDecl = struct { param_names: []const []const u8, // parameter names (excluding implicit self) param_name_spans: []const Span = &.{}, // one per `param_names` entry; empty for synthesized methods /// One per `param_names` entry: true when written as a backtick raw - /// identifier — exempt from the reserved-type-name check (issue 0089). + /// identifier — exempt from the reserved-type-name check. /// Empty for synthesized methods (treated as all-false). param_name_is_raw: []const bool = &.{}, return_type: ?*Node, // null = void return @@ -781,7 +781,7 @@ pub const ProtocolDecl = struct { is_inline: bool = false, // #inline — embedded fn ptrs instead of vtable pointer type_params: []const StructTypeParam = &.{}, // for `protocol(Target: Type) { ... }` /// True when the declared NAME was a backtick raw identifier — exempt from - /// the reserved-type-name decl check (issue 0089). + /// the reserved-type-name decl check. is_raw: bool = false, /// Defining module path (stamped by `resolveImports`), so a parameterized /// protocol instantiated cross-module resolves its method signature types in @@ -806,7 +806,7 @@ pub const ForeignMethodDecl = struct { param_names: []const []const u8, param_name_spans: []const Span = &.{}, // one per `param_names` entry; empty for synthesized methods /// One per `param_names` entry: true when written as a backtick raw - /// identifier — exempt from the reserved-type-name check (issue 0089). + /// identifier — exempt from the reserved-type-name check. /// Empty for synthesized methods (treated as all-false). param_name_is_raw: []const bool = &.{}, return_type: ?*Node, // null = void @@ -845,7 +845,7 @@ pub const ForeignClassDecl = struct { is_foreign: bool = false, // `#foreign #...` prefix — class is provided by the foreign runtime; we only reference it is_main: bool = false, // `#jni_main` / `#objc_main` — class is the launchable entry (Activity / UIApplicationDelegate / ...) /// True when the sx-side alias NAME was a backtick raw identifier — exempt - /// from the reserved-type-name decl check (issue 0089). + /// from the reserved-type-name decl check. is_raw: bool = false, /// Defining module path (stamped by `resolveImports`), so the IMP trampolines /// emitted for an sx-defined class resolve their method-signature types in the diff --git a/src/backend/llvm/ops.zig b/src/backend/llvm/ops.zig index 224f10c..f7865bd 100644 --- a/src/backend/llvm/ops.zig +++ b/src/backend/llvm/ops.zig @@ -1299,7 +1299,7 @@ pub const Ops = struct { if (st_kind == c.LLVMVectorTypeKind or st_kind == c.LLVMScalableVectorTypeKind) { // Vector lane address: GEP [0, lane] into the in-memory vector, // yielding a pointer to the lane element for a scalar store - // (vector lane assignment — issue 0086). Mirrors how the read + // (vector lane assignment). Mirrors how the read // path extracts a lane; here we address it for a store. var indices = [_]c.LLVMValueRef{ c.LLVMConstInt(self.e.cached_i64, 0, 0), diff --git a/src/c_import.zig b/src/c_import.zig index f0c09b3..5439084 100644 --- a/src/c_import.zig +++ b/src/c_import.zig @@ -129,7 +129,7 @@ pub fn processCImport( .type_expr = ptype_node, // Foreign C param names (`s1`, `s2`, …) are RAW — exempt from // the reserved-type-name binding check; generated bindings - // must import without hand-edits (issue 0089). + // must import without hand-edits. .is_raw = true, }); } @@ -159,7 +159,7 @@ pub fn processCImport( // A foreign C function whose own NAME collides with a reserved // type spelling (`int s2(int);`) is RAW — exempt from the // reserved-type-name decl check so generated bindings import - // without hand-edits (issue 0089). + // without hand-edits. .is_raw = true, } }, }; diff --git a/src/imports.test.zig b/src/imports.test.zig index fd99293..d1ae23d 100644 --- a/src/imports.test.zig +++ b/src/imports.test.zig @@ -1,4 +1,4 @@ -// Tests for imports.zig — flat-import name-resolution data retention (fix-0102a). +// Tests for imports.zig — flat-import name-resolution data retention. const std = @import("std"); const ast = @import("ast.zig"); @@ -179,7 +179,7 @@ test "imports: module_decls retains same-name cross-module fns; flat_import_grap } // Mixed collision: a.sx authors `Widget` as a STRUCT (non-fn), b.sx authors it -// as a FUNCTION. fix-0102a must NOT let the function-author retention shift the +// as a FUNCTION. The function-author retention must NOT shift the // merged scope — first-wins keeps a.sx's struct and drops b.sx's function. // (The fn author may still be indexed in `module_decls`; resolution is what // must be untouched.) diff --git a/src/imports.zig b/src/imports.zig index ed15bfa..0ca35a5 100644 --- a/src/imports.zig +++ b/src/imports.zig @@ -304,7 +304,7 @@ pub const ResolvedModule = struct { // A cross-module name collision: drop from the global list // (first-wins) UNLESS this is a per-source decl (a type, alias, // or non-function const), which must reach registration as a - // distinct author of its own module (issues 0104/0105). + // distinct author of its own module. append_to_global = isPerSourceDecl(decl); } else { try seen_list.put(name, {}); @@ -343,8 +343,8 @@ pub const ResolvedModule = struct { // per-source decl (a named type, or any non-function const: // type alias + value const), each of which must reach // registration as a distinct same-name author of its own - // module (issues 0104/0105 types, step E5 value consts). Only - // FUNCTIONS keep first-wins (issue 0102 — the shadowed author + // module (types and aliases; step E5 value consts). Only + // FUNCTIONS keep first-wins (the shadowed author // stays reachable via its qualified name / SelectedFunc). // Node identity (above) still de-dups a diamond import of the // SAME decl. @@ -362,9 +362,9 @@ pub const ResolvedModule = struct { /// registers against its OWN module rather than collapsing to a single /// first-wins winner. NAMED types and every non-function `const_decl` (type /// aliases + inline type decls + VALUE consts, source-keyed via the alias / - /// const caches) are per-source — that is what closes issues 0104/0105 for + /// const caches) are per-source — that is what prevents same-name collapse for /// types/aliases and supports same-name value consts (step E5). Everything - /// else keeps the first-wins name-merge: FUNCTIONS (issue 0102 — the shadowed + /// else keeps the first-wins name-merge: FUNCTIONS (the shadowed /// author stays reachable via its qualified name / SelectedFunc), and crucially /// `var_decl`s, including a `#foreign` extern global declared in two files /// (e.g. `__stdinp : *void #foreign;`) that MUST resolve to the ONE libSystem @@ -406,7 +406,7 @@ pub const ResolvedModule = struct { .name = name, .decls = other.decls, // The module's OWN authored decls — what `ns.fn` should bind - // to (issue 0100). `decls` stays the full transitive list so + // to. `decls` stays the full transitive list so // the lowering pass can still resolve transitive callees. .own_decls = other.own_decls, // The aliased module's resolved path (== the `resolved_path` @@ -414,7 +414,7 @@ pub const ResolvedModule = struct { .target_module_path = other.path, // Carry the backtick raw escape from the `name :: #import …` // form so a reserved-name namespace is exempt from the decl - // check, symmetric to every other decl site (issue 0089). + // check, symmetric to every other decl site. .is_raw = is_raw, } }, }; @@ -796,7 +796,7 @@ fn reportDuplicateName(diagnostics: ?*errors.DiagnosticList, added: bool, name: /// Stamp the DEFINING module path onto a function body node, so a later /// pack/comptime monomorphization can pin `current_source_file` to the body's /// own module and resolve its bare names in that module's visibility context -/// (issue 0106) — mirroring how a normally-declared function carries +/// — mirroring how a normally-declared function carries /// `Function.source_file`. Only top-level decl Nodes are otherwise stamped, so /// the body Node would carry no source; a null body source after this means a /// synthesized/sourceless decl (the monomorphizer then keeps its caller's @@ -820,7 +820,7 @@ fn stampFnBodySource(decl: *Node, file_path: []const u8) void { .fn_decl => |fd| fd.body.source_file = file_path, // `List :: struct { … append :: (…) { … } }` — the methods of a // (possibly generic) struct are monomorphized in their template's - // OWN module (issue 0106 + the E4 instantiation source-pin), so their + // OWN module (the E4 instantiation source-pin), so their // bodies need the defining path stamped just like a top-level fn. .struct_decl => |sd| stampStructMethodSources(sd, file_path), .protocol_decl => cd.value.data.protocol_decl.source_file = file_path, @@ -892,7 +892,7 @@ pub fn resolveImports( } // FLAT-only edge set: identical to `import_graph` but records ONLY bare // `#import "…"` edges (`imp.name == null`), never a namespaced - // `ns :: #import "…"`. fix-0102c's bare-name disambiguation walks this to + // `ns :: #import "…"`. The bare-name disambiguation walks this to // decide which same-name authors a flat importer can actually reach. if (flat_import_graph) |g| { if (!g.contains(file_path)) { @@ -983,7 +983,7 @@ pub fn resolveImports( .name = ns_name, .decls = ns_slice, // A C-import namespace authors exactly the wrapped fn - // decls — they ARE its own decls (issue 0100). + // decls — they ARE its own decls. .own_decls = ns_slice, // No separate sx module: the synthesized members are // authored in THIS file. Record the importer's path. diff --git a/src/ir/calls.zig b/src/ir/calls.zig index bdf6c63..978a7a2 100644 --- a/src/ir/calls.zig +++ b/src/ir/calls.zig @@ -75,7 +75,7 @@ pub const CallPlan = struct { /// The single bare-call author `selectPlainCallableAuthor` selected for a /// genuine flat same-name collision (R5 §#3). Carries the resolved /// `*FnDecl` + source so `plan` and the lowering call-path read ONE - /// author and can no longer disagree (fix-0102 F2); the FuncId is + /// author and can no longer disagree; the FuncId is /// materialized on demand. Only set when the bare name reroutes away from /// the first-wins winner; the common path still uses `func` / `named`. selected: Lowering.SelectedFunc, @@ -159,7 +159,7 @@ pub const CallResolver = struct { // Plain bare same-name flat collision (R5 §C): route through the ONE // author producer `selectedFreeAuthor` so `plan` types the call as the // SAME author the lowering call-path binds — they can no longer - // disagree (fix-0102 F2). A generic / foreign / builtin author is not + // disagree. A generic / foreign / builtin author is not // plain-free so the producer returns `.none`; `.ambiguous` / `.none` // fall through to the first-wins path below, byte-for-byte. switch (self.selectedFreeAuthor(c)) { @@ -319,7 +319,7 @@ pub const CallResolver = struct { // routes through the SAME author producer `selectedFreeAuthor` as a // bare call, so the planned target / return type IS the author // lowering dispatches — they can't disagree under a flat same-name - // collision (fix-0102 F2 / R5 §C). Without this, plan typed the + // collision (R5 §C). Without this, plan typed the // first-wins winner while lowering bound the selected shadow, // mis-tagging the call's result (a string-typed winner over an s64 // shadow boxes a raw int as a string pointer → segfault). @@ -451,7 +451,7 @@ pub const CallResolver = struct { /// verdict (R5 §#3). Both `plan` (typing, via its `.selected` arm) and /// `lowerCall` (default expansion / param typing / dispatch) consume THIS one /// result, so they can never pick different same-name authors for the same - /// call (fix-0102 F2). Side-effect-free: it consults ONLY the author selector + /// call. Side-effect-free: it consults ONLY the author selector /// (`selectPlainCallableAuthor`) — never return-type inference or type-arg /// resolution — so `lowerCall` can compute it eagerly without emitting a /// premature diagnostic the full `plan` would (e.g. `cast(type)`'s type-arg). diff --git a/src/ir/emit_llvm.test.zig b/src/ir/emit_llvm.test.zig index 99c4e30..db9fe09 100644 --- a/src/ir/emit_llvm.test.zig +++ b/src/ir/emit_llvm.test.zig @@ -1066,7 +1066,7 @@ test "emit: ERR E3.0 — DWARF debug info (compile unit + subprogram + per-inst try std.testing.expect(std.mem.indexOf(u8, ir_str, "\"Debug Info Version\"") != null); try std.testing.expect(std.mem.indexOf(u8, ir_str, "\"Dwarf Version\"") != null); try std.testing.expect(std.mem.indexOf(u8, ir_str, "DICompileUnit") != null); - // Regression (issue 0058): a bare filename (no directory component) must + // Regression: a bare filename (no directory component) must // still get a NON-EMPTY `directory:` — an empty `DW_AT_comp_dir` makes ld // silently drop the whole debug map, so the binary becomes undebuggable. try std.testing.expect(std.mem.indexOf(u8, ir_str, "DIFile(filename: \"probe.sx\", directory: \".\")") != null); @@ -1098,7 +1098,7 @@ test "emit: ERR E3.0 — no DWARF without a debug context (unit-test default)" { try std.testing.expect(std.mem.indexOf(u8, ir_str, "!dbg") == null); } -// ── issue 0074: FFI arg-type lookup must fail loudly, never silently `.void` ── +// ── FFI arg-type lookup must fail loudly, never silently `.void` ── // `argIRTypeOrFail` backs the four FFI call-arg lowering sites (objc_msgSend, // JNI CallMethod / non-virtual / constructor). A ref it cannot resolve is // a codegen invariant violation; it must surface the dedicated `.unresolved` @@ -1145,7 +1145,7 @@ test "emit: argIRTypeOrFail surfaces .unresolved for an unresolvable FFI arg ref try std.testing.expect(emitter.argIRTypeOrFail(bogus) != .void); } -// ── issue 0075: reflection-builtin arg-type lookup must fail loudly, never `.s64` ── +// ── reflection-builtin arg-type lookup must fail loudly, never `.s64` ── // `reflectArgRepr` backs the `type_name` / `type_eq` reflection builtins, which read // their `Type` arg as a boxed `Any` aggregate (`.any` → extract value field) or a bare // i64 TypeId index. A ref it cannot resolve is a codegen invariant violation; it must diff --git a/src/ir/emit_llvm.zig b/src/ir/emit_llvm.zig index 0c8d962..48a68b8 100644 --- a/src/ir/emit_llvm.zig +++ b/src/ir/emit_llvm.zig @@ -930,7 +930,7 @@ pub const LLVMEmitter = struct { .vtable => c.LLVMConstNull(llvm_ty), // placeholder — initialized in initVtableGlobals after function declarations // A top-level null-pointer global (`p : *s64 = null;`) and a // zero-initialized global both emit as the all-zero constant - // of the global's type (issue 0081). + // of the global's type. .null_val, .zeroinit => c.LLVMConstNull(llvm_ty), .undef => c.LLVMGetUndef(llvm_ty), // func_map is empty in Pass 0 (functions are declared in @@ -2527,7 +2527,7 @@ pub const LLVMEmitter = struct { break :blk c.LLVMConstNull(elem_ty); }, // A null pointer field and a zero-initialized field both emit as - // the all-zero constant of the leaf type (issue 0081). + // the all-zero constant of the leaf type. .null_val, .zeroinit => c.LLVMConstNull(elem_ty), .undef => c.LLVMGetUndef(elem_ty), // Vtable constants are only ever produced for top-level protocol diff --git a/src/ir/expr_typer.test.zig b/src/ir/expr_typer.test.zig index cabebe3..af4a586 100644 --- a/src/ir/expr_typer.test.zig +++ b/src/ir/expr_typer.test.zig @@ -50,7 +50,7 @@ test "expr_typer: binary comparison is bool, int arithmetic stays int" { try std.testing.expectEqual(TypeId.s64, l.inferExprType(&add)); } -// issue 0088 (attempt 3): a non-comparison binary op infers the PROMOTED result +// A non-comparison binary op infers the PROMOTED result // of (lhs, rhs), not the LHS alone — so a mixed int+float op types as the float // in EITHER operand order (was LHS-biased: `int + float` → s64 while // `float + int` → f64). This is what feeds the typed-const validation that @@ -116,7 +116,7 @@ test "expr_typer: deref of a non-pointer is unresolved" { try std.testing.expectEqual(TypeId.unresolved, l.inferExprType(&deref_n)); } -// issue 0092: a raw `` `f64 `` value binding shadows the builtin numeric type +// a raw `` `f64 `` value binding shadows the builtin numeric type // name — `` `f64.epsilon `` (an `.identifier` receiver) must type as the value's // field, NOT the float numeric-limit fold. A bare `f64.epsilon` (a `.type_expr` // receiver, never shadowed) still folds to the queried float type. This pins the @@ -159,8 +159,8 @@ test "expr_typer: raw value binding shadows numeric-limit, bare type still folds try std.testing.expectEqual(TypeId.f64, l.inferExprType(&type_fa)); } -// issue 0093: a raw value binding can shadow a builtin numeric type name through -// any of three sources — lexical scope (issue 0092), program globals, or module +// a raw value binding can shadow a builtin numeric type name through +// any of three sources — lexical scope, program globals, or module // value constants. The shared `identifierBindsValue` guard consults all three, // so a global `` `f32 := Box.{…} `` and a module-const `` `s16 :: Box.{…} `` each // read the value's field (NOT the numeric-limit fold), while a bare `f32.max` / diff --git a/src/ir/expr_typer.zig b/src/ir/expr_typer.zig index e7b5b70..555a47b 100644 --- a/src/ir/expr_typer.zig +++ b/src/ir/expr_typer.zig @@ -160,8 +160,8 @@ pub const ExprTyper = struct { if (type_name) |tn| { // Skip the fold when a raw value binding shadows the // builtin type name (`` `f64 := … ``) — mirrors the - // lowerNumericLimit guard so inference matches lowering - // (issues 0092, 0093). The shared helper consults all + // lowerNumericLimit guard so inference matches + // lowering. The shared helper consults all // three value sources (scope / globals / module consts); // a `.type_expr` receiver is never shadowed. const shadowed = fa.object.data == .identifier and diff --git a/src/ir/generics.zig b/src/ir/generics.zig index ab7fce3..feae1ea 100644 --- a/src/ir/generics.zig +++ b/src/ir/generics.zig @@ -52,7 +52,7 @@ pub const GenericResolver = struct { const info = self.l.module.types.get(ty); return switch (info) { // A nominal type's mangle includes its `nominal_id` when nonzero so two - // same-DISPLAY-name authors in different sources (issue 0105) produce + // same-DISPLAY-name authors in different sources produce // DISTINCT monomorph symbols (`struct_to_string__Box` vs // `struct_to_string__Box__n1`) instead of one symbol with conflicting // signatures. `nominal_id == 0` (the single-author / structural case) @@ -103,7 +103,7 @@ pub const GenericResolver = struct { } /// Append a `__n` disambiguator to a nominal type's display name when its - /// `nominal_id` is nonzero (a same-name shadow, issue 0105); id 0 returns the + /// `nominal_id` is nonzero (a same-name shadow); id 0 returns the /// name unchanged so single-author mangling is byte-identical. fn mangleNominalName(self: GenericResolver, name: []const u8, nominal_id: u32) []const u8 { if (nominal_id == 0) return name; diff --git a/src/ir/interp.test.zig b/src/ir/interp.test.zig index 3b44999..f27bfe6 100644 --- a/src/ir/interp.test.zig +++ b/src/ir/interp.test.zig @@ -808,7 +808,7 @@ test "comptime: type_eq builtin on type_tag values" { // ── Test: reflectTypeId reads an Any's runtime TYPE-TAG, not its payload ── // A reflection builtin on an Any must report the type OF a held value (the // tag) and only read the payload when the Any holds a Type value (tag == -// `.any`). Regression for issue 0090 (attempt 3): a boxed value like +// `.any`). Regression: a boxed value like // `av : Any = 6` (`{ tag = s64, value = 6 }`) must resolve to `s64`, NOT // `types[6]` (`u8`). test "reflect: reflectTypeId branches on the Any tag" { diff --git a/src/ir/lower.test.zig b/src/ir/lower.test.zig index 4010820..d387a57 100644 --- a/src/ir/lower.test.zig +++ b/src/ir/lower.test.zig @@ -1082,7 +1082,7 @@ test "lower: vectorLaneIndex maps swizzle components, colour aliases, rejects no try std.testing.expectEqual(@as(?u32, 3), Lowering.vectorLaneIndex("a")); // Any non-lane field is rejected (null) so the read and write paths share // one rule — a non-lane store no longer falls through to an .unresolved - // pointee that panics at LLVM emission (issue 0086). + // pointee that panics at LLVM emission. try std.testing.expectEqual(@as(?u32, null), Lowering.vectorLaneIndex("q")); try std.testing.expectEqual(@as(?u32, null), Lowering.vectorLaneIndex("xy")); try std.testing.expectEqual(@as(?u32, null), Lowering.vectorLaneIndex("len")); @@ -1301,10 +1301,10 @@ fn countRealBodies(module: *ir_mod.Module, name: []const u8) usize { return n; } -// fix-0102b: two flat-imported modules each author `greet`. The first-wins merge +// two flat-imported modules each author `greet`. The first-wins merge // keeps a.sx's author in the merged decl list (the WINNER) and drops b.sx's, // which the `module_decls` raw facts still retain (0102a). `main` itself can't bare-call `greet` -// — under fix-0102c two flat authors make that ambiguous — so it calls a.sx's +// — with two flat authors this is ambiguous; two flat authors make that ambiguous — so it calls a.sx's // `use_greet` wrapper, whose own-author call to `greet` binds a.sx's winner. // BEFORE the identity-addressable pass, only the winner has a real body — the // shadowed author has no slot at all (the pre-fix symptom: one `greet`). @@ -1420,8 +1420,8 @@ test "lower: shadowed same-name author gets its own FuncId + real body (fix-0102 // pointer for BOTH same-name authors — the exact pointers `fn_ast_map` and // the `module_decls` raw facts carry — not a per-iteration switch-capture // temporary. If the winner were keyed by `&fd` (the scanDecls bug), this - // lookup by the stable `fn_ast_map` pointer would miss (null). fix-0102c - // routes calls through exactly these pointers, so the round-trip must hold. + // lookup by the stable `fn_ast_map` pointer would miss (null). Bare-call + // routing goes through exactly these pointers, so the round-trip must hold. const winner_fd = lowering.program_index.fn_ast_map.get("greet").?; const winner_fid = lowering.fn_decl_fids.get(winner_fd); try std.testing.expect(winner_fid != null); @@ -1442,7 +1442,7 @@ test "lower: shadowed same-name author gets its own FuncId + real body (fix-0102 try std.testing.expect(shadow_fid != null); try std.testing.expect(shadow_fid.? != winner_fid.?); - // fix-0102c / Phase C: THE bare-name selector routes per caller file over the + // Phase C: THE bare-name selector routes per caller file over the // Phase A author collector. `main` flat-imports two `greet` authors and is its // own author of neither → a bare `greet()` from `main` is ambiguous. a.sx // authors the WINNER, so its bare `greet` resolves through the existing path diff --git a/src/ir/lower.zig b/src/ir/lower.zig index d292c28..ef5a891 100644 --- a/src/ir/lower.zig +++ b/src/ir/lower.zig @@ -214,13 +214,13 @@ pub const Lowering = struct { /// Identity map: authoring `*const ast.FnDecl` → the FuncId `declareFunction` /// created for it. The name-keyed function table (`resolveFuncByName`) returns /// the FIRST author of a name, so two same-name authors collide there; this - /// map addresses each author's OWN slot by decl identity (fix-0102b), letting + /// map addresses each author's OWN slot by decl identity, letting /// a SHADOWED author lower its body into a distinct FuncId. fn_decl_fids: std.AutoHashMap(*const ast.FnDecl, FuncId), /// FuncId-keyed lowered tracking — the identity twin of `lowered_functions` /// (which keys by name). A shadowed same-name author shares the winner's name /// but not its FuncId, so name-keyed tracking can't tell them apart; this - /// records which specific FuncIds have had a real body lowered (fix-0102b). + /// records which specific FuncIds have had a real body lowered. lowered_fids: std.AutoHashMap(FuncId, void), local_fn_counter: u32 = 0, // unique counter for mangling local function names /// Per-declaration nominal identity bookkeeping (E2). The FIRST source to @@ -228,7 +228,7 @@ pub const Lowering = struct { /// byte-identical to pre-E2 single-author registration); a later registration /// of the same name from a DIFFERENT source is a same-name SHADOW and gets a /// fresh id from `next_nominal_id`, so the two authors intern to DISTINCT - /// TypeIds (closing issue 0105's last-wins collapse). `nominal_name_authors` + /// TypeIds (closing the last-wins collapse). `nominal_name_authors` /// records each name's first author source to make that decision. nominal_name_authors: std.AutoHashMap(types.StringId, []const u8), next_nominal_id: u32 = 0, @@ -419,7 +419,7 @@ pub const Lowering = struct { /// `restore` puts the caller's state back. Lowering a callee must be /// transparent to the caller's own lowering — notably `block_terminated`, /// which leaking back would mark the caller's trailing statements - /// dead-after-terminator (issue 0100 F2). + /// dead-after-terminator. pub const FnBodyReentry = struct { l: *Lowering, func: ?FuncId, @@ -543,7 +543,7 @@ pub const Lowering = struct { // params aren't pushed into `self.scope` until body lowering, so bind // them into a temporary scope here; otherwise `inferExprType` can't // resolve `x`, the inference yields `.unresolved`, and that reaches LLVM - // emission as `func.ret` (issue 0059). Whether it slipped through used to + // emission as `func.ret`. Whether it slipped through used to // depend on a same-named binding lingering from earlier lowering. var tmp_scope = Scope.init(self.alloc, self.scope); defer tmp_scope.deinit(); @@ -647,7 +647,7 @@ pub const Lowering = struct { /// bare-visible only inside the callee's own module — namespaced-only from the /// call site's view. Post-E1 the bare leaf is source-aware, so resolving that /// return type in the CALL SITE's context would wrongly reject it (the type - /// analog of the issue-0100-F1 source pin that lowers a namespaced fn body in + /// analog of the namespaced-fn-body source pin that lowers a namespaced fn body in /// its own module's context). `src == null` falls back to the call site's /// context unchanged. pub fn resolveTypeInSource(self: *Lowering, src: ?[]const u8, type_ann: *const Node) TypeId { @@ -706,13 +706,13 @@ pub const Lowering = struct { /// value / module-const tables the stateful lowering owns) and is narrowed to /// `u32` through the single range-checked `program_index.foldDimU32` — never a /// bare `@intCast`, so an oversized-but-valid `i64` dim (`[5_000_000_000]`) - /// diagnoses instead of panicking the compiler (issue 0087). A dimension that + /// diagnoses instead of panicking the compiler. A dimension that /// isn't a compile-time integer (or doesn't fit a `u32`) is a hard error: /// emit a diagnostic so the driver aborts (`hasErrors()`), then return a /// harmless `0` so body lowering finishes without touching the `.unresolved` /// sentinel (which would `@panic` in `sizeOf` mid-lowering, before the /// diagnostic surfaces). The diagnostic — not the returned length — is what - /// guarantees no garbage ships (issue 0083). + /// guarantees no garbage ships. pub fn resolveArrayLen(self: *Lowering, len_node: *const Node) ?u32 { const result = program_index_mod.foldDimU32(len_node, self, 0); if (result == .ok) return result.ok; @@ -720,7 +720,7 @@ pub const Lowering = struct { // shared diagnostic (single wording source — `program_index.reportDimError`, // also used by the stateless alias path so the two cannot diverge) and // return null so `resolveCompound` yields the `.unresolved` sentinel — NO - // fabricated length (issue 0083: a `0` here gives a 0-byte alloca and OOB + // fabricated length (a `0` here gives a 0-byte alloca and OOB // element access). Lowering the binding never computes the failed type's // size: `alloca` records the type but defers `sizeOf` to LLVM emission, // which the emitted diagnostic pre-empts via `hasErrors()`, and a @@ -764,7 +764,7 @@ pub const Lowering = struct { /// True iff `name` is a FLOAT-valued module const (`F : f64 : 2.5`, /// `K : f64 : 4.0`, untyped `M :: 4.0`, untyped-EXPR `ME :: 4.0 + 1.0`). The /// int folder's division arm consults this so a `/` with a float-const operand - /// is recognised as float division (issue 0095 / F0.11-6). Comptime / generic + /// is recognised as float division. Comptime / generic /// value bindings are always integer-valued, so only the module-const table /// can name a float. pub fn nameIsFloatTyped(self: *Lowering, name: []const u8) bool { @@ -894,7 +894,7 @@ pub const Lowering = struct { .identifier => |id| return self.resolveNominalLeaf(id.name, id.is_raw, node.span), // A non-spread tuple literal in a type position is a tuple-type // literal (`(s32, s32)`); validate its elements are types and reject - // non-type elements loudly (issue 0067). + // non-type elements loudly. .tuple_literal => return self.resolveTupleLiteralTypeArg(node), else => return type_bridge.resolveAstType(node, &self.module.types, &self.program_index.type_alias_map, &self.program_index.module_const_map), } @@ -912,7 +912,7 @@ pub const Lowering = struct { /// (`Vector(4, f32)`), a module/generic const (`Vector(N, f32)`), and a const /// expression (`Vector(M + 1, f32)`) all resolve identically, and the i64→u32 /// narrowing is range-checked (an oversized lane diagnoses instead of - /// panicking — issue 0087). A non-const lane (`Vector(get(), f32)`) or a + /// panicking). A non-const lane (`Vector(get(), f32)`) or a /// non-positive one emits a clean diagnostic and returns null; the caller /// yields `.unresolved` rather than fabricating a `<0 x float>` lane count /// that crashes LLVM verification. @@ -1045,7 +1045,7 @@ pub const Lowering = struct { pub fn emitFieldError(self: *Lowering, obj_ty: TypeId, field: []const u8, span: ast.Span) Ref { // A field access on an already-`.unresolved` object is a cascade from an // upstream type-resolution failure that was ALREADY diagnosed (e.g. an - // unresolvable / oversized array dimension — issue 0083). The + // unresolvable / oversized array dimension). The // `.unresolved` sentinel never exists without an accompanying error, so // piling a second "field not found on unresolved" onto the real one is // pure noise; stay silent and return a placeholder so lowering finishes @@ -1173,7 +1173,7 @@ pub const Lowering = struct { } /// Human-readable description of a typed module-const initializer, used in - /// the issue-0088 type-mismatch diagnostic. A literal names its kind; a + /// the typed-const type-mismatch diagnostic. A literal names its kind; a /// const-expression is described by its inferred type category, so the /// message is accurate for `N : string : M + 2` ("an integer expression") /// as well as for `N : string : 4` ("an integer literal"). diff --git a/src/ir/lower/call.zig b/src/ir/lower/call.zig index 5b510d0..eee7215 100644 --- a/src/ir/lower/call.zig +++ b/src/ir/lower/call.zig @@ -34,7 +34,7 @@ pub fn lowerCall(self: *Lowering, c_in: *const ast.Call) Ref { // function. `TypeName(val)` is not a cast (casts are `cast(T, val)`), so // there is no ambiguity. Rewrite the callee to an identifier so the // normal call machinery resolves it, symmetric to the bare-value - // reference that already resolves via scope/globals (issue 0089). + // reference that already resolves via scope/globals. // // Scoped to RAW provenance: only a backtick (`is_raw`) or `#import c` // foreign fn declaration may legally carry a reserved-name spelling @@ -55,7 +55,7 @@ pub fn lowerCall(self: *Lowering, c_in: *const ast.Call) Ref { c = rewritten; }; } - // fix-0102 F2 / R5 §C: select the bare / value-UFCS same-name call author + // R5 §C: select the bare / value-UFCS same-name call author // ONCE, via `CallResolver.selectedFreeAuthor` — the SINGLE producer of // this verdict, the exact same one `CallResolver.plan` consumes for typing. // The call-path consumers (default expansion, param typing, dispatch) all @@ -128,7 +128,7 @@ pub fn lowerCall(self: *Lowering, c_in: *const ast.Call) Ref { // If argument is a bare function name, create a proper closure from it if (arg.data == .identifier) { const fn_name = arg.data.identifier.name; - // fix-0102d site 2: `closure(fn)` over a genuine flat same-name + // `closure(fn)` over a genuine flat same-name // collision must capture the RESOLVED author's FuncId, not the // first-wins winner's. Plain bare name only; `.ambiguous` // → loud diagnostic; `.none` → existing first-wins path. @@ -188,7 +188,7 @@ pub fn lowerCall(self: *Lowering, c_in: *const ast.Call) Ref { } break :blk scoped; }; - // fix-0102 F2 / R5 §C: the early pack/comptime/generic dispatch reads + // R5 §C: the early pack/comptime/generic dispatch reads // the SAME author the call resolver SELECTED — not the first-wins // winner — whenever a genuine flat same-name collision rerouted the // call (`sel_author != null`). The selector only ever returns a plain @@ -455,14 +455,14 @@ pub fn lowerCall(self: *Lowering, c_in: *const ast.Call) Ref { } } } - // fix-0102c / R5 §C: a genuine flat same-name collision — bind the + // R5 §C: a genuine flat same-name collision — bind the // author the call resolver selected (own-author-wins, or the single // flat-reachable author), or reject a bare call to a name ≥2 // imported modules author. `selectedFreeAuthor` (computed once // above, and the exact verdict `plan` consumes for typing) is the // single producer; lowering CONSUMES it rather than re-resolving // the name, so typing and dispatch read the SAME author and can't - // disagree (fix-0102 F2). Reached only for an identifier callee, so + // disagree. Reached only for an identifier callee, so // `sel_author` / `author_ambiguous` here are the bare verdict. if (author_ambiguous) { if (self.diagnostics) |d| @@ -476,7 +476,7 @@ pub fn lowerCall(self: *Lowering, c_in: *const ast.Call) Ref { const params = func.params; // The RESOLVED author's decl drives variadic packing — not a // first-wins re-lookup by name, whose variadic shape may - // differ (fix-0102c F1). + // differ. self.packVariadicCallArgs(sf.decl, c, &args); const final_args = self.prependCtxIfNeeded(func, args.items); self.coerceCallArgs(final_args, params); @@ -956,13 +956,13 @@ pub fn lowerCall(self: *Lowering, c_in: *const ast.Call) Ref { // Try to resolve as bare function name (free-function UFCS: // `recv.fn(args)` → `fn(recv, args)`). Lazily lower the body — // a function reached ONLY via UFCS would otherwise be declared - // but never emitted (issue 0063: undefined symbol at link). + // but never emitted (undefined symbol at link). // - // fix-0102d site 3 / R5 §C: a free-function UFCS target with a + // R5 §C: a free-function UFCS target with a // genuine flat same-name collision dispatches to the author the // call PLAN selected for the receiver's source — the SAME author // plan typed the call's result as, so dispatch and typing can't - // disagree (fix-0102 F2; without this, a string-typed winner over + // disagree (without this, a string-typed winner over // an s64 shadow boxes a raw int as a string pointer → segfault). // The plan is the single producer; lowering consumes its verdict // (`sel_author` / `cplan.ambiguous_collision`, computed once above) @@ -991,7 +991,7 @@ pub fn lowerCall(self: *Lowering, c_in: *const ast.Call) Ref { // Same implicit address-of as a struct-defined method: if the // free function's first param is `*T` and the receiver is a // value `T`, pass its address instead of a by-value copy - // (issue 0063). + self.fixupMethodReceiver(&method_args, func, effective_obj_node, obj_ty); const final_args = self.prependCtxIfNeeded(func, method_args.items); self.coerceCallArgs(final_args, params); @@ -1517,7 +1517,7 @@ pub fn tryLowerReflectionCall(self: *Lowering, name: []const u8, c: *const ast.C // Strict `$T: Type` guard for the type-introspection builtins. A // value argument (`6`, `true`, `5.2`, a struct) is rejected with a // diagnostic instead of being silently reinterpreted as a TypeId - // index / sized via its `typeof` (issue 0090). One shared + // index / sized via its `typeof`. One shared // classification covers all 7; it runs before dispatch. if (self.reflectionTypeArgGuard(name, c)) |sentinel| return sentinel; @@ -1776,7 +1776,7 @@ pub fn reflectionArgIsType(self: *Lowering, arg: *const Node) bool { /// `field_count`, `type_name`, `type_eq`, `type_is_unsigned`, /// `is_flags`): every argument must denote a type. A value argument is /// rejected with a diagnostic rather than silently reinterpreted as a -/// TypeId index or sized via its `typeof` (issue 0090). +/// TypeId index or sized via its `typeof`. /// /// Returns null when `name` is not a guarded builtin OR every argument /// is a type (→ fall through to normal dispatch). Returns a harmless @@ -1866,7 +1866,7 @@ pub fn expandCallDefaults(self: *Lowering, c: *const ast.Call, sel_author: ?*con } break :blk2 scoped; }; - // fix-0102d site 1 / R5 §C: for a genuine flat same-name + // R5 §C: for a genuine flat same-name // collision the omitted trailing args are filled from the // author the call resolver selected — its `*FnDecl` defaults — // not the first-wins winner's. lowering consumes the ONE author @@ -2097,7 +2097,7 @@ pub fn resolveCallParamTypes(self: *Lowering, c: *const ast.Call, sel_author: ?* break :blk scoped; }; - // fix-0102c F2 / R5 §C: a genuine flat same-name collision must type this + // R5 §C: a genuine flat same-name collision must type this // call's args against the author the call resolver selected, not the // first-wins winner's params. lowering consumes the ONE author verdict // (`selectedFreeAuthor`, computed once in `lowerCall`) rather than diff --git a/src/ir/lower/closure.zig b/src/ir/lower/closure.zig index a407dfc..e7d4d86 100644 --- a/src/ir/lower/closure.zig +++ b/src/ir/lower/closure.zig @@ -189,7 +189,7 @@ pub fn lowerLambda(self: *Lowering, lam: *const ast.Lambda) Ref { // `defer`s, not the enclosing function's. Open a fresh defer window // (like `lowerFunction`/`monomorphizeFunction`) and restore on exit — // otherwise lowering a closure literal inside a `defer` body re-enters - // the enclosing function's defer drain (infinite recursion — issue 0073). + // the enclosing function's defer drain (infinite recursion). const saved_func_defer_base = self.func_defer_base; const saved_defer_len = self.defer_stack.items.len; defer { diff --git a/src/ir/lower/coerce.zig b/src/ir/lower/coerce.zig index 1caf7c6..e866b01 100644 --- a/src/ir/lower/coerce.zig +++ b/src/ir/lower/coerce.zig @@ -543,8 +543,8 @@ pub fn zeroValue(self: *Lowering, ty: TypeId) Ref { }; } -/// Emit the unified non-integral float→int narrowing diagnostic (F0.11 / -/// issue 0095). ONE wording, ONE place: every site that rejects an implicit +/// Emit the unified non-integral float→int narrowing diagnostic (F0.11). +/// ONE wording, ONE place: every site that rejects an implicit /// narrowing of a non-integral compile-time float to an integer type calls /// this, so the message + fix-it stay identical across the typed-binding /// coerce arm, the field/param-default sites, the typed-const path, and the diff --git a/src/ir/lower/comptime.zig b/src/ir/lower/comptime.zig index 18952d3..07438d4 100644 --- a/src/ir/lower/comptime.zig +++ b/src/ir/lower/comptime.zig @@ -45,7 +45,7 @@ pub fn constArrayLiteral(self: *Lowering, elements: []const *const Node, array_t /// Try to convert a single AST expression into a compile-time ConstantValue. /// `expected_ty` is the destination element/field type — it lets aggregate /// leaves (struct literals, nested arrays) serialize with the correct shape -/// rather than collapsing to null (issue 0080). Returns null if the +/// rather than collapsing to null. Returns null if the /// expression is not constant-foldable here. pub fn constExprValue(self: *Lowering, expr: *const Node, expected_ty: TypeId) ?inst_mod.ConstantValue { return switch (expr.data) { @@ -66,7 +66,7 @@ pub fn constExprValue(self: *Lowering, expr: *const Node, expected_ty: TypeId) ? .undef_literal => .zeroinit, // A `null` in a pointer (or optional-pointer) field is a // compile-time constant: the zero pointer. Without this arm the - // aggregate is wrongly rejected as non-constant (issue 0081). + // aggregate is wrongly rejected as non-constant. .null_literal => .null_val, .unary_op => |uo| switch (uo.op) { .negate => switch (uo.operand.data) { @@ -80,7 +80,7 @@ pub fn constExprValue(self: *Lowering, expr: *const Node, expected_ty: TypeId) ? .struct_literal => |sl| self.constStructLiteral(&sl, expected_ty), // An enum tag as an aggregate leaf (`[2]Color = .[.green, .blue]`, or // an enum field inside a global struct) serializes to its tag int - // against the leaf's declared enum type (issue 0082). + // against the leaf's declared enum type. .enum_literal => |el| self.constEnumLiteral(&el, expected_ty, expr.span), else => null, }; @@ -92,7 +92,7 @@ pub fn constExprValue(self: *Lowering, expr: *const Node, expected_ty: TypeId) ? /// (`enum { a; b :: 5; }`); the enum's backing width is applied by the /// const emitters via the destination type's LLVM type. Plain enums only — /// a tagged-union or non-enum destination is diagnosed loudly rather than -/// silently zero-initialized (issue 0082). +/// silently zero-initialized. pub fn constEnumLiteral(self: *Lowering, el: *const ast.EnumLiteral, ty: TypeId, span: ast.Span) ?inst_mod.ConstantValue { if (!ty.isBuiltin()) { const info = self.module.types.get(ty); @@ -543,7 +543,7 @@ pub fn lowerComptimeCall(self: *Lowering, fd: *const ast.FnDecl, call_node: *con // its return type + anything it `#insert`s, e.g. `build_format` / `out` // / `emit` inside `std.print` / `log.*`), so those bare names resolve // in the defining module's visibility context rather than the call - // site's (issue 0106). The call-site ARGS above are deliberately lowered + // site's. The call-site ARGS above are deliberately lowered // BEFORE this, in the caller's context. Mirrors `lowerFunctionBodyInto`, // which switches to `func.source_file`. The defining path is stamped on // the body node by `resolveImports`; a sourceless body keeps the @@ -848,7 +848,7 @@ const ConstAuthor = union(enum) { /// /// - **own-wins**: the querying module's OWN const author is selected outright. /// - else the FLAT-import-reachable const authors: exactly one → it; ≥2 distinct -/// → `.ambiguous` (issue 0105 / 0760 — never a silent first-/last-wins pick). +/// → `.ambiguous` (never a silent first-/last-wins pick). /// - none visible → `.none` (a namespaced-only const must be qualified `ns.X`; /// a non-const name folds to `.none` too). /// diff --git a/src/ir/lower/control_flow.zig b/src/ir/lower/control_flow.zig index c4eeeef..efa1152 100644 --- a/src/ir/lower/control_flow.zig +++ b/src/ir/lower/control_flow.zig @@ -779,7 +779,7 @@ pub fn lowerMatch(self: *Lowering, me: *const ast.MatchExpr) Ref { if (has_value_merge) { // Lower the arm body against the merge's result type so literals // (and negated literals) in the arm pick the right width — the - // phi operands must all match `result_type` (issue 0066). + // phi operands must all match `result_type`. const saved_arm_target = self.target_type; self.target_type = result_type; const maybe_v = self.lowerBlockValue(arm.body); @@ -790,7 +790,7 @@ pub fn lowerMatch(self: *Lowering, me: *const ast.MatchExpr) Ref { // Only materialize a value + branch to the merge when the arm // body did NOT diverge. A diverging arm (e.g. `return x`) has // already terminated its block; emitting the fallback const - // here would land AFTER the terminator (the issue-0057 bug). + // here would land AFTER the terminator . if (!self.currentBlockHasTerminator()) { var v = maybe_v orelse if (result_type == .string or !result_type.isBuiltin()) self.builder.constUndef(result_type) diff --git a/src/ir/lower/decl.zig b/src/ir/lower/decl.zig index 75b52e3..fab95ce 100644 --- a/src/ir/lower/decl.zig +++ b/src/ir/lower/decl.zig @@ -92,7 +92,7 @@ pub fn lowerRoot(self: *Lowering, root: *const Node) void { // any error before codegen. self.errorFlow().checkErrorFlow(decls); // Pass 1f: reject identifiers used in a type position that name no - // declared type / primitive / in-scope generic param (issue 0064). + // declared type / primitive / in-scope generic param. // Runs after scanning (so every real type name is registered) and // before body lowering, so the diagnostic halts via `core.zig` // `hasErrors()` before the empty-struct stub can reach codegen. Owned by @@ -447,11 +447,11 @@ pub fn scanDecls(self: *Lowering, decls: []const *const Node) void { // declaration order (pass 1) and typed ones only after the alias fixpoint // (pass 2) — so an alias declared before its const, or any alias over a // typed const, saw an empty table and miscompiled the dimension to length - // 0 (issue 0083). A float-valued const resolves to a dimension only when + // 0. A float-valued const resolves to a dimension only when // its value is integral (`floatToIntExact`); pre-registering it keeps the // forward-alias float path identical to the int path. The dimension only // needs the value, so a placeholder type is fine; pass 2 overwrites typed - // consts with the resolved annotation type (issue 0070). + // consts with the resolved annotation type. for (decls) |decl| { if (decl.data != .const_decl) continue; const cd = decl.data.const_decl; @@ -467,7 +467,7 @@ pub fn scanDecls(self: *Lowering, decls: []const *const Node) void { // A const whose RHS is an integer EXPRESSION over other consts // (`M :: 2; N :: M + 1`) is itself a usable count: register it so // `moduleConstInt` can fold the RHS through `evalConstIntExpr` - // (issue 0083). Placeholder `.s64` type — the count consumers read + //. Placeholder `.s64` type — the count consumers read // only the value; if the expression doesn't fold (references a // non-const), `moduleConstInt` yields null and the use diagnoses. .binary_op, .unary_op => { @@ -483,7 +483,7 @@ pub fn scanDecls(self: *Lowering, decls: []const *const Node) void { // self (`next: *Box`), or a forward / mutual ref to a shadow declared LATER // in the same module (`peer: *Node`) — then binds to its OWN nominal TypeId // via `type_decl_tids`, never the global findByName first-author fallback - // (issue 0105). + // // "Genuine" = ≥2 DISTINCT decls of the SAME KIND in THIS scan author the name // (so it needs ≥2 distinct nominal TypeIds). Grouping by (kind, name) keeps a @@ -529,7 +529,7 @@ pub fn scanDecls(self: *Lowering, decls: []const *const Node) void { // re-introduces a same-named function (e.g. a second module // also exporting `parse`) must NOT clobber the AST while the // function table keeps the first — that split lowers one - // signature against the other's body (issue 0100). The + // signature against the other's body. The // shadowed function stays reachable via its qualified name. if (!self.program_index.fn_ast_map.contains(fd.name)) { self.program_index.fn_ast_map.put(fd.name, &decl.data.fn_decl) catch {}; @@ -574,7 +574,7 @@ pub fn scanDecls(self: *Lowering, decls: []const *const Node) void { // dimension is not a compile-time integer constant. Surface // it as a clean diagnostic so the build aborts here rather // than letting `.unresolved` reach codegen and `@panic` in - // sizeOf (issue 0083 — no fabricated 0-length array). For a + // sizeOf (no fabricated 0-length array). For a // top-level array alias, re-fold the dimension so an // oversized / negative constant emits the SAME precise // message as the direct form (`a : [N]T`) via the shared @@ -710,7 +710,7 @@ pub fn scanDecls(self: *Lowering, decls: []const *const Node) void { // Typed value constants (`AF_INET :s32: 2`) are registered in // pass 2 below — after the forward-alias fixpoint — so a // forward identifier alias in the annotation resolves to its - // target instead of a fabricated stub (issue 0070). Untyped + // target instead of a fabricated stub. Untyped // literal constants carry no annotation to resolve, so they // stay here (their type comes from the literal / inference). if (cd.type_annotation == null) { @@ -765,7 +765,7 @@ pub fn scanDecls(self: *Lowering, decls: []const *const Node) void { }, // Top-level globals are registered in a second pass (below), // after the forward-alias fixpoint, so a forward identifier - // alias used as a global's type annotation resolves (issue 0070). + // alias used as a global's type annotation resolves. .var_decl => {}, else => {}, } @@ -773,7 +773,7 @@ pub fn scanDecls(self: *Lowering, decls: []const *const Node) void { self.resolveForwardIdentifierAliases(decls); // Pass 2: registrations that resolve a top-level type annotation run // after the alias fixpoint, so a forward identifier alias used as the - // annotation resolves to its target (issue 0070). + // annotation resolves to its target. for (decls) |decl| { self.setCurrentSourceFile(decl.source_file); switch (decl.data) { @@ -788,14 +788,14 @@ pub fn scanDecls(self: *Lowering, decls: []const *const Node) void { /// scanDecls pass 2 (after `resolveForwardIdentifierAliases`) so a forward /// identifier alias in the annotation (`A :: B; B :: s32; K : A : 42;`) /// resolves to its target rather than a fabricated empty-struct stub, which -/// would otherwise mistype the constant (issue 0070). +/// would otherwise mistype the constant. pub fn registerTypedModuleConst(self: *Lowering, cd: *const ast.ConstDecl) void { const ta = cd.type_annotation orelse return; // Only initializer shapes that pass 0 (binary_op / unary_op → placeholder // `.s64`) or the literal path register as a USABLE module const need // reconciling against the annotation. Every other shape (call, // struct/array literal, bare identifier) is never registered as a - // foldable / emittable const, so it cannot manifest the issue-0088 + // foldable / emittable const, so it cannot manifest a // wrong-type fold/emit; a use-site diagnostic covers it. switch (cd.value.data) { .int_literal, .float_literal, .bool_literal, .string_literal, .undef_literal, .null_literal, .binary_op, .unary_op => {}, @@ -901,8 +901,7 @@ pub fn typedConstInitFits(self: *Lowering, value: *const Node, dst_ty: TypeId) b // Const-EXPRESSION initializer (binary_op / unary_op — the only // non-literal kinds the caller admits): validate by the initializer's // INFERRED type so coverage is type-based, not a per-node-kind - // allowlist where an unenumerated kind silently escapes (issue 0088, - // attempt 2). The integer/float fit mirrors the literal arms above. + // allowlist where an unenumerated kind silently escapes. The integer/float fit mirrors the literal arms above. else => self.constExprInitFits(self.inferExprType(value), dst_ty), }; } @@ -930,7 +929,7 @@ pub fn constExprInitFits(self: *Lowering, init_ty: TypeId, dst_ty: TypeId) bool /// in the type annotation (`A :: B; B :: s32; g : A = 7;`) resolves to its /// target instead of a fabricated empty-struct stub, which would otherwise /// give the global a type that mismatches its initializer at LLVM -/// verification (issue 0070). Globals can't be named in a type position, so +/// verification. Globals can't be named in a type position, so /// deferring them past type/alias registration introduces no ordering hazard. pub fn registerTopLevelGlobal(self: *Lowering, vd: *const ast.VarDecl) void { // Use self.resolveType so type aliases like `Handle :: u32;` resolve @@ -967,7 +966,7 @@ pub fn registerTopLevelGlobal(self: *Lowering, vd: *const ast.VarDecl) void { /// Foreign globals (extern symbol) and value-less declarations carry no /// payload — they default to zero/extern at link, which is correct. An /// identifier initializer that names a module constant is materialized from -/// the recorded constant (`K : A : 42; g : A = K;` → 42, issue 0071); a +/// the recorded constant (`K : A : 42; g : A = K;` → 42); a /// global initialized from an identifier that resolves to no usable constant /// is rejected with a diagnostic rather than silently zero-initialized — a /// global has no run site for a dynamic initializer. @@ -1026,7 +1025,7 @@ pub fn globalInitValue(self: *Lowering, vd: *const ast.VarDecl, var_ty: TypeId) // Any other initializer shape (`.field_access` on a const, a call, an // arithmetic expression, …) is not a static constant the compiler can // evaluate here. Diagnose loudly rather than emit a null payload that - // silently zero-initializes the global (issues 0071/0072). + // silently zero-initializes the global. else => blk: { if (self.diagnostics) |d| d.addFmt(.err, v.span, "global '{s}' must be initialized by a compile-time constant", .{vd.name}); @@ -1038,7 +1037,7 @@ pub fn globalInitValue(self: *Lowering, vd: *const ast.VarDecl, var_ty: TypeId) /// A global aggregate initializer (array/struct literal) that does not fully /// reduce to a compile-time constant is rejected loudly. Without this the /// `null` payload would fall through to a zero-initialized global, silently -/// dropping the declared fields (issues 0071/0072/0080). +/// dropping the declared fields. pub fn diagnoseNonConstGlobal(self: *Lowering, vd: *const ast.VarDecl, v: *const Node) ?inst_mod.ConstantValue { if (self.diagnostics) |d| d.addFmt(.err, v.span, "global '{s}' must be initialized by a compile-time constant", .{vd.name}); @@ -1049,11 +1048,11 @@ pub fn diagnoseNonConstGlobal(self: *Lowering, vd: *const ast.VarDecl, v: *const /// file. The forward scan above only registers an alias (`A :: B`) when `B` /// is already resolved as a type author; a forward target isn't yet present, /// so `A` is left unregistered and its uses get falsely flagged as an unknown -/// type (issue 0069). Re-resolve to a fixpoint now that every top-level name +/// type. Re-resolve to a fixpoint now that every top-level name /// has been seen, so `A :: B; B :: s32;` converges the same as the ordered /// `B :: s32; A :: B;`. A value const is never an `.identifier` node /// (`NotAType :: 123` is an int literal), and an alias whose target is a value -/// const stays unresolved, so neither this pass nor issue 0068 can register a +/// const stays unresolved, so neither this pass nor the unknown-type suppression can register a /// non-type name. /// /// SOURCE-AWARE (R5 §4, E1.5). The target `B` is resolved AS SEEN FROM `A`'s @@ -1116,8 +1115,7 @@ pub fn aliasResolvedInSource(self: *Lowering, src: []const u8, name: []const u8) /// Pass 2: Lower main function body and comptime side-effects. pub fn lowerMainAndComptime(self: *Lowering, decls: []const *const Node) void { for (decls) |decl| { - // A `#run` body lowers in its OWN module's source context (fix-0102d - // site 4): `NAME :: #run f()` written in an imported module must + // A `#run` body lowers in its OWN module's source context: `NAME :: #run f()` written in an imported module must // resolve a bare `f` from that module's flat imports, not the main // file's. Without this, `selectPlainCallableAuthor` runs with the main // file's perspective and reports a genuine per-source author as @@ -1154,15 +1152,15 @@ pub fn lowerMainAndComptime(self: *Lowering, decls: []const *const Node) void { /// Lower every SHADOWED same-name function author into its OWN FuncId with a /// real (non-extern) body — the identity-addressable lowering PATH this step -/// adds (fix-0102b). It does NOT run during a default compile: the name path -/// stays the sole resolver, so the suite is byte-for-byte unchanged. fix-0102c -/// invokes it as part of routing bare flat calls to the right author; until +/// adds. It does NOT run during a default compile: the name path +/// stays the sole resolver, so the suite is byte-for-byte unchanged. The bare-call +/// disambiguation invokes it as part of routing bare flat calls to the right author; until /// then it is exercised by the lower-test regression that asserts two distinct /// non-extern bodies for a same-name collision. /// /// The first-wins flat/directory merge keeps exactly one author per name in /// the merged decl list; `scanDecls` declares that WINNER (lowered on demand -/// through the name-keyed `lazyLowerFunction`). fix-0102a retained every +/// through the name-keyed `lazyLowerFunction`). The merge retains every /// dropped same-name author in the `module_decls` raw facts (path → name → /// `RawDeclRef`) without touching resolution; this walks that index, filters /// each author to its `*FnDecl` (`fnDeclOfRaw`), and gives each shadowed @@ -1211,7 +1209,7 @@ pub fn lowerRetainedSameNameAuthors(self: *Lowering) void { } } -/// Result of bare-call disambiguation (fix-0102c, now over the Phase B +/// Result of bare-call disambiguation (now over the Phase B /// author collector). pub const BareCallee = union(enum) { /// Bind the call to this specific author, carried as the shared @@ -1219,7 +1217,7 @@ pub const BareCallee = union(enum) { /// materialized on demand. Every callee-signature decision in the call /// path (variadic packing, param typing, default expansion) reads the /// RESOLVED author from this one object — never a first-wins re-lookup - /// by name (fix-0102c F1). + /// by name. func: SelectedFunc, /// ≥2 distinct flat authors are reachable from the caller and none is /// the caller's own — the bare call can't pick one; require a qualifier. @@ -1285,13 +1283,13 @@ pub const TypeHeadResolution = union(enum) { /// would mis-size it). not_visible, /// ≥2 DISTINCT same-name type authors are flat-visible from the querying - /// source and none is its own (E2, issue 0105). The selection is genuinely + /// source and none is its own (E2). The selection is genuinely /// ambiguous: `resolveNominalLeaf` emits a loud diagnostic and returns the /// `.unresolved` poison sentinel — never a silent first-/last-wins pick. ambiguous, }; -/// THE plain bare-name call selector (fix-0102c, R5 §C). `resolveBareCallee`'s +/// THE plain bare-name call selector. `resolveBareCallee`'s /// body verbatim, now over the Phase B author collector /// (`resolver.collectVisibleAuthors` — the ONE graph-walk) instead of a direct /// `module_decls` + `flat_import_graph` traversal. Routes a bare identifier @@ -1372,7 +1370,7 @@ pub fn selectPlainCallableAuthor(self: *Lowering, name: []const u8, caller_file: /// selected author's OWN source — never the global `findByName` first-match /// nor the global `type_alias_map`. /// -/// `raw` is the backtick raw-identifier escape (issue 0089): a raw reference +/// `raw` is the backtick raw-identifier escape: a raw reference /// bypasses the builtin classifier and resolves only through the nominal /// author / alias path. /// @@ -1454,7 +1452,7 @@ pub fn selectNominalLeaf(self: *Lowering, name: []const u8, from: []const u8, ra const author_set = res_walk.collectVisibleAuthors(name, from, .user_bare_flat); defer if (author_set.flat.len > 0) self.alloc.free(author_set.flat); - // 1a. Own type author wins outright (own-wins, issue 0105/0107). + // 1a. Own type author wins outright (own-wins). if (author_set.own) |own| switch (own.raw) { .const_decl => { // Type alias: present in type_aliases_by_source → resolved. @@ -1462,7 +1460,7 @@ pub fn selectNominalLeaf(self: *Lowering, name: []const u8, from: []const u8, ra if (inner.get(name)) |tid| return .{ .resolved = tid }; } // Own const_decl not yet resolved: pending (own takes priority - // over any flat author — prevents issue 0107 flat-preemption). + // over any flat author — prevents flat-preemption). return .pending; }, else => if (isNamedTypeKind(own.raw)) { @@ -1559,7 +1557,7 @@ pub fn isNamedTypeKind(raw: resolver_mod.RawDeclRef) bool { /// mid-registration → the caller yields the legacy empty-struct stub). A /// STRUCT resolves first through its `type_decl_tids` nominal identity (E2) /// keyed by the raw-facts decl pointer, so two same-name struct authors in -/// different sources resolve to their OWN distinct TypeIds (issue 0105). A +/// different sources resolve to their OWN distinct TypeIds. A /// `type_decl_tids` MISS falls back to the global `findByName` — correct for a /// SINGLE-author struct registered via a non-`internNamedTypeDecl` path (a /// `struct #compiler`, a protocol-backed struct, a generic instance) or before @@ -1773,7 +1771,7 @@ pub fn selectedFuncId(self: *Lowering, sf: *SelectedFunc, name: []const u8) Func /// winner): the winner owns the name-keyed slot and lowers through the /// normal lazy path, so `selectPlainCallableAuthor` returns `.none` for it. A shadow /// is declared a fresh same-name FuncId in its OWN module's visibility -/// context and its body lowered into that slot via fix-0102b's identity- +/// context and its body lowered into that slot via the identity- /// addressable `lowerFunctionBodyInto`. Idempotent: `lowered_fids` tracks /// which slots already carry a body. pub fn bareAuthorFuncId(self: *Lowering, fd: *const ast.FnDecl, name: []const u8, path: []const u8) FuncId { @@ -1868,7 +1866,7 @@ pub fn declareFunction(self: *Lowering, fd: *const ast.FnDecl, name: []const u8) /// modules each exporting a top-level `parse` otherwise collide in the /// bare-name `fn_ast_map` / function table (last-wins) while `resolveFuncByName` /// picks the first declared, so `lazyLowerFunction` lowers one signature -/// against the other's body and trips its param-count assert (issue 0100). +/// against the other's body and trips its param-count assert. /// The bare recursion in `scanDecls` still registers intra-module bare calls; /// this adds the qualified identity the `pkg.fn(...)` resolution paths in /// `CallResolver.plan` / `lowerCall` already prefer. @@ -1894,7 +1892,7 @@ pub fn registerQualifiedFn(self: *Lowering, ns_name: []const u8, fd: *const ast. // comptime / pack functions (`Vector`, `print`, `any_to_string`) are // dispatched by monomorphization off their BARE template name, not the // plain `resolveFuncByName` / `lazyLowerFunction` path that trips the - // collision assert (issue 0100); registering a qualified alias for them + // collision assert; registering a qualified alias for them // would divert that machinery and strand a per-call type binding. if (fd.type_params.len > 0 or hasComptimeParams(fd) or isPackFn(fd)) return; // Foreign / builtin / #compiler bodies keep their literal name; a @@ -1911,7 +1909,7 @@ pub fn registerQualifiedFn(self: *Lowering, ns_name: []const u8, fd: *const ast. // `registerNamespaceQualifiedFns` pins `current_source_file` to the // decl's source before each call). `lazyLowerFunction`'s null-FuncId // path restores this so `ns.fn`'s body lowers in its own module's - // visibility context, not the call site's (issue 0100 F1). + // visibility context, not the call site's. if (self.current_source_file) |src| { self.program_index.qualified_fn_source.put(qualified, src) catch {}; } @@ -2032,7 +2030,7 @@ pub fn lazyLowerFunction(self: *Lowering, name: []const u8) void { // Find the existing extern stub (from scanDecls), keyed by NAME — the // FIRST author of a name owns this slot. A shadowed same-name author is // not here (it has no name-keyed slot); it is lowered out-of-line into - // its OWN FuncId by `lowerRetainedSameNameAuthors` (fix-0102b). + // its OWN FuncId by `lowerRetainedSameNameAuthors`. const name_id = self.module.types.internString(name); var func_id: ?FuncId = null; for (self.module.functions.items, 0..) |func, i| { @@ -2048,7 +2046,7 @@ pub fn lazyLowerFunction(self: *Lowering, name: []const u8) void { } // Function not yet declared — create it fresh via lowerFunction. A - // module-qualified alias (`ns.fn`, issue 0100) is registered in + // module-qualified alias (`ns.fn`) is registered in // `fn_ast_map` without an eager `declareFunction`, so there's no // `Function.source_file` to switch to. Restore the alias's OWN declaring // source before lowering its body, otherwise it lowers in the caller's @@ -2067,9 +2065,9 @@ pub fn lazyLowerFunction(self: *Lowering, name: []const u8) void { /// real function. Identity-addressable: the caller passes the exact FuncId, /// so a SHADOWED same-name author lowers into its OWN slot instead of /// colliding on the name-keyed `resolveFuncByName` (which returns the first -/// author, the very split that trips issue 0100's param-count assert). Self- +/// author, the very split that trips the param-count assert). Self- /// contained — the `FnBodyReentry` guard makes the nested lowering -/// transparent to any in-progress caller body (issue 0100 F2) — so it serves +/// transparent to any in-progress caller body — so it serves /// both `lazyLowerFunction`'s name-keyed found path and the out-of-line /// `lowerRetainedSameNameAuthors` pass. pub fn lowerFunctionBodyInto(self: *Lowering, fd: *const ast.FnDecl, fid: FuncId, name: []const u8) void { @@ -2086,7 +2084,7 @@ pub fn lowerFunctionBodyInto(self: *Lowering, fd: *const ast.FnDecl, fid: FuncId // Re-use the existing function slot — switch builder to it. Pin the // function's OWN source BEFORE resolving the return type, so a same-name - // shadowed type in the signature (issue 0105) resolves against THIS + // shadowed type in the signature resolves against THIS // function's module rather than the caller's (which, importing two // same-name authors, would be ambiguous). Param types below already // resolve after this point. @@ -2229,7 +2227,7 @@ pub fn lowerFunction(self: *Lowering, fd: *const ast.FnDecl, name: []const u8, i // Record the declaring source so the function carries its own module // for diagnostics/emit and for any later `lazyLowerFunction` re-entry // that switches to `func.source_file`. The caller sets - // `current_source_file` to the decl's source before lowering (issue 0100 F1). + // `current_source_file` to the decl's source before lowering. self.builder.currentFunc().source_file = self.current_source_file; // Set linkage. Default for fn defs is `internal` (LLVM DCE-friendly, diff --git a/src/ir/lower/expr.zig b/src/ir/lower/expr.zig index 7433686..20042cb 100644 --- a/src/ir/lower/expr.zig +++ b/src/ir/lower/expr.zig @@ -472,7 +472,7 @@ pub fn lowerFieldAccess(self: *Lowering, fa: *const ast.FieldAccess, span: ast.S // const of the queried type (sibling of the identifier-receiver // intercepts above). Placed AFTER `Struct.CONST` so a user const named // `min`/`max` wins on its own struct; a builtin type name can never - // name a user struct (reserved — issue 0076), so they never collide. + // name a user struct (reserved), so they never collide. if (self.lowerNumericLimit(fa, span)) |ref| return ref; // M1.3 — `obj.class` on any Obj-C-class pointer lowers to @@ -558,9 +558,9 @@ pub fn lowerFieldAccess(self: *Lowering, fa: *const ast.FieldAccess, span: ast.S /// constants `module_const_map`. The numeric-limit intercept must defer to /// ordinary field access whenever ANY of the three binds the name, so a /// raw value field read is never hijacked into a numeric-limit fold -/// (issues 0092 local / 0093 global + module-const). A single helper used +/// (locals, globals, and module-consts alike). A single helper used /// by both lowering and inference keeps the two resolvers in lockstep -/// (issue-0083 two-resolver defect class). +/// (two-resolver defect class). pub fn identifierBindsValue(self: *Lowering, name: []const u8) bool { if (self.scope) |scope| { if (scope.lookup(name) != null) return true; @@ -600,7 +600,7 @@ pub fn lowerNumericLimit(self: *Lowering, fa: *const ast.FieldAccess, span: ast. // value is an ordinary field read, not a numeric-limit fold — defer to // the normal field-access path when the receiver identifier resolves to // a value binding through any of scope / globals / module consts - // (issues 0092, 0093). A `.type_expr` receiver is unambiguously a type + //. A `.type_expr` receiver is unambiguously a type // and can never be value-shadowed. if (fa.object.data == .identifier and self.identifierBindsValue(name)) return null; @@ -684,7 +684,7 @@ pub fn lowerOptionalChain(self: *Lowering, obj: Ref, fa: *const ast.FieldAccess, /// aliases `.r`/`.g`/`.b`/`.a`) to its lane index. Returns null for any /// other field name so the read path (`lowerFieldAccessOnType`) and the /// write path (`lowerAssignment`) share one resolver and reject a -/// non-lane field identically (issue 0086). +/// non-lane field identically. pub fn vectorLaneIndex(field: []const u8) ?u32 { if (std.mem.eql(u8, field, "x") or std.mem.eql(u8, field, "r")) return 0; if (std.mem.eql(u8, field, "y") or std.mem.eql(u8, field, "g")) return 1; @@ -1079,7 +1079,7 @@ pub fn lowerArrayLiteral(self: *Lowering, al: *const ast.ArrayLiteral) Ref { // aggregate array `[N]U` (lowerArrayLiteral always yields an array // value); materialize it into a `[]U` slice so the element is a real // {ptr,len} header rather than a raw array the callee would read its - // header off of (issue 0085). This per-element coercion recurses with + // header off of. This per-element coercion recurses with // the literal nesting, so `[][]T` and deeper coerce at every level. if (!elem_ty.isBuiltin()) { const ei = self.module.types.get(elem_ty); @@ -1570,7 +1570,7 @@ pub fn lowerExpr(self: *Lowering, node: *const Node) Ref { } // F2: emit the SOURCE-AWARE author's value (own-wins), not the // global last-wins `ci_global`. ≥2 flat-visible same-name const - // authors → a loud ambiguity (issue 0105 / 0760), never a silent + // authors → a loud ambiguity, never a silent // pick. `.none` after a visible name is the registration-only // author (no per-source partition) — emit its global value. switch (self.selectModuleConst(id.name)) { @@ -1607,7 +1607,7 @@ pub fn lowerExpr(self: *Lowering, node: *const Node) Ref { const str = self.builder.constString(sid); break :blk self.builder.boxAny(str, .string); } - // fix-0102d site 2: taking a bare same-name fn as a VALUE + // taking a bare same-name fn as a VALUE // (func_ref, fn-ptr / closure coercion) must capture the // RESOLVED author's FuncId for a genuine flat collision, not // the first-wins winner's. Plain bare name only; `.ambiguous` diff --git a/src/ir/lower/generic.zig b/src/ir/lower/generic.zig index e3fb5c8..46a880e 100644 --- a/src/ir/lower/generic.zig +++ b/src/ir/lower/generic.zig @@ -73,7 +73,7 @@ pub fn monomorphizeFunction(self: *Lowering, fd: *const ast.FnDecl, mangled_name // — e.g. `List(T).append`'s `alloc: Allocator` default-param type, or a // body reference to a type visible only in the template's module — // resolves where it is visible, not at the (possibly cross-module) call - // site. This is the issue-0100-F1 plain-fn pin extended to generic + // site. This is the namespaced-fn-body plain-fn pin extended to generic // instantiation; without it the non-transitive bare-TYPE gate (E4) would // reject a 2-flat-hop library type the call site cannot see directly. // A synthesized / sourceless body keeps the caller's context. @@ -291,7 +291,7 @@ pub fn isStaticTypeRef(self: *Lowering, node: *const Node) bool { /// must itself denote a type; a non-type element — e.g. the `1` in /// `(s32, 1)` — is a user error. Emit a diagnostic pointing at the offending /// element and return `.unresolved`; never fabricate a tuple with a bogus -/// field (issue 0067). type_bridge.resolveAstType builds the tuple only after +/// field. type_bridge.resolveAstType builds the tuple only after /// this validation passes. pub fn resolveTupleLiteralTypeArg(self: *Lowering, node: *const Node) TypeId { for (node.data.tuple_literal.elements) |el| { @@ -806,7 +806,7 @@ pub fn hasComptimeParams(fd: *const ast.FnDecl) bool { /// A plain free function: no type params (not generic) and an ordinary sx /// body (not `#foreign` / `#builtin` / `#compiler`). Only these get an /// out-of-line identity-addressable slot — the bare-call disambiguation -/// (fix-0102c) and the shadow-author lowering pass leave every other shape +/// and the shadow-author lowering pass leave every other shape /// to the existing name-keyed dispatch. pub fn isPlainFreeFn(fd: *const ast.FnDecl) bool { if (fd.type_params.len > 0) return false; @@ -835,7 +835,7 @@ pub fn isPlainFreeFn(fd: *const ast.FnDecl) bool { pub fn resolveValueParamArg(self: *Lowering, arg_node: *const Node, param_name: []const u8, type_name: ?[]const u8) ?i64 { // Resolve an ALIASED integer constraint (`$K: Count` where `Count :: u32`, // `$K: Small` where `Small :: s8`) to its underlying builtin so the range - // gate below treats it exactly like `$K: u32` / `$K: s8` (issue 0083 — an + // gate below treats it exactly like `$K: u32` / `$K: s8` (an // alias previously slipped past `intTypeRange`, so `Box(5_000_000_000)` // with `$K: Count` bound a truncated value). A non-integer / unrecognised // constraint yields null → no range bound (fold only), as before. diff --git a/src/ir/lower/nominal.zig b/src/ir/lower/nominal.zig index b26ec0f..b0eef4a 100644 --- a/src/ir/lower/nominal.zig +++ b/src/ir/lower/nominal.zig @@ -68,7 +68,7 @@ pub fn stampNominalId(info: types.TypeInfo, nid: u32) types.TypeInfo { /// BEFORE any field resolves, so a self / forward / mutual reference to a shadow /// name (`next: *Box`; `peer: *Node` where Node is a shadow declared later) /// binds to ITS nominal TypeId via `type_decl_tids` instead of the global -/// findByName first-author fallback (issue 0105 / F1). Called only from the +/// findByName first-author fallback. Called only from the /// `scanDecls` genuine-shadow pass, which has already established that ≥2 /// distinct struct decls author this name; ALL of them reserve — the FIRST at /// id 0, the rest at fresh nonzero ids — so none falls through to the name-only @@ -192,7 +192,7 @@ pub fn reserveShadowSlot(self: *Lowering, td: ShadowTypeDecl) void { /// orelse intern) — BYTE-IDENTICAL to pre-E2 registration. For a genuinely /// multi-authored name, the FIRST source keeps id 0 and later sources get /// fresh ids → DISTINCT TypeIds, so the authors no longer collapse last-wins -/// (issue 0105). Idempotent per `decl_key`: a re-registration — OR an up-front +///. Idempotent per `decl_key`: a re-registration — OR an up-front /// shadow reservation — reuses the recorded slot, refreshing its body via /// `updatePreservingKey` (key-stable because a struct's intern key is its /// name + nominal id, not its fields). @@ -593,7 +593,7 @@ pub fn registerStructDecl(self: *Lowering, sd: *const ast.StructDecl, source_fil // shadow author's slot was already reserved before fields resolved, so this // fills it (key-stable updatePreservingKey); a first / single author adopts // any forward-reference stub. Same-name structs in DIFFERENT sources get - // distinct TypeIds instead of last-wins clobbering the first (issue 0105). + // distinct TypeIds instead of last-wins clobbering the first. const info: types.TypeInfo = .{ .@"struct" = .{ .name = name_id, .fields = fields.items } }; _ = self.internNamedTypeDecl(decl_key, name_id, info, nominal_id); diff --git a/src/ir/lower/pack.zig b/src/ir/lower/pack.zig index d124910..3cd97f4 100644 --- a/src/ir/lower/pack.zig +++ b/src/ir/lower/pack.zig @@ -627,7 +627,7 @@ pub fn lowerPackFnCall(self: *Lowering, fd: *const ast.FnDecl, call_node: *const // `target_type`) would cast to the stale target — e.g. `format("…", xx i)` // inside a `-> string` fn mis-typed the arg as `string`, monomorphizing // `__pack_string` and ABI-coercing the 4-byte int as a 16-byte fat - // pointer → memory corruption (issue 0057). + // pointer → memory corruption. const saved_pack_tt = self.target_type; self.target_type = null; var pack_refs = std.ArrayList(Ref).empty; @@ -895,7 +895,7 @@ pub fn monomorphizePackFn( // OWN module (E4), so a 2-flat-hop library type named in the signature is // bare-visible — mirrors the body pin further down and the // `monomorphizeFunction` pin. The comptime call-site args below are - // lowered AFTER this restore, in the caller's context (issue 0106). + // lowered AFTER this restore, in the caller's context. const saved_sig_src = self.current_source_file; if (fd.body.source_file) |src| self.setCurrentSourceFile(src); @@ -1023,7 +1023,7 @@ pub fn monomorphizePackFn( // Pin to the metaprogram's OWN module for the BODY lowering only, so its // bare names (and anything it `#insert`s — e.g. `build_format` / `out` / // `emit` inside `std.print`) resolve in the defining module's visibility - // context, not the call site's (issue 0106). The comptime-param call-site + // context, not the call site's. The comptime-param call-site // args above were deliberately lowered FIRST, in the caller's context. // Mirrors `lowerFunctionBodyInto`, which switches to `func.source_file`; // the defining path is stamped on the body node by `resolveImports`. A diff --git a/src/ir/lower/stmt.zig b/src/ir/lower/stmt.zig index afa992f..f8ac77f 100644 --- a/src/ir/lower/stmt.zig +++ b/src/ir/lower/stmt.zig @@ -689,7 +689,7 @@ pub fn lowerAssignment(self: *Lowering, asgn: *const ast.Assignment) void { // the shared lvalue resolver — the same one the address-of // and multi-target store paths use — so the three never // resolve a field to a different slot or default field 0 - // (issue 0094 / issue-0083 two-resolver class). fl.ptr is + // (two-resolver defect class). fl.ptr is // *field_ty (the store handler unwraps one pointer level); // fl.ty is the value type to coerce the rhs to. const src_ty = self.builder.getRefType(val); @@ -701,7 +701,7 @@ pub fn lowerAssignment(self: *Lowering, asgn: *const ast.Assignment) void { // diagnostic the read path uses (emitFieldError) and bail; // building a pointer with field_ty = .unresolved would // otherwise store through a pointer-to-.unresolved that - // panics at LLVM emission (issue 0094). + // panics at LLVM emission. _ = self.emitFieldError(obj_ty, fa.field, asgn.target.span); } }, @@ -786,7 +786,7 @@ const FieldLvalue = struct { ptr: Ref, ty: TypeId }; /// Single source of lvalue field resolution shared by all three store/ /// address-of sites — lowerAssignment (single-target store), lowerExprAsPtr /// (address-of), and lowerMultiAssign (multi-target store) — so they never -/// resolve a field to a different slot or default field 0 (issue 0094). +/// resolve a field to a different slot or default field 0. pub fn fieldLvaluePtr(self: *Lowering, obj_ptr: Ref, obj_ty: TypeId, field: []const u8) ?FieldLvalue { if (obj_ty.isBuiltin()) return null; const field_name_id = self.module.types.internString(field); @@ -918,7 +918,7 @@ pub fn lowerExprAsPtr(self: *Lowering, node: *const Node) Ref { // field-not-found diagnostic (lowerFieldAccessOnType → // emitFieldError) instead of silently GEPing field 0 as .s64; // that bogus pointer reaches LLVM emission as ptrTo(.unresolved) - // and panics (issue 0094). + // and panics. if (self.fieldLvaluePtr(obj_ptr, obj_ty, fa.field)) |r| return r.ptr; return self.emitFieldError(obj_ty, fa.field, node.span); }, @@ -1150,7 +1150,7 @@ pub fn lowerMultiAssign(self: *Lowering, ma: *const ast.MultiAssign) void { // the same one address-of uses — so a missing field emits a // diagnostic instead of defaulting to field 0 / field_ty // .unresolved, which silently corrupted a neighbouring field - // (or panicked at LLVM emission) (issue 0094). + // (or panicked at LLVM emission). if (self.fieldLvaluePtr(obj_ptr, obj_ty, fa.field)) |r| { const val_ty = self.builder.getRefType(val); const store_val = if (val_ty != r.ty and val_ty != .void and r.ty != .void) diff --git a/src/ir/program_index.test.zig b/src/ir/program_index.test.zig index 1ca8971..879119f 100644 --- a/src/ir/program_index.test.zig +++ b/src/ir/program_index.test.zig @@ -392,7 +392,7 @@ test "moduleConstInt gates the fold on the declared type, not the initializer no // An `int_literal` value node folds to an integer ONLY when the declared // type is numeric. A `string`/`bool`-typed const carrying an integer-looking - // initializer must never be folded into a count (issue 0088): the count path + // initializer must never be folded into a count: the count path // consults `ModuleConstInfo.ty`, not just the node shape. var int_val = nLit(4); try map.put("OK", .{ .value = &int_val, .ty = .s64 }); @@ -405,8 +405,8 @@ test "moduleConstInt gates the fold on the declared type, not the initializer no // The same gate holds for a const-EXPRESSION value node (`M + 2`), not just // a bare literal: a `string`-typed const whose initializer is a foldable - // integer expression must still never fold as a count (issue 0088 attempt 2 — - // the const-expression leak). `KEXPR : s64 : M + 2` (numeric type) folds; the + // integer expression must still never fold as a count (the + // const-expression leak). `KEXPR : s64 : M + 2` (numeric type) folds; the // same expression declared `string` does not. var m_lit = nLit(2); var add2 = nLit(2); @@ -471,7 +471,7 @@ test "evalConstFloatExpr folds comptime float expressions, halts on runtime leav // an expression like `F + 0.25` (= 2.75) is now recognised as a compile-time // float and rejected by the narrowing rule instead of silently truncating; // `F + 1.5` (= 4.0) is integral and folds. This completes the evaluator for - // float-const-leaf expressions (issue 0095, attempt 3). + // float-const-leaf expressions. var f = nIdent("F"); var quarter = nFloat(0.25); var three_half = nFloat(1.5); @@ -486,7 +486,7 @@ test "evalConstFloatExpr folds comptime float expressions, halts on runtime leav // `type_resolver.floatLimitFor`. It folds as a direct leaf AND inside an // expression: `f64.max - f64.max` = 0.0 (integral → folds), `f64.true_min + // 0.5` = 0.5 (non-integral → the narrowing rule rejects it). A non-limit - // field on a float type is not a leaf → null (issue 0095, attempt 5 parity). + // field on a float type is not a leaf → null. var f64ty = nIdent("f64"); var f32ty = nIdent("f32"); var fmax = nField(&f64ty, "max"); @@ -542,7 +542,7 @@ test "a backtick raw-shadow receiver is a field read, not a numeric-limit fold ( // field access is an ordinary runtime field READ, so it is NOT a compile-time // leaf in either evaluator (→ null), exactly as the sibling `isFloatValuedExpr` // already treats it. The whole point: a value-shadow can never be misread as - // the builtin limit (issue 0095 / F0.11-7). + // the builtin limit. var f64raw = nIdentRaw("f64"); var s8raw = nIdentRaw("s8"); var raw_feps = nField(&f64raw, "epsilon"); @@ -594,7 +594,7 @@ test "foldCountI64 / foldDimU32 fold an integral float count, reject a non-integ try std.testing.expectEqual(pi.DimU32{ .below_min = -4 }, pi.foldDimU32(&negf, ctx, 0)); } -test "the int folder refuses a FLOAT division (issue 0095 / F0.11-6)" { +test "the int folder refuses a FLOAT division" { const eval = pi.evalConstIntExpr; const ctx = DimCtx{}; // K : f64 : 4.0 (integral float const), M = 4 (int const) diff --git a/src/ir/program_index.zig b/src/ir/program_index.zig index a5efd7e..e56f6c3 100644 --- a/src/ir/program_index.zig +++ b/src/ir/program_index.zig @@ -146,7 +146,7 @@ pub fn isFloatConstType(ty: TypeId) bool { /// division apart from an integer one even when both operands fold to integers /// (`K / 3`, `ME / 3`). `frame` cycle-guards a const whose value references /// another const; a name already on the chain has no compile-time value → not -/// float-valued (issue 0095 / F0.11-6). +/// float-valued. fn moduleConstFloatValuedFramed(consts: *const std.StringHashMap(ModuleConstInfo), table: *const types.TypeTable, name: []const u8, parent: ?*const ModuleConstFrame) bool { if (moduleConstFrameContains(parent, name)) return false; const ci = consts.get(name) orelse return false; @@ -160,7 +160,7 @@ fn moduleConstFloatValuedFramed(consts: *const std.StringHashMap(ModuleConstInfo /// int via `floatToIntExact`). `moduleConstIntFramed` consults this so a count /// is gated on `ModuleConstInfo.ty`, not just the shape of the initializer node: /// a `string`/`bool`/pointer/struct-typed const can never be folded into a count -/// off an integer-looking initializer (issue 0088 — the second symptom, where +/// off an integer-looking initializer (the second symptom, where /// `N : string : 4` folded `[N]s64` to 4 by reading the `int_literal` node and /// ignoring the `string` annotation). pub fn isCountableConstType(table: *const types.TypeTable, ty: TypeId) bool { @@ -187,7 +187,7 @@ fn moduleConstIntFramed(consts: *const std.StringHashMap(ModuleConstInfo), table /// registration-time path (`type_bridge.StatelessInner`). They must agree on /// which named consts a `[N]T` dimension resolves to; if they diverge, an array /// laid out via a type alias (`Arr :: [N]T`, stateless) gets a different length -/// than the direct form (`a : [N]T`, stateful) — the issue-0083 miscompile. +/// than the direct form (`a : [N]T`, stateful) — that miscompile class. /// Every const's RHS is folded through the shared `evalConstIntExpr`, so an /// untyped (`N :: 16`) / typed (`N : s64 : 16`) literal, an integral float /// (`N : f64 : 4.0` → 4, via `floatToIntExact`; `4.5` → null), AND an expression @@ -225,7 +225,7 @@ pub fn moduleConstFloat(consts: *const std.StringHashMap(ModuleConstInfo), table /// (`ME :: 4.0 + 1.0`, whose placeholder type is `s64`), and a non-integral float /// const (`F : f64 : 2.5`). SINGLE source for the stateful (`Lowering`) and /// stateless (`type_bridge`) division-arm float checks, so they agree on which -/// const-leaf divisions are float (issue 0095 / F0.11-6). +/// const-leaf divisions are float. pub fn moduleConstIsFloatTyped(consts: *const std.StringHashMap(ModuleConstInfo), table: *const types.TypeTable, name: []const u8) bool { return moduleConstFloatValuedFramed(consts, table, name, null); } @@ -235,8 +235,8 @@ pub fn moduleConstIsFloatTyped(consts: *const std.StringHashMap(ModuleConstInfo) /// numeric-limit (`f64.max`), or arithmetic over any of those. THE predicate the /// int folder's division arm consults: `/` with a float operand is FLOAT division /// (`5.0 / 2.0` = 2.5), and folding it with integer truncating division would -/// silently accept a non-integral float at a count / typed binding (issue 0095 / -/// F0.11-6). `+ - *` agree between int and float arithmetic for the integral +/// silently accept a non-integral float at a count / typed binding. +/// `+ - *` agree between int and float arithmetic for the integral /// operands the int folder ever sees (a non-integral operand folds to null first), /// so ONLY `/` needs this guard. A leaf name resolves through `ctx.nameIsFloatTyped` /// — the same ctx that supplies `lookupDimName`/`lookupFloatName` — so an INTEGRAL @@ -257,8 +257,7 @@ pub fn isFloatValuedExpr(node: *const Node, ctx: anytype) bool { .field_access => |fa| blk: { // A backtick RAW receiver (`` `f64.epsilon ``) is an ordinary field // READ on a value whose spelling shadows a builtin type, NOT the - // numeric-limit accessor — so it is not a float leaf (issues 0092 / - // 0093). Only a BARE type receiver folds to a float limit. + // numeric-limit accessor — so it is not a float leaf. Only a BARE type receiver folds to a float limit. const obj_name: ?[]const u8 = switch (fa.object.data) { .identifier => |id| if (id.is_raw) null else id.name, .type_expr => |te| if (te.is_raw) null else te.name, @@ -279,7 +278,7 @@ pub fn isFloatValuedExpr(node: *const Node, ctx: anytype) bool { /// integer-expression folder for the compiler — array dimensions (`[N]T`, /// `[M + 1]T`), Vector lane counts (`Vector(N, f32)`), generic value-param /// args (`Vec(N, f32)`), and `inline for 0..M` bounds all route here so they -/// cannot disagree on what a given expression evaluates to (the issue-0083 +/// cannot disagree on what a given expression evaluates to (the /// two-resolver class of bug). Folds integer `+ - * / %` and unary negate over /// int literals, integral float literals (`[4.0]T` → 4, via `floatToIntExact`), /// and named module / comptime consts — recursively, so nested and parenthesised @@ -290,7 +289,7 @@ pub fn isFloatValuedExpr(node: *const Node, ctx: anytype) bool { /// lhs/rhs is float-valued (`5.0 / 2.0`, `K / 3` with `K : f64 : 4.0`) is FLOAT /// division, NOT integer truncation, so this folder refuses it (`isFloatValuedExpr`) /// and lets `evalConstFloatExpr` + the unified narrowing rule see the true value -/// (issue 0095 / F0.11-6). `+ - *` need no such guard — they agree between int and +///. `+ - *` need no such guard — they agree between int and /// float arithmetic for the integral operands this folder ever sees. /// /// Leaves resolve through the ctx, so each call site shares the SAME folding @@ -319,7 +318,7 @@ pub fn evalConstIntExpr(node: *const Node, ctx: anytype) ?i64 { // ordinary field READ on a value whose spelling shadows a builtin // type name, NOT a numeric-limit / pack-arity accessor — so it is // never a compile-time leaf here; its field is a runtime value - // (issues 0092/0093, F0.11-7). Only a BARE type/name receiver folds a + //. Only a BARE type/name receiver folds a // `.len` / `.min`/`.max`. Mirrors the same `is_raw` // guard `isFloatValuedExpr` already applies, so the const cluster // (this folder, `evalConstFloatExpr`, `isFloatValuedExpr`) agrees. @@ -360,7 +359,7 @@ pub fn evalConstIntExpr(node: *const Node, ctx: anytype) ?i64 { // truncating division — refuse to fold it here so the value // surfaces through `evalConstFloatExpr` + the unified float→int // rule (integral folds, non-integral errors) instead of silently - // truncating to an integer (issue 0095 / F0.11-6). A genuine + // truncating to an integer. A genuine // integer `/` (both operands integer-valued) still truncates. .div => if (isFloatValuedExpr(b.lhs, ctx) or isFloatValuedExpr(b.rhs, ctx)) null @@ -425,7 +424,7 @@ pub fn evalConstFloatExpr(node: *const Node, ctx: anytype) ?f64 { // A backtick RAW receiver (`` `f64.epsilon ``) is an ordinary field // READ on a value that shadows a builtin float type name, NOT the // numeric-limit accessor — its field is a runtime value, never a - // compile-time leaf (issues 0092/0093, F0.11-7). Mirrors the `is_raw` + // compile-time leaf. Mirrors the `is_raw` // guard `isFloatValuedExpr` already applies; only a BARE type receiver // folds a float limit. const obj_name: ?[]const u8 = switch (fa.object.data) { @@ -465,10 +464,10 @@ pub fn evalConstFloatExpr(node: *const Node, ctx: anytype) ?f64 { } /// The outcome of folding a compile-time COUNT expression to an `i64` under the -/// unified float→int narrowing rule (F0.11 / issue 0095). THE single int-or- +/// unified float→int narrowing rule. THE single int-or- /// integral-float count fold: `foldDimU32` (array dim / Vector lane / u32 value- /// param) and the non-`u32` value-param gate both route through `foldCountI64`, -/// so no count site can disagree on which floats fold (the issue-0083 unify-or- +/// so no count site can disagree on which floats fold (the unify-or- /// diverge rule extended to floats). pub const CountFold = union(enum) { /// An integer expression, or an INTEGRAL compile-time float (`[F + 1.5]` → 4). @@ -500,7 +499,7 @@ pub fn foldCountI64(node: *const Node, ctx: anytype) CountFold { /// SINGLE place a folded integer becomes a `u32`, so the i64→u32 narrowing is /// range-checked exactly once and no call site does a bare `@intCast` that could /// panic the compiler on a valid-but-oversized fold (a literal `5_000_000_000` -/// is a valid `i64` yet `> maxInt(u32)` — issue 0087). Each call site maps a +/// is a valid `i64` yet `> maxInt(u32)`). Each call site maps a /// non-`.ok` variant onto its own clean diagnostic + `.unresolved` / abort. pub const DimU32 = union(enum) { /// Folded to a `u32` in `[min, maxInt(u32)]`. @@ -520,7 +519,7 @@ pub const DimU32 = union(enum) { /// integral-float fold), then range-check against `[min, maxInt(u32)]`. THE single /// fold-to-u32 for every array dimension, Vector lane, and value-param count — /// routing all of them here guarantees the narrowing is checked once and can never -/// abort the compiler (issue 0087). The fold itself stays in `i64`; only this one +/// abort the compiler. The fold itself stays in `i64`; only this one /// conversion is the `u32` gate. pub fn foldDimU32(node: *const Node, ctx: anytype, min: u32) DimU32 { const v = switch (foldCountI64(node, ctx)) { @@ -539,7 +538,7 @@ pub fn foldDimU32(node: *const Node, ctx: anytype, min: u32) DimU32 { /// `type_bridge.foldArrayDim`) — emit through here, so an oversized / negative / /// non-const dimension reports the SAME message regardless of whether it was /// written directly (`a : [N]T`) or via a type alias (`Arr :: [N]T`). Folding -/// the wording into one place is the diagnostic-accuracy half of the issue-0083 +/// the wording into one place is the diagnostic-accuracy half of the /// unify-or-diverge story: `foldDimU32` is the single fold, this is the single /// message map. Only call with a non-`.ok` result (the `.ok` arm is a no-op). pub fn reportDimError(diag: *errors.DiagnosticList, span: ?ast.Span, result: DimU32) void { @@ -593,8 +592,8 @@ pub const GlobalInfo = struct { id: inst.GlobalId, ty: TypeId }; /// read-only views and are never freed here. /// /// Every owned map allocates through the compilation allocator passed to -/// `init` (arena-backed in both the driver and the tests — KB-9 removed the -/// old `page_allocator` field defaults). Written only by the +/// `init` (arena-backed in both the driver and the tests; +/// no `page_allocator` field defaults). Written only by the /// declaration scan / registration code in `Lowering`; read everywhere else. pub const ProgramIndex = struct { /// The lowering/compilation allocator (`module.alloc`), retained so the @@ -612,7 +611,7 @@ pub const ProgramIndex = struct { import_graph: ?*std.StringHashMap(std.StringHashMap(void)) = null, /// Module path → set of directly FLAT-imported paths — the subset of /// `import_graph` edges from a bare `#import` (never a namespaced - /// `ns :: #import`). fix-0102c's bare-name disambiguation walks this to + /// `ns :: #import`). The bare-name disambiguation walks this to /// decide which same-name authors a flat importer can reach. Borrowed view. flat_import_graph: ?*std.StringHashMap(std.StringHashMap(void)) = null, /// Per-module scalar raw-decl index (`path → name → RawDeclRef`), built by @@ -636,7 +635,7 @@ pub const ProgramIndex = struct { /// null-FuncId `lowerFunction` path with no `Function.source_file` to /// restore. This carries the alias's OWN module source so its body lowers /// in the right visibility context — its intra-module / own-import callees - /// resolve (issue 0100 F1). Keyed/allocated with the lowering allocator. + /// resolve. Keyed/allocated with the lowering allocator. qualified_fn_source: std.StringHashMap([]const u8), /// sx alias → ForeignClassDecl (jni_class / objc_class / swift_class / ... — registered in scan pass). foreign_class_map: std.StringHashMap(*const ast.ForeignClassDecl), diff --git a/src/ir/semantic_diagnostics.zig b/src/ir/semantic_diagnostics.zig index 78805bf..6cc9f0f 100644 --- a/src/ir/semantic_diagnostics.zig +++ b/src/ir/semantic_diagnostics.zig @@ -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 diff --git a/src/ir/type_bridge.zig b/src/ir/type_bridge.zig index 5631c27..23cf998 100644 --- a/src/ir/type_bridge.zig +++ b/src/ir/type_bridge.zig @@ -24,7 +24,7 @@ pub const AliasMap = ?*const std.StringHashMap(TypeId); /// resolves to the same length as a literal dimension on EVERY registration-time /// path — type aliases (`Arr :: [N]T`), inline union/enum field types — not just /// the stateful body-lowering path. Without it the stateless dim resolver had no -/// way to evaluate a named const and silently fabricated a 0 length (issue 0083). +/// way to evaluate a named const and silently fabricated a 0 length. /// `null` for contexts with no const table (e.g. unit tests). pub const ConstMap = ?*const std.StringHashMap(ModuleConstInfo); @@ -48,7 +48,7 @@ const StatelessInner = struct { /// so a dimension resolves to one length on every registration-time path /// (aliases, inline union/enum fields) and matches the direct form (issue /// 0083), and an oversized-but-valid `i64` dim returns null instead of - /// panicking the `@intCast` (issue 0087). Returns null when the dimension + /// panicking the `@intCast`. Returns null when the dimension /// isn't a compile-time integer (a runtime value / non-comptime call, or a /// name not bound to an integer const), is negative, or doesn't fit a `u32`. /// Null propagates to `resolveCompound`, which yields the `.unresolved` @@ -65,7 +65,7 @@ const StatelessInner = struct { /// to a module-global integer constant → its value. Shares /// `program_index.moduleConstInt` with the stateful body-lowering resolver so /// the two paths cannot disagree on which named consts a dimension resolves - /// to (issue 0083). The non-negative check is applied once, on the final + /// to. The non-negative check is applied once, on the final /// dimension value in `resolveArrayLen` — not here, so an intermediate /// operand may legitimately be negative. pub fn lookupDimName(self: StatelessInner, name: []const u8) ?i64 { @@ -84,7 +84,7 @@ const StatelessInner = struct { /// the stateful body-lowering path uses, so a float-const-leaf dimension /// (`Arr :: [F + 1.5]T`, `F : f64 : 2.5` → len 4) folds to the SAME count on /// the registration-time alias path as on the direct form `a : [F + 1.5]T` - /// (issue 0083 unify-or-diverge). Integer / integral-float leaves are already + /// (unify-or-diverge). Integer / integral-float leaves are already /// resolved by the `evalConstIntExpr` delegation inside `evalConstFloatExpr`; /// this surfaces a non-integral float const so the unified rule rejects it. pub fn lookupFloatName(self: StatelessInner, name: []const u8) ?f64 { @@ -95,7 +95,7 @@ const StatelessInner = struct { /// of `Lowering.nameIsFloatTyped`, routed through the SAME /// `program_index.moduleConstIsFloatTyped` so the int folder's division arm /// classifies a const-leaf division identically on the alias-registration path - /// as on the direct form (issue 0095 / F0.11-6, the issue-0083 unify-or-diverge + /// as on the direct form (the unify-or-diverge /// rule extended to the division guard). pub fn nameIsFloatTyped(self: StatelessInner, name: []const u8) bool { const consts = self.consts orelse return false; @@ -109,8 +109,8 @@ const StatelessInner = struct { /// alias-registration site calls this so an unresolved `Arr :: [N]T` alias can /// emit the PRECISE dim diagnostic (oversized `[5_000_000_000]` / negative / /// non-const) that matches the stateful direct form, rather than one generic -/// "not a compile-time integer constant" message for every failure (issue 0083 — -/// the stateful/stateless diagnostic divergence). +/// "not a compile-time integer constant" message for every failure (the +/// stateful/stateless diagnostic divergence). pub fn foldArrayDim(len_node: *const Node, table: *TypeTable, alias_map: AliasMap, consts: ConstMap) program_index_mod.DimU32 { const si = StatelessInner{ .table = table, .alias_map = alias_map, .consts = consts }; return program_index_mod.foldDimU32(len_node, si, 0); @@ -196,7 +196,7 @@ pub fn resolveAstType(node: ?*const Node, table: *TypeTable, alias_map: AliasMap /// Resolve a bare type name. The algorithm lives in `type_resolver.zig` /// (`TypeResolver.resolveNamed`, the single source); `type_bridge` forwards the /// caller-threaded `alias_map` (the single-source `ProgramIndex.type_alias_map`). -/// `skip_builtin` carries the backtick raw escape (issue 0089). +/// `skip_builtin` carries the backtick raw escape. fn resolveTypeName(name: []const u8, table: *TypeTable, alias_map: AliasMap, skip_builtin: bool) TypeId { return type_resolver.TypeResolver.resolveNamed(name, table, alias_map, skip_builtin); } @@ -251,7 +251,7 @@ fn resolveTupleSpreadShape(tt: *const ast.TupleTypeExpr, table: *TypeTable, alia // every element is itself a type expression. A non-type element (e.g. the `1` // in `(s32, 1)`) means this literal is NOT a type: refuse to fabricate a tuple // and return the `.unresolved` sentinel (never `.s64`, which would silently lie -// about the size — issue 0067). type_bridge is stateless and has no diagnostics; +// about the size). type_bridge is stateless and has no diagnostics; // the user-facing diagnostic is emitted by the stateful caller // (`Lowering.resolveTupleLiteralTypeArg`), which validates before delegating // here, so the valid path below builds the tuple and the invalid path never @@ -317,7 +317,7 @@ fn resolveParameterizedType(pt: *const ast.ParameterizedTypeExpr, table: *TypeTa // The lane count is a literal or a named module-const integer — the // same dimension forms a fixed array accepts. An unresolvable count // is NOT a 0-lane vector (which would silently mis-size every load / - // store); yield `.unresolved` so the failure surfaces (issue 0083). + // store); yield `.unresolved` so the failure surfaces. const si = StatelessInner{ .table = table, .alias_map = alias_map, .consts = consts }; const length = si.resolveArrayLen(pt.args[0]) orelse return .unresolved; const elem = resolveAstType(pt.args[1], table, alias_map, consts); diff --git a/src/ir/type_resolver.zig b/src/ir/type_resolver.zig index 56fc60c..e8fcf2e 100644 --- a/src/ir/type_resolver.zig +++ b/src/ir/type_resolver.zig @@ -72,7 +72,7 @@ pub const TypeResolver = struct { /// null. THE single width parser — `resolveBuiltinName` (to intern the /// `TypeId`) and the numeric-limit accessors (`.min`/`.max`, via /// `integerWidthSign`) both classify through here, so the recognized width - /// set cannot diverge (the issue-0083 two-resolver defect class). + /// set cannot diverge (the two-resolver defect class). pub const WidthInt = struct { width: u8, signed: bool }; pub fn parseWidthInt(name: []const u8) ?WidthInt { if (name.len < 2) return null; @@ -211,7 +211,7 @@ pub const TypeResolver = struct { // produce the same length. `resolveArrayLen` returns null when the // dimension can't be resolved to a compile-time integer; that is // never a 0-length array (which gives a 0-byte alloca and OOB - // element access — issue 0083). Yield the `.unresolved` sentinel + // element access). Yield the `.unresolved` sentinel // instead, so the failure halts the build (the stateful resolver // also emits a diagnostic; the registration-time caller surfaces // the unresolved alias) rather than silently miscompiling. @@ -289,7 +289,7 @@ pub const TypeResolver = struct { /// unregistered names. /// /// `skip_builtin` is the backtick raw-identifier escape (`` `s2 `` in type - /// position, issue 0089): a raw reference is the LITERAL name used as a + /// position): a raw reference is the LITERAL name used as a /// type, so it bypasses the builtin/reserved classifier and resolves only /// through registered-type → alias → stub. A bare `s2` keeps the default /// (`false`) and resolves to the builtin int type. The string-prefix @@ -334,7 +334,7 @@ pub const TypeResolver = struct { /// Resolve a bare type name through the canonical alias source /// (`ProgramIndex.type_alias_map`). `skip_builtin` carries the backtick raw - /// escape (issue 0089) — see `resolveNamed`. + /// escape — see `resolveNamed`. pub fn resolveName(self: TypeResolver, name: []const u8, skip_builtin: bool) TypeId { return resolveNamed(name, self.types, &self.index.type_alias_map, skip_builtin); } diff --git a/src/lsp/corpus_sweep.test.zig b/src/lsp/corpus_sweep.test.zig index 22dd784..ffd9fb8 100644 --- a/src/lsp/corpus_sweep.test.zig +++ b/src/lsp/corpus_sweep.test.zig @@ -8,7 +8,7 @@ const doc_mod = @import("document.zig"); // issue corpora, in process. The contract is simply: analysis must complete // without a panic/abort for any file. A panic aborts the whole test binary — // that is the loud CI signal that some new AST node shape crashes the analyzer -// (the bug class issue 0099 fixed at `sema.zig`'s `resolveTypeNode`). Files +// (the bug class fixed at `sema.zig`'s `resolveTypeNode`). Files // that merely fail to parse or sema cleanly are fine: `analyzeDocument` records // a null index and returns, which counts as a clean (non-crashing) outcome. // diff --git a/src/lsp/document.test.zig b/src/lsp/document.test.zig index 188b151..c24090c 100644 --- a/src/lsp/document.test.zig +++ b/src/lsp/document.test.zig @@ -5,7 +5,7 @@ const sx = struct { }; const doc_mod = @import("document.zig"); -// Minimal LSP test harness (issue 0099): drive the editor analyzer through the +// Minimal LSP test harness: drive the editor analyzer through the // real didOpen path (`DocumentStore.analyzeDocument`) and inspect the resulting // editor index. This is the FIRST `src/lsp/*.test.zig`; it is pulled into the // `zig build test` graph via the `_ = lsp.document;` reference in `src/root.zig` diff --git a/src/parser.zig b/src/parser.zig index 2450f49..5898e58 100644 --- a/src/parser.zig +++ b/src/parser.zig @@ -637,7 +637,7 @@ pub const Parser = struct { // bare name (so `` `s2(s64) ``, `` `s2.Inner ``, `` *`s2 `` all // parse); it is threaded onto the final `type_expr` / // `parameterized_type_expr` so resolution skips the builtin - // classifier and looks up a `` `s2 ``-declared type (issue 0089). + // classifier and looks up a `` `s2 ``-declared type. const atom_is_raw = self.current.is_raw; var name = self.tokenSlice(self.current); self.advance(); @@ -2738,7 +2738,7 @@ pub const Parser = struct { const is_raw = self.current.is_raw; // A backtick raw identifier (`` `s2 ``) is NEVER type-classified — // it is always a value identifier, bypassing the reserved-type-name - // rule (issue 0089). Only a bare spelling is checked for a type name + // rule. Only a bare spelling is checked for a type name // (e.g. s32, u8, s128). if (!is_raw and Type.fromName(name) != null) { self.advance(); diff --git a/src/sema.test.zig b/src/sema.test.zig index 150bac5..a4b9be9 100644 --- a/src/sema.test.zig +++ b/src/sema.test.zig @@ -11,11 +11,11 @@ const sema = @import("sema.zig"); const types = @import("types.zig"); const Type = types.Type; -// issue 0089 — the backtick raw escape must hold in BOTH classifiers. A raw +// the backtick raw escape must hold in BOTH classifiers. A raw // reserved-name type reference (`` `s2 ``) resolves to the user-declared type, // while a BARE `s2` stays the builtin int. Before the fix sema's // `resolveTypeNode` ran `Type.fromName` first and ignored `is_raw`, so the -// editor index would show the builtin for backtick code (the issue-0083 +// editor index would show the builtin for backtick code (the // two-resolver divergence applied to raw types). test "sema: backtick raw type reference resolves to the user type; bare stays builtin" { var arena = std.heap.ArenaAllocator.init(std.testing.allocator); @@ -85,7 +85,7 @@ test "sema: a raw struct-field annotation resolves to the user type; bare stays try std.testing.expectEqual(@as(u8, 8), b_ty.?.unsigned); } -// ── issue 0089: raw provenance through sema's COMPOUND type metadata ──────── +// ── raw provenance through sema's COMPOUND type metadata ──────── // // The direct-case fix (above) only covered a bare `` `s2 `` reference. A // COMPOUND raw type (`*`s2`, `?`s2`, `[N]`s2`, …) stores its inner name as a diff --git a/src/sema.zig b/src/sema.zig index a081f4e..90c599a 100644 --- a/src/sema.zig +++ b/src/sema.zig @@ -117,7 +117,7 @@ pub const Analyzer = struct { /// Module-global integer consts, by bare name → value. Lets an array /// dimension written as a named const (`MAX :: 4; [MAX]u8`) fold to a /// concrete editor length instead of panicking on the `.int_literal` - /// union access (issue 0099). Populated at registration time, so it shares + /// union access. Populated at registration time, so it shares /// the analyzer's existing intra-pass forward-reference limitation (a const /// declared after the struct that uses it resolves to "unknown" length). const_int_values: std.StringHashMap(i64), @@ -226,7 +226,7 @@ pub const Analyzer = struct { const kind = classifyConstDecl(cd); try self.addSymbol(cd.name, kind, ty, node.span); // Record integer-literal consts so a named array dimension - // (`MAX :: 4; [MAX]u8`) can fold to a concrete length (issue 0099). + // (`MAX :: 4; [MAX]u8`) can fold to a concrete length. if (cd.value.data == .int_literal) { try self.const_int_values.put(cd.name, cd.value.data.int_literal.value); } @@ -370,7 +370,7 @@ pub const Analyzer = struct { /// Fold an array dimension node to a concrete editor length, or null /// ("unknown") when it isn't a compile-time integer this index can resolve. /// Metadata-only — NEVER panic on an unexpected node shape and never - /// fabricate a misleading concrete length (issue 0099). A literal dim is + /// fabricate a misleading concrete length. A literal dim is /// taken directly; a bare identifier naming an integer const folds to its /// recorded value; anything else (unknown name, non-const expression, /// out-of-`u32`-range value) is unknown. @@ -448,7 +448,7 @@ pub const Analyzer = struct { } // type_expr or identifier — check aliases, enums, structs. A raw // reference (`` `s2 ``) skips the builtin classifier and resolves - // through user-defined types only (issue 0089). + // through user-defined types only. if (tn.data == .type_expr or tn.data == .identifier) { const name = if (tn.data == .type_expr) tn.data.type_expr.name else tn.data.identifier.name; const is_raw = if (tn.data == .type_expr) tn.data.type_expr.is_raw else tn.data.identifier.is_raw; @@ -470,7 +470,7 @@ pub const Analyzer = struct { /// Resolve a bare type-name string against the registry (aliases, enums, /// structs), falling back to primitive spellings. Unlike `Type.fromName`, /// this knows user-defined types; returns `unresolved` when it can't place - /// the name. `skip_builtin` is the backtick raw escape (issue 0089) — a raw + /// the name. `skip_builtin` is the backtick raw escape — a raw /// reference (`` `s2 ``) bypasses the builtin/reserved classifier and /// resolves only through user-defined types, mirroring the codegen-side /// `TypeResolver.resolveNamed`. Inner names of compound shapes @@ -503,7 +503,7 @@ pub const Analyzer = struct { /// The backtick raw bit of an inner type-name node (`` `s2 ``). A compound /// shape (`*T`, `?T`, `[]T`, …) stores its inner name as a bare string, so - /// this bit must travel ALONGSIDE that name (issue 0089) — otherwise the + /// this bit must travel ALONGSIDE that name — otherwise the /// resolver re-reads `s2` as the builtin int. Non-leaf nodes are never raw. fn typeExprIsRaw(node: *Node) bool { return switch (node.data) { diff --git a/src/types.zig b/src/types.zig index 5120671..6b34f2a 100644 --- a/src/types.zig +++ b/src/types.zig @@ -45,7 +45,7 @@ pub const Type = union(enum) { /// `is_raw` records whether the inner type-name came from a backtick raw /// reference (`` `s2 ``) or an already-resolved user type. It is the /// `skip_builtin` the resolver MUST pass when re-resolving the stored inner - /// name (issue 0089) — without it `resolveTypeNameStr` would reclassify a + /// name — without it `resolveTypeNameStr` would reclassify a /// user type named `s2` as the builtin int, diverging from codegen. The /// field is REQUIRED (no default) so a future construction site cannot /// silently drop the bit, the way the LSP index did for compound shapes. @@ -79,7 +79,7 @@ pub const Type = union(enum) { /// null = the dimension could not be folded to a compile-time integer /// by the editor index (an identifier const it couldn't resolve, or a /// non-const expression). Explicit "unknown" rather than a fabricated - /// concrete length — this is hover/metadata, not codegen (issue 0099). + /// concrete length — this is hover/metadata, not codegen. length: ?u32, is_raw: bool, }; @@ -216,7 +216,7 @@ pub const Type = union(enum) { if (node.data != .type_expr) return null; // A backtick raw type reference (`` `s2 ``) is the LITERAL name used as // a type — it must skip this builtin/reserved classifier and resolve - // through user-defined types only (issue 0089), mirroring the codegen- + // through user-defined types only, mirroring the codegen- // side `resolveNamed`'s `skip_builtin`. Returning null lets the sema // callers fall through to their struct/enum/alias registry lookup. if (node.data.type_expr.is_raw) return null;