Skip to content

Commit 2553876

Browse files
committed
Fix letfn with duplicate function names
When letfn had duplicate names like (letfn [(a [] 1) (a [] 2)] (a)), the inner let that calls var-get would try to deref the already-unwrapped function value, causing a ClassCastException (fn cannot be cast to Future). Fix: deduplicate syms in the inner var-get let block.
1 parent 03eae28 commit 2553876

File tree

2 files changed

+6
-4
lines changed

2 files changed

+6
-4
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ SCI is used in [babashka](https://github.com/babashka/babashka),
1313
## Unreleased
1414

1515
- Fix `read` with `nil` or `false` as eof-value throwing instead of returning the eof-value
16+
- Fix `letfn` with duplicate function names crashing with ClassCastException
1617
- `deftype` now macroexpands to `deftype*`, matching JVM Clojure, enabling code walkers like riddley
1718
- `case` now macroexpands to JVM-compatible `case*` format, enabling tools like riddley and cloverage to work with SCI
1819
- Fix `.method` on class objects (e.g. `(.getDeclaredField String "value")`) routing to static instead of instance method path

src/sci/impl/namespaces.cljc

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -314,14 +314,15 @@
314314
:cljs ::TODO)))
315315

316316
(defn letfn* [_ _ fnspecs & body]
317-
(let [syms (map first fnspecs)]
317+
(let [syms (map first fnspecs)
318+
unique-syms (distinct syms)]
318319
`(let ~(vec (interleave syms (repeat '(clojure.core/-new-var))))
319320
~@(map (fn [sym fn-spec]
320321
`(clojure.core/alter-var-root ~sym (constantly (fn ~sym ~@(rest fn-spec)))))
321322
syms fnspecs)
322-
(let ~(vec (interleave syms (map (fn [sym]
323-
`(clojure.core/var-get ~sym))
324-
syms)))
323+
(let ~(vec (interleave unique-syms (map (fn [sym]
324+
`(clojure.core/var-get ~sym))
325+
unique-syms)))
325326
~@body))))
326327

327328
(defn with-local-vars* [form _ name-vals-vec & body]

0 commit comments

Comments
 (0)