ir: generalize type-alias resolution via TypeTable.aliases borrow
Previously, type aliases (`ShaderHandle :: u32`, `Vec4 ::
Vector(4, f32)`) were resolved at three explicit call sites:
- `resolveTypeWithBindings` fallthrough (lower.zig: was 10481-83)
- Protocol method param resolution (was 11154-61)
- Protocol method return resolution (was 11169-76)
Every other `type_bridge.resolveAstType` caller silently fell into
`resolveTypeName`'s "create empty struct stub" path at the bottom,
materialising the alias name as a fresh `{Name=}` struct instead of
its target type. Symptom: the IR call signature got `{}` parameters
where the user meant `u32` etc.
This pushes the alias check inside `resolveTypeName` itself. A new
`TypeTable.aliases: ?*const std.StringHashMap(TypeId)` borrow is
loaned at `lowerRoot` from the owning Lowering. `resolveTypeName`
consults it before falling through to the stub default. Every
caller of `resolveAstType` (and its recursive helpers — `*Alias`,
`[]Alias`, `?Alias`, etc.) now picks up the same resolution.
The three pre-check sites in lower.zig collapse:
- `resolveTypeWithBindings`: the trailing alias pre-check is gone;
the comment now points at the new path.
- Protocol method param: the `Self → *void` short-circuit stays;
the alias arm is gone — the fallthrough handles it.
- Protocol method return: same shape.
Tests:
- `type_bridge.test.zig` gains `resolveAstType: TypeTable.aliases
resolves named alias` pinning the new behaviour. Demonstrates:
(1) no alias set → unknown name becomes empty struct stub (the
silent-fail shape we're fixing); (2) alias set → resolves to the
alias target; (3) compound forms (`*Alias`) recurse into
`resolveTypeName` for the inner name and pick up the alias.
224/224 example tests pass; zig build test green.
This commit is contained in:
@@ -280,6 +280,12 @@ pub const Lowering = struct {
|
||||
/// Pass 1: Scan all declarations (register ASTs, types, extern stubs).
|
||||
/// Pass 2: Lower only `main` (everything else is lowered lazily on demand).
|
||||
pub fn lowerRoot(self: *Lowering, root: *const Node) void {
|
||||
// Loan our alias map to the TypeTable. Done here (not in
|
||||
// init) because `init` returns by value and `&self.type_alias_map`
|
||||
// wouldn't survive the return. `lowerRoot` runs on the
|
||||
// caller's stable Lowering, so the borrow stays valid for
|
||||
// every subsequent `resolveAstType` / `resolveTypeName` call.
|
||||
self.module.types.aliases = &self.type_alias_map;
|
||||
const decls = switch (root.data) {
|
||||
.root => |r| r.decls,
|
||||
else => return,
|
||||
@@ -10472,10 +10478,9 @@ pub const Lowering = struct {
|
||||
},
|
||||
else => {},
|
||||
}
|
||||
// Check type aliases before falling through to type_bridge
|
||||
if (node.data == .type_expr) {
|
||||
if (self.type_alias_map.get(node.data.type_expr.name)) |alias_ty| return alias_ty;
|
||||
}
|
||||
// Alias resolution (`ShaderHandle :: u32`, `Vec4 ::
|
||||
// Vector(4,f32)`) is now handled inside `resolveTypeName`
|
||||
// via the `TypeTable.aliases` borrow loaned at lowerRoot.
|
||||
return type_bridge.resolveAstType(node, &self.module.types);
|
||||
}
|
||||
|
||||
@@ -11141,19 +11146,12 @@ pub const Lowering = struct {
|
||||
for (pd.methods) |method| {
|
||||
var ptypes = std.ArrayList(TypeId).empty;
|
||||
for (method.params) |p| {
|
||||
// Resolve param type; Self → *void for protocol context.
|
||||
// Type aliases (e.g. `ShaderHandle :: u32`) need to be
|
||||
// resolved through type_alias_map before falling through
|
||||
// to type_bridge — otherwise they're treated as named
|
||||
// empty structs and the LLVM call gets `{}` parameters.
|
||||
// Self → *void for protocol context; everything else
|
||||
// goes through `resolveAstType`, which now consults
|
||||
// the alias map via `TypeTable.aliases`.
|
||||
const pty = blk: {
|
||||
if (p.data == .type_expr) {
|
||||
if (std.mem.eql(u8, p.data.type_expr.name, "Self")) {
|
||||
break :blk void_ptr_ty;
|
||||
}
|
||||
if (self.type_alias_map.get(p.data.type_expr.name)) |aliased| {
|
||||
break :blk aliased;
|
||||
}
|
||||
if (p.data == .type_expr and std.mem.eql(u8, p.data.type_expr.name, "Self")) {
|
||||
break :blk void_ptr_ty;
|
||||
}
|
||||
break :blk type_bridge.resolveAstType(p, table);
|
||||
};
|
||||
@@ -11161,14 +11159,9 @@ pub const Lowering = struct {
|
||||
}
|
||||
var ret_is_self = false;
|
||||
const ret = if (method.return_type) |rt| blk: {
|
||||
if (rt.data == .type_expr) {
|
||||
if (std.mem.eql(u8, rt.data.type_expr.name, "Self")) {
|
||||
ret_is_self = true;
|
||||
break :blk void_ptr_ty;
|
||||
}
|
||||
if (self.type_alias_map.get(rt.data.type_expr.name)) |aliased| {
|
||||
break :blk aliased;
|
||||
}
|
||||
if (rt.data == .type_expr and std.mem.eql(u8, rt.data.type_expr.name, "Self")) {
|
||||
ret_is_self = true;
|
||||
break :blk void_ptr_ty;
|
||||
}
|
||||
break :blk type_bridge.resolveAstType(rt, table);
|
||||
} else .void;
|
||||
|
||||
Reference in New Issue
Block a user