Record type hints resolve across namespace boundaries (fields and params)
A ^RecordType hint only resolved against the current namespace's ctor key, so a hint naming a record defined in another namespace degraded to :any. That made a decomposed multi-namespace program much slower than the monolith: per-namespace inference can't see a record param's callers in other namespaces, and the declared hint that could have typed it was dropped. Resolution now works cross-namespace, for both record FIELD hints (defrecord) and fn PARAM hints, in both spellings — ^Vec3 where the type is referred and ^v/Vec3 where the namespace is aliased: - reader keeps a tag's namespace qualifier (^t/Ray -> "t/Ray", was "Ray"). - make-deftype-ctor-impl indexes each ctor closure by value; record-hint-ctor-key resolves a hint name against the COMPILE ns (referred names live there; aliases resolve through it) and maps the type var's root back to its home ctor key. Using the ctor value, not the var's :ns, is what makes :refer work — :refer re-interns a fresh var whose :ns is the referring ns. - the analyzer captures record param hints as arity :phints [name ctor-key]; reinfer-def seeds those param types, so a record param is typed even with no inferred caller — the open-world / cross-ns case. Effect on the multi-namespace ray tracer: per-ns compile 30.4s -> 7.9s with param hints, matching whole-program (8.1s) and the single-ns monolith (8.3s). cross-ns-hints-test covers field + param hints, refer + as, and the reader tag.
This commit is contained in:
parent
4018eb87ed
commit
1525c7adfb
6 changed files with 197 additions and 29 deletions
|
|
@ -1425,7 +1425,20 @@
|
|||
(if (= :fn (get fnode :op))
|
||||
(assoc def-node :init
|
||||
(assoc fnode :arities
|
||||
(mapv (fn [a] (assoc a :body (nth (infer (get a :body) ptmap) 1)))
|
||||
(mapv (fn [a]
|
||||
;; seed declared record param hints (:phints, name ->
|
||||
;; ctor-key) so a record param is typed even with no
|
||||
;; inferred caller type — the open-world / cross-ns
|
||||
;; case. An inferred type in ptmap wins (it's at least
|
||||
;; as precise), so this only fills the gaps.
|
||||
(let [pt (reduce (fn [m pr]
|
||||
(let [nm (nth pr 0)
|
||||
e (get @record-shapes-box (nth pr 1))]
|
||||
(if (and e (not (contains? m nm)))
|
||||
(assoc m nm (record-type-from-entry e type-depth))
|
||||
m)))
|
||||
ptmap (get a :phints))]
|
||||
(assoc a :body (nth (infer (get a :body) pt) 1))))
|
||||
(get fnode :arities))))
|
||||
def-node)))
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue