Skip to content

Commit 6f08c06

Browse files
committed
Merge pull request scala#790 from axel22/issue/3326
Fix SI-3326.
2 parents df00b41 + 5362f3d commit 6f08c06

File tree

3 files changed

+90
-0
lines changed

3 files changed

+90
-0
lines changed

src/library/scala/collection/SortedMapLike.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,4 +72,12 @@ self =>
7272
for (e <- elems) m = m + e
7373
m
7474
}
75+
76+
/** Adds a number of elements provided by a traversable object
77+
* and returns a new collection with the added elements.
78+
*
79+
* @param xs the traversable object.
80+
*/
81+
override def ++[B1 >: B](xs: GenTraversableOnce[(A, B1)]): SortedMap[A, B1] =
82+
((repr: SortedMap[A, B1]) /: xs.seq) (_ + _)
7583
}

test/files/run/t3326.check

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
Map(2 -> Hello, 1 -> World)
2+
Map(5 -> Foo, 4 -> Bar)
3+
Map(5 -> Foo, 4 -> Bar, 2 -> Hello, 1 -> World)
4+
Map(3 -> ?, 2 -> Hello, 1 -> World)
5+
Map(2 -> Hello, 1 -> World)
6+
Map(5 -> Foo, 4 -> Bar)
7+
Map(5 -> Foo, 4 -> Bar, 2 -> Hello, 1 -> World)
8+
Map(3 -> ?, 2 -> Hello, 1 -> World)

test/files/run/t3326.scala

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
2+
3+
4+
import scala.math.Ordering
5+
6+
7+
8+
/** The heart of the problem - we want to retain the ordering when
9+
* using `++` on sorted maps.
10+
*
11+
* There are 2 `++` overloads - a generic one in traversables and
12+
* a map-specific one in `MapLike` - which knows about the ordering.
13+
*
14+
* The problem here is that the expected return type for the expression
15+
* in which `++` appears drives the decision of the overload that needs
16+
* to be taken.
17+
* The `collection.SortedMap` does not have `++` overridden to return
18+
* `SortedMap`, but `immutable.Map` instead.
19+
* This is why `collection.SortedMap` used to resort to the generic
20+
* `TraversableLike.++` which knows nothing about the ordering.
21+
*
22+
* To avoid `collection.SortedMap`s resort to the more generic `TraverableLike.++`,
23+
* we override the `MapLike.++` overload in `collection.SortedMap` to return
24+
* the proper type `SortedMap`.
25+
*/
26+
object Test {
27+
28+
def main(args: Array[String]) {
29+
testCollectionSorted()
30+
testImmutableSorted()
31+
}
32+
33+
def testCollectionSorted() {
34+
import collection._
35+
val order = implicitly[Ordering[Int]].reverse
36+
var m1: SortedMap[Int, String] = SortedMap.empty[Int, String](order)
37+
var m2: SortedMap[Int, String] = SortedMap.empty[Int, String](order)
38+
39+
m1 += (1 -> "World")
40+
m1 += (2 -> "Hello")
41+
42+
m2 += (4 -> "Bar")
43+
m2 += (5 -> "Foo")
44+
45+
val m3: SortedMap[Int, String] = m1 ++ m2
46+
47+
println(m1)
48+
println(m2)
49+
println(m3)
50+
51+
println(m1 + (3 -> "?"))
52+
}
53+
54+
def testImmutableSorted() {
55+
import collection.immutable._
56+
val order = implicitly[Ordering[Int]].reverse
57+
var m1: SortedMap[Int, String] = SortedMap.empty[Int, String](order)
58+
var m2: SortedMap[Int, String] = SortedMap.empty[Int, String](order)
59+
60+
m1 += (1 -> "World")
61+
m1 += (2 -> "Hello")
62+
63+
m2 += (4 -> "Bar")
64+
m2 += (5 -> "Foo")
65+
66+
val m3: SortedMap[Int, String] = m1 ++ m2
67+
68+
println(m1)
69+
println(m2)
70+
println(m3)
71+
72+
println(m1 + (3 -> "?"))
73+
}
74+
}

0 commit comments

Comments
 (0)