Skip to content

Commit e4f06aa

Browse files
authored
Merge pull request #6855 from dotty-staging/refactor-iarray
Refactor IArray so that creation methods can be inlined
2 parents e579bfa + 85c4bb3 commit e4f06aa

File tree

2 files changed

+71
-63
lines changed

2 files changed

+71
-63
lines changed

compiler/src/dotty/tools/dotc/ast/Desugar.scala

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1153,17 +1153,21 @@ object desugar {
11531153
* - all pattern, value and method definitions
11541154
* - non-class type definitions
11551155
* - implicit classes and objects
1156-
* - companion objects of opaque types
1156+
* - "companion objects" of wrapped type definitions
1157+
* (i.e. objects having the same name as a wrapped type)
11571158
*/
11581159
def packageDef(pdef: PackageDef)(implicit ctx: Context): PackageDef = {
1159-
val opaqueNames = pdef.stats.collect {
1160-
case stat: TypeDef if stat.mods.is(Opaque) => stat.name
1160+
def isWrappedType(stat: TypeDef): Boolean =
1161+
!stat.isClassDef || stat.mods.isOneOf(DelegateOrImplicit)
1162+
val wrappedTypeNames = pdef.stats.collect {
1163+
case stat: TypeDef if isWrappedType(stat) => stat.name
11611164
}
11621165
def needsObject(stat: Tree) = stat match {
11631166
case _: ValDef | _: PatDef | _: DefDef | _: Export => true
11641167
case stat: ModuleDef =>
1165-
stat.mods.isOneOf(DelegateOrImplicit) || opaqueNames.contains(stat.name.stripModuleClassSuffix.toTypeName)
1166-
case stat: TypeDef => !stat.isClassDef || stat.mods.isOneOf(DelegateOrImplicit)
1168+
stat.mods.isOneOf(DelegateOrImplicit) ||
1169+
wrappedTypeNames.contains(stat.name.stripModuleClassSuffix.toTypeName)
1170+
case stat: TypeDef => isWrappedType(stat)
11671171
case _ => false
11681172
}
11691173
val (nestedStats, topStats) = pdef.stats.partition(needsObject)

library/src-bootstrapped/scala/IArray.scala

Lines changed: 62 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -4,66 +4,70 @@ import reflect.ClassTag
44
/** An immutable array. An `IArray[T]` has the same representation as an `Array[T]`,
55
* but it cannot be updated. Unlike regular arrays, immutable arrays are covariant.
66
*/
7-
opaque type IArray[+T] = Array[_ <: T]
8-
9-
/** Defines extension methods for immutable arrays */
10-
implicit object arrayOps {
11-
12-
/** The selection operation on an immutable array.
13-
*
14-
* @param arr the immutable array
15-
* @param n the index of the element to select
16-
* @return the element of the array at the given index
17-
*/
18-
def (arr: IArray[Byte]) apply (n: Int): Byte = arr.asInstanceOf[Array[Byte]].apply(n)
19-
def (arr: IArray[Short]) apply (n: Int): Short = arr.asInstanceOf[Array[Short]].apply(n)
20-
def (arr: IArray[Char]) apply (n: Int): Char = arr.asInstanceOf[Array[Char]].apply(n)
21-
def (arr: IArray[Int]) apply (n: Int): Int = arr.asInstanceOf[Array[Int]].apply(n)
22-
def (arr: IArray[Long]) apply (n: Int): Long = arr.asInstanceOf[Array[Long]].apply(n)
23-
def (arr: IArray[Float]) apply (n: Int): Float = arr.asInstanceOf[Array[Float]].apply(n)
24-
def (arr: IArray[Double]) apply (n: Int): Double = arr.asInstanceOf[Array[Double]].apply(n)
25-
def (arr: IArray[T]) apply[T <: Object] (n: Int): T = arr.asInstanceOf[Array[T]].apply(n)
26-
def (arr: IArray[T]) apply[T] (n: Int): T = arr.asInstanceOf[Array[T]].apply(n)
27-
28-
/** The number of elements in an immutable array
29-
* @param arr the immutable array
30-
*/
31-
def (arr: IArray[Byte]) length: Int = arr.asInstanceOf[Array[Byte]].length
32-
def (arr: IArray[Short]) length: Int = arr.asInstanceOf[Array[Short]].length
33-
def (arr: IArray[Char]) length: Int = arr.asInstanceOf[Array[Char]].length
34-
def (arr: IArray[Int]) length: Int = arr.asInstanceOf[Array[Int]].length
35-
def (arr: IArray[Long]) length: Int = arr.asInstanceOf[Array[Long]].length
36-
def (arr: IArray[Float]) length: Int = arr.asInstanceOf[Array[Float]].length
37-
def (arr: IArray[Double]) length: Int = arr.asInstanceOf[Array[Double]].length
38-
def (arr: IArray[Object]) length: Int = arr.asInstanceOf[Array[Object]].length
39-
def (arr: IArray[T]) length[T] : Int = arr.asInstanceOf[Array[T]].length
7+
object opaques {
8+
opaque type IArray[+T] = Array[_ <: T]
9+
10+
/** Defines extension methods for immutable arrays */
11+
given arrayOps {
12+
13+
/** The selection operation on an immutable array.
14+
*
15+
* @param arr the immutable array
16+
* @param n the index of the element to select
17+
* @return the element of the array at the given index
18+
*/
19+
def (arr: IArray[Byte]) apply (n: Int): Byte = arr.asInstanceOf[Array[Byte]].apply(n)
20+
def (arr: IArray[Short]) apply (n: Int): Short = arr.asInstanceOf[Array[Short]].apply(n)
21+
def (arr: IArray[Char]) apply (n: Int): Char = arr.asInstanceOf[Array[Char]].apply(n)
22+
def (arr: IArray[Int]) apply (n: Int): Int = arr.asInstanceOf[Array[Int]].apply(n)
23+
def (arr: IArray[Long]) apply (n: Int): Long = arr.asInstanceOf[Array[Long]].apply(n)
24+
def (arr: IArray[Float]) apply (n: Int): Float = arr.asInstanceOf[Array[Float]].apply(n)
25+
def (arr: IArray[Double]) apply (n: Int): Double = arr.asInstanceOf[Array[Double]].apply(n)
26+
def (arr: IArray[T]) apply[T <: Object] (n: Int): T = arr.asInstanceOf[Array[T]].apply(n)
27+
def (arr: IArray[T]) apply[T] (n: Int): T = arr.asInstanceOf[Array[T]].apply(n)
28+
29+
/** The number of elements in an immutable array
30+
* @param arr the immutable array
31+
*/
32+
def (arr: IArray[Byte]) length: Int = arr.asInstanceOf[Array[Byte]].length
33+
def (arr: IArray[Short]) length: Int = arr.asInstanceOf[Array[Short]].length
34+
def (arr: IArray[Char]) length: Int = arr.asInstanceOf[Array[Char]].length
35+
def (arr: IArray[Int]) length: Int = arr.asInstanceOf[Array[Int]].length
36+
def (arr: IArray[Long]) length: Int = arr.asInstanceOf[Array[Long]].length
37+
def (arr: IArray[Float]) length: Int = arr.asInstanceOf[Array[Float]].length
38+
def (arr: IArray[Double]) length: Int = arr.asInstanceOf[Array[Double]].length
39+
def (arr: IArray[Object]) length: Int = arr.asInstanceOf[Array[Object]].length
40+
def (arr: IArray[T]) length[T] : Int = arr.asInstanceOf[Array[T]].length
41+
}
4042
}
43+
type IArray[+T] = opaques.IArray[T]
4144

4245
object IArray {
4346

4447
/** An immutable array of length 0.
4548
*/
46-
def empty[T: ClassTag]: IArray[T] = new Array[T](0)
49+
def empty[T: ClassTag]: IArray[T] = new Array[T](0).asInstanceOf
4750

4851
/** An immutable array with given elements.
4952
*/
50-
def apply[T: ClassTag](xs: T*): IArray[T] = Array(xs: _*)
51-
def apply(x: Boolean, xs: Boolean*): IArray[Boolean] = Array(x, xs: _*)
52-
def apply(x: Byte, xs: Byte*): IArray[Byte] = Array(x, xs: _*)
53-
def apply(x: Short, xs: Short*): IArray[Short] = Array(x, xs: _*)
54-
def apply(x: Char, xs: Char*): IArray[Char] = Array(x, xs: _*)
55-
def apply(x: Int, xs: Int*): IArray[Int] = Array(x, xs: _*)
56-
def apply(x: Long, xs: Long*): IArray[Long] = Array(x, xs: _*)
57-
def apply(x: Float, xs: Float*): IArray[Float] = Array(x, xs: _*)
58-
def apply(x: Double, xs: Double*): IArray[Double] = Array(x, xs: _*)
59-
def apply(x: Unit, xs: Unit*): IArray[Unit] = Array(x, xs: _*)
53+
def apply[T: ClassTag](xs: T*): IArray[T] = Array(xs: _*).asInstanceOf
54+
def apply(x: Boolean, xs: Boolean*): IArray[Boolean] = Array(x, xs: _*).asInstanceOf
55+
def apply(x: Byte, xs: Byte*): IArray[Byte] = Array(x, xs: _*).asInstanceOf
56+
def apply(x: Short, xs: Short*): IArray[Short] = Array(x, xs: _*).asInstanceOf
57+
def apply(x: Char, xs: Char*): IArray[Char] = Array(x, xs: _*).asInstanceOf
58+
def apply(x: Int, xs: Int*): IArray[Int] = Array(x, xs: _*).asInstanceOf
59+
def apply(x: Long, xs: Long*): IArray[Long] = Array(x, xs: _*).asInstanceOf
60+
def apply(x: Float, xs: Float*): IArray[Float] = Array(x, xs: _*).asInstanceOf
61+
def apply(x: Double, xs: Double*): IArray[Double] = Array(x, xs: _*).asInstanceOf
62+
def apply(x: Unit, xs: Unit*): IArray[Unit] = Array(x, xs: _*).asInstanceOf
6063

6164
/** Concatenates all arrays into a single immutable array.
6265
*
6366
* @param xss the given immutable arrays
6467
* @return the array created from concatenating `xss`
6568
*/
66-
def concat[T: ClassTag](xss: IArray[T]*): IArray[T] = Array.concat[T](xss.asInstanceOf[Seq[Array[T]]]: _*)
69+
def concat[T: ClassTag](xss: IArray[T]*): IArray[T] =
70+
Array.concat[T](xss.asInstanceOf[Seq[Array[T]]]: _*).asInstanceOf
6771

6872
/** Returns an immutable array that contains the results of some element computation a number
6973
* of times. Each element is determined by a separate computation.
@@ -72,7 +76,7 @@ object IArray {
7276
* @param elem the element computation
7377
*/
7478
def fill[T: ClassTag](n: Int)(elem: => T): IArray[T] =
75-
Array.fill(n)(elem)
79+
Array.fill(n)(elem).asInstanceOf
7680

7781
/** Returns a two-dimensional immutable array that contains the results of some element computation a number
7882
* of times. Each element is determined by a separate computation.
@@ -82,7 +86,7 @@ object IArray {
8286
* @param elem the element computation
8387
*/
8488
def fill[T: ClassTag](n1: Int, n2: Int)(elem: => T): IArray[IArray[T]] =
85-
Array.fill(n1, n2)(elem)
89+
Array.fill(n1, n2)(elem).asInstanceOf
8690

8791
/** Returns a three-dimensional immutable array that contains the results of some element computation a number
8892
* of times. Each element is determined by a separate computation.
@@ -93,7 +97,7 @@ object IArray {
9397
* @param elem the element computation
9498
*/
9599
def fill[T: ClassTag](n1: Int, n2: Int, n3: Int)(elem: => T): IArray[IArray[IArray[T]]] =
96-
Array.fill(n1, n2, n3)(elem)
100+
Array.fill(n1, n2, n3)(elem).asInstanceOf
97101

98102
/** Returns a four-dimensional immutable array that contains the results of some element computation a number
99103
* of times. Each element is determined by a separate computation.
@@ -105,7 +109,7 @@ object IArray {
105109
* @param elem the element computation
106110
*/
107111
def fill[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int)(elem: => T): IArray[IArray[IArray[IArray[T]]]] =
108-
Array.fill(n1, n2, n3, n4)(elem)
112+
Array.fill(n1, n2, n3, n4)(elem).asInstanceOf
109113

110114
/** Returns a five-dimensional immutable array that contains the results of some element computation a number
111115
* of times. Each element is determined by a separate computation.
@@ -118,7 +122,7 @@ object IArray {
118122
* @param elem the element computation
119123
*/
120124
def fill[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(elem: => T): IArray[IArray[IArray[IArray[IArray[T]]]]] =
121-
Array.fill(n1, n2, n3, n4, n5)(elem)
125+
Array.fill(n1, n2, n3, n4, n5)(elem).asInstanceOf
122126

123127
/** Returns an immutable array containing values of a given function over a range of integer
124128
* values starting from 0.
@@ -127,7 +131,7 @@ object IArray {
127131
* @param f The function computing element values
128132
*/
129133
def tabulate[T: ClassTag](n: Int)(f: Int => T): IArray[T] =
130-
Array.tabulate(n)(f)
134+
Array.tabulate(n)(f).asInstanceOf
131135

132136
/** Returns a two-dimensional immutable array containing values of a given function
133137
* over ranges of integer values starting from `0`.
@@ -137,7 +141,7 @@ object IArray {
137141
* @param f The function computing element values
138142
*/
139143
def tabulate[T: ClassTag](n1: Int, n2: Int)(f: (Int, Int) => T): IArray[IArray[T]] =
140-
Array.tabulate(n1, n2)(f)
144+
Array.tabulate(n1, n2)(f).asInstanceOf
141145

142146
/** Returns a three-dimensional immutable array containing values of a given function
143147
* over ranges of integer values starting from `0`.
@@ -148,7 +152,7 @@ object IArray {
148152
* @param f The function computing element values
149153
*/
150154
def tabulate[T: ClassTag](n1: Int, n2: Int, n3: Int)(f: (Int, Int, Int) => T): IArray[IArray[IArray[T]]] =
151-
Array.tabulate(n1, n2, n3)(f)
155+
Array.tabulate(n1, n2, n3)(f).asInstanceOf
152156

153157
/** Returns a four-dimensional immutable array containing values of a given function
154158
* over ranges of integer values starting from `0`.
@@ -160,7 +164,7 @@ object IArray {
160164
* @param f The function computing element values
161165
*/
162166
def tabulate[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int)(f: (Int, Int, Int, Int) => T): IArray[IArray[IArray[IArray[T]]]] =
163-
Array.tabulate(n1, n2, n3, n4)(f)
167+
Array.tabulate(n1, n2, n3, n4)(f).asInstanceOf
164168

165169
/** Returns a five-dimensional immutable array containing values of a given function
166170
* over ranges of integer values starting from `0`.
@@ -173,7 +177,7 @@ object IArray {
173177
* @param f The function computing element values
174178
*/
175179
def tabulate[T: ClassTag](n1: Int, n2: Int, n3: Int, n4: Int, n5: Int)(f: (Int, Int, Int, Int, Int) => T): IArray[IArray[IArray[IArray[IArray[T]]]]] =
176-
Array.tabulate(n1, n2, n3, n4, n5)(f)
180+
Array.tabulate(n1, n2, n3, n4, n5)(f).asInstanceOf
177181

178182
/** Returns an immutable array containing a sequence of increasing integers in a range.
179183
*
@@ -182,7 +186,7 @@ object IArray {
182186
* @return the immutable array with values in range `start, start + 1, ..., end - 1`
183187
* up to, but excluding, `end`.
184188
*/
185-
def range(start: Int, end: Int): IArray[Int] = Array.range(start, end)
189+
def range(start: Int, end: Int): IArray[Int] = Array.range(start, end).asInstanceOf
186190

187191
/** Returns an immutable array containing equally spaced values in some integer interval.
188192
*
@@ -191,7 +195,7 @@ object IArray {
191195
* @param step the increment value of the array (may not be zero)
192196
* @return the immutable array with values in `start, start + step, ...` up to, but excluding `end`
193197
*/
194-
def range(start: Int, end: Int, step: Int): IArray[Int] = Array.range(start, end, step)
198+
def range(start: Int, end: Int, step: Int): IArray[Int] = Array.range(start, end, step).asInstanceOf
195199

196200
/** Returns an immutable array containing repeated applications of a function to a start value.
197201
*
@@ -200,7 +204,7 @@ object IArray {
200204
* @param f the function that is repeatedly applied
201205
* @return the immutable array returning `len` values in the sequence `start, f(start), f(f(start)), ...`
202206
*/
203-
def iterate[T: ClassTag](start: T, len: Int)(f: T => T): IArray[T] = Array.iterate(start, len)(f)
207+
def iterate[T: ClassTag](start: T, len: Int)(f: T => T): IArray[T] = Array.iterate(start, len)(f).asInstanceOf
204208

205209
/** Returns a decomposition of the array into a sequence. This supports
206210
* a pattern match like `{ case IArray(x,y,z) => println('3 elements')}`.

0 commit comments

Comments
 (0)