Skip to content

Commit 86eb1bb

Browse files
committed
Merge pull request #261 from dotty-staging/fix/type-seqliteral
Fix/type seqliteral
2 parents 1ec141e + a612da8 commit 86eb1bb

File tree

6 files changed

+58
-7
lines changed

6 files changed

+58
-7
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,

src/dotty/tools/dotc/ast/tpd.scala

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -129,7 +129,6 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
129129
def JavaSeqLiteral(elems: List[Tree])(implicit ctx: Context): SeqLiteral =
130130
ta.assignType(new untpd.JavaSeqLiteral(elems), elems)
131131

132-
133132
def TypeTree(original: Tree)(implicit ctx: Context): TypeTree =
134133
TypeTree(original.tpe, original)
135134

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,8 @@ class Definitions {
394394

395395
object ArrayType {
396396
def apply(elem: Type)(implicit ctx: Context) =
397-
ArrayClass.typeRef.appliedTo(elem :: Nil)
397+
if (ctx.erasedTypes) JavaArrayType(elem)
398+
else ArrayClass.typeRef.appliedTo(elem :: Nil)
398399
def unapply(tp: Type)(implicit ctx: Context) = tp.dealias match {
399400
case at: RefinedType if (at isRef ArrayClass) && at.argInfos.length == 1 => Some(at.argInfos.head)
400401
case _ => None

src/dotty/tools/dotc/core/Uniques.scala

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ object Uniques {
4545
private def findPrevious(h: Int, prefix: Type, name: Name): NamedType = {
4646
var e = findEntryByHash(h)
4747
while (e != null) {
48-
if ((e.prefix == prefix) && (e.name eq name)) return e
48+
if ((e.prefix eq prefix) && (e.name eq name)) return e
4949
e = nextEntryByHash(h)
5050
}
5151
e
@@ -71,7 +71,7 @@ object Uniques {
7171
private def findPrevious(h: Int, lo: Type, hi: Type, variance: Int): TypeBounds = {
7272
var e = findEntryByHash(h)
7373
while (e != null) {
74-
if ((e.lo == lo) && (e.hi == hi) && (e.variance == variance)) return e
74+
if ((e.lo eq lo) && (e.hi eq hi) && (e.variance == variance)) return e
7575
e = nextEntryByHash(h)
7676
}
7777
e
@@ -87,7 +87,8 @@ object Uniques {
8787
if (h == NotCached) newBounds
8888
else {
8989
val r = findPrevious(h, lo, hi, variance)
90-
if (r ne null) r else addEntryAfterScan(newBounds)
90+
if (r ne null) r
91+
else addEntryAfterScan(newBounds)
9192
}
9293
}
9394
}
@@ -99,7 +100,7 @@ object Uniques {
99100
private def findPrevious(h: Int, parent: Type, refinedName: Name, refinedInfo: Type): RefinedType = {
100101
var e = findEntryByHash(h)
101102
while (e != null) {
102-
if ((e.parent == parent) && (e.refinedName eq refinedName) && (e.refinedInfo == refinedInfo))
103+
if ((e.parent eq parent) && (e.refinedName eq refinedName) && (e.refinedInfo eq refinedInfo))
103104
return e
104105
e = nextEntryByHash(h)
105106
}
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+
}

src/dotty/tools/dotc/typer/TypeAssigner.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -324,7 +324,7 @@ trait TypeAssigner {
324324

325325
def assignType(tree: untpd.SeqLiteral, elems: List[Tree])(implicit ctx: Context) = tree match {
326326
case tree: JavaSeqLiteral =>
327-
tree.withType(defn.ArrayClass.typeRef.appliedTo(ctx.typeComparer.lub(elems.tpes)))
327+
tree.withType(defn.ArrayType(ctx.typeComparer.lub(elems.tpes).widen))
328328
case _ =>
329329
val ownType =
330330
if (ctx.erasedTypes) defn.SeqType

0 commit comments

Comments
 (0)