Skip to content

Commit 9dd4d41

Browse files
committed
CLJS-2641: cljs.spec.alpha/fdef with s/* is broken
The problem was while `instrument` redefs the var, the original fn internals still self references through the namespace, thus triggering an infinite loop by calling into the instrumented version again. This change relies on the fact that `apply` will always bind the original fn via `Function.prototype.call` when invoking. In the dispatch helpers we now check if `this` is bound to a Function - if so we invoke methods on that value instead as it will be the *original* fn.
1 parent 728acc4 commit 9dd4d41

2 files changed

Lines changed: 22 additions & 5 deletions

File tree

src/main/clojure/cljs/core.cljc

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3016,10 +3016,16 @@
30163016
`(fn
30173017
([~restarg]
30183018
(let [~@(mapcat param-bind params)]
3019-
(. ~sym (~(get-delegate) ~@params ~restarg))))))
3019+
(this-as self#
3020+
(if (identical? js/Function (type self#))
3021+
(. self# (~(get-delegate) ~@params ~restarg))
3022+
(. ~sym (~(get-delegate) ~@params ~restarg))))))))
30203023
`(fn
30213024
([~restarg]
3022-
(. ~sym (~(get-delegate) (seq ~restarg)))))))]
3025+
(this-as self#
3026+
(if (identical? js/Function (type self#))
3027+
(. self# (~(get-delegate) (seq ~restarg)))
3028+
(. ~sym (~(get-delegate) (seq ~restarg)))))))))]
30233029
`(do
30243030
(set! (. ~sym ~(get-delegate-prop))
30253031
(fn (~(vec sig) ~@body)))
@@ -3058,8 +3064,10 @@
30583064
(let [argseq# (when (< ~c-1 (alength args#))
30593065
(new ^::ana/no-resolve cljs.core/IndexedSeq
30603066
(.slice args# ~c-1) 0 nil))]
3061-
(. ~rname
3062-
(~'cljs$core$IFn$_invoke$arity$variadic ~@(dest-args c-1) argseq#))))))
3067+
(this-as self#
3068+
(if (identical? js/Function (type self#))
3069+
(. self# (~'cljs$core$IFn$_invoke$arity$variadic ~@(dest-args c-1) argseq#))
3070+
(. ~rname (~'cljs$core$IFn$_invoke$arity$variadic ~@(dest-args c-1) argseq#))))))))
30633071
~(variadic-fn* rname method)
30643072
~(core/when emit-var? `(var ~name))))))
30653073

src/test/cljs/cljs/spec/test_test.cljs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,13 @@
7272
(stest/instrument `arities)
7373
(is (arities 1))
7474
(is (thrown? js/Error (arities "bad")))
75-
(stest/unstrument `arities))
75+
(stest/unstrument `arities))
76+
77+
(defn foo [& args] args)
78+
(s/fdef foo :args (s/cat :args (s/* int?)))
79+
80+
(deftest test-2641
81+
(stest/instrument `foo)
82+
(is (= [1 2 3] (foo 1 2 3)))
83+
(is (thrown? js/Error (foo 1 :hello)))
84+
(stest/unstrument `foo))

0 commit comments

Comments
 (0)