From d8d8e62c00287491bdbee33700a5575fafeabdc2 Mon Sep 17 00:00:00 2001 From: Roman Liutikov Date: Wed, 26 Nov 2025 14:53:21 +0200 Subject: [PATCH 1/5] CLJS-3415: Missing duplicate key exception for sets --- src/main/clojure/cljs/compiler.cljc | 2 +- src/test/cljs/cljs/core_test.cljs | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/src/main/clojure/cljs/compiler.cljc b/src/main/clojure/cljs/compiler.cljc index 1fbf54ec2..05f731294 100644 --- a/src/main/clojure/cljs/compiler.cljc +++ b/src/main/clojure/cljs/compiler.cljc @@ -614,7 +614,7 @@ (emits "new cljs.core.PersistentHashSet(null, new cljs.core.PersistentArrayMap(null, " (count items) ", [" (comma-sep (interleave items (repeat "null"))) "], null), null)") - :else (emits "cljs.core.PersistentHashSet.createAsIfByAssoc([" (comma-sep items) "])"))) + :else (emits "cljs.core.PersistentHashSet.createWithCheck([" (comma-sep items) "])"))) (defn emit-lite-set [items comma-sep distinct-constants?] (if (empty? items) diff --git a/src/test/cljs/cljs/core_test.cljs b/src/test/cljs/cljs/core_test.cljs index 01f6f0b52..8bff60d3b 100644 --- a/src/test/cljs/cljs/core_test.cljs +++ b/src/test/cljs/cljs/core_test.cljs @@ -824,9 +824,6 @@ (def some-x 1) (def some-y 1) -(deftest test-583 - (is (= (count #{some-x some-y}) 1))) - (deftest test-584 (is (= (count {some-x :foo some-y :bar}) 1))) @@ -2012,3 +2009,7 @@ (deftest test-instance-method-new (is (= ["FOO" "BAR" "BAZ"] (map String/.toUpperCase ["foo" "bar" "baz"])))) + +(deftest test-cljs-3415 + (let [a 1 b 1] + (is (thrown? js/Error #{a b})))) \ No newline at end of file From 3971edb3ccd01aff6764c75fb9368761db4e1f8f Mon Sep 17 00:00:00 2001 From: davidnolen Date: Sat, 11 Jul 2026 09:09:21 -0400 Subject: [PATCH 2/5] add duplicate key check to set-lite constructor --- src/main/cljs/cljs/core.cljs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/cljs/cljs/core.cljs b/src/main/cljs/cljs/core.cljs index ae991f0a6..0df5c1510 100644 --- a/src/main/cljs/cljs/core.cljs +++ b/src/main/cljs/cljs/core.cljs @@ -13149,7 +13149,12 @@ reduces them without incurring seq initialization" (let [in (seq coll)] (if (nil? in) #{} - (loop [in in out (. SetLite -EMPTY)] + (loop [in in out (. SetLite -EMPTY) i 0] (if-not (nil? in) - (recur (next in) (-conj out (first in))) + (let [x (first in) + out' (conj out x) + i' (inc i)] + (if-not (== i (count out)) + (throw (js/Error. (str_ "Duplicate key: " x))) + (recur (next in) out' i'))) out)))))) From 06cd9a8bbde6a118370012353537be0d06c71f0d Mon Sep 17 00:00:00 2001 From: davidnolen Date: Sat, 11 Jul 2026 09:15:51 -0400 Subject: [PATCH 3/5] typo in last commit --- src/main/cljs/cljs/core.cljs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/cljs/cljs/core.cljs b/src/main/cljs/cljs/core.cljs index 0df5c1510..8cec28ef3 100644 --- a/src/main/cljs/cljs/core.cljs +++ b/src/main/cljs/cljs/core.cljs @@ -13154,7 +13154,7 @@ reduces them without incurring seq initialization" (let [x (first in) out' (conj out x) i' (inc i)] - (if-not (== i (count out)) + (if-not (== i (count out')) (throw (js/Error. (str_ "Duplicate key: " x))) (recur (next in) out' i'))) out)))))) From 84ec416dadb32105e312ed46e0f684fc2e4337b8 Mon Sep 17 00:00:00 2001 From: davidnolen Date: Sat, 11 Jul 2026 09:29:01 -0400 Subject: [PATCH 4/5] we need to replicate the compiler logic for sets in lite mode as well --- src/main/cljs/cljs/core.cljs | 15 ++++++++++++++- src/main/clojure/cljs/compiler.cljc | 9 +++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/main/cljs/cljs/core.cljs b/src/main/cljs/cljs/core.cljs index 8cec28ef3..3edec060c 100644 --- a/src/main/cljs/cljs/core.cljs +++ b/src/main/cljs/cljs/core.cljs @@ -13142,7 +13142,20 @@ reduces them without incurring seq initialization" (set! (. SetLite -EMPTY) (SetLite. nil (. HashMapLite -EMPTY) empty-unordered-hash)) (defn set-lite - ":lite-mode version of set, not intended ot be used directly." + ":lite-mode version of set, not intended to be used directly." + [coll] + (if (set? coll) + (-with-meta coll nil) + (let [in (seq coll)] + (if (nil? in) + #{} + (loop [in in out (. SetLite -EMPTY)] + (if-not (nil? in) + (recur (next in) (conj out (first in))) + out)))))) + +(defn set-lite-check + ":lite-mode version of set with check, not intended to be used directly." [coll] (if (set? coll) (-with-meta coll nil) diff --git a/src/main/clojure/cljs/compiler.cljc b/src/main/clojure/cljs/compiler.cljc index 05f731294..4bc7ea215 100644 --- a/src/main/clojure/cljs/compiler.cljc +++ b/src/main/clojure/cljs/compiler.cljc @@ -617,9 +617,14 @@ :else (emits "cljs.core.PersistentHashSet.createWithCheck([" (comma-sep items) "])"))) (defn emit-lite-set [items comma-sep distinct-constants?] - (if (empty? items) + (cond + (empty? items) (emits "cljs.core.SetLite.EMPTY") - (emits "cljs.core.set_lite([" (comma-sep items) "])"))) + + (distinct-constants? items) + (emits "cljs.core.set_lite([" (comma-sep items) "])") + + :else (emits "cljs.core.set_lite_check([" (comma-sep items) "])"))) (defmethod emit* :set [{:keys [items env]}] From b733fd46e825aea7e865b198e568bade098004cc Mon Sep 17 00:00:00 2001 From: davidnolen Date: Sat, 11 Jul 2026 11:02:42 -0400 Subject: [PATCH 5/5] another typo --- src/main/cljs/cljs/core.cljs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/cljs/cljs/core.cljs b/src/main/cljs/cljs/core.cljs index 3edec060c..993a5d5fe 100644 --- a/src/main/cljs/cljs/core.cljs +++ b/src/main/cljs/cljs/core.cljs @@ -13167,7 +13167,7 @@ reduces them without incurring seq initialization" (let [x (first in) out' (conj out x) i' (inc i)] - (if-not (== i (count out')) + (if-not (== i' (count out')) (throw (js/Error. (str_ "Duplicate key: " x))) (recur (next in) out' i'))) out))))))