lang: generic struct head aliases bind the template (fix 0120) — alias-follow from each author's source in head selection; loud unknown-type on the .call type tail
BoxAlias :: Box; / Box :: r.Box; now resolve instantiation, methods,
annotations, and chains through the aliased template, and re-export one
flat-import level as ordinary own decls (the facade shape the std.sx
restructure needs). selectGenericStructHead consults aliasedStructTemplate
(nominal.zig) before the global template map — own-wins/single-flat alias
author, each hop pinned to the alias author's source, ns.X RHS through
namespaceAliasVerdictFrom, depth-capped. resolveTypeCallWithBindings'
silent .unresolved tail (panicked in LLVM emission) now diagnoses
"unknown type". Also aligns the stale pre-existing calls.test.zig UFCS
plan test with the opt-in model (a47ea14). Regression: examples/0211
(+rich/+facade). Gates: zig build test 426/426, suite 587/587.
This commit is contained in:
@@ -974,6 +974,17 @@ pub fn selectGenericStructHead(self: *Lowering, name: []const u8, alias: ?[]cons
|
||||
if (self.program_index.struct_template_map.getPtr(name)) |tmpl| return .{ .template = tmpl.* };
|
||||
return .not_generic;
|
||||
}
|
||||
// Const-alias head (`BoxAlias :: Box;` / `Box :: r.Box;`, issue 0120):
|
||||
// follow the alias decl hop-by-hop to its authoring template, each hop
|
||||
// resolved from that alias author's own source. Checked BEFORE the map:
|
||||
// the alias may share its name with a same-name template that is NOT
|
||||
// visible from here (a facade's `Box :: r.Box;` re-export of rich's
|
||||
// `Box`), and the map branch would poison on that invisible author.
|
||||
// Only fires when the single visible author (own-wins / single-flat)
|
||||
// IS an alias-shaped const decl, so real template heads are untouched.
|
||||
if (self.current_source_file) |from| {
|
||||
if (self.aliasedStructTemplate(name, from)) |t| return .{ .template = t };
|
||||
}
|
||||
if (self.program_index.struct_template_map.getPtr(name)) |tmpl| {
|
||||
if (self.headTypeLeak(name, span)) return .poisoned;
|
||||
if (self.bareVisibleStructTemplate(name)) |vt| return .{ .template = vt };
|
||||
@@ -1230,7 +1241,14 @@ pub fn resolveTypeCallWithBindings(self: *Lowering, cl: *const ast.Call) TypeId
|
||||
}
|
||||
// Try as a named type
|
||||
const name_id = self.module.types.internString(callee_name);
|
||||
return self.module.types.findByName(name_id) orelse .unresolved;
|
||||
if (self.module.types.findByName(name_id)) |t| return t;
|
||||
// The callee names no known type constructor — not Vector, not a generic
|
||||
// struct template (or alias), not a type-returning function, not a named
|
||||
// type. A silent `.unresolved` here reaches LLVM emission as a panic;
|
||||
// diagnose and poison (the parameterized sibling below already does).
|
||||
if (self.diagnostics) |d|
|
||||
d.addFmt(.err, cl.callee.span, "unknown type '{s}'", .{callee_name});
|
||||
return .unresolved;
|
||||
}
|
||||
|
||||
/// Resolve a parameterized type expr, substituting bindings for type/value params.
|
||||
|
||||
Reference in New Issue
Block a user