fix(KB-9): move Lowering/ProgramIndex maps off page_allocator defaults
16 Lowering map fields and 8 ProgramIndex map fields were declared with `= ....init(std.heap.page_allocator)` field defaults that init() never replaced — every instance really allocated page-at-a-time outside the compilation allocator, invisible to leak checking and never reclaimed. All 24 now init explicitly with the compilation allocator (module.alloc / the init alloc param), which is arena-backed in both the driver (main's arena) and the test suites (per-test arenas), so backing is reclaimed at teardown. ProgramIndex's struct doc no longer claims the page_allocator defaults. Six lower.test.zig tests that constructed Module with bare std.testing.allocator leaked once the checker could finally see these maps; they now use the same per-test ArenaAllocator idiom as the rest of the file and the facade test suites. Gate: zig build OK; zig build test 426/426 (6/6 steps, leak-clean); run_examples 541/0; zero expected/ snapshot churn.
This commit is contained in:
@@ -288,21 +288,21 @@ pub const Lowering = struct {
|
||||
/// visible ONLY within the source that declares it: an imported template's field
|
||||
/// resolution (run in the template's source context, E3 attempt-4) must NOT bind a
|
||||
/// name the CALLER declared block-local (E3 attempt-5).
|
||||
local_type_names: std.StringHashMap(std.StringHashMap(void)) = std.StringHashMap(std.StringHashMap(void)).init(std.heap.page_allocator),
|
||||
struct_defaults_map: std.StringHashMap([]const ?*const Node) = std.StringHashMap([]const ?*const Node).init(std.heap.page_allocator), // struct name → field defaults
|
||||
struct_instance_bindings: std.StringHashMap(std.StringHashMap(TypeId)) = std.StringHashMap(std.StringHashMap(TypeId)).init(std.heap.page_allocator), // mangled struct name → type param bindings
|
||||
struct_instance_template: std.StringHashMap([]const u8) = std.StringHashMap([]const u8).init(std.heap.page_allocator), // mangled struct name → template name
|
||||
struct_instance_author: std.StringHashMap(*const ast.StructDecl) = std.StringHashMap(*const ast.StructDecl).init(std.heap.page_allocator), // mangled struct name → authoring StructDecl (CP-2: body-author ≡ layout-author)
|
||||
local_type_names: std.StringHashMap(std.StringHashMap(void)),
|
||||
struct_defaults_map: std.StringHashMap([]const ?*const Node), // struct name → field defaults
|
||||
struct_instance_bindings: std.StringHashMap(std.StringHashMap(TypeId)), // mangled struct name → type param bindings
|
||||
struct_instance_template: std.StringHashMap([]const u8), // mangled struct name → template name
|
||||
struct_instance_author: std.StringHashMap(*const ast.StructDecl), // mangled struct name → authoring StructDecl (CP-2: body-author ≡ layout-author)
|
||||
comptime_value_bindings: ?std.StringHashMap(i64) = null, // comptime value bindings ($N → integer value)
|
||||
protocol_thunk_map: std.StringHashMap([]const FuncId) = std.StringHashMap([]const FuncId).init(std.heap.page_allocator), // "Proto\x00Type" → thunk FuncIds
|
||||
protocol_vtable_type_map: std.StringHashMap(TypeId) = std.StringHashMap(TypeId).init(std.heap.page_allocator), // protocol name → vtable struct TypeId
|
||||
protocol_vtable_global_map: std.StringHashMap(inst_mod.GlobalId) = std.StringHashMap(inst_mod.GlobalId).init(std.heap.page_allocator), // "Proto\x00Type" → vtable GlobalId
|
||||
param_impl_map: std.StringHashMap(std.ArrayList(ParamImplEntry)) = std.StringHashMap(std.ArrayList(ParamImplEntry)).init(std.heap.page_allocator), // "Proto\x00<arg_mangled>\x00<src_mangled>" → impl entries (parameterised protocols only; list lets Phase 4/5 detect cross-module overlap)
|
||||
protocol_thunk_map: std.StringHashMap([]const FuncId), // "Proto\x00Type" → thunk FuncIds
|
||||
protocol_vtable_type_map: std.StringHashMap(TypeId), // protocol name → vtable struct TypeId
|
||||
protocol_vtable_global_map: std.StringHashMap(inst_mod.GlobalId), // "Proto\x00Type" → vtable GlobalId
|
||||
param_impl_map: std.StringHashMap(std.ArrayList(ParamImplEntry)), // "Proto\x00<arg_mangled>\x00<src_mangled>" → impl entries (parameterised protocols only; list lets Phase 4/5 detect cross-module overlap)
|
||||
/// Pack-variadic impl entries — separate map keyed by `"Proto\x00<arg_mangled>"`
|
||||
/// (NO source suffix) so a single impl `Closure(..$args) -> $R` can be
|
||||
/// matched against many concrete source shapes. Concrete impls in
|
||||
/// `param_impl_map` win when both match (specificity rule).
|
||||
param_impl_pack_map: std.StringHashMap(std.ArrayList(PackParamImplEntry)) = std.StringHashMap(std.ArrayList(PackParamImplEntry)).init(std.heap.page_allocator),
|
||||
param_impl_pack_map: std.StringHashMap(std.ArrayList(PackParamImplEntry)),
|
||||
/// Active pack bindings during monomorphisation. Mirrors `type_bindings`
|
||||
/// but for variadic pack names: `args → [T1, T2, ...]`. Read by
|
||||
/// `resolveTypeWithBindings` on closure_type_expr to substitute
|
||||
@@ -346,26 +346,26 @@ pub const Lowering = struct {
|
||||
/// `xs[i].<m>` is rejected unless `<m>` is one of the protocol's methods.
|
||||
/// Null / absent for the comptime `..$args` pack (no constraint).
|
||||
pack_constraint: ?std.StringHashMap([]const u8) = null,
|
||||
struct_const_map: std.StringHashMap(StructConstInfo) = std.StringHashMap(StructConstInfo).init(std.heap.page_allocator), // "Struct.CONST" → value info
|
||||
foreign_name_map: std.StringHashMap([]const u8) = std.StringHashMap([]const u8).init(std.heap.page_allocator), // sx name → C name for #foreign renames
|
||||
struct_const_map: std.StringHashMap(StructConstInfo), // "Struct.CONST" → value info
|
||||
foreign_name_map: std.StringHashMap([]const u8), // sx name → C name for #foreign renames
|
||||
target_config: ?@import("../target.zig").TargetConfig = null, // compilation target (for inline if)
|
||||
comptime_constants: std.StringHashMap(ComptimeValue) = std.StringHashMap(ComptimeValue).init(std.heap.page_allocator), // compile-time known constants (e.g. OS, ARCH)
|
||||
comptime_constants: std.StringHashMap(ComptimeValue), // compile-time known constants (e.g. OS, ARCH)
|
||||
diagnostics: ?*errors.DiagnosticList = null, // error reporting with source locations
|
||||
xx_reentrancy: std.AutoHashMap(u64, void) = std.AutoHashMap(u64, void).init(std.heap.page_allocator), // (src_ty, dst_ty) pairs currently being resolved through user-space Into; prevents infinite monomorphisation when a convert body re-enters the same xx
|
||||
xx_reentrancy: std.AutoHashMap(u64, void), // (src_ty, dst_ty) pairs currently being resolved through user-space Into; prevents infinite monomorphisation when a convert body re-enters the same xx
|
||||
/// Whole-program-converged inferred error sets (ERR E1.4b): top-level
|
||||
/// bare-`!` function name → its sorted escape-tag ids (literal raises +
|
||||
/// pure-failable `try` edges, fix-pointed across the call graph). The
|
||||
/// shared `!` placeholder TypeId stays empty; this side map holds the real
|
||||
/// per-function sets (sidesteps the name-only error-set interning). Read by
|
||||
/// `lowerTry`'s named-caller widening and the empty-inferred warning.
|
||||
inferred_error_sets: std.StringHashMap([]const u32) = std.StringHashMap([]const u32).init(std.heap.page_allocator),
|
||||
inferred_error_sets: std.StringHashMap([]const u32),
|
||||
/// Whole-program-converged inferred error sets keyed by closure/function
|
||||
/// VALUE-signature shape (ERR E5.1 sub-feature 2): every occurrence of
|
||||
/// `Closure(<sig>) -> (T, !)` with a structurally identical value-signature
|
||||
/// shares one node; each bare-`!` closure literal of that shape unions its
|
||||
/// escape tags in. Read by `checkEscapeWidening` when a `try` operand is a
|
||||
/// closure/fn-type SLOT call (no static fn name). Key = `closureShapeKey`.
|
||||
shape_inferred_sets: std.StringHashMap([]const u32) = std.StringHashMap([]const u32).init(std.heap.page_allocator),
|
||||
shape_inferred_sets: std.StringHashMap([]const u32),
|
||||
|
||||
pub const ComptimeValue = union(enum) {
|
||||
int_val: i64,
|
||||
@@ -496,6 +496,22 @@ pub const Lowering = struct {
|
||||
.fn_decl_fids = std.AutoHashMap(*const ast.FnDecl, FuncId).init(module.alloc),
|
||||
.lowered_fids = std.AutoHashMap(FuncId, void).init(module.alloc),
|
||||
.nominal_name_authors = std.AutoHashMap(types.StringId, []const u8).init(module.alloc),
|
||||
.local_type_names = std.StringHashMap(std.StringHashMap(void)).init(module.alloc),
|
||||
.struct_defaults_map = std.StringHashMap([]const ?*const Node).init(module.alloc),
|
||||
.struct_instance_bindings = std.StringHashMap(std.StringHashMap(TypeId)).init(module.alloc),
|
||||
.struct_instance_template = std.StringHashMap([]const u8).init(module.alloc),
|
||||
.struct_instance_author = std.StringHashMap(*const ast.StructDecl).init(module.alloc),
|
||||
.protocol_thunk_map = std.StringHashMap([]const FuncId).init(module.alloc),
|
||||
.protocol_vtable_type_map = std.StringHashMap(TypeId).init(module.alloc),
|
||||
.protocol_vtable_global_map = std.StringHashMap(inst_mod.GlobalId).init(module.alloc),
|
||||
.param_impl_map = std.StringHashMap(std.ArrayList(ParamImplEntry)).init(module.alloc),
|
||||
.param_impl_pack_map = std.StringHashMap(std.ArrayList(PackParamImplEntry)).init(module.alloc),
|
||||
.struct_const_map = std.StringHashMap(StructConstInfo).init(module.alloc),
|
||||
.foreign_name_map = std.StringHashMap([]const u8).init(module.alloc),
|
||||
.comptime_constants = std.StringHashMap(ComptimeValue).init(module.alloc),
|
||||
.xx_reentrancy = std.AutoHashMap(u64, void).init(module.alloc),
|
||||
.inferred_error_sets = std.StringHashMap([]const u32).init(module.alloc),
|
||||
.shape_inferred_sets = std.StringHashMap([]const u32).init(module.alloc),
|
||||
.program_index = ProgramIndex.init(module.alloc),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user