Skip to content

Fix/type seqliteral #261

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 4 commits into from
Dec 4, 2014
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
1 change: 1 addition & 0 deletions src/dotty/tools/dotc/Compiler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ class Compiler {
new ExplicitOuter,
new Splitter),
List(new ElimByName,
new SeqLiterals,
new InterceptedMethods,
new Literalize,
new Getters,
Expand Down
1 change: 0 additions & 1 deletion src/dotty/tools/dotc/ast/tpd.scala
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,6 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
def JavaSeqLiteral(elems: List[Tree])(implicit ctx: Context): SeqLiteral =
ta.assignType(new untpd.JavaSeqLiteral(elems), elems)


def TypeTree(original: Tree)(implicit ctx: Context): TypeTree =
TypeTree(original.tpe, original)

Expand Down
3 changes: 2 additions & 1 deletion src/dotty/tools/dotc/core/Definitions.scala
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,8 @@ class Definitions {

object ArrayType {
def apply(elem: Type)(implicit ctx: Context) =
ArrayClass.typeRef.appliedTo(elem :: Nil)
if (ctx.erasedTypes) JavaArrayType(elem)
else ArrayClass.typeRef.appliedTo(elem :: Nil)
def unapply(tp: Type)(implicit ctx: Context) = tp.dealias match {
case at: RefinedType if (at isRef ArrayClass) && at.argInfos.length == 1 => Some(at.argInfos.head)
case _ => None
Expand Down
9 changes: 5 additions & 4 deletions src/dotty/tools/dotc/core/Uniques.scala
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ object Uniques {
private def findPrevious(h: Int, prefix: Type, name: Name): NamedType = {
var e = findEntryByHash(h)
while (e != null) {
if ((e.prefix == prefix) && (e.name eq name)) return e
if ((e.prefix eq prefix) && (e.name eq name)) return e
e = nextEntryByHash(h)
}
e
Expand All @@ -71,7 +71,7 @@ object Uniques {
private def findPrevious(h: Int, lo: Type, hi: Type, variance: Int): TypeBounds = {
var e = findEntryByHash(h)
while (e != null) {
if ((e.lo == lo) && (e.hi == hi) && (e.variance == variance)) return e
if ((e.lo eq lo) && (e.hi eq hi) && (e.variance == variance)) return e
e = nextEntryByHash(h)
}
e
Expand All @@ -87,7 +87,8 @@ object Uniques {
if (h == NotCached) newBounds
else {
val r = findPrevious(h, lo, hi, variance)
if (r ne null) r else addEntryAfterScan(newBounds)
if (r ne null) r
else addEntryAfterScan(newBounds)
}
}
}
Expand All @@ -99,7 +100,7 @@ object Uniques {
private def findPrevious(h: Int, parent: Type, refinedName: Name, refinedInfo: Type): RefinedType = {
var e = findEntryByHash(h)
while (e != null) {
if ((e.parent == parent) && (e.refinedName eq refinedName) && (e.refinedInfo == refinedInfo))
if ((e.parent eq parent) && (e.refinedName eq refinedName) && (e.refinedInfo eq refinedInfo))
return e
e = nextEntryByHash(h)
}
Expand Down
49 changes: 49 additions & 0 deletions src/dotty/tools/dotc/transform/SeqLiterals.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package dotty.tools.dotc
package transform

import core._
import Types._
import dotty.tools.dotc.transform.TreeTransforms._
import Contexts.Context
import Symbols._
import Phases._
import Decorators._

/** A transformer that eliminates SeqLiteral's, transforming `SeqLiteral(elems)` to an operation
* equivalent to
*
* JavaSeqLiteral(elems).toSeq
*
* Instead of `toSeq`, which takes an implicit, the appropriate "wrapArray" method
* is called directly. The reason for this step is that JavaSeqLiterals, being arrays
* keep a precise type after erasure, whereas SeqLiterals only get the erased type `Seq`,
*/
class SeqLiterals extends MiniPhaseTransform { thisTransformer =>
import ast.tpd._

override def phaseName = "seqLiterals"
override def treeTransformPhase = thisTransformer.next
override def runsAfter: Set[Class[_ <: Phase]] = Set(classOf[PatternMatcher])

override def checkPostCondition(tree: Tree)(implicit ctx: Context): Unit = tree match {
case tpd: SeqLiteral => assert(tpd.isInstanceOf[JavaSeqLiteral])
case _ =>
}

override def transformSeqLiteral(tree: SeqLiteral)(implicit ctx: Context, info: TransformerInfo): Tree = tree match {
case tree: JavaSeqLiteral => tree
case _ =>
val arr = JavaSeqLiteral(tree.elems)
//println(i"trans seq $tree, arr = $arr: ${arr.tpe} ${arr.tpe.elemType}")
val elemtp = arr.tpe.elemType.bounds.hi
val elemCls = elemtp.classSymbol
val (wrapMethStr, targs) =
if (elemCls.isPrimitiveValueClass) (s"wrap${elemCls.name}Array", Nil)
else if (elemtp derivesFrom defn.ObjectClass) ("wrapRefArray", elemtp :: Nil)
else ("genericWrapArray", elemtp :: Nil)
ref(defn.ScalaPredefModule)
.select(wrapMethStr.toTermName)
.appliedToTypes(targs)
.appliedTo(arr)
}
}
2 changes: 1 addition & 1 deletion src/dotty/tools/dotc/typer/TypeAssigner.scala
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ trait TypeAssigner {

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