Skip to content

Commit a612da8

Browse files
committed
Add new SeqLiterals phase.
Replaces SeqLiterals by JavaSeqLiterals, because the latter's (array-)type is preserved after erasure.
1 parent 8fb5e1e commit a612da8

File tree

2 files changed

+50
-0
lines changed

2 files changed

+50
-0
lines changed

src/dotty/tools/dotc/Compiler.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ class Compiler {
4848
new ExplicitOuter,
4949
new Splitter),
5050
List(new ElimByName,
51+
new SeqLiterals,
5152
new InterceptedMethods,
5253
new Literalize,
5354
new Getters,
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
package dotty.tools.dotc
2+
package transform
3+
4+
import core._
5+
import Types._
6+
import dotty.tools.dotc.transform.TreeTransforms._
7+
import Contexts.Context
8+
import Symbols._
9+
import Phases._
10+
import Decorators._
11+
12+
/** A transformer that eliminates SeqLiteral's, transforming `SeqLiteral(elems)` to an operation
13+
* equivalent to
14+
*
15+
* JavaSeqLiteral(elems).toSeq
16+
*
17+
* Instead of `toSeq`, which takes an implicit, the appropriate "wrapArray" method
18+
* is called directly. The reason for this step is that JavaSeqLiterals, being arrays
19+
* keep a precise type after erasure, whereas SeqLiterals only get the erased type `Seq`,
20+
*/
21+
class SeqLiterals extends MiniPhaseTransform { thisTransformer =>
22+
import ast.tpd._
23+
24+
override def phaseName = "seqLiterals"
25+
override def treeTransformPhase = thisTransformer.next
26+
override def runsAfter: Set[Class[_ <: Phase]] = Set(classOf[PatternMatcher])
27+
28+
override def checkPostCondition(tree: Tree)(implicit ctx: Context): Unit = tree match {
29+
case tpd: SeqLiteral => assert(tpd.isInstanceOf[JavaSeqLiteral])
30+
case _ =>
31+
}
32+
33+
override def transformSeqLiteral(tree: SeqLiteral)(implicit ctx: Context, info: TransformerInfo): Tree = tree match {
34+
case tree: JavaSeqLiteral => tree
35+
case _ =>
36+
val arr = JavaSeqLiteral(tree.elems)
37+
//println(i"trans seq $tree, arr = $arr: ${arr.tpe} ${arr.tpe.elemType}")
38+
val elemtp = arr.tpe.elemType.bounds.hi
39+
val elemCls = elemtp.classSymbol
40+
val (wrapMethStr, targs) =
41+
if (elemCls.isPrimitiveValueClass) (s"wrap${elemCls.name}Array", Nil)
42+
else if (elemtp derivesFrom defn.ObjectClass) ("wrapRefArray", elemtp :: Nil)
43+
else ("genericWrapArray", elemtp :: Nil)
44+
ref(defn.ScalaPredefModule)
45+
.select(wrapMethStr.toTermName)
46+
.appliedToTypes(targs)
47+
.appliedTo(arr)
48+
}
49+
}

0 commit comments

Comments
 (0)