Skip to content

Commit 68ef035

Browse files
committed
Fixed TreeSet newCanBuildFrom ambiguity
Fixed ScalaCheck treeset.scala compiler error and reinstated t2030.scala as a pos test by adding a newCanBuildFrom override in object TreeSet as suggested in this comment on related Dotty changes, scala/scala3#1246 (comment) This change will be made obsolete when the new collections land.
1 parent 0407d6a commit 68ef035

File tree

6 files changed

+70
-7
lines changed

6 files changed

+70
-7
lines changed

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

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ object TreeSet extends ImmutableSortedSetFactory[TreeSet] {
2424
implicit def implicitBuilder[A](implicit ordering: Ordering[A]): Builder[A, TreeSet[A]] = newBuilder[A](ordering)
2525
override def newBuilder[A](implicit ordering: Ordering[A]): Builder[A, TreeSet[A]] =
2626
new SetBuilder(empty[A](ordering))
27+
override implicit def newCanBuildFrom[A](implicit ord : Ordering[A]) : CanBuildFrom[Coll, A, TreeSet[A]] = super.newCanBuildFrom
2728

2829
/** The empty set of this type
2930
*/

test/files/neg/t2030.check

Lines changed: 0 additions & 7 deletions
This file was deleted.

test/files/neg/t2509-7b.check

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
t2509-7b.scala:30: error: ambiguous implicit values:
2+
both method make in object X of type => Both[X,X]
3+
and method make in trait Factory of type => Both[Y,Y]
4+
match expected type Both[Y,X]
5+
get
6+
^
7+
one error found

test/files/neg/t2509-7b.scala

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
class Both[-A, +B]
2+
3+
trait Factory[A] {
4+
implicit def make: Both[A, A] = new Both[A, A]
5+
}
6+
7+
trait X
8+
object X extends Factory[X] {
9+
override implicit def make: Both[X, X] = super.make
10+
}
11+
12+
class Y extends X
13+
object Y extends Factory[Y] {
14+
// See test/files/pos/t2509-7a.scala ... discussion below
15+
// override implicit def make: Both[Y, Y] = super.make
16+
}
17+
18+
object Test {
19+
def get(implicit ev: Both[Y, X]) = ev
20+
21+
// There are two possible implicits here: X.make and Y.make, neither are
22+
// subtype of each other, so who wins?
23+
// - Under the old scheme it's X.make because `isAsGood` sees that X.make is defined
24+
// in X whereas Y.make is defined in Factory
25+
// - Under the new scheme it's ambiguous because we replace contravariance by covariance
26+
// in top-level type parameters so Y.make is treated as a subtype of X.make
27+
// In both schemes we can get Y.make to win by uncommenting the override for make in Y
28+
// (Y wins against X because `isDerived` also considers the subtyping relationships
29+
// of companion classes)
30+
get
31+
}
File renamed without changes.

test/files/pos/t2509-7a.scala

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
class Both[-A, +B]
2+
3+
trait Factory[A] {
4+
implicit def make: Both[A, A] = new Both[A, A]
5+
}
6+
7+
trait X
8+
object X extends Factory[X] {
9+
override implicit def make: Both[X, X] = super.make
10+
}
11+
12+
class Y extends X
13+
object Y extends Factory[Y] {
14+
// See test/files/neg/t2509-7b.scala ... discussion below
15+
override implicit def make: Both[Y, Y] = super.make
16+
}
17+
18+
object Test {
19+
def get(implicit ev: Both[Y, X]) = ev
20+
21+
// There are two possible implicits here: X.make and Y.make, neither are
22+
// subtype of each other, so who wins?
23+
// - Under the old scheme it's X.make because `isAsGood` sees that X.make is defined
24+
// in X whereas Y.make is defined in Factory
25+
// - Under the new scheme it's ambiguous because we replace contravariance by covariance
26+
// in top-level type parameters so Y.make is treated as a subtype of X.make
27+
// In both schemes we can get Y.make to win by uncommenting the override for make in Y
28+
// (Y wins against X because `isDerived` also considers the subtyping relationships
29+
// of companion classes)
30+
get
31+
}

0 commit comments

Comments
 (0)