Skip to content

Commit f803d07

Browse files
committed
Alternative layout for IArray definition
1 parent b052e8b commit f803d07

File tree

4 files changed

+79
-32
lines changed

4 files changed

+79
-32
lines changed

compiler/src/dotty/tools/dotc/Compiler.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -93,7 +93,8 @@ class Compiler {
9393
new FunctionXXLForwarders, // Add forwarders for FunctionXXL apply method
9494
new ParamForwarding, // Add forwarders for aliases of superclass parameters
9595
new TupleOptimizations, // Optimize generic operations on tuples
96-
new LetOverApply, // Lift blocks from receivers of applications
96+
new IArrayOptimizations, // Optimize IArray operations
97+
new LetOverApply, // Lift blocks from receivers of applications
9798
new ArrayConstructors) :: // Intercept creation of (non-generic) arrays and intrinsify.
9899
List(new Erasure) :: // Rewrite types to JVM model, erasing all type parameters, abstract types and refinements.
99100
List(new ElimErasedValueType, // Expand erased value types to their underlying implmementation types

compiler/src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -853,6 +853,9 @@ class Definitions {
853853
@tu lazy val CLP_parseRemainingArguments: Symbol = CommandLineParserModule.requiredMethod("parseRemainingArguments")
854854
@tu lazy val CLP_showError: Symbol = CommandLineParserModule.requiredMethod("showError")
855855

856+
@tu lazy val IArrayModule: Symbol = requiredModule("scala.IArray")
857+
@tu lazy val IArrayModuleClass: Symbol = IArrayModule.moduleClass
858+
856859
@tu lazy val TupleTypeRef: TypeRef = requiredClassRef("scala.Tuple")
857860
def TupleClass(using Context): ClassSymbol = TupleTypeRef.symbol.asClass
858861
@tu lazy val Tuple_cons: Symbol = TupleClass.requiredMethod("*:")
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package dotty.tools.dotc
2+
package transform
3+
4+
import core._
5+
import Constants.Constant
6+
import Contexts._
7+
import Decorators._
8+
import Flags._
9+
import ast.Trees._
10+
import Definitions._
11+
import DenotTransformers._
12+
import StdNames._
13+
import Symbols._
14+
import MegaPhase._
15+
import Types._
16+
import dotty.tools.dotc.ast.tpd
17+
18+
import scala.annotation.tailrec
19+
20+
/** Optimize IArray operations */
21+
class IArrayOptimizations extends MiniPhase with IdentityDenotTransformer {
22+
import tpd._
23+
24+
def phaseName: String = "iarrays"
25+
26+
override def transformApply(tree: tpd.Apply)(using Context): tpd.Tree =
27+
val sym = tree.symbol
28+
if !sym.exists then tree
29+
else if sym.owner == defn.IArrayModuleClass then
30+
if sym.name == nme.apply then transformIArrayModuleApply(tree)
31+
else tree
32+
// TODO optimize IArrayClass apply and length
33+
else
34+
tree
35+
36+
/** Transform a call to `IArray.apply(...)` to `Array.apply(...).asInstanceOf[IArray[X]]` */
37+
private def transformIArrayModuleApply(tree: tpd.Apply)(using Context): tpd.Tree =
38+
tree.fun match
39+
// Call to: def apply(x: X, xs: X*): IArray[X]
40+
case fun: RefTree =>
41+
ref(defn.ArrayModule).withSpan(fun.span)
42+
.selectWithSig(tree.symbol)
43+
.appliedToArgs(tree.args)
44+
.asInstance(tree.tpe).withSpan(tree.span)
45+
// Call to: def apply[T](xs: T*)(using ct: ClassTag[T]): IArray[T]
46+
case Apply(tapp @ TypeApply(fun, targs), args1) =>
47+
ref(defn.ArrayModule).withSpan(fun.span)
48+
.selectWithSig(tree.symbol)
49+
.appliedToTypeTrees(targs).withSpan(tapp.span)
50+
.appliedToArgs(args1).withSpan(tree.fun.span)
51+
.appliedToArgs(tree.args)
52+
.asInstance(tree.tpe).withSpan(tree.span)
53+
case _ =>
54+
tree
55+
56+
}
57+

library/src/scala/IArray.scala

Lines changed: 17 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,12 @@
11
package scala
22
import reflect.ClassTag
33

4+
opaque type IArray[+T] = Array[_ <: T]
5+
46
/** An immutable array. An `IArray[T]` has the same representation as an `Array[T]`,
57
* but it cannot be updated. Unlike regular arrays, immutable arrays are covariant.
68
*/
7-
object opaques:
8-
opaque type IArray[+T] = Array[_ <: T]
9-
10-
private[scala] type Sub[A] >: Array[A] <: IArray[A]
11-
private[scala] type Sup[A] >: IArray[A] <: Array[_ <: A]
9+
object IArray:
1210

1311
/** The selection operation on an immutable array.
1412
*
@@ -314,17 +312,6 @@ object opaques:
314312
given genericWrapUnitIArray(using DummyImplicit): Conversion[IArray[Unit], scala.collection.immutable.ArraySeq[Unit]] =
315313
arr => scala.collection.immutable.ArraySeq.ofUnit(arr.asInstanceOf[Array[Unit]])
316314

317-
end opaques
318-
319-
type IArray[+T] = opaques.IArray[T]
320-
321-
object IArray {
322-
import opaques.Sub
323-
import opaques.Sup
324-
325-
// A convenience to avoid having to cast everything by hand
326-
private given [A]: Conversion[Array[A], IArray[A]] = identity[Sub[A]]
327-
328315
/** Convert an array into an immutable array without copying, the original array
329316
* must _not_ be mutated after this or the guaranteed immutablity of IArray will
330317
* be violated.
@@ -354,25 +341,25 @@ object IArray {
354341
def emptyObjectIArray: IArray[Object] = Array.emptyObjectArray
355342

356343
/** An immutable array with given elements. */
357-
inline def apply[T](inline xs: T*)(using inline ct: ClassTag[T]): IArray[T] = Array(xs: _*).asInstanceOf
344+
def apply[T](xs: T*)(using ct: ClassTag[T]): IArray[T] = Array(xs: _*).asInstanceOf
358345
/** An immutable array with given elements. */
359-
inline def apply(inline x: Boolean, inline xs: Boolean*): IArray[Boolean] = Array(x, xs: _*).asInstanceOf
346+
def apply(x: Boolean, xs: Boolean*): IArray[Boolean] = Array(x, xs: _*).asInstanceOf
360347
/** An immutable array with given elements. */
361-
inline def apply(inline x: Byte, inline xs: Byte*): IArray[Byte] = Array(x, xs: _*).asInstanceOf
348+
def apply(x: Byte, xs: Byte*): IArray[Byte] = Array(x, xs: _*).asInstanceOf
362349
/** An immutable array with given elements. */
363-
inline def apply(inline x: Short, inline xs: Short*): IArray[Short] = Array(x, xs: _*).asInstanceOf
350+
def apply(x: Short, xs: Short*): IArray[Short] = Array(x, xs: _*).asInstanceOf
364351
/** An immutable array with given elements. */
365-
inline def apply(inline x: Char, inline xs: Char*): IArray[Char] = Array(x, xs: _*).asInstanceOf
352+
def apply(x: Char, xs: Char*): IArray[Char] = Array(x, xs: _*).asInstanceOf
366353
/** An immutable array with given elements. */
367-
inline def apply(inline x: Int, inline xs: Int*): IArray[Int] = Array(x, xs: _*).asInstanceOf
354+
def apply(x: Int, xs: Int*): IArray[Int] = Array(x, xs: _*).asInstanceOf
368355
/** An immutable array with given elements. */
369-
inline def apply(inline x: Long, inline xs: Long*): IArray[Long] = Array(x, xs: _*).asInstanceOf
356+
def apply(x: Long, xs: Long*): IArray[Long] = Array(x, xs: _*).asInstanceOf
370357
/** An immutable array with given elements. */
371-
inline def apply(inline x: Float, inline xs: Float*): IArray[Float] = Array(x, xs: _*).asInstanceOf
358+
def apply(x: Float, xs: Float*): IArray[Float] = Array(x, xs: _*).asInstanceOf
372359
/** An immutable array with given elements. */
373-
inline def apply(inline x: Double, inline xs: Double*): IArray[Double] = Array(x, xs: _*).asInstanceOf
360+
def apply(x: Double, xs: Double*): IArray[Double] = Array(x, xs: _*).asInstanceOf
374361
/** An immutable array with given elements. */
375-
inline def apply(inline x: Unit, inline xs: Unit*): IArray[Unit] = Array(x, xs: _*).asInstanceOf
362+
def apply(x: Unit, xs: Unit*): IArray[Unit] = Array(x, xs: _*).asInstanceOf
376363

377364
/** Concatenates all arrays into a single immutable array.
378365
*
@@ -529,8 +516,7 @@ object IArray {
529516
* @param x the selector value
530517
* @return sequence wrapped in a [[scala.Some]], if `x` is a Seq, otherwise `None`
531518
*/
532-
def unapplySeq[T](x: IArray[T]) =
533-
// The double type ascription is currently needed,
534-
// for some reason (see: https://scastie.scala-lang.org/sSsmOhKxSKym405MgNRKqQ)
535-
Array.unapplySeq((x: Sup[T]): Array[_ <: T])
536-
}
519+
def unapplySeq[T](x: IArray[T]): Array.UnapplySeqWrapper[_ <: T] =
520+
Array.unapplySeq(x)
521+
522+
end IArray

0 commit comments

Comments
 (0)