fix(0057): clear target_type when lowering variadic pack args
An `xx <int>` argument to a variadic `format`/`print` (a comptime `..$args`
pack) segfaulted when the call was inside an imported-module function. Root
cause: lowerPackCall lowered each pack arg with whatever self.target_type was
set to from the surrounding context. A bare arg is unaffected (inferExprType
ignores target_type), but `xx <expr>`'s result type IS target_type — so
`format("…", xx i)` inside a `-> string` fn cast the int to `string`,
monomorphized __pack_string, and ABI-coerced the 4-byte int as a 16-byte string
fat pointer → corruption. Inline it worked only because target_type was null
there; the imported-module path left it set.
Fix: save/clear/restore self.target_type around the pack-arg lowering loop. A
pack arg is independently typed — comptime `..$args` auto-boxes to Any; a value
pack takes its declared element/protocol type — never a leftover outer target.
examples/242-xx-any-pack-cross-module.sx (+ companion fmt.sx) is the regression.
issues/0057 marked resolved. Unblocks ERR E3.3 (the trace.sx formatter formats
frames with `xx frame`).
Gates: zig build, zig build test, bash tests/run_examples.sh (279 passed; lone
failure is the user's uncommitted 213-canonical-map pack WIP).
This commit is contained in:
@@ -9591,6 +9591,16 @@ pub const Lowering = struct {
|
||||
// lambda arg types its params from the projected closure signature.
|
||||
// (A comptime `..$args` pack keeps `inferExprType` — its args may be
|
||||
// type-position.)
|
||||
// A pack arg is independently typed — it takes its natural type and
|
||||
// (for a comptime `..$args` pack) auto-boxes to `Any` at the call
|
||||
// boundary. It is NEVER coerced to a leftover outer `target_type`, so
|
||||
// clear it: otherwise an `xx <expr>` pack arg (whose result type IS
|
||||
// `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).
|
||||
const saved_pack_tt = self.target_type;
|
||||
self.target_type = null;
|
||||
var pack_refs = std.ArrayList(Ref).empty;
|
||||
defer pack_refs.deinit(self.alloc);
|
||||
for (call_node.args[pack_start..]) |a| {
|
||||
@@ -9603,6 +9613,7 @@ pub const Lowering = struct {
|
||||
pack_arg_types.append(self.alloc, self.builder.getRefType(r)) catch return self.builder.constInt(0, .void);
|
||||
}
|
||||
}
|
||||
self.target_type = saved_pack_tt;
|
||||
|
||||
// Install the pack's element types + constraint so prefix-arg param
|
||||
// types like `Closure(..sources.T)` resolve while lowering the prefix.
|
||||
|
||||
Reference in New Issue
Block a user