Minimal case:
`
(fn foo [x]
(if true
(^:once fn* []
;; x is not cleared here
x)))
`
This is a severe bug as it means that every local used inside a loop or try/catch expression that the clojure compiler internally hoists in a FNONCE, in a conditional branch, cannot be cleared at the moment.
As a concrete example reported in slack,
`
;; THIS OOMs
(defn test1 [x]
(if true
(do
(try (doseq [_ x] _))
1)
0))
(test1 (take 1000000 (range)))
;; THIS DOESN'T OOM
(defn test2 [x]
(do
(try (doseq [_ x] _))
1))
(test2 (take 1000000 (range)))
`
Approach: don't set a new clearing frame if the fn is ^:once and there's an existing clearing frame
Patch: 0001-CLJ-2145-fix-clearing-of-locals-closed-over-by-a-FNO.patch