From 59f08e32dacebffa52151a62061902157e4eeea7 Mon Sep 17 00:00:00 2001 From: "Norman Nunley, Jr" Date: Thu, 23 Jul 2026 11:39:53 -0400 Subject: [PATCH] fix(rt): resolve ns alias in LookupOrRegisterNSNoLoad MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit RegisterGeneratedPrimitives (the lginterop-generated //lg:native registrar) Defs primitives via LookupOrRegisterNSNoLoad("clojure.core"), but that path — unlike the loading LookupOrRegisterNS — never resolved the ns alias, so it registered into a DISTINCT "clojure.core" namespace instead of the canonical "core". Hand-registered primitives masked this by also Def'ing into the canonical ns via installLangNS; a primitive hoisted to a pure //lg:native decl has ONLY the generated registration, so it landed in the wrong namespace and was invisible to core.lg's own bootstrap compile ("Can't resolve +"). Resolve the alias as the first step of LookupOrRegisterNSNoLoad, matching the loading variant. This unblocks hoisting native closures in lang.go to named //lg:native primitives for real stack-trace frames. Verified: make check-generated OK (bundle + lowered tree unchanged, this is a Go-only registration fix); clojure.core surface = 807 publics, byte-identical before/after a proof hoist of + - * /. --- pkg/rt/lang.go | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/pkg/rt/lang.go b/pkg/rt/lang.go index 76936f244..94df497c9 100644 --- a/pkg/rt/lang.go +++ b/pkg/rt/lang.go @@ -686,6 +686,16 @@ func LookupOrRegisterNS(name string) *vm.Namespace { } func LookupOrRegisterNSNoLoad(name string) *vm.Namespace { + // Resolve the alias BEFORE touching the registry, as the loading callers do. + // Without this, LookupOrRegisterNSNoLoad("clojure.core") registers a DISTINCT + // "clojure.core" namespace instead of returning the canonical "core" — so the + // generated primitive registrar (RegisterGeneratedPrimitives, which calls this + // with "clojure.core"/"clojure.string"/…) Defs into the wrong namespace, + // invisible to core.lg's own bootstrap compile. Hand-registered primitives + // hid this by also Def'ing into the canonical ns via installLangNS; a primitive + // hoisted to //lg:native has ONLY the generated registration, so it must land + // in the canonical namespace to resolve. + name = resolveNSAlias(name) nsMu.RLock() e := nsRegistry[name] nsMu.RUnlock()