fix: diagnose ?(?T) tuple-payload mismatch instead of malformed IR (issue 0165)
In type position (T) is a 1-tuple (specs.md:843), so ?(?i64) is optional(tuple(?i64)); assigning a bare ?i64 had coerceToType classify .none and pass the value through, then optionalWrap built a corrupt insertvalue that aborted the LLVM verifier. After coercing toward an optional's child, verify the coerced type equals the child type (stmt.zig decl-init + coerce.zig .optional_wrap); on mismatch emit a located diagnostic (tuple-specific note only when the child is a tuple). formatTypeName now renders tuples as (x: i64, y: i64). Regressions: optionals/0911 (nested optional via alias, round-trip), diagnostics/1195 (the mismatch diagnostic). Updated diagnostics/1101 + protocols/0414 goldens for the improved tuple type-name rendering. Verified by 3 adversarial reviews. Filed adjacent bug 0171 (?any child not canonicalized).
This commit is contained in:
@@ -556,6 +556,23 @@ pub fn formatTypeName(self: *Lowering, ty: TypeId) []const u8 {
|
||||
const inner = self.formatTypeName(v.element);
|
||||
break :blk std.fmt.allocPrint(self.alloc, "Vector({d},{s})", .{ v.length, inner }) catch "vector";
|
||||
},
|
||||
.tuple => |t| blk: {
|
||||
var buf = std.ArrayList(u8).empty;
|
||||
buf.append(self.alloc, '(') catch break :blk "tuple";
|
||||
for (t.fields, 0..) |f, i| {
|
||||
if (i > 0) buf.appendSlice(self.alloc, ", ") catch break :blk "tuple";
|
||||
// Render the field name for named tuples: `(x: i64, y: i64)`.
|
||||
if (t.names) |ns| {
|
||||
if (i < ns.len) {
|
||||
buf.appendSlice(self.alloc, self.module.types.getString(ns[i])) catch break :blk "tuple";
|
||||
buf.appendSlice(self.alloc, ": ") catch break :blk "tuple";
|
||||
}
|
||||
}
|
||||
buf.appendSlice(self.alloc, self.formatTypeName(f)) catch break :blk "tuple";
|
||||
}
|
||||
buf.append(self.alloc, ')') catch break :blk "tuple";
|
||||
break :blk buf.toOwnedSlice(self.alloc) catch "tuple";
|
||||
},
|
||||
else => @tagName(info),
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user