green(reify): type-fn over reify memoizes by mangled name (identity)
REIFY Phase 1.1 (Phase 1 complete). instantiateTypeFunction detects a type-fn body that returns reify(...) (findReturnReifyCall) and routes it to reifyType under the instantiation's name — mangled for inline use, the alias name for `Foo :: Box(i64)` — with the type-arg bindings active so reify payloads (`payload = T`) resolve against the instantiation args. Placed before the general case, whose resolveTypeWithBindings would route the reify call to the inline-position loud bail. Registering under the mangled name lets the top-of-instantiation cache return the SAME TypeId on a second instantiation, so Box(i64) resolved at two independent sites is ONE type (Contract 1). examples/0615 green (build()->consume() cross-site + `b : Box(i64) = .none`). Suite green (671 examples, 447 unit).
This commit is contained in:
@@ -1709,6 +1709,19 @@ pub fn instantiateTypeFunction(self: *Lowering, alias_name: []const u8, template
|
||||
return self.instantiateTypeUnion(if (has_alias) alias_name else mangled_name, mangled_name, &enum_decl);
|
||||
}
|
||||
|
||||
// A type-fn body that RETURNS `reify(...)` — mint the enum under THIS
|
||||
// instantiation's name (mangled for inline use, the alias name for
|
||||
// `Foo :: Box(i64)`). The type-arg bindings are active here, so the reify
|
||||
// payloads resolve against the instantiation's args (`payload = T` → the
|
||||
// bound type). Registering under the mangled name lets the cache check at
|
||||
// the top of this fn return the SAME TypeId on a second instantiation —
|
||||
// so `Box(i64)` at two sites is ONE type (Contract 1). Must precede the
|
||||
// general case below, whose `resolveTypeWithBindings` would route the
|
||||
// reify call to the inline-position loud bail.
|
||||
if (findReturnReifyCall(fd.body)) |reify_call| {
|
||||
return self.reifyType(if (has_alias) alias_name else mangled_name, reify_call);
|
||||
}
|
||||
|
||||
// General case: the body returns a TYPE EXPRESSION that is not an inline
|
||||
// struct/union/enum — `return [K]T`, `Vector(K, T)`, `*T`, an alias, etc.
|
||||
// Resolve it with the value/type bindings active (so `[K]T` folds K to a
|
||||
@@ -1739,6 +1752,19 @@ pub fn findReturnTypeExpr(body: *const Node) ?*const Node {
|
||||
return body;
|
||||
}
|
||||
|
||||
/// The `reify(...)` call a type-fn body returns (block `return reify(...)` or
|
||||
/// arrow `=> reify(...)`), or null if the body's return is not a bare `reify`
|
||||
/// call. Used to route a reify-returning type-fn through `reifyType` under the
|
||||
/// instantiation name (Phase 1 nominal identity).
|
||||
pub fn findReturnReifyCall(body: *const Node) ?*const ast.Call {
|
||||
const ret = findReturnTypeExpr(body) orelse return null;
|
||||
if (ret.data != .call) return null;
|
||||
const callee = ret.data.call.callee;
|
||||
if (callee.data != .identifier) return null;
|
||||
if (!std.mem.eql(u8, callee.data.identifier.name, "reify")) return null;
|
||||
return &ret.data.call;
|
||||
}
|
||||
|
||||
/// Instantiate a tagged enum from a type function body.
|
||||
pub fn instantiateTypeUnion(self: *Lowering, alias_name: []const u8, mangled_name: []const u8, ed: *const ast.EnumDecl) ?TypeId {
|
||||
const table = &self.module.types;
|
||||
|
||||
Reference in New Issue
Block a user