refactor(ir): converge structural type-shape resolution onto resolveCompound (A2.3b)
Codex corrective step before the A2 merge gate: A2.3 left type_bridge with a parallel structural type-resolution algorithm and an inline tuple-literal-spread shape in lower.zig with a `.void` fallback. Finding 1 — single owner for structural shapes: - TypeResolver.resolveCompound is now the sole structural type-shape constructor. Namespaced on `table` (so the stateless type_bridge can call it) and extended to own function types, plain `Closure(P...) -> R`, and plain positional/named tuples (it already owned *T/[*]T/[]T/?T/[N]T). It returns null only for the pack-shaped forms that need caller state (`Closure(..p)`, spread tuples); OOM yields `.unresolved`. - type_bridge: deleted its 8 independent structural resolvers (resolveArray/Slice/Pointer/ManyPointer/Optional/Function/Closure/TupleType). resolveAstType delegates those node kinds to resolveCompound via a binding-free StatelessInner adapter. The only residual stateless shape code is two tiny fallbacks for the pack-shaped forms resolveCompound defers (resolveClosurePackShape — used by Into(Block) at registration time — and resolveTupleSpreadShape) plus resolveParameterizedType (kept: generic-instantiation convergence is A4.1 per PLAN-ARCH). - lower.zig: stateful resolveTypeWithBindings uses resolveCompound; the `.function_type_expr` switch arm is gone. PackResolver.resolveFunctionTypeWithBindings deleted (subsumed). Plain closures/tuples now resolve via resolveCompound in both paths; only pack closures / spread tuples reach PackResolver. Finding 2 — no `.void` failure fallback in lower.zig pack handling: - the inline tuple_literal-with-spread type assembly moved into PackResolver.resolveTupleLiteralType (returns ?TypeId; OOM `catch return .void` became `catch return .unresolved`). Alias result preserved: TypeTable.aliases stays gone; no table.aliases reads; ProgramIndex.type_alias_map threaded explicitly. type_resolver.test.zig: resolveCompound test rewritten (namespaced + new function/closure/tuple/pack-shape arms, arena-backed). Gate green: zig build, zig build test, run_examples 350/0.
This commit is contained in:
@@ -97,24 +97,36 @@ pub const PackResolver = struct {
|
||||
} });
|
||||
}
|
||||
|
||||
/// Resolve a `(Params...) -> Ret` function type expression with the
|
||||
/// active type/pack bindings applied. Mirrors
|
||||
/// `resolveClosureTypeWithBindings` but for `function_type_expr`.
|
||||
/// Unlocks `$args[$i]` in fn-pointer type literals like
|
||||
/// `fp : (*void, $args[0]) -> $args[1] = ...` — used in step 5's
|
||||
/// generic trampoline body.
|
||||
pub fn resolveFunctionTypeWithBindings(self: PackResolver, ft: *const ast.FunctionTypeExpr) TypeId {
|
||||
var param_ids = std.ArrayList(TypeId).empty;
|
||||
defer param_ids.deinit(self.l.alloc);
|
||||
for (ft.param_types) |pt| {
|
||||
param_ids.append(self.l.alloc, self.l.resolveTypeWithBindings(pt)) catch return .unresolved;
|
||||
/// Resolve a tuple LITERAL used in a type position whose elements include a
|
||||
/// pack spread (`(..$Ts)` / `(..xs.T)` — these parse as a tuple literal, not
|
||||
/// a `tuple_type_expr`). Returns null when no element is a spread, so the
|
||||
/// caller falls through to ordinary name/type resolution. A failed
|
||||
/// allocation yields `.unresolved` (never a real `.void`).
|
||||
pub fn resolveTupleLiteralType(self: PackResolver, tl: *const ast.TupleLiteral) ?TypeId {
|
||||
var any_spread = false;
|
||||
for (tl.elements) |el| {
|
||||
if (el.value.data == .spread_expr) {
|
||||
any_spread = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
const ret_ty = if (ft.return_type) |rt| self.l.resolveTypeWithBindings(rt) else .void;
|
||||
const cc: types.TypeInfo.CallConv = switch (ft.call_conv) {
|
||||
.default => .default,
|
||||
.c => .c,
|
||||
};
|
||||
return self.l.module.types.functionTypeCC(param_ids.items, ret_ty, cc);
|
||||
if (!any_spread) return null;
|
||||
var field_ids = std.ArrayList(TypeId).empty;
|
||||
defer field_ids.deinit(self.l.alloc);
|
||||
for (tl.elements) |el| {
|
||||
if (el.value.data == .spread_expr) {
|
||||
if (self.packTypeElems(el.value.data.spread_expr.operand)) |elems| {
|
||||
defer self.l.alloc.free(elems);
|
||||
for (elems) |e| field_ids.append(self.l.alloc, e) catch return .unresolved;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
field_ids.append(self.l.alloc, self.l.resolveTypeWithBindings(el.value)) catch return .unresolved;
|
||||
}
|
||||
return self.l.module.types.intern(.{ .tuple = .{
|
||||
.fields = self.l.alloc.dupe(TypeId, field_ids.items) catch return .unresolved,
|
||||
.names = null,
|
||||
} });
|
||||
}
|
||||
|
||||
/// TYPE-position pack expansion: given a spread operand, return the
|
||||
|
||||
Reference in New Issue
Block a user