fix(stdlib/E4): source-pin sx-defined objc-class IMP trampolines + finish non-transitive bare-TYPE gate

Final E4 piece: the IMP trampolines emitted for an sx-defined #objc_class
resolved their method-signature types (e.g. -> BOOL) at whatever lowering
site triggered emission, not the class's defining module — so under the
single-hop bare-TYPE gate a 2-flat-hop objc type (BOOL via uikit->objc)
leaked as 'not visible' when m3te's main triggered emission.

- ast.ForeignClassDecl gains source_file (stamped by resolveImports, like
  ProtocolDecl/StructTemplate); stampFnBodySource stamps the decl + each
  bodied method body.
- emitObjcDefinedClassImps pins current_source_file to fcd.source_file for
  the whole per-class emission (alloc/dealloc/method/property IMPs).
- Removes the BOOLLEAF debug probe.

Completes E4: bare-TYPE visibility is single-hop non-transitive across all
member kinds; every instantiation kind (generic struct/fn, pack fn, param
protocol, type fn, objc-block, objc-class IMP) is source-pinned to its
defining module. Full gate green; m3te ios-sim builds + launches (exit 0).
This commit is contained in:
agra
2026-06-08 11:22:05 +03:00
parent 33a6f5c650
commit 9d5143aee6
3 changed files with 32 additions and 3 deletions

View File

@@ -2231,9 +2231,6 @@ pub const Lowering = struct {
fn resolveNominalLeaf(self: *Lowering, name: []const u8, raw: bool, span: ?ast.Span) TypeId {
const from = self.current_source_file orelse
return self.typeResolver().resolveName(name, raw);
if (std.mem.eql(u8, name, "BOOL")) {
std.debug.print("[BOOLLEAF] from={s} -> {s}\n", .{ from, @tagName(self.selectNominalLeaf(name, from, raw)) });
}
return switch (self.selectNominalLeaf(name, from, raw)) {
.resolved => |t| t,
// A forward alias (`.pending`) or a forward / not-yet-interned named
@@ -18042,6 +18039,12 @@ pub const Lowering = struct {
fn emitObjcDefinedClassImps(self: *Lowering) void {
for (self.module.objc_defined_class_cache.items) |entry| {
const fcd = entry.decl;
// Pin to the class's defining module (E4) so the IMP trampolines'
// method-signature types (`-> BOOL`, param types) resolve where they
// are visible, not at whatever lowering site triggered emission.
const saved_src = self.current_source_file;
defer self.setCurrentSourceFile(saved_src);
if (fcd.source_file) |src| self.setCurrentSourceFile(src);
// Synthesize +alloc (M1.2 A.5) and -dealloc (M1.2 A.6). emit_llvm
// registers +alloc on the metaclass and -dealloc on the class
// itself after objc_registerClassPair.