@@ -16,6 +16,8 @@ import scala.annotation.implicitNotFound
16
16
import scala .collection .mutable .Builder
17
17
import scala .collection .immutable .WrappedString
18
18
import scala .reflect .ClassTag
19
+ import language .experimental .captureChecking
20
+ import caps .unsafe .unsafeAssumePure
19
21
20
22
/** Builds a collection of type `C` from elements of type `A` when a source collection of type `From` is available.
21
23
* Implicit instances of `BuildFrom` are available for all collection types.
@@ -26,7 +28,11 @@ import scala.reflect.ClassTag
26
28
*/
27
29
@ implicitNotFound(msg = " Cannot construct a collection of type ${C} with elements of type ${A} based on a collection of type ${From}." )
28
30
trait BuildFrom [- From , - A , + C ] extends Any { self =>
29
- def fromSpecific (from : From )(it : IterableOnce [A ]): C
31
+ def fromSpecific (from : From )(it : IterableOnce [A ]^ ): C
32
+ // !!! this is wrong, we need two versions of fromSpecific; one mapping
33
+ // to C^{it} when C is an Iterable, and one mapping to C when C is a Seq, Map, or Set.
34
+ // But that requires a large scale refactoring of BuildFrom. The unsafeAssumePure
35
+ // calls in this file are needed to sweep that problem under the carpet.
30
36
31
37
/** Get a Builder for the collection. For non-strict collection types this will use an intermediate buffer.
32
38
* Building collections with `fromSpecific` is preferred because it can be lazy for lazy collections. */
@@ -37,7 +43,7 @@ trait BuildFrom[-From, -A, +C] extends Any { self =>
37
43
38
44
/** Partially apply a BuildFrom to a Factory */
39
45
def toFactory (from : From ): Factory [A , C ] = new Factory [A , C ] {
40
- def fromSpecific (it : IterableOnce [A ]): C = self.fromSpecific(from)(it)
46
+ def fromSpecific (it : IterableOnce [A ]^ ): C = self.fromSpecific(from)(it)
41
47
def newBuilder : Builder [A , C ] = self.newBuilder(from)
42
48
}
43
49
}
@@ -48,42 +54,42 @@ object BuildFrom extends BuildFromLowPriority1 {
48
54
implicit def buildFromMapOps [CC [X , Y ] <: Map [X , Y ] with MapOps [X , Y , CC , _], K0 , V0 , K , V ]: BuildFrom [CC [K0 , V0 ] with Map [K0 , V0 ], (K , V ), CC [K , V ] with Map [K , V ]] = new BuildFrom [CC [K0 , V0 ], (K , V ), CC [K , V ]] {
49
55
// TODO: Reuse a prototype instance
50
56
def newBuilder (from : CC [K0 , V0 ]): Builder [(K , V ), CC [K , V ]] = (from : MapOps [K0 , V0 , CC , _]).mapFactory.newBuilder[K , V ]
51
- def fromSpecific (from : CC [K0 , V0 ])(it : IterableOnce [(K , V )]): CC [K , V ] = (from : MapOps [K0 , V0 , CC , _]).mapFactory.from(it)
57
+ def fromSpecific (from : CC [K0 , V0 ])(it : IterableOnce [(K , V )]^ ): CC [K , V ] = (from : MapOps [K0 , V0 , CC , _]).mapFactory.from(it)
52
58
}
53
59
54
60
/** Build the source collection type from a SortedMapOps */
55
61
implicit def buildFromSortedMapOps [CC [X , Y ] <: SortedMap [X , Y ] with SortedMapOps [X , Y , CC , _], K0 , V0 , K : Ordering , V ]: BuildFrom [CC [K0 , V0 ] with SortedMap [K0 , V0 ], (K , V ), CC [K , V ] with SortedMap [K , V ]] = new BuildFrom [CC [K0 , V0 ], (K , V ), CC [K , V ]] {
56
62
def newBuilder (from : CC [K0 , V0 ]): Builder [(K , V ), CC [K , V ]] = (from : SortedMapOps [K0 , V0 , CC , _]).sortedMapFactory.newBuilder[K , V ]
57
- def fromSpecific (from : CC [K0 , V0 ])(it : IterableOnce [(K , V )]): CC [K , V ] = (from : SortedMapOps [K0 , V0 , CC , _]).sortedMapFactory.from(it)
63
+ def fromSpecific (from : CC [K0 , V0 ])(it : IterableOnce [(K , V )]^ ): CC [K , V ] = (from : SortedMapOps [K0 , V0 , CC , _]).sortedMapFactory.from(it)
58
64
}
59
65
60
66
implicit def buildFromBitSet [C <: BitSet with BitSetOps [C ]]: BuildFrom [C , Int , C ] =
61
67
new BuildFrom [C , Int , C ] {
62
- def fromSpecific (from : C )(it : IterableOnce [Int ]): C = from.bitSetFactory.fromSpecific(it)
68
+ def fromSpecific (from : C )(it : IterableOnce [Int ]^ ): C = from.bitSetFactory.fromSpecific(it)
63
69
def newBuilder (from : C ): Builder [Int , C ] = from.bitSetFactory.newBuilder
64
70
}
65
71
66
72
implicit val buildFromString : BuildFrom [String , Char , String ] =
67
73
new BuildFrom [String , Char , String ] {
68
- def fromSpecific (from : String )(it : IterableOnce [Char ]): String = Factory .stringFactory.fromSpecific(it)
74
+ def fromSpecific (from : String )(it : IterableOnce [Char ]^ ): String = Factory .stringFactory.fromSpecific(it)
69
75
def newBuilder (from : String ): Builder [Char , String ] = Factory .stringFactory.newBuilder
70
76
}
71
77
72
78
implicit val buildFromWrappedString : BuildFrom [WrappedString , Char , WrappedString ] =
73
79
new BuildFrom [WrappedString , Char , WrappedString ] {
74
- def fromSpecific (from : WrappedString )(it : IterableOnce [Char ]): WrappedString = WrappedString .fromSpecific(it)
80
+ def fromSpecific (from : WrappedString )(it : IterableOnce [Char ]^ ): WrappedString = WrappedString .fromSpecific(it)
75
81
def newBuilder (from : WrappedString ): mutable.Builder [Char , WrappedString ] = WrappedString .newBuilder
76
82
}
77
83
78
84
implicit def buildFromArray [A : ClassTag ]: BuildFrom [Array [_], A , Array [A ]] =
79
85
new BuildFrom [Array [_], A , Array [A ]] {
80
- def fromSpecific (from : Array [_])(it : IterableOnce [A ]): Array [A ] = Factory .arrayFactory[A ].fromSpecific(it)
86
+ def fromSpecific (from : Array [_])(it : IterableOnce [A ]^ ): Array [A ] = Factory .arrayFactory[A ].fromSpecific(it)
81
87
def newBuilder (from : Array [_]): Builder [A , Array [A ]] = Factory .arrayFactory[A ].newBuilder
82
88
}
83
89
84
90
implicit def buildFromView [A , B ]: BuildFrom [View [A ], B , View [B ]] =
85
91
new BuildFrom [View [A ], B , View [B ]] {
86
- def fromSpecific (from : View [A ])(it : IterableOnce [B ]): View [B ] = View .from(it)
92
+ def fromSpecific (from : View [A ])(it : IterableOnce [B ]^ ): View [B ] = View .from(it).unsafeAssumePure
87
93
def newBuilder (from : View [A ]): Builder [B , View [B ]] = View .newBuilder
88
94
}
89
95
@@ -97,12 +103,12 @@ trait BuildFromLowPriority1 extends BuildFromLowPriority2 {
97
103
// test in test/junit/scala/collection/BuildFromTest.scala and discussion in https://github.com/scala/scala/pull/10209
98
104
implicit def buildFromSortedSetOps [CC [X ] <: SortedSet [X ] with SortedSetOps [X , CC , _], A0 , A : Ordering ]: BuildFrom [CC [A0 ] with SortedSet [A0 ], A , CC [A ] with SortedSet [A ]] = new BuildFrom [CC [A0 ], A , CC [A ]] {
99
105
def newBuilder (from : CC [A0 ]): Builder [A , CC [A ]] = (from : SortedSetOps [A0 , CC , _]).sortedIterableFactory.newBuilder[A ]
100
- def fromSpecific (from : CC [A0 ])(it : IterableOnce [A ]): CC [A ] = (from : SortedSetOps [A0 , CC , _]).sortedIterableFactory.from(it)
106
+ def fromSpecific (from : CC [A0 ])(it : IterableOnce [A ]^ ): CC [A ] = (from : SortedSetOps [A0 , CC , _]).sortedIterableFactory.from(it)
101
107
}
102
108
103
109
implicit def fallbackStringCanBuildFrom [A ]: BuildFrom [String , A , immutable.IndexedSeq [A ]] =
104
110
new BuildFrom [String , A , immutable.IndexedSeq [A ]] {
105
- def fromSpecific (from : String )(it : IterableOnce [A ]): immutable.IndexedSeq [A ] = immutable.IndexedSeq .from(it)
111
+ def fromSpecific (from : String )(it : IterableOnce [A ]^ ): immutable.IndexedSeq [A ] = immutable.IndexedSeq .from(it)
106
112
def newBuilder (from : String ): Builder [A , immutable.IndexedSeq [A ]] = immutable.IndexedSeq .newBuilder[A ]
107
113
}
108
114
}
@@ -112,11 +118,11 @@ trait BuildFromLowPriority2 {
112
118
implicit def buildFromIterableOps [CC [X ] <: Iterable [X ] with IterableOps [X , CC , _], A0 , A ]: BuildFrom [CC [A0 ], A , CC [A ]] = new BuildFrom [CC [A0 ], A , CC [A ]] {
113
119
// TODO: Reuse a prototype instance
114
120
def newBuilder (from : CC [A0 ]): Builder [A , CC [A ]] = (from : IterableOps [A0 , CC , _]).iterableFactory.newBuilder[A ]
115
- def fromSpecific (from : CC [A0 ])(it : IterableOnce [A ]): CC [A ] = (from : IterableOps [A0 , CC , _]).iterableFactory.from(it)
121
+ def fromSpecific (from : CC [A0 ])(it : IterableOnce [A ]^ ): CC [A ] = (from : IterableOps [A0 , CC , _]).iterableFactory.from(it).unsafeAssumePure
116
122
}
117
123
118
124
implicit def buildFromIterator [A ]: BuildFrom [Iterator [_], A , Iterator [A ]] = new BuildFrom [Iterator [_], A , Iterator [A ]] {
119
125
def newBuilder (from : Iterator [_]): mutable.Builder [A , Iterator [A ]] = Iterator .newBuilder
120
- def fromSpecific (from : Iterator [_])(it : IterableOnce [A ]): Iterator [A ] = Iterator .from(it)
126
+ def fromSpecific (from : Iterator [_])(it : IterableOnce [A ]^ ): Iterator [A ] = Iterator .from(it).unsafeAssumePure
121
127
}
122
128
}
0 commit comments