Skip to content
This repository was archived by the owner on Sep 1, 2020. It is now read-only.

Commit 1ae80e8

Browse files
committed
Fix ParVector#padTo
This was throwing a UnsupportedOperationError for small operations. The parallel collections test suite sets `-minSuccessfulTests 5` in test/files/scalacheck/parallel-collections/pc.scala, which is far lower thatn the default of 100, and means that we are less likely to falsify properties. This parameter seems to have been added in scala#2476, assuming I'm reading it correctly. Not sure of the motiviation, perhaps just to make the slowest part of the scalacheck test suite run faster? I haven't changed the paramater now, but instead have included a one element collection in generator. I also found that when the test failed, Scalacheck would try to minimize the example, but did so assuming that the elements of the tuple of test data could be independentally shrunk. This breaks the invariant that the two collections contain equal elements, and led to spurious error reports. I have disabled shrinking in all tests tests affected by this.
1 parent 22dac31 commit 1ae80e8

File tree

7 files changed

+49
-43
lines changed

7 files changed

+49
-43
lines changed

src/library/scala/collection/parallel/immutable/package.scala

+6-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,12 @@ package immutable {
2020
self =>
2121

2222
def apply(idx: Int) = if (0 <= idx && idx < length) elem else throw new IndexOutOfBoundsException("" + idx)
23-
override def seq = throw new UnsupportedOperationException
23+
override def seq: collection.immutable.Seq[T] = new collection.AbstractSeq[T] with collection.immutable.Seq[T] {
24+
override def length: Int = self.length
25+
override def apply(idx: Int): T = self.apply(idx)
26+
override def iterator: Iterator[T] = Iterator.continually(elem).take(length)
27+
override def par: ParSeq[T] = self
28+
}
2429
def update(idx: Int, elem: T) = throw new UnsupportedOperationException
2530

2631
class ParIterator(var i: Int = 0, val until: Int = length, elem: T = self.elem) extends SeqSplitter[T] {

test/files/scalacheck/parallel-collections/ParallelArrayCheck.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ abstract class ParallelArrayCheck[T](tp: String) extends ParallelSeqCheck[T]("Pa
4444
pa
4545
}
4646

47-
property("array mappings must be equal") = forAll(collectionPairs) { case (t, coll) =>
47+
property("array mappings must be equal") = forAllNoShrink(collectionPairs) { case (t, coll) =>
4848
val results = for ((f, ind) <- mapFunctions.zipWithIndex)
4949
yield ("op index: " + ind) |: t.map(f) == coll.map(f)
5050
results.reduceLeft(_ && _)

test/files/scalacheck/parallel-collections/ParallelArrayViewCheck.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@
4646
// pa.view
4747
// }
4848

49-
// property("forces must be equal") = forAll(collectionPairs) { case (s, coll) =>
49+
// property("forces must be equal") = forAllNoShrink(collectionPairs) { case (s, coll) =>
5050
// val smodif = (s ++ s).reverse.take(s.length).reverse.zip(s).drop(s.length / 2)
5151
// val cmodif = (coll ++ s).reverse.take(s.length).reverse.zip(s).drop(s.length / 2).force
5252
// smodif == cmodif

test/files/scalacheck/parallel-collections/ParallelIterableCheck.scala

+22-22
Original file line numberDiff line numberDiff line change
@@ -109,7 +109,7 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
109109
println("cf == tf - " + (cf == tf))
110110
}
111111

112-
property("reductions must be equal for assoc. operators") = forAll(collectionPairs) { case (t, coll) =>
112+
property("reductions must be equal for assoc. operators") = forAllNoShrink(collectionPairs) { case (t, coll) =>
113113
if (t.size != 0) {
114114
val results = for ((op, ind) <- reduceOperators.zipWithIndex) yield {
115115
val tr = t.reduceLeft(op)
@@ -127,7 +127,7 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
127127
} else "has size 0" |: true
128128
}
129129

130-
property("counts must be equal") = forAll(collectionPairs) { case (t, coll) =>
130+
property("counts must be equal") = forAllNoShrink(collectionPairs) { case (t, coll) =>
131131
val results = for ((pred, ind) <- countPredicates.zipWithIndex) yield {
132132
val tc = t.count(pred)
133133
val cc = coll.count(pred)
@@ -143,19 +143,19 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
143143
results.reduceLeft(_ && _)
144144
}
145145

146-
property("forall must be equal") = forAll(collectionPairs) { case (t, coll) =>
146+
property("forall must be equal") = forAllNoShrink(collectionPairs) { case (t, coll) =>
147147
val results = for ((pred, ind) <- forallPredicates.zipWithIndex)
148148
yield ("op index: " + ind) |: t.forall(pred) == coll.forall(pred)
149149
results.reduceLeft(_ && _)
150150
}
151151

152-
property("exists must be equal") = forAll(collectionPairs) { case (t, coll) =>
152+
property("exists must be equal") = forAllNoShrink(collectionPairs) { case (t, coll) =>
153153
val results = for ((pred, ind) <- existsPredicates.zipWithIndex)
154154
yield ("op index: " + ind) |: t.exists(pred) == coll.exists(pred)
155155
results.reduceLeft(_ && _)
156156
}
157157

158-
property("both must find or not find an element") = forAll(collectionPairs) { case (t, coll) =>
158+
property("both must find or not find an element") = forAllNoShrink(collectionPairs) { case (t, coll) =>
159159
val results = for ((pred, ind) <- findPredicates.zipWithIndex) yield {
160160
val ft = t.find(pred)
161161
val fcoll = coll.find(pred)
@@ -164,7 +164,7 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
164164
results.reduceLeft(_ && _)
165165
}
166166

167-
property("mappings must be equal") = forAll(collectionPairs) { case (t, coll) =>
167+
property("mappings must be equal") = forAllNoShrink(collectionPairs) { case (t, coll) =>
168168
val results = for ((f, ind) <- mapFunctions.zipWithIndex) yield {
169169
val ms = t.map(f)
170170
val mp = coll.map(f)
@@ -185,7 +185,7 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
185185
results.reduceLeft(_ && _)
186186
}
187187

188-
property("collects must be equal") = forAll(collectionPairs) { case (t, coll) =>
188+
property("collects must be equal") = forAllNoShrink(collectionPairs) { case (t, coll) =>
189189
val results = for ((f, ind) <- partialMapFunctions.zipWithIndex) yield {
190190
val ps = t.collect(f)
191191
val pp = coll.collect(f)
@@ -201,12 +201,12 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
201201
results.reduceLeft(_ && _)
202202
}
203203

204-
property("flatMaps must be equal") = forAll(collectionPairs) { case (t, coll) =>
204+
property("flatMaps must be equal") = forAllNoShrink(collectionPairs) { case (t, coll) =>
205205
(for ((f, ind) <- flatMapFunctions.zipWithIndex)
206206
yield ("op index: " + ind) |: areEqual(t.flatMap(f), coll.flatMap(f))).reduceLeft(_ && _)
207207
}
208208

209-
property("filters must be equal") = forAll(collectionPairs) { case (t, coll) =>
209+
property("filters must be equal") = forAllNoShrink(collectionPairs) { case (t, coll) =>
210210
(for ((p, ind) <- filterPredicates.zipWithIndex) yield {
211211
val tf = t.filter(p)
212212
val cf = coll.filter(p)
@@ -235,7 +235,7 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
235235
}).reduceLeft(_ && _)
236236
}
237237

238-
property("filterNots must be equal") = forAll(collectionPairs) { case (t, coll) =>
238+
property("filterNots must be equal") = forAllNoShrink(collectionPairs) { case (t, coll) =>
239239
(for ((p, ind) <- filterNotPredicates.zipWithIndex) yield {
240240
val tf = t.filterNot(p)
241241
val cf = coll.filterNot(p)
@@ -244,7 +244,7 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
244244
}).reduceLeft(_ && _)
245245
}
246246

247-
if (!isCheckingViews) property("partitions must be equal") = forAll(collectionPairs) { case (t, coll) =>
247+
if (!isCheckingViews) property("partitions must be equal") = forAllNoShrink(collectionPairs) { case (t, coll) =>
248248
(for ((p, ind) <- partitionPredicates.zipWithIndex) yield {
249249
val tpart = t.partition(p)
250250
val cpart = coll.partition(p)
@@ -258,15 +258,15 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
258258
}).reduceLeft(_ && _)
259259
}
260260

261-
if (hasStrictOrder) property("takes must be equal") = forAll(collectionPairsWithLengths) { case (t, coll, n) =>
261+
if (hasStrictOrder) property("takes must be equal") = forAllNoShrink(collectionPairsWithLengths) { case (t, coll, n) =>
262262
("take " + n + " elements") |: t.take(n) == coll.take(n)
263263
}
264264

265-
if (hasStrictOrder) property("drops must be equal") = forAll(collectionPairsWithLengths) { case (t, coll, n) =>
265+
if (hasStrictOrder) property("drops must be equal") = forAllNoShrink(collectionPairsWithLengths) { case (t, coll, n) =>
266266
("drop " + n + " elements") |: t.drop(n) == coll.drop(n)
267267
}
268268

269-
if (hasStrictOrder) property("slices must be equal") = forAll(collectionPairsWith2Indices)
269+
if (hasStrictOrder) property("slices must be equal") = forAllNoShrink(collectionPairsWith2Indices)
270270
{ case (t, coll, fr, slicelength) =>
271271
val from = if (fr < 0) 0 else fr
272272
val until = if (from + slicelength > t.size) t.size else from + slicelength
@@ -290,7 +290,7 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
290290
("slice from " + from + " until " + until) |: tsl == collsl
291291
}
292292

293-
if (hasStrictOrder) property("splits must be equal") = forAll(collectionPairsWithLengths) { case (t, coll, n) =>
293+
if (hasStrictOrder) property("splits must be equal") = forAllNoShrink(collectionPairsWithLengths) { case (t, coll, n) =>
294294
val tspl = t.splitAt(n)
295295
val cspl = coll.splitAt(n)
296296
if (tspl != cspl) {
@@ -303,7 +303,7 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
303303
("splitAt " + n) |: tspl == cspl
304304
}
305305

306-
if (hasStrictOrder) property("takeWhiles must be equal") = forAll(collectionPairs) { case (t, coll) =>
306+
if (hasStrictOrder) property("takeWhiles must be equal") = forAllNoShrink(collectionPairs) { case (t, coll) =>
307307
(for ((pred, ind) <- takeWhilePredicates.zipWithIndex) yield {
308308
val tt = t.takeWhile(pred)
309309
val ct = coll.takeWhile(pred)
@@ -318,7 +318,7 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
318318
}).reduceLeft(_ && _)
319319
}
320320

321-
if (hasStrictOrder) property("spans must be equal") = forAll(collectionPairs) { case (t, coll) =>
321+
if (hasStrictOrder) property("spans must be equal") = forAllNoShrink(collectionPairs) { case (t, coll) =>
322322
(for ((pred, ind) <- spanPredicates.zipWithIndex) yield {
323323
val tsp = t.span(pred)
324324
val csp = coll.span(pred)
@@ -336,13 +336,13 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
336336
}).reduceLeft(_ && _)
337337
}
338338

339-
if (hasStrictOrder) property("dropWhiles must be equal") = forAll(collectionPairs) { case (t, coll) =>
339+
if (hasStrictOrder) property("dropWhiles must be equal") = forAllNoShrink(collectionPairs) { case (t, coll) =>
340340
(for ((pred, ind) <- dropWhilePredicates.zipWithIndex) yield {
341341
("operator " + ind) |: t.dropWhile(pred) == coll.dropWhile(pred)
342342
}).reduceLeft(_ && _)
343343
}
344344

345-
property("folds must be equal for assoc. operators") = forAll(collectionPairs) { case (t, coll) =>
345+
property("folds must be equal for assoc. operators") = forAllNoShrink(collectionPairs) { case (t, coll) =>
346346
(for (((first, op), ind) <- foldArguments.zipWithIndex) yield {
347347
val tres = t.foldLeft(first)(op)
348348
val cres = coll.fold(first)(op)
@@ -389,7 +389,7 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
389389
}
390390
}
391391

392-
if (hasStrictOrder) property("copies to array must be equal") = forAll(collectionPairs) { case (t, coll) =>
392+
if (hasStrictOrder) property("copies to array must be equal") = forAllNoShrink(collectionPairs) { case (t, coll) =>
393393
val tarr = newArray(t.size)
394394
val collarr = newArray(coll.size)
395395
t.copyToArray(tarr, 0, t.size)
@@ -403,7 +403,7 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
403403
tarr.toSeq == collarr.toSeq
404404
}
405405

406-
if (hasStrictOrder) property("scans must be equal") = forAll(collectionPairs) {
406+
if (hasStrictOrder) property("scans must be equal") = forAllNoShrink(collectionPairs) {
407407
case (t, coll) =>
408408
(for (((first, op), ind) <- foldArguments.zipWithIndex) yield {
409409
val tscan = t.scanLeft(first)(op)
@@ -419,7 +419,7 @@ abstract class ParallelIterableCheck[T](collName: String) extends Properties(col
419419
}).reduceLeft(_ && _)
420420
}
421421

422-
property("groupBy must be equal") = forAll(collectionPairs) {
422+
property("groupBy must be equal") = forAllNoShrink(collectionPairs) {
423423
case (t, coll) =>
424424
(for ((f, ind) <- groupByFunctions.zipWithIndex) yield {
425425
val tgroup = t.groupBy(f)

test/files/scalacheck/parallel-collections/ParallelMapCheck1.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import scala.collection.parallel._
1717
abstract class ParallelMapCheck[K, V](collname: String) extends ParallelIterableCheck[(K, V)](collname) {
1818
type CollType <: ParMap[K, V]
1919

20-
property("gets iterated keys") = forAll(collectionPairs) {
20+
property("gets iterated keys") = forAllNoShrink(collectionPairs) {
2121
case (t, coll) =>
2222
val containsT = for ((k, v) <- t) yield (coll.get(k) == Some(v))
2323
val containsSelf = coll.map { case (k, v) => coll.get(k) == Some(v) }

test/files/scalacheck/parallel-collections/ParallelSeqCheck.scala

+17-16
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ abstract class ParallelSeqCheck[T](collName: String) extends ParallelIterableChe
2424
def fromSeq(s: Seq[T]): CollType
2525

2626
override def instances(vals: Seq[Gen[T]]): Gen[Seq[T]] = oneOf(
27+
Gen.const(ofSize(vals, 1)),
2728
sized(
2829
sz =>
2930
ofSize(vals, sz)
@@ -74,7 +75,7 @@ abstract class ParallelSeqCheck[T](collName: String) extends ParallelIterableChe
7475
coll.patch(updateStart, coll, howMany)
7576
}
7677

77-
property("segmentLengths must be equal") = forAll(collectionPairsWithLengths) { case (s, coll, len) =>
78+
property("segmentLengths must be equal") = forAllNoShrink(collectionPairsWithLengths) { case (s, coll, len) =>
7879
(for ((pred, ind) <- segmentLengthPredicates.zipWithIndex) yield {
7980
val slen = s.segmentLength(pred, if (len < 0) 0 else len)
8081
val clen = coll.segmentLength(pred, len)
@@ -88,13 +89,13 @@ abstract class ParallelSeqCheck[T](collName: String) extends ParallelIterableChe
8889
}).reduceLeft(_ && _)
8990
}
9091

91-
property("prefixLengths must be equal") = forAll(collectionPairs) { case (s, coll) =>
92+
property("prefixLengths must be equal") = forAllNoShrink(collectionPairs) { case (s, coll) =>
9293
(for ((pred, ind) <- segmentLengthPredicates.zipWithIndex) yield {
9394
("operator " + ind) |: s.prefixLength(pred) == coll.prefixLength(pred)
9495
}).reduceLeft(_ && _)
9596
}
9697

97-
property("indexWheres must be equal") = forAll(collectionPairsWithLengths) { case (s, coll, len) =>
98+
property("indexWheres must be equal") = forAllNoShrink(collectionPairsWithLengths) { case (s, coll, len) =>
9899
(for ((pred, ind) <- indexWherePredicates.zipWithIndex) yield {
99100
val sind = s.indexWhere(pred, len)
100101
val cind = coll.indexWhere(pred, len)
@@ -109,7 +110,7 @@ abstract class ParallelSeqCheck[T](collName: String) extends ParallelIterableChe
109110
}).reduceLeft(_ && _)
110111
}
111112

112-
property("lastIndexWheres must be equal") = forAll(collectionPairsWithLengths) { case (s, coll, len) =>
113+
property("lastIndexWheres must be equal") = forAllNoShrink(collectionPairsWithLengths) { case (s, coll, len) =>
113114
(for ((pred, ind) <- lastIndexWherePredicates.zipWithIndex) yield {
114115
val end = if (len >= s.size) s.size - 1 else len
115116
val sind = s.lastIndexWhere(pred, end)
@@ -118,7 +119,7 @@ abstract class ParallelSeqCheck[T](collName: String) extends ParallelIterableChe
118119
}).reduceLeft(_ && _)
119120
}
120121

121-
property("reverses must be equal") = forAll(collectionPairs) { case (s, coll) =>
122+
property("reverses must be equal") = forAllNoShrink(collectionPairs) { case (s, coll) =>
122123
(s.length == 0 && s.getClass == classOf[collection.immutable.Range]) ||
123124
{
124125
val sr = s.reverse
@@ -133,13 +134,13 @@ abstract class ParallelSeqCheck[T](collName: String) extends ParallelIterableChe
133134
}
134135
}
135136

136-
property("reverseMaps must be equal") = forAll(collectionPairs) { case (s, coll) =>
137+
property("reverseMaps must be equal") = forAllNoShrink(collectionPairs) { case (s, coll) =>
137138
(for ((f, ind) <- reverseMapFunctions.zipWithIndex) yield {
138139
("operator " + ind) |: s.reverseMap(f) == coll.reverseMap(f)
139140
}).reduceLeft(_ && _)
140141
}
141142

142-
property("sameElements must be equal") = forAll(collectionPairsWithModifiedWithLengths) {
143+
property("sameElements must be equal") = forAllNoShrink(collectionPairsWithModifiedWithLengths) {
143144
case (s, coll, collmodif, len) =>
144145
val pos = if (len < 0) 0 else len
145146
val scm = s.sameElements(collmodif)
@@ -171,7 +172,7 @@ abstract class ParallelSeqCheck[T](collName: String) extends ParallelIterableChe
171172
}).reduceLeft(_ && _)
172173
}
173174

174-
property("startsWiths must be equal") = forAll(collectionPairsWithModifiedWithLengths) {
175+
property("startsWiths must be equal") = forAllNoShrink(collectionPairsWithModifiedWithLengths) {
175176
case (s, coll, collmodif, len) =>
176177
val pos = if (len < 0) 0 else len
177178
("start with self" |: s.startsWith(s) == coll.startsWith(coll)) &&
@@ -195,7 +196,7 @@ abstract class ParallelSeqCheck[T](collName: String) extends ParallelIterableChe
195196
}).reduceLeft(_ && _)
196197
}
197198

198-
property("endsWiths must be equal") = forAll(collectionPairsWithModified) {
199+
property("endsWiths must be equal") = forAllNoShrink(collectionPairsWithModified) {
199200
case (s, coll, collmodif) =>
200201
("ends with self" |: s.endsWith(s) == coll.endsWith(s)) &&
201202
("ends with tail" |: (s.length == 0 || s.endsWith(s.tail) == coll.endsWith(coll.tail))) &&
@@ -214,7 +215,7 @@ abstract class ParallelSeqCheck[T](collName: String) extends ParallelIterableChe
214215
}).reduceLeft(_ && _)
215216
}
216217

217-
property("unions must be equal") = forAll(collectionPairsWithModified) { case (s, coll, collmodif) =>
218+
property("unions must be equal") = forAllNoShrink(collectionPairsWithModified) { case (s, coll, collmodif) =>
218219
("modified" |: s.union(collmodif.seq) == coll.union(collmodif)) &&
219220
("empty" |: s.union(Nil) == coll.union(fromSeq(Nil)))
220221
}
@@ -233,7 +234,7 @@ abstract class ParallelSeqCheck[T](collName: String) extends ParallelIterableChe
233234
("with one" |: (s.length == 0 || s.patch(from, List(s(0)), 1) == coll.patch(from, fromSeq(List(coll(0))), 1)))
234235
}
235236

236-
if (!isCheckingViews) property("updates must be equal") = forAll(collectionPairsWithLengths) { case (s, coll, len) =>
237+
if (!isCheckingViews) property("updates must be equal") = forAllNoShrink(collectionPairsWithLengths) { case (s, coll, len) =>
237238
val pos = if (len >= s.length) s.length - 1 else len
238239
if (s.length > 0) {
239240
val supd = s.updated(pos, s(0))
@@ -248,15 +249,15 @@ abstract class ParallelSeqCheck[T](collName: String) extends ParallelIterableChe
248249
} else "trivially" |: true
249250
}
250251

251-
property("prepends must be equal") = forAll(collectionPairs) { case (s, coll) =>
252+
property("prepends must be equal") = forAllNoShrink(collectionPairs) { case (s, coll) =>
252253
s.length == 0 || s(0) +: s == coll(0) +: coll
253254
}
254255

255-
property("appends must be equal") = forAll(collectionPairs) { case (s, coll) =>
256+
property("appends must be equal") = forAllNoShrink(collectionPairs) { case (s, coll) =>
256257
s.length == 0 || s :+ s(0) == coll :+ coll(0)
257258
}
258259

259-
property("padTos must be equal") = forAll(collectionPairsWithLengths) { case (s, coll, len) =>
260+
property("padTos must be equal") = forAllNoShrink(collectionPairsWithLengths) { case (s, coll, len) =>
260261
val someValue = sampleValue
261262
val sdoub = s.padTo(len * 2, someValue)
262263
val cdoub = coll.padTo(len * 2, someValue)
@@ -267,10 +268,10 @@ abstract class ParallelSeqCheck[T](collName: String) extends ParallelIterableChe
267268
println(cdoub)
268269
}
269270
("smaller" |: s.padTo(len / 2, someValue) == coll.padTo(len / 2, someValue)) &&
270-
("bigger" |: sdoub == cdoub)
271+
("bigger" |: sdoub == cdoub)
271272
}
272273

273-
property("corresponds must be equal") = forAll(collectionPairsWithModified) { case (s, coll, modified) =>
274+
property("corresponds must be equal") = forAllNoShrink(collectionPairsWithModified) { case (s, coll, modified) =>
274275
val modifcut = modified.toSeq.slice(0, modified.length)
275276
("self" |: s.corresponds(s)(_ == _) == coll.corresponds(coll)(_ == _)) &&
276277
("modified" |: s.corresponds(modified.seq)(_ == _) == coll.corresponds(modified)(_ == _)) &&

test/files/scalacheck/parallel-collections/ParallelSetCheck.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ import scala.collection.parallel._
1717
abstract class ParallelSetCheck[T](collname: String) extends ParallelIterableCheck[T](collname) {
1818
type CollType <: ParSet[T]
1919

20-
property("gets iterated keys") = forAll(collectionPairs) {
20+
property("gets iterated keys") = forAllNoShrink(collectionPairs) {
2121
case (t, coll) =>
2222
val containsT = for (elem <- t) yield (coll.contains(elem))
2323
val containsSelf = for (elem <- coll) yield (coll.contains(elem))

0 commit comments

Comments
 (0)