Skip to content

Commit 77aa78f

Browse files
committed
Fix SimpleIdentitySet#map
Previously, the result of a map could contain duplicates. I verified that with the current code base this could cause problems only for capture checking.
1 parent c4aefa1 commit 77aa78f

File tree

1 file changed

+16
-9
lines changed

1 file changed

+16
-9
lines changed

compiler/src/dotty/tools/dotc/util/SimpleIdentitySet.scala

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,10 @@ abstract class SimpleIdentitySet[+Elem <: AnyRef] {
1414
def contains[E >: Elem <: AnyRef](x: E): Boolean
1515
def foreach(f: Elem => Unit): Unit
1616
def exists[E >: Elem <: AnyRef](p: E => Boolean): Boolean
17-
def map[B <: AnyRef](f: Elem => B): SimpleIdentitySet[B]
17+
def map[B <: AnyRef](f: Elem => B): SimpleIdentitySet[B] =
18+
var acc: SimpleIdentitySet[B] = SimpleIdentitySet.empty
19+
foreach(x => acc += f(x))
20+
acc
1821
def /: [A, E >: Elem <: AnyRef](z: A)(f: (A, E) => A): A
1922
def toList: List[Elem]
2023
def iterator: Iterator[Elem]
@@ -63,7 +66,7 @@ object SimpleIdentitySet {
6366
def contains[E <: AnyRef](x: E): Boolean = false
6467
def foreach(f: Nothing => Unit): Unit = ()
6568
def exists[E <: AnyRef](p: E => Boolean): Boolean = false
66-
def map[B <: AnyRef](f: Nothing => B): SimpleIdentitySet[B] = empty
69+
override def map[B <: AnyRef](f: Nothing => B): SimpleIdentitySet[B] = empty
6770
def /: [A, E <: AnyRef](z: A)(f: (A, E) => A): A = z
6871
def toList = Nil
6972
def iterator = Iterator.empty
@@ -79,7 +82,7 @@ object SimpleIdentitySet {
7982
def foreach(f: Elem => Unit): Unit = f(x0.asInstanceOf[Elem])
8083
def exists[E >: Elem <: AnyRef](p: E => Boolean): Boolean =
8184
p(x0.asInstanceOf[E])
82-
def map[B <: AnyRef](f: Elem => B): SimpleIdentitySet[B] =
85+
override def map[B <: AnyRef](f: Elem => B): SimpleIdentitySet[B] =
8386
Set1(f(x0.asInstanceOf[Elem]))
8487
def /: [A, E >: Elem <: AnyRef](z: A)(f: (A, E) => A): A =
8588
f(z, x0.asInstanceOf[E])
@@ -99,8 +102,10 @@ object SimpleIdentitySet {
99102
def foreach(f: Elem => Unit): Unit = { f(x0.asInstanceOf[Elem]); f(x1.asInstanceOf[Elem]) }
100103
def exists[E >: Elem <: AnyRef](p: E => Boolean): Boolean =
101104
p(x0.asInstanceOf[E]) || p(x1.asInstanceOf[E])
102-
def map[B <: AnyRef](f: Elem => B): SimpleIdentitySet[B] =
103-
Set2(f(x0.asInstanceOf[Elem]), f(x1.asInstanceOf[Elem]))
105+
override def map[B <: AnyRef](f: Elem => B): SimpleIdentitySet[B] =
106+
val y0 = f(x0.asInstanceOf[Elem])
107+
val y1 = f(x1.asInstanceOf[Elem])
108+
if y0 eq y1 then Set1(y0) else Set2(y0, y1)
104109
def /: [A, E >: Elem <: AnyRef](z: A)(f: (A, E) => A): A =
105110
f(f(z, x0.asInstanceOf[E]), x1.asInstanceOf[E])
106111
def toList = x0.asInstanceOf[Elem] :: x1.asInstanceOf[Elem] :: Nil
@@ -133,8 +138,12 @@ object SimpleIdentitySet {
133138
}
134139
def exists[E >: Elem <: AnyRef](p: E => Boolean): Boolean =
135140
p(x0.asInstanceOf[E]) || p(x1.asInstanceOf[E]) || p(x2.asInstanceOf[E])
136-
def map[B <: AnyRef](f: Elem => B): SimpleIdentitySet[B] =
137-
Set3(f(x0.asInstanceOf[Elem]), f(x1.asInstanceOf[Elem]), f(x2.asInstanceOf[Elem]))
141+
override def map[B <: AnyRef](f: Elem => B): SimpleIdentitySet[B] =
142+
val y0 = f(x0.asInstanceOf[Elem])
143+
val y1 = f(x1.asInstanceOf[Elem])
144+
val y2 = f(x2.asInstanceOf[Elem])
145+
if (y0 ne y1) && (y0 ne y2) && (y1 ne y2) then Set3(y0, y1, y2)
146+
else super.map(f)
138147
def /: [A, E >: Elem <: AnyRef](z: A)(f: (A, E) => A): A =
139148
f(f(f(z, x0.asInstanceOf[E]), x1.asInstanceOf[E]), x2.asInstanceOf[E])
140149
def toList = x0.asInstanceOf[Elem] :: x1.asInstanceOf[Elem] :: x2.asInstanceOf[Elem] :: Nil
@@ -182,8 +191,6 @@ object SimpleIdentitySet {
182191
}
183192
def exists[E >: Elem <: AnyRef](p: E => Boolean): Boolean =
184193
xs.asInstanceOf[Array[E]].exists(p)
185-
def map[B <: AnyRef](f: Elem => B): SimpleIdentitySet[B] =
186-
SetN(xs.map(x => f(x.asInstanceOf[Elem]).asInstanceOf[AnyRef]))
187194
def /: [A, E >: Elem <: AnyRef](z: A)(f: (A, E) => A): A =
188195
xs.asInstanceOf[Array[E]].foldLeft(z)(f)
189196
def toList: List[Elem] = {

0 commit comments

Comments
 (0)