Auto-resolve ::keywords; honor clojure.edn reader opts

The reader dropped the namespace on ::kw (read ::foo as :foo), so auto-resolved
keywords never matched their qualified form — code that round-trips them (spec
keys, aero's :aero.core/* expansion keys) silently broke. Resolve ::name against
the current ns and ::alias/name through the alias table, as Clojure does. The
runtime loader reads form-by-form with the ns set after the ns form; the
cross-compile reads all forms up front, so ei-emit-ns*/ei-emit-ns-records set the
ns before reading.

clojure.edn/read over a reader discarded its opts map — :readers/:default/:eof
were ignored, so a custom :default never saw the tag. Route the reader arity
through read-string so opts apply, and pass the tag to :default as a symbol (not
the internal :#name keyword), matching Clojure.

Seed re-minted (the ::halt transducer key in clojure.core now reads as
:clojure.core/halt). Corpus gains ::-keyword rows; the unit case that asserted the
old ns-dropping behavior now asserts the qualified result.
This commit is contained in:
Yogthos 2026-06-24 09:13:14 -04:00
parent 53b1c79d99
commit 6d56982abe
7 changed files with 31 additions and 12 deletions

View file

@ -59,6 +59,10 @@
;; that fails to emit) and `jolt build` (bld-emit-ns: optimize? #t, guard? #f —
;; strict, a failing form errors the build).
(define (ei-emit-ns* ns-name src optimize? guard?)
;; set the ns before reading so ::kw auto-resolves against this ns (the runtime
;; loader reads form-by-form after the ns form sets it; the cross-compile reads
;; all forms up front, so set it here).
(set-chez-ns! ns-name)
(let loop ((forms (ei-read-all src)) (acc '()))
(if (null? forms)
(reverse acc)
@ -92,6 +96,7 @@
;; record whose refs are roots. A macro is prunable — its expander isn't called at
;; runtime in an AOT build.
(define (ei-emit-ns-records ns-name src)
(set-chez-ns! ns-name) ; ::kw resolves against this ns (see ei-emit-ns*)
(let loop ((forms (ei-read-all src)) (acc '()))
(if (null? forms)
(reverse acc)