diff --git a/compiler/src/dotty/tools/dotc/ast/Desugar.scala b/compiler/src/dotty/tools/dotc/ast/Desugar.scala index 35e62d523894..bc4a1d62ef06 100644 --- a/compiler/src/dotty/tools/dotc/ast/Desugar.scala +++ b/compiler/src/dotty/tools/dotc/ast/Desugar.scala @@ -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) diff --git a/library/src-bootstrapped/scala/IArray.scala b/library/src-bootstrapped/scala/IArray.scala index 16d92077b9ad..d6f0156136f3 100644 --- a/library/src-bootstrapped/scala/IArray.scala +++ b/library/src-bootstrapped/scala/IArray.scala @@ -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. @@ -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. @@ -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. @@ -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. @@ -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. @@ -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. @@ -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`. @@ -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`. @@ -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`. @@ -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`. @@ -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. * @@ -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. * @@ -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. * @@ -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')}`.