Skip to content

Refactor IArray so that creation methods can be inlined #6855

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Jul 15, 2019
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions compiler/src/dotty/tools/dotc/ast/Desugar.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1153,17 +1153,21 @@ object desugar {
* - all pattern, value and method definitions
* - non-class type definitions
* - implicit classes and objects
* - companion objects of opaque types
* - "companion objects" of wrapped type definitions
* (i.e. objects having the same name as a wrapped type)
*/
def packageDef(pdef: PackageDef)(implicit ctx: Context): PackageDef = {
val opaqueNames = pdef.stats.collect {
case stat: TypeDef if stat.mods.is(Opaque) => stat.name
def isWrappedType(stat: TypeDef): Boolean =
!stat.isClassDef || stat.mods.isOneOf(DelegateOrImplicit)
val wrappedTypeNames = pdef.stats.collect {
case stat: TypeDef if isWrappedType(stat) => stat.name
}
def needsObject(stat: Tree) = stat match {
case _: ValDef | _: PatDef | _: DefDef | _: Export => true
case stat: ModuleDef =>
stat.mods.isOneOf(DelegateOrImplicit) || opaqueNames.contains(stat.name.stripModuleClassSuffix.toTypeName)
case stat: TypeDef => !stat.isClassDef || stat.mods.isOneOf(DelegateOrImplicit)
stat.mods.isOneOf(DelegateOrImplicit) ||
wrappedTypeNames.contains(stat.name.stripModuleClassSuffix.toTypeName)
case stat: TypeDef => isWrappedType(stat)
case _ => false
}
val (nestedStats, topStats) = pdef.stats.partition(needsObject)
Expand Down
120 changes: 62 additions & 58 deletions library/src-bootstrapped/scala/IArray.scala
Original file line number Diff line number Diff line change
Expand Up @@ -4,66 +4,70 @@ import reflect.ClassTag
/** An immutable array. An `IArray[T]` has the same representation as an `Array[T]`,
* but it cannot be updated. Unlike regular arrays, immutable arrays are covariant.
*/
opaque type IArray[+T] = Array[_ <: T]

/** Defines extension methods for immutable arrays */
implicit object arrayOps {

/** The selection operation on an immutable array.
*
* @param arr the immutable array
* @param n the index of the element to select
* @return the element of the array at the given index
*/
def (arr: IArray[Byte]) apply (n: Int): Byte = arr.asInstanceOf[Array[Byte]].apply(n)
def (arr: IArray[Short]) apply (n: Int): Short = arr.asInstanceOf[Array[Short]].apply(n)
def (arr: IArray[Char]) apply (n: Int): Char = arr.asInstanceOf[Array[Char]].apply(n)
def (arr: IArray[Int]) apply (n: Int): Int = arr.asInstanceOf[Array[Int]].apply(n)
def (arr: IArray[Long]) apply (n: Int): Long = arr.asInstanceOf[Array[Long]].apply(n)
def (arr: IArray[Float]) apply (n: Int): Float = arr.asInstanceOf[Array[Float]].apply(n)
def (arr: IArray[Double]) apply (n: Int): Double = arr.asInstanceOf[Array[Double]].apply(n)
def (arr: IArray[T]) apply[T <: Object] (n: Int): T = arr.asInstanceOf[Array[T]].apply(n)
def (arr: IArray[T]) apply[T] (n: Int): T = arr.asInstanceOf[Array[T]].apply(n)

/** The number of elements in an immutable array
* @param arr the immutable array
*/
def (arr: IArray[Byte]) length: Int = arr.asInstanceOf[Array[Byte]].length
def (arr: IArray[Short]) length: Int = arr.asInstanceOf[Array[Short]].length
def (arr: IArray[Char]) length: Int = arr.asInstanceOf[Array[Char]].length
def (arr: IArray[Int]) length: Int = arr.asInstanceOf[Array[Int]].length
def (arr: IArray[Long]) length: Int = arr.asInstanceOf[Array[Long]].length
def (arr: IArray[Float]) length: Int = arr.asInstanceOf[Array[Float]].length
def (arr: IArray[Double]) length: Int = arr.asInstanceOf[Array[Double]].length
def (arr: IArray[Object]) length: Int = arr.asInstanceOf[Array[Object]].length
def (arr: IArray[T]) length[T] : Int = arr.asInstanceOf[Array[T]].length
object opaques {
opaque type IArray[+T] = Array[_ <: T]

/** Defines extension methods for immutable arrays */
given arrayOps {

/** The selection operation on an immutable array.
*
* @param arr the immutable array
* @param n the index of the element to select
* @return the element of the array at the given index
*/
def (arr: IArray[Byte]) apply (n: Int): Byte = arr.asInstanceOf[Array[Byte]].apply(n)
def (arr: IArray[Short]) apply (n: Int): Short = arr.asInstanceOf[Array[Short]].apply(n)
def (arr: IArray[Char]) apply (n: Int): Char = arr.asInstanceOf[Array[Char]].apply(n)
def (arr: IArray[Int]) apply (n: Int): Int = arr.asInstanceOf[Array[Int]].apply(n)
def (arr: IArray[Long]) apply (n: Int): Long = arr.asInstanceOf[Array[Long]].apply(n)
def (arr: IArray[Float]) apply (n: Int): Float = arr.asInstanceOf[Array[Float]].apply(n)
def (arr: IArray[Double]) apply (n: Int): Double = arr.asInstanceOf[Array[Double]].apply(n)
def (arr: IArray[T]) apply[T <: Object] (n: Int): T = arr.asInstanceOf[Array[T]].apply(n)
def (arr: IArray[T]) apply[T] (n: Int): T = arr.asInstanceOf[Array[T]].apply(n)

/** The number of elements in an immutable array
* @param arr the immutable array
*/
def (arr: IArray[Byte]) length: Int = arr.asInstanceOf[Array[Byte]].length
def (arr: IArray[Short]) length: Int = arr.asInstanceOf[Array[Short]].length
def (arr: IArray[Char]) length: Int = arr.asInstanceOf[Array[Char]].length
def (arr: IArray[Int]) length: Int = arr.asInstanceOf[Array[Int]].length
def (arr: IArray[Long]) length: Int = arr.asInstanceOf[Array[Long]].length
def (arr: IArray[Float]) length: Int = arr.asInstanceOf[Array[Float]].length
def (arr: IArray[Double]) length: Int = arr.asInstanceOf[Array[Double]].length
def (arr: IArray[Object]) length: Int = arr.asInstanceOf[Array[Object]].length
def (arr: IArray[T]) length[T] : Int = arr.asInstanceOf[Array[T]].length
}
}
type IArray[+T] = opaques.IArray[T]

object IArray {

/** An immutable array of length 0.
*/
def empty[T: ClassTag]: IArray[T] = new Array[T](0)
def empty[T: ClassTag]: IArray[T] = new Array[T](0).asInstanceOf

/** An immutable array with given elements.
*/
def apply[T: ClassTag](xs: T*): IArray[T] = Array(xs: _*)
def apply(x: Boolean, xs: Boolean*): IArray[Boolean] = Array(x, xs: _*)
def apply(x: Byte, xs: Byte*): IArray[Byte] = Array(x, xs: _*)
def apply(x: Short, xs: Short*): IArray[Short] = Array(x, xs: _*)
def apply(x: Char, xs: Char*): IArray[Char] = Array(x, xs: _*)
def apply(x: Int, xs: Int*): IArray[Int] = Array(x, xs: _*)
def apply(x: Long, xs: Long*): IArray[Long] = Array(x, xs: _*)
def apply(x: Float, xs: Float*): IArray[Float] = Array(x, xs: _*)
def apply(x: Double, xs: Double*): IArray[Double] = Array(x, xs: _*)
def apply(x: Unit, xs: Unit*): IArray[Unit] = Array(x, xs: _*)
def apply[T: ClassTag](xs: T*): IArray[T] = Array(xs: _*).asInstanceOf
def apply(x: Boolean, xs: Boolean*): IArray[Boolean] = Array(x, xs: _*).asInstanceOf
def apply(x: Byte, xs: Byte*): IArray[Byte] = Array(x, xs: _*).asInstanceOf
def apply(x: Short, xs: Short*): IArray[Short] = Array(x, xs: _*).asInstanceOf
def apply(x: Char, xs: Char*): IArray[Char] = Array(x, xs: _*).asInstanceOf
def apply(x: Int, xs: Int*): IArray[Int] = Array(x, xs: _*).asInstanceOf
def apply(x: Long, xs: Long*): IArray[Long] = Array(x, xs: _*).asInstanceOf
def apply(x: Float, xs: Float*): IArray[Float] = Array(x, xs: _*).asInstanceOf
def apply(x: Double, xs: Double*): IArray[Double] = Array(x, xs: _*).asInstanceOf
def apply(x: Unit, xs: Unit*): IArray[Unit] = Array(x, xs: _*).asInstanceOf

/** Concatenates all arrays into a single immutable array.
*
* @param xss the given immutable arrays
* @return the array created from concatenating `xss`
*/
def concat[T: ClassTag](xss: IArray[T]*): IArray[T] = Array.concat[T](xss.asInstanceOf[Seq[Array[T]]]: _*)
def concat[T: ClassTag](xss: IArray[T]*): IArray[T] =
Array.concat[T](xss.asInstanceOf[Seq[Array[T]]]: _*).asInstanceOf

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

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

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

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

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

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

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

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

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

/** Returns a five-dimensional immutable array containing values of a given function
* over ranges of integer values starting from `0`.
Expand All @@ -173,7 +177,7 @@ object IArray {
* @param f The function computing element values
*/
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]]]]] =
Array.tabulate(n1, n2, n3, n4, n5)(f)
Array.tabulate(n1, n2, n3, n4, n5)(f).asInstanceOf

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

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

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

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