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:
agra
2026-05-28 15:12:53 +03:00
parent 6d258ad82b
commit 29bd182f3f
4 changed files with 83 additions and 24 deletions

View File

@@ -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;