Skip to content

Commit 4366332

Browse files
committed
Set#concat: avoid clashing overloads by adding a DummyImplicit
Because Dotty adds mixing forwarders before erasure, classes can end up with forwarders for both the non-polymorphic and polymorphic concats that will clash after erasure.
1 parent fd8a658 commit 4366332

File tree

6 files changed

+11
-7
lines changed

6 files changed

+11
-7
lines changed

src/library/scala/collection/BitSet.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -233,7 +233,7 @@ trait BitSetOps[+C <: BitSet with BitSetOps[C]]
233233
coll.fromBitMaskNoCopy(a)
234234
}
235235

236-
override def concat(other: collection.IterableOnce[Int]): C = other match {
236+
override def concat(other: collection.IterableOnce[Int])(implicit dummy: DummyImplicit): C = other match {
237237
case otherBitset: BitSet =>
238238
val len = coll.nwords max otherBitset.nwords
239239
val words = new Array[Long](len)

src/library/scala/collection/Set.scala

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,10 @@ trait SetOps[A, +CC[_], +C <: SetOps[A, CC, C]]
176176
@deprecated("Use &- with an explicit collection argument instead of - with varargs", "2.13.0")
177177
def - (elem1: A, elem2: A, elems: A*): C = diff(elems.toSet + elem1 + elem2)
178178

179+
// The implicit dummy parameter is necessary to avoid erased signature clashes
180+
// between this `concat` and the polymorphic one defined in `IterableOps`.
181+
// Note that these clashes only happen in Dotty because it adds mixin
182+
// forwarders before erasure unlike Scala 2.
179183
/** Creates a new $coll by adding all elements contained in another collection to this $coll, omitting duplicates.
180184
*
181185
* This method takes a collection of elements and adds all elements, omitting duplicates, into $coll.
@@ -189,7 +193,7 @@ trait SetOps[A, +CC[_], +C <: SetOps[A, CC, C]]
189193
* @param that the collection containing the elements to add.
190194
* @return a new $coll with the given elements added, omitting duplicates.
191195
*/
192-
def concat(that: collection.IterableOnce[A]): C = fromSpecific(that match {
196+
def concat(that: collection.IterableOnce[A])(implicit dummy: DummyImplicit): C = fromSpecific(that match {
193197
case that: collection.Iterable[A] => new View.Concat(toIterable, that)
194198
case _ => iterator.concat(that.iterator)
195199
})
@@ -201,7 +205,7 @@ trait SetOps[A, +CC[_], +C <: SetOps[A, CC, C]]
201205
def + (elem1: A, elem2: A, elems: A*): C = fromSpecific(new View.Concat(new View.Appended(new View.Appended(toIterable, elem1), elem2), elems))
202206

203207
/** Alias for `concat` */
204-
@`inline` final def ++ (that: collection.IterableOnce[A]): C = concat(that)
208+
@`inline` final def ++ (that: collection.IterableOnce[A])(implicit dummy: DummyImplicit): C = concat(that)
205209

206210
/** Computes the union between of set and another set.
207211
*

src/library/scala/collection/StrictOptimizedSetOps.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ trait StrictOptimizedSetOps[A, +CC[_], +C <: SetOps[A, CC, C]]
2323
extends SetOps[A, CC, C]
2424
with StrictOptimizedIterableOps[A, CC, C] {
2525

26-
override def concat(that: IterableOnce[A]): C =
26+
override def concat(that: IterableOnce[A])(implicit dummy: DummyImplicit): C =
2727
strictOptimizedConcat(that, newSpecificBuilder)
2828

2929
}

src/library/scala/collection/immutable/HashSet.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ final class HashSet[A] private[immutable] (val rootNode: SetNode[A])
7373
if (rootNode ne newRootNode) new HashSet(newRootNode) else this
7474
}
7575

76-
override def concat(that: IterableOnce[A]): HashSet[A] = {
76+
override def concat(that: IterableOnce[A])(implicit dummy: DummyImplicit): HashSet[A] = {
7777
val builder = iterableFactory.newBuilder[A]
7878
builder ++= this
7979
builder ++= that

src/library/scala/collection/immutable/Set.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,7 @@ trait StrictOptimizedSetOps[A, +CC[X], +C <: SetOps[A, CC, C]]
7979
with collection.StrictOptimizedSetOps[A, CC, C]
8080
with StrictOptimizedIterableOps[A, CC, C] {
8181

82-
override def concat(that: collection.IterableOnce[A]): C = {
82+
override def concat(that: collection.IterableOnce[A])(implicit dummy: DummyImplicit): C = {
8383
var result: C = coll
8484
val it = that.iterator
8585
while (it.hasNext) result = result + it.next()

src/library/scala/collection/immutable/TreeSet.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -139,7 +139,7 @@ final class TreeSet[A] private[immutable] (private[immutable] val tree: RB.Tree[
139139
def excl(elem: A): TreeSet[A] =
140140
newSetOrSelf(RB.delete(tree, elem))
141141

142-
override def concat(that: collection.IterableOnce[A]): TreeSet[A] = {
142+
override def concat(that: collection.IterableOnce[A])(implicit dummy: DummyImplicit): TreeSet[A] = {
143143
val t = that match {
144144
case ts: TreeSet[A] if ordering == ts.ordering =>
145145
RB.union(tree, ts.tree)

0 commit comments

Comments
 (0)