Skip to content

Commit f4cc128

Browse files
roman01lamfikes
authored andcommitted
CLJS-2863: Need to reject incorrect fn with fixed arity of more params than variadic
1 parent 05cd4d5 commit f4cc128

File tree

2 files changed

+38
-7
lines changed

2 files changed

+38
-7
lines changed

src/main/clojure/cljs/core.cljc

Lines changed: 17 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3217,18 +3217,23 @@
32173217
(fn ~method))))]
32183218
(core/let [rname (symbol (core/str ana/*cljs-ns*) (core/str name))
32193219
arglists (map first fdecl)
3220-
varsig? #(some '#{&} %)
3221-
variadic (boolean (some varsig? arglists))
3222-
sigs (remove varsig? arglists)
3220+
macro? (:macro meta)
3221+
varsig? #(boolean (some '#{&} %))
3222+
{sigs false var-sigs true} (group-by varsig? arglists)
3223+
variadic? (core/pos? (core/count var-sigs))
3224+
variadic-params (if variadic?
3225+
(core/cond-> (remove '#{&} (first var-sigs))
3226+
true core/count
3227+
macro? (core/- 2))
3228+
0)
32233229
maxfa (apply core/max
32243230
(concat
32253231
(map count sigs)
3226-
[(core/- (count (first (filter varsig? arglists))) 2)]))
3227-
macro? (:macro meta)
3232+
[(core/- (count (first var-sigs)) 2)]))
32283233
mfa (core/cond-> maxfa macro? (core/- 2))
32293234
meta (assoc meta
32303235
:top-fn
3231-
{:variadic? variadic
3236+
{:variadic? variadic?
32323237
:fixed-arity mfa
32333238
:max-fixed-arity mfa
32343239
:method-params (core/cond-> sigs macro? elide-implicit-macro-args)
@@ -3237,14 +3242,19 @@
32373242
args-sym (gensym "args")
32383243
param-counts (map count arglists)
32393244
name (with-meta name meta)]
3245+
(core/when (core/< 1 (count var-sigs))
3246+
(ana/warning :multiple-variadic-overloads {} {:name name}))
3247+
(core/when (core/and (core/pos? variadic-params)
3248+
(not (core/== variadic-params (core/+ 1 mfa))))
3249+
(ana/warning :variadic-max-arity {} {:name name}))
32403250
(core/when (not= (distinct param-counts) param-counts)
32413251
(ana/warning :overload-arity {} {:name name}))
32423252
`(do
32433253
(def ~name
32443254
(fn [~'var_args]
32453255
(case (alength (js-arguments))
32463256
~@(mapcat #(fixed-arity rname %) sigs)
3247-
~(if variadic
3257+
~(if variadic?
32483258
`(let [args-arr# (array)]
32493259
(copy-arguments args-arr#)
32503260
(let [argseq# (new ^::ana/no-resolve cljs.core/IndexedSeq

src/test/clojure/cljs/analyzer_tests.clj

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -399,6 +399,27 @@
399399
(catch Exception _))
400400
(is (.startsWith (first @ws) "myfun: Can't have 2 overloads with same arity"))))
401401

402+
(deftest test-cljs-2863
403+
(let [ws (atom [])]
404+
(try
405+
(ana/with-warning-handlers [(collecting-warning-handler ws)]
406+
(analyze (ana/empty-env)
407+
'(defn myfun
408+
([x] x)
409+
([& xs] xs))))
410+
(catch Exception _))
411+
(is (.startsWith (first @ws) "myfun: Can't have fixed arity function with more params than variadic function")))
412+
413+
(let [ws (atom [])]
414+
(try
415+
(ana/with-warning-handlers [(collecting-warning-handler ws)]
416+
(analyze (ana/empty-env)
417+
'(defn myfun
418+
([& x] x)
419+
([& xs] xs))))
420+
(catch Exception _))
421+
(is (.startsWith (first @ws) "myfun: Can't have more than 1 variadic overload"))))
422+
402423
(deftest test-canonicalize-specs
403424
(is (= (ana/canonicalize-specs '((quote [clojure.set :as set])))
404425
'([clojure.set :as set])))

0 commit comments

Comments
 (0)