aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/transform/Erasure.scala
diff options
context:
space:
mode:
Diffstat (limited to 'src/dotty/tools/dotc/transform/Erasure.scala')
-rw-r--r--src/dotty/tools/dotc/transform/Erasure.scala72
1 files changed, 35 insertions, 37 deletions
diff --git a/src/dotty/tools/dotc/transform/Erasure.scala b/src/dotty/tools/dotc/transform/Erasure.scala
index 1efc6b53c..86151fae2 100644
--- a/src/dotty/tools/dotc/transform/Erasure.scala
+++ b/src/dotty/tools/dotc/transform/Erasure.scala
@@ -24,7 +24,7 @@ import scala.collection.mutable.ListBuffer
import dotty.tools.dotc.core.Flags
import ValueClasses._
import TypeUtils._
-import com.sun.j3d.utils.behaviors.picking.Intersect
+import typer.Mode
class Erasure extends Phase with DenotTransformer { thisTransformer =>
@@ -51,10 +51,13 @@ class Erasure extends Phase with DenotTransformer { thisTransformer =>
val newOwner = if (oldOwner eq defn.AnyClass) defn.ObjectClass else oldOwner
val oldInfo = ref.info
val newInfo = transformInfo(ref.symbol, oldInfo)
- if ((oldOwner eq newOwner) && (oldInfo eq newInfo)) ref
+ val oldFlags = ref.flags
+ val newFlags = ref.flags &~ Flags.HasDefaultParams // HasDefaultParams needs to be dropped because overriding might become overloading
+ // TODO: define derivedSymDenotation?
+ if ((oldOwner eq newOwner) && (oldInfo eq newInfo) && (oldFlags == newFlags)) ref
else {
assert(!ref.is(Flags.PackageClass), s"trans $ref @ ${ctx.phase} oldOwner = $oldOwner, newOwner = $newOwner, oldInfo = $oldInfo, newInfo = $newInfo ${oldOwner eq newOwner} ${oldInfo eq newInfo}")
- ref.copySymDenotation(owner = newOwner, info = newInfo)
+ ref.copySymDenotation(owner = newOwner, initFlags = newFlags, info = newInfo)
}
}
case ref =>
@@ -155,7 +158,7 @@ object Erasure {
// assert(!pt.isInstanceOf[SingletonType], pt)
if (pt isRef defn.UnitClass) unbox(tree, pt)
else (tree.tpe, pt) match {
- case (defn.ArrayType(treeElem), defn.ArrayType(ptElem))
+ case (JavaArrayType(treeElem), JavaArrayType(ptElem))
if treeElem.widen.isPrimitiveValueType && !ptElem.isPrimitiveValueType =>
// See SI-2386 for one example of when this might be necessary.
cast(ref(defn.runtimeMethod(nme.toObjectArray)).appliedTo(tree), pt)
@@ -209,22 +212,24 @@ object Erasure {
}
/** Type check select nodes, applying the following rewritings exhaustively
- * on selections `e.m`.
+ * on selections `e.m`, where `OT` is the type of the owner of `m` and `ET`
+ * is the erased type of the selection's original qualifier expression.
*
- * e.m1 -> e.m2 if `m1` is a member of Any or AnyVal and `m2` is
- * the same-named member in Object.
- * e.m -> box(e).m if `e` is primitive and `m` is a member or a reference class
- * or `e` has an erased value class type.
- * e.m -> unbox(e).m if `e` is not primitive and `m` is a member of a primtive type.
+ * e.m1 -> e.m2 if `m1` is a member of Any or AnyVal and `m2` is
+ * the same-named member in Object.
+ * e.m -> box(e).m if `e` is primitive and `m` is a member or a reference class
+ * or `e` has an erased value class type.
+ * e.m -> unbox(e).m if `e` is not primitive and `m` is a member of a primtive type.
+ * e.m -> cast(e, OT).m if the type of `e` does not conform to OT and `m`
+ * is not an array operation.
*
- * Additionally, if the type of `e` does not derive from the type `OT` of the owner of `m`,
- * the following rewritings are performed, where `ET` is the erased type of the selection's
- * original qualifier expression.
+ * If `m` is an array operation, i.e. one of the members apply, update, length, clone, and
+ * <init> of class Array, we additionally try the following rewritings:
*
- * e.m -> cast(OT).m if `m` is not an array operation
- * e.m -> cast(ET).m if `m` is an array operation and `ET` is an array type
- * e.m -> runtime.array_m(e)
- * if `m` is an array operation and `ET` is Object
+ * e.m -> runtime.array_m(e) if ET is Object
+ * e.m -> cast(e, ET).m if the type of `e` does not conform to ET
+ * e.clone -> e.clone' where clone' is Object's clone method
+ * e.m -> e.[]m if `m` is an array operation other than `clone`.
*/
override def typedSelect(tree: untpd.Select, pt: Type)(implicit ctx: Context): Tree = {
val sym = tree.symbol
@@ -233,10 +238,15 @@ object Erasure {
def select(qual: Tree, sym: Symbol): Tree =
untpd.cpy.Select(tree)(qual, sym.name) withType qual.tpe.select(sym)
- def selectArrayMember(qual: Tree, erasedPre: Type) = {
- if (erasedPre isRef defn.ObjectClass) runtimeCallWithProtoArgs(tree.name.genericArrayOp, pt, qual)
- else recur(cast(qual, erasedPre))
- }
+ def selectArrayMember(qual: Tree, erasedPre: Type): Tree =
+ if (erasedPre isRef defn.ObjectClass)
+ runtimeCallWithProtoArgs(tree.name.genericArrayOp, pt, qual)
+ else if (!(qual.tpe <:< erasedPre))
+ selectArrayMember(cast(qual, erasedPre), erasedPre)
+ else if (sym == defn.Array_clone)
+ untpd.cpy.Select(tree)(qual, tree.name).withType(defn.Object_clone.termRef)
+ else
+ assignType(untpd.cpy.Select(tree)(qual, tree.name.primitiveArrayOp), qual)
def recur(qual: Tree): Tree = {
val qualIsPrimitive = qual.tpe.widen.isPrimitiveValueType
@@ -249,10 +259,10 @@ object Erasure {
recur(box(qual))
else if (!qualIsPrimitive && symIsPrimitive)
recur(unbox(qual, sym.owner.typeRef))
- else if (qual.tpe.derivesFrom(sym.owner) || qual.isInstanceOf[Super])
- select(qual, sym)
else if (sym.owner eq defn.ArrayClass)
selectArrayMember(qual, erasure(tree.qualifier.typeOpt.widen.finalResultType))
+ else if (qual.tpe.derivesFrom(sym.owner) || qual.isInstanceOf[Super])
+ select(qual, sym)
else
recur(cast(qual, sym.owner.typeRef))
}
@@ -274,7 +284,7 @@ object Erasure {
override def typedTypeApply(tree: untpd.TypeApply, pt: Type)(implicit ctx: Context) = {
val TypeApply(fun, args) = tree
- val fun1 = typedExpr(fun, pt)
+ val fun1 = typedExpr(fun, WildcardType)
fun1.tpe.widen match {
case funTpe: PolyType =>
val args1 = args.mapconserve(typedType(_))
@@ -283,19 +293,6 @@ object Erasure {
}
}
-/*
- private def contextArgs(tree: untpd.Tree)(implicit ctx: Context): List[untpd.Tree] = {
- def nextOuter(ctx: Context): Context =
- if (ctx.outer.tree eq tree) nextOuter(ctx.outer) else ctx.outer
- ctx.tree match {
- case enclApp @ Apply(enclFun, enclArgs) if enclFun eq tree =>
- enclArgs ++ contextArgs(enclApp)(nextOuter(ctx))
- case _ =>
- Nil
- }
- }
-*/
-
override def typedApply(tree: untpd.Apply, pt: Type)(implicit ctx: Context): Tree = {
val Apply(fun, args) = tree
typedExpr(fun, FunProto(args, pt, this)) match {
@@ -425,6 +422,7 @@ object Erasure {
ctx.traceIndented(i"adapting ${tree.showSummary}: ${tree.tpe} to $pt", show = true) {
assert(ctx.phase == ctx.erasurePhase.next, ctx.phase)
if (tree.isEmpty) tree
+ else if (ctx.mode is Mode.Pattern) tree // TODO: replace with assertion once pattern matcher is active
else {
val tree1 = adaptToType(tree, pt)
tree1.tpe match {