feat: precise file:line:col source locations for type errors (jolt-fqy)
RFC 0006 error reporting wanted file:line:col but IR nodes carried no
position, so diagnostics read only "type error in <ns>: <msg>". Now:
type error /tmp/scene.clj:5:5: `inc` requires a number, but argument 1 is a string
The reader records each LIST form's absolute start offset in a table keyed
by form identity (lists are fresh arrays, never interned), gated behind a
flag the loaders enable only when JOLT_TYPE_CHECK is on — zero cost off.
Keying by identity makes positions survive macroexpansion exactly when the
user's own sub-form is spliced through, and absent for macro-synthesized
structure: a `(inc :k)` written inside `(when c ...)` reports at its own
line, never at the expansion's generated if/do.
The analyzer stamps the offset onto :invoke nodes (form-position host
contract fn); the checker carries it into each diagnostic as :pos; the
loaders stash the file's source + path on the env (save/restored across
nested requires); backend/type-check! converts offset -> line:col via the
reader's line-col and renders the RFC format. Falls back to the ns when no
position is available (synthetic forms), so it is never worse than before.
Gate green, conformance 335/335, suite 4718, runtime bench even (positions
are compile-time only; off by default).
This commit is contained in:
parent
824b30defd
commit
f2d65addc8
9 changed files with 106 additions and 17 deletions
|
|
@ -10,6 +10,7 @@
|
|||
(print "Success-type checking (jolt-y3b)...")
|
||||
|
||||
(os/setenv "JOLT_DIRECT_LINK" "1")
|
||||
(reader/track-positions! true) # record form positions (jolt-fqy)
|
||||
(def ctx (api/init {:compile? true}))
|
||||
(def pns (types/ctx-find-ns ctx "jolt.passes"))
|
||||
(def check (types/var-get (types/ns-find pns "check-form")))
|
||||
|
|
@ -89,6 +90,11 @@
|
|||
(def one (in (diags "(inc \"x\")") 0))
|
||||
(assert (= "inc" (get one :op)) "diagnostic names the op")
|
||||
(assert (string/find "number" (get one :msg)) "message says a number is required")
|
||||
# --- the diagnostic carries the offending form's source offset (jolt-fqy) -----
|
||||
(assert (= 0 (get one :pos)) "diagnostic carries :pos (offset 0 for a single form)")
|
||||
(def nested (in (diags "(do 1 2 (inc :k))") 0))
|
||||
(assert (= 8 (get nested :pos))
|
||||
"the inner (inc :k) form is positioned at its own offset, not the do's")
|
||||
|
||||
# --- end-to-end: strictness drives compilation (decoupled from :inline?) -----
|
||||
# error mode aborts a provably-wrong form's compilation; a correct form compiles.
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue