Skip to content

Commit 667b757

Browse files
committed
Drop all but one usages of @uncheckedCaptures from stdlib
1 parent e54c2ac commit 667b757

32 files changed

+100
-131
lines changed

tests/pos-special/stdlib/collection/IterableOnce.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ package scala
1414
package collection
1515

1616
import scala.annotation.tailrec
17-
import scala.annotation.unchecked.{uncheckedVariance, uncheckedCaptures}
17+
import scala.annotation.unchecked.uncheckedVariance
1818
import scala.collection.mutable.StringBuilder
1919
import scala.language.implicitConversions
2020
import scala.math.{Numeric, Ordering}
@@ -1341,8 +1341,8 @@ object IterableOnceOps:
13411341
// Moved out of trait IterableOnceOps to here, since universal traits cannot
13421342
// have nested classes in Scala 3
13431343
private class Maximized[X, B](descriptor: String)(f: X -> B)(cmp: (B, B) -> Boolean) extends AbstractFunction2[Maximized[X, B], X, Maximized[X, B]] {
1344-
var maxElem: X @uncheckedCaptures = null.asInstanceOf[X]
1345-
var maxF: B @uncheckedCaptures = null.asInstanceOf[B]
1344+
var maxElem: X = null.asInstanceOf[X]
1345+
var maxF: B = null.asInstanceOf[B]
13461346
var nonEmpty = false
13471347
def toOption: Option[X] = if (nonEmpty) Some(maxElem) else None
13481348
def result: X = if (nonEmpty) maxElem else throw new UnsupportedOperationException(s"empty.$descriptor")

tests/pos-special/stdlib/collection/Iterator.scala

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,9 @@ package scala.collection
1414

1515
import scala.collection.mutable.{ArrayBuffer, ArrayBuilder, Builder, ImmutableBuilder}
1616
import scala.annotation.tailrec
17-
import scala.annotation.unchecked.{uncheckedVariance, uncheckedCaptures}
17+
import scala.annotation.unchecked.uncheckedVariance
1818
import scala.runtime.Statics
1919
import language.experimental.captureChecking
20-
import annotation.unchecked.uncheckedCaptures
2120

2221

2322
/** Iterators are data structures that allow to iterate over a sequence
@@ -161,12 +160,12 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite
161160

162161
require(size >= 1 && step >= 1, f"size=$size%d and step=$step%d, but both must be positive")
163162

164-
private[this] var buffer: Array[B @uncheckedCaptures] = null // current result
165-
private[this] var prev: Array[B @uncheckedCaptures] = null // if sliding, overlap from previous result
163+
private[this] var buffer: Array[B] = null // current result
164+
private[this] var prev: Array[B] = null // if sliding, overlap from previous result
166165
private[this] var first = true // if !first, advancing may skip ahead
167166
private[this] var filled = false // whether the buffer is "hot"
168167
private[this] var partial = true // whether to emit partial sequence
169-
private[this] var padding: () -> B @uncheckedCaptures = null // what to pad short sequences with
168+
private[this] var padding: () -> B = null // what to pad short sequences with
170169
private[this] def pad = padding != null // irrespective of partial flag
171170
private[this] def newBuilder = {
172171
val b = ArrayBuilder.make[Any]
@@ -258,7 +257,7 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite
258257
}
259258
// segment must have data, and must be complete unless they allow partial
260259
val ok = index > 0 && (partial || index == size)
261-
if (ok) buffer = builder.result().asInstanceOf[Array[B @uncheckedCaptures]]
260+
if (ok) buffer = builder.result().asInstanceOf[Array[B]]
262261
else prev = null
263262
ok
264263
}
@@ -417,8 +416,7 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite
417416

418417
@deprecated("Call scanRight on an Iterable instead.", "2.13.0")
419418
def scanRight[B](z: B)(op: (A, B) => B): Iterator[B]^{this} =
420-
ArrayBuffer.from[A @uncheckedCaptures](this).scanRight(z)(op).iterator
421-
// @uncheckedCaptures is safe since the ArrayBuffer is local temporrary storage
419+
ArrayBuffer.from[A](this).scanRight(z)(op).iterator
422420

423421
def indexWhere(p: A => Boolean, from: Int = 0): Int = {
424422
var i = math.max(from, 0)
@@ -561,7 +559,7 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite
561559
*/
562560
def distinctBy[B](f: A -> B): Iterator[A]^{this} = new AbstractIterator[A] {
563561

564-
private[this] val traversedValues = mutable.HashSet.empty[B @uncheckedCaptures]
562+
private[this] val traversedValues = mutable.HashSet.empty[B]
565563
private[this] var nextElementDefined: Boolean = false
566564
private[this] var nextElement: A = _
567565

@@ -704,7 +702,7 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite
704702
*/
705703
private[this] var status = 0
706704
private def store(a: A): Unit = {
707-
if (lookahead == null) lookahead = new mutable.Queue[A @uncheckedCaptures]
705+
if (lookahead == null) lookahead = new mutable.Queue[A]
708706
lookahead += a
709707
}
710708
def hasNext = {
@@ -867,8 +865,8 @@ trait Iterator[+A] extends IterableOnce[A] with IterableOnceOps[A, Iterator, Ite
867865
* @note Reuse: $consumesOneAndProducesTwoIterators
868866
*/
869867
def duplicate: (Iterator[A]^{this}, Iterator[A]^{this}) = {
870-
val gap = new scala.collection.mutable.Queue[A @uncheckedCaptures]
871-
var ahead: Iterator[A @uncheckedCaptures] = null // ahead is captured by Partner, so A is not recognized as parametric
868+
val gap = new scala.collection.mutable.Queue[A]
869+
var ahead: Iterator[A] = null // ahead is captured by Partner, so A is not recognized as parametric
872870
class Partner extends AbstractIterator[A] {
873871
override def knownSize: Int = self.synchronized {
874872
val thisSize = self.knownSize
@@ -1145,9 +1143,9 @@ object Iterator extends IterableFactory[Iterator] {
11451143
* Nested ConcatIterators are merged to avoid blowing the stack.
11461144
*/
11471145
private final class ConcatIterator[+A](val from: Iterator[A]^) extends AbstractIterator[A] {
1148-
private var current: Iterator[A @uncheckedCaptures]^{from*} = from
1149-
private var tail: ConcatIteratorCell[A @uncheckedVariance @uncheckedCaptures] = null
1150-
private var last: ConcatIteratorCell[A @uncheckedVariance @uncheckedCaptures] = null
1146+
private var current: Iterator[A]^{from*} = from
1147+
private var tail: ConcatIteratorCell[A @uncheckedVariance] = null
1148+
private var last: ConcatIteratorCell[A @uncheckedVariance] = null
11511149
private var currentHasNextChecked = false
11521150

11531151
def hasNext =
@@ -1216,7 +1214,7 @@ object Iterator extends IterableFactory[Iterator] {
12161214
}
12171215
}
12181216

1219-
private[this] final class ConcatIteratorCell[A](head: => IterableOnce[A]^, var tail: ConcatIteratorCell[A @uncheckedCaptures]) {
1217+
private[this] final class ConcatIteratorCell[A](head: => IterableOnce[A]^, var tail: ConcatIteratorCell[A]) {
12201218
def headIterator: Iterator[A]^{this} = head.iterator // CC todo: can't use {head} as capture set, gives "cannot establish a reference"
12211219
}
12221220

@@ -1277,8 +1275,8 @@ object Iterator extends IterableFactory[Iterator] {
12771275
* type `A` and update an internal state of type `S`.
12781276
*/
12791277
private final class UnfoldIterator[A, S](init: S)(f: S => Option[(A, S)])extends AbstractIterator[A] {
1280-
private[this] var state: S @uncheckedCaptures = init
1281-
private[this] var nextResult: Option[(A, S)] @uncheckedCaptures = null
1278+
private[this] var state: S = init
1279+
private[this] var nextResult: Option[(A, S)] = null
12821280

12831281
override def hasNext: Boolean = {
12841282
if (nextResult eq null) {

tests/pos-special/stdlib/collection/Seq.scala

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@ import Searching.{Found, InsertionPoint, SearchResult}
1818
import scala.annotation.nowarn
1919
import language.experimental.captureChecking
2020
import caps.unsafe.unsafeAssumePure
21-
import scala.annotation.unchecked.uncheckedCaptures
2221

2322
/** Base trait for sequence collections
2423
*
@@ -601,8 +600,7 @@ trait SeqOps[+A, +CC[_], +C] extends Any with SeqViewOps[A, CC, C] { self =>
601600
if (!hasNext)
602601
Iterator.empty.next()
603602

604-
val forcedElms = new mutable.ArrayBuffer[A @uncheckedCaptures](elms.size) ++= elms
605-
// uncheckedCaptures OK since used only locally
603+
val forcedElms = new mutable.ArrayBuffer[A](elms.size) ++= elms
606604
val result = (newSpecificBuilder ++= forcedElms).result()
607605
var i = idxs.length - 2
608606
while(i >= 0 && idxs(i) >= idxs(i+1))
@@ -893,7 +891,7 @@ trait SeqOps[+A, +CC[_], +C] extends Any with SeqViewOps[A, CC, C] { self =>
893891
* part of the result, but any following occurrences will.
894892
*/
895893
def diff[B >: A](that: Seq[B]): C = {
896-
val occ = occCounts[B @uncheckedCaptures](that)
894+
val occ = occCounts[B](that)
897895
fromSpecific(iterator.filter { x =>
898896
var include = false
899897
occ.updateWith(x) {
@@ -918,7 +916,7 @@ trait SeqOps[+A, +CC[_], +C] extends Any with SeqViewOps[A, CC, C] { self =>
918916
* in the result, but any following occurrences will be omitted.
919917
*/
920918
def intersect[B >: A](that: Seq[B]): C = {
921-
val occ = occCounts[B @uncheckedCaptures](that)
919+
val occ = occCounts[B](that)
922920
fromSpecific(iterator.filter { x =>
923921
var include = true
924922
occ.updateWith(x) {

tests/pos-special/stdlib/collection/SeqView.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -196,7 +196,7 @@ object SeqView {
196196
// contains items of another type, we'd get a CCE anyway)
197197
// - the cast doesn't actually do anything in the runtime because the
198198
// type of A is not known and Array[_] is Array[AnyRef]
199-
immutable.ArraySeq.unsafeWrapArray(arr.asInstanceOf[Array[A @uncheckedCaptures]])
199+
immutable.ArraySeq.unsafeWrapArray(arr.asInstanceOf[Array[A]])
200200
}
201201
}
202202
evaluated = true

tests/pos-special/stdlib/collection/StrictOptimizedSeqOps.scala

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212

1313
package scala.collection
1414
import language.experimental.captureChecking
15-
import scala.annotation.unchecked.uncheckedCaptures
1615

1716
/**
1817
* Trait that overrides operations on sequences in order
@@ -25,7 +24,7 @@ trait StrictOptimizedSeqOps [+A, +CC[_], +C]
2524

2625
override def distinctBy[B](f: A -> B): C = {
2726
val builder = newSpecificBuilder
28-
val seen = mutable.HashSet.empty[B @uncheckedCaptures]
27+
val seen = mutable.HashSet.empty[B]
2928
val it = this.iterator
3029
while (it.hasNext) {
3130
val next = it.next()
@@ -80,7 +79,7 @@ trait StrictOptimizedSeqOps [+A, +CC[_], +C]
8079
override def diff[B >: A](that: Seq[B]): C =
8180
if (isEmpty || that.isEmpty) coll
8281
else {
83-
val occ = occCounts[B @uncheckedCaptures](that)
82+
val occ = occCounts[B](that)
8483
val b = newSpecificBuilder
8584
for (x <- this) {
8685
occ.updateWith(x) {
@@ -98,7 +97,7 @@ trait StrictOptimizedSeqOps [+A, +CC[_], +C]
9897
override def intersect[B >: A](that: Seq[B]): C =
9998
if (isEmpty || that.isEmpty) empty
10099
else {
101-
val occ = occCounts[B @uncheckedCaptures](that)
100+
val occ = occCounts[B](that)
102101
val b = newSpecificBuilder
103102
for (x <- this) {
104103
occ.updateWith(x) {

tests/pos-special/stdlib/collection/View.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ package scala.collection
1515
import scala.annotation.{nowarn, tailrec}
1616
import scala.collection.mutable.{ArrayBuffer, Builder}
1717
import scala.collection.immutable.LazyList
18-
import scala.annotation.unchecked.uncheckedCaptures
1918
import language.experimental.captureChecking
2019

2120
/** Views are collections whose transformation operations are non strict: the resulting elements
@@ -449,7 +448,7 @@ object View extends IterableFactory[View] {
449448
}
450449

451450
private final class TakeRightIterator[A](underlying: Iterator[A]^, maxlen: Int) extends AbstractIterator[A] {
452-
private[this] var current: Iterator[A @uncheckedCaptures]^{underlying} = underlying
451+
private[this] var current: Iterator[A]^{underlying} = underlying
453452
private[this] var len: Int = -1
454453
private[this] var pos: Int = 0
455454
private[this] var buf: ArrayBuffer[AnyRef] = _

tests/pos-special/stdlib/collection/generic/DefaultSerializationProxy.scala

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,6 @@ import java.io.{ObjectInputStream, ObjectOutputStream}
1717
import scala.collection.{Factory, Iterable}
1818
import scala.collection.mutable.Builder
1919
import language.experimental.captureChecking
20-
import scala.annotation.unchecked.uncheckedCaptures
2120

2221
/** The default serialization proxy for collection implementations.
2322
*
@@ -29,8 +28,7 @@ import scala.annotation.unchecked.uncheckedCaptures
2928
@SerialVersionUID(3L)
3029
final class DefaultSerializationProxy[A](factory: Factory[A, Any], @transient private[this] val coll: Iterable[A]) extends Serializable {
3130

32-
@transient protected var builder: Builder[A @uncheckedCaptures, Any] = _
33-
// @uncheckedCaptures OK since builder is used only locally when reading objects
31+
@transient protected var builder: Builder[A, Any] = _
3432

3533
private[this] def writeObject(out: ObjectOutputStream): Unit = {
3634
out.defaultWriteObject()

tests/pos-special/stdlib/collection/generic/IsSeq.scala

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ package generic
1616
import scala.reflect.ClassTag
1717
import language.experimental.captureChecking
1818
import language.experimental.captureChecking
19-
import scala.annotation.unchecked.uncheckedCaptures
2019

2120
/** Type class witnessing that a collection representation type `Repr` has
2221
* elements of type `A` and has a conversion to `SeqOps[A, Iterable, C]`, for
@@ -100,7 +99,7 @@ object IsSeq {
10099
new SeqOps[A, mutable.ArraySeq, Array[A]] {
101100
def apply(i: Int): A = a(i)
102101
def length: Int = a.length
103-
def toIterable: Iterable[A] = mutable.ArraySeq.make[A @uncheckedCaptures](a)
102+
def toIterable: Iterable[A] = mutable.ArraySeq.make[A](a)
104103
protected def coll: Array[A] = a
105104
protected def fromSpecific(coll: IterableOnce[A]^): Array[A] = Array.from(coll)
106105
def iterableFactory: FreeSeqFactory[mutable.ArraySeq] = mutable.ArraySeq.untagged

tests/pos-special/stdlib/collection/immutable/ArraySeq.scala

Lines changed: 9 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ import scala.runtime.ScalaRunTime
2424
import scala.util.Sorting
2525
import scala.util.hashing.MurmurHash3
2626
import language.experimental.captureChecking
27-
import scala.annotation.unchecked.uncheckedCaptures
2827

2928
/**
3029
* An immutable array.
@@ -59,7 +58,7 @@ sealed abstract class ArraySeq[+A]
5958
def unsafeArrayAsAnyArray = unsafeArray.asInstanceOf[Array[Any]]
6059

6160
protected def evidenceIterableFactory: ArraySeq.type = ArraySeq
62-
protected def iterableEvidence: ClassTag[A @uncheckedVariance @uncheckedCaptures] = elemTag.asInstanceOf[ClassTag[A]]
61+
protected def iterableEvidence: ClassTag[A @uncheckedVariance] = elemTag.asInstanceOf[ClassTag[A]]
6362

6463
def stepper[S <: Stepper[_]](implicit shape: StepperShape[A, S]): S with EfficientSplit
6564

@@ -109,17 +108,17 @@ sealed abstract class ArraySeq[+A]
109108
null
110109
else if (thisIsObj) {
111110
// A and B are objects
112-
val ax = this.unsafeArray.asInstanceOf[Array[A @uncheckedCaptures]]
113-
val ay = that.unsafeArray.asInstanceOf[Array[B @uncheckedCaptures]]
111+
val ax = this.unsafeArray.asInstanceOf[Array[A]]
112+
val ay = that.unsafeArray.asInstanceOf[Array[B]]
114113
val len = ax.length + ay.length
115114
val a = new Array[AnyRef](len)
116115
System.arraycopy(ax, 0, a, 0, ax.length)
117116
System.arraycopy(ay, 0, a, ax.length, ay.length)
118117
ArraySeq.unsafeWrapArray(a).asInstanceOf[ArraySeq[B]]
119118
} else {
120119
// A is a primative and B = A. Use this instance's protected ClassTag.
121-
val ax = this.unsafeArray.asInstanceOf[Array[A @uncheckedCaptures]]
122-
val ay = that.unsafeArray.asInstanceOf[Array[A @uncheckedCaptures]]
120+
val ax = this.unsafeArray.asInstanceOf[Array[A]]
121+
val ay = that.unsafeArray.asInstanceOf[Array[A]]
123122
val len = ax.length + ay.length
124123
val a = iterableEvidence.newArray(len)
125124
System.arraycopy(ax, 0, a, 0, ax.length)
@@ -186,7 +185,7 @@ sealed abstract class ArraySeq[+A]
186185
strictOptimizedZip[B, ArraySeq[(A, B)]](that, iterableFactory.newBuilder)
187186
}
188187

189-
private inline def ops[A](xs: Array[A @uncheckedCaptures]): ArrayOps[A] = new ArrayOps[A @uncheckedCaptures](xs)
188+
private inline def ops[A](xs: Array[A]): ArrayOps[A] = new ArrayOps[A](xs)
190189

191190
override def take(n: Int): ArraySeq[A] =
192191
if (unsafeArray.length <= n)
@@ -290,12 +289,12 @@ object ArraySeq extends StrictOptimizedClassTagSeqFactory[ArraySeq] { self =>
290289
}
291290

292291
def newBuilder[A : ClassTag]: Builder[A, ArraySeq[A]] =
293-
ArrayBuffer.newBuilder[A @uncheckedCaptures].mapResult(b => unsafeWrapArray[A](b.toArray))
292+
ArrayBuffer.newBuilder[A].mapResult(b => unsafeWrapArray[A](b.toArray))
294293

295294
override def fill[A : ClassTag](n: Int)(elem: => A): ArraySeq[A] = tabulate(n)(_ => elem)
296295

297296
override def tabulate[A : ClassTag](n: Int)(f: Int => A): ArraySeq[A] = {
298-
val elements = Array.ofDim[A @uncheckedCaptures](scala.math.max(n, 0))
297+
val elements = Array.ofDim[A](scala.math.max(n, 0))
299298
var i = 0
300299
while (i < n) {
301300
ScalaRunTime.array_update(elements, i, f(i))
@@ -316,7 +315,7 @@ object ArraySeq extends StrictOptimizedClassTagSeqFactory[ArraySeq] { self =>
316315
* `ArraySeq.unsafeWrapArray(a.asInstanceOf[Array[Int]])` does not work, it throws a
317316
* `ClassCastException` at runtime.
318317
*/
319-
def unsafeWrapArray[T](x: Array[T @uncheckedCaptures]): ArraySeq[T] = ((x: @unchecked) match {
318+
def unsafeWrapArray[T](x: Array[T]): ArraySeq[T] = ((x: @unchecked) match {
320319
case null => null
321320
case x: Array[AnyRef] => new ofRef[AnyRef](x)
322321
case x: Array[Int] => new ofInt(x)

tests/pos-special/stdlib/collection/immutable/HashMap.scala

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@ import scala.runtime.AbstractFunction2
2626
import scala.runtime.Statics.releaseFence
2727
import scala.util.hashing.MurmurHash3
2828
import language.experimental.captureChecking
29-
import scala.annotation.unchecked.uncheckedCaptures
3029

3130
/** This class implements immutable maps using a Compressed Hash-Array Mapped Prefix-tree.
3231
* See paper https://michael.steindorfer.name/publications/oopsla15.pdf for more details.
@@ -1768,7 +1767,7 @@ private final class BitmapIndexedMapNode[K, +V](
17681767
} else {
17691768
mapOfNewNodes |= bitpos
17701769
if (newNodes eq null) {
1771-
newNodes = mutable.Queue.empty[MapNode[K, V] @uncheckedCaptures]
1770+
newNodes = mutable.Queue.empty[MapNode[K, V]]
17721771
}
17731772
newNodes += newSubNode
17741773
}
@@ -1853,7 +1852,7 @@ private final class BitmapIndexedMapNode[K, +V](
18531852
private final class HashCollisionMapNode[K, +V ](
18541853
val originalHash: Int,
18551854
val hash: Int,
1856-
var content: Vector[(K, V @uV) @uncheckedCaptures]
1855+
var content: Vector[(K, V @uV)]
18571856
) extends MapNode[K, V] {
18581857

18591858
import Node._
@@ -2157,7 +2156,7 @@ private final class MapKeyValueTupleReverseIterator[K, V](rootNode: MapNode[K, V
21572156
private final class MapKeyValueTupleHashIterator[K, V](rootNode: MapNode[K, V])
21582157
extends ChampBaseReverseIterator[MapNode[K, V]](rootNode) with Iterator[Any] {
21592158
private[this] var hash = 0
2160-
private[this] var value: V @uncheckedCaptures = _
2159+
private[this] var value: V = _
21612160
override def hashCode(): Int = MurmurHash3.tuple2Hash(hash, value.##, MurmurHash3.productSeed)
21622161
def next() = {
21632162
if (!hasNext)
@@ -2229,12 +2228,12 @@ private[immutable] final class HashMapBuilder[K, V] extends ReusableBuilder[(K,
22292228
/** The last given out HashMap as a return value of `result()`, if any, otherwise null.
22302229
* Indicates that on next add, the elements should be copied to an identical structure, before continuing
22312230
* mutations. */
2232-
private var aliased: HashMap[K, V] @uncheckedCaptures = _
2231+
private var aliased: HashMap[K, V] = _
22332232

22342233
private def isAliased: Boolean = aliased != null
22352234

22362235
/** The root node of the partially build hashmap */
2237-
private var rootNode: BitmapIndexedMapNode[K, V] @uncheckedCaptures = newEmptyRootNode
2236+
private var rootNode: BitmapIndexedMapNode[K, V] = newEmptyRootNode
22382237

22392238
private[immutable] def getOrElse[V0 >: V](key: K, value: V0): V0 =
22402239
if (rootNode.size == 0) value

0 commit comments

Comments
 (0)