Skip to content

Commit

Permalink
catch duplicate set keys for literals and hash-set calls.
Browse files Browse the repository at this point in the history
  • Loading branch information
richhickey committed Apr 5, 2010
1 parent e6e39d5 commit c733148
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 21 deletions.
4 changes: 2 additions & 2 deletions src/clj/clojure/core.clj
Expand Up @@ -289,7 +289,7 @@
"Returns a new hash set with supplied keys."
([] #{})
([& keys]
(clojure.lang.PersistentHashSet/create keys)))
(clojure.lang.PersistentHashSet/createWithCheck keys)))

(defn sorted-map
"keyval => key val
Expand Down Expand Up @@ -2773,7 +2773,7 @@

(defn set
"Returns a set of the distinct elements of coll."
[coll] (apply hash-set coll))
[coll] (clojure.lang.PersistentHashSet/create #^clojure.lang.ISeq (seq coll)))

(defn #^{:private true}
filter-key [keyfn pred amap]
Expand Down
2 changes: 1 addition & 1 deletion src/jvm/clojure/lang/LispReader.java
Expand Up @@ -1008,7 +1008,7 @@ public Object invoke(Object reader, Object leftparen) throws Exception{
public static class SetReader extends AFn{
public Object invoke(Object reader, Object leftbracket) throws Exception{
PushbackReader r = (PushbackReader) reader;
return PersistentHashSet.create(readDelimitedList('}', r, true));
return PersistentHashSet.createWithCheck(readDelimitedList('}', r, true));
}

}
Expand Down
35 changes: 35 additions & 0 deletions src/jvm/clojure/lang/PersistentHashSet.java
Expand Up @@ -47,6 +47,41 @@ static public PersistentHashSet create(ISeq items){
return ret;
}

public static PersistentHashSet createWithCheck(Object... init){
PersistentHashSet ret = EMPTY;
for(int i = 0; i < init.length; i++)
{
ret = (PersistentHashSet) ret.cons(init[i]);
if(ret.count() != i + 1)
throw new IllegalArgumentException("Duplicate key: " + init[i]);
}
return ret;
}

public static PersistentHashSet createWithCheck(List init){
PersistentHashSet ret = EMPTY;
int i=0;
for(Object key : init)
{
ret = (PersistentHashSet) ret.cons(key);
if(ret.count() != i + 1)
throw new IllegalArgumentException("Duplicate key: " + key);
++i;
}
return ret;
}

static public PersistentHashSet createWithCheck(ISeq items){
PersistentHashSet ret = EMPTY;
for(int i=0; items != null; items = items.next(), ++i)
{
ret = (PersistentHashSet) ret.cons(items.first());
if(ret.count() != i + 1)
throw new IllegalArgumentException("Duplicate key: " + items.first());
}
return ret;
}

PersistentHashSet(IPersistentMap meta, IPersistentMap impl){
super(impl);
this._meta = meta;
Expand Down
2 changes: 1 addition & 1 deletion src/jvm/clojure/lang/RT.java
Expand Up @@ -1023,7 +1023,7 @@ else if(init.length <= PersistentArrayMap.HASHTABLE_THRESHOLD)
}

static public IPersistentSet set(Object... init){
return PersistentHashSet.create(init);
return PersistentHashSet.createWithCheck(init);
}

static public IPersistentVector vector(Object... init){
Expand Down
17 changes: 0 additions & 17 deletions test/clojure/test_clojure/data_structures.clj
Expand Up @@ -534,23 +534,6 @@
(hash-set 1 2) (hash-set 2 1)
(hash-set 3 1 2) (hash-set 1 2 3) )

; equal and unique
(are [x] (and (= (hash-set x) #{x})
(= (hash-set x x) #{x}))
nil
false true
0 42
0.0 3.14
2/3
0M 1M
\c
"" "abc"
'sym
:kw
() '(1 2)
[] [1 2]
{} {:a 1 :b 2}
#{} #{1 2} )

This comment has been minimized.

Copy link
@Chouser

Chouser Apr 6, 2010

Should this test be replaced with something else, or is it entirely useless now?

This comment has been minimized.

Copy link
@richhickey

richhickey Apr 6, 2010

Author Owner

It seemed useless to me, basically encoding what is now considered to be wrong behavior


(are [x y] (= x y)
; equal classes
Expand Down

0 comments on commit c733148

Please sign in to comment.