aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/transform/Erasure.scala
diff options
context:
space:
mode:
authorGuillaume Martres <smarter@ubuntu.com>2015-03-18 23:56:19 +0100
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2015-05-01 13:26:23 +0200
commit5dec4ce8a64d44ee602c09d468414b13eecba389 (patch)
tree3df31764445c447029d2114e25c95d83a60e4c0a /src/dotty/tools/dotc/transform/Erasure.scala
parent391c80c4dfb2489e4098af33265b22332ef3d5f1 (diff)
downloaddotty-5dec4ce8a64d44ee602c09d468414b13eecba389.tar.gz
dotty-5dec4ce8a64d44ee602c09d468414b13eecba389.tar.bz2
dotty-5dec4ce8a64d44ee602c09d468414b13eecba389.zip
Erasure: properly erase value classes
There are three ways to erase a value class: - In most case, it should be semi-erased to an ErasedValueType, which will be fully erased to its underlying type in ElimErasedValueType. This corresponds to semiEraseVCs = true in TypeErasure. - In a few cases, it should be erased like a normal class, so far this seems to be necessary for: * The return type of a constructor * The underlying type of a ThisType * TypeTree nodes inside New nodes * TypeApply nodes * Arrays In these cases, we set semiEraseVCs = false - When calling `sigName` it should be erased to its underlying type. This commit implements all these cases. Note that this breaks most tests because ElimErasedValueType has not been implemented yet, it is part of the next commit.
Diffstat (limited to 'src/dotty/tools/dotc/transform/Erasure.scala')
-rw-r--r--src/dotty/tools/dotc/transform/Erasure.scala37
1 files changed, 29 insertions, 8 deletions
diff --git a/src/dotty/tools/dotc/transform/Erasure.scala b/src/dotty/tools/dotc/transform/Erasure.scala
index 01f86915d..293059af2 100644
--- a/src/dotty/tools/dotc/transform/Erasure.scala
+++ b/src/dotty/tools/dotc/transform/Erasure.scala
@@ -254,18 +254,39 @@ object Erasure extends TypeTestsCasts{
class Typer extends typer.ReTyper with NoChecking {
import Boxing._
- def erasedType(tree: untpd.Tree)(implicit ctx: Context): Type = tree.typeOpt match {
- case tp: TermRef if tree.isTerm => erasedRef(tp)
- case tp => erasure(tp)
- }
+ def erasedType(tree: untpd.Tree, semiEraseVCs: Boolean = true)(implicit ctx: Context): Type =
+ tree.typeOpt match {
+ case tp: TermRef if tree.isTerm => erasedRef(tp)
+ case tp => erasure(tp, semiEraseVCs)
+ }
- override def promote(tree: untpd.Tree)(implicit ctx: Context): tree.ThisTree[Type] = {
+ def promote(tree: untpd.Tree, semiEraseVCs: Boolean)(implicit ctx: Context): tree.ThisTree[Type] = {
assert(tree.hasType)
- val erased = erasedType(tree)
+ val erased = erasedType(tree, semiEraseVCs)
ctx.log(s"promoting ${tree.show}: ${erased.showWithUnderlying()}")
tree.withType(erased)
}
+ override def promote(tree: untpd.Tree)(implicit ctx: Context): tree.ThisTree[Type] = {
+ promote(tree, true)
+ }
+
+ /** When erasing most TypeTrees we should not semi-erase value types.
+ * This is not the case for [[DefDef#tpt]], [[ValDef#tpt]] and [[Typed#tpt]], they
+ * are handled separately by [[typedDefDef]], [[typedValDef]] and [[typedTyped]].
+ */
+ override def typedTypeTree(tree: untpd.TypeTree, pt: Type)(implicit ctx: Context): TypeTree = {
+ promote(tree, semiEraseVCs = false)
+ }
+
+ /** This override is only needed to semi-erase type ascriptions */
+ override def typedTyped(tree: untpd.Typed, pt: Type)(implicit ctx: Context): Tree = {
+ val Typed(expr, tpt) = tree
+ val tpt1 = promote(tpt)
+ val expr1 = typed(expr, tpt1.tpe)
+ assignType(untpd.cpy.Typed(tree)(expr1, tpt1), tpt1)
+ }
+
override def typedLiteral(tree: untpd.Literal)(implicit ctc: Context): Literal =
if (tree.typeOpt.isRef(defn.UnitClass)) tree.withType(tree.typeOpt)
else super.typedLiteral(tree)
@@ -330,7 +351,7 @@ object Erasure extends TypeTestsCasts{
assert(sym.isConstructor, s"${sym.showLocated}")
select(qual, defn.ObjectClass.info.decl(sym.name).symbol)
}
- else if (qualIsPrimitive && !symIsPrimitive || qual.tpe.isErasedValueType)
+ else if (qualIsPrimitive && !symIsPrimitive || qual.tpe.widenDealias.isErasedValueType)
recur(box(qual))
else if (!qualIsPrimitive && symIsPrimitive)
recur(unbox(qual, sym.owner.typeRef))
@@ -349,7 +370,7 @@ object Erasure extends TypeTestsCasts{
}
override def typedSelectFromTypeTree(tree: untpd.SelectFromTypeTree, pt: Type)(implicit ctx: Context) =
- untpd.Ident(tree.name).withPos(tree.pos).withType(erasedType(tree))
+ untpd.Ident(tree.name).withPos(tree.pos).withType(erasedType(tree, semiEraseVCs = false))
override def typedThis(tree: untpd.This)(implicit ctx: Context): Tree =
if (tree.symbol == ctx.owner.enclosingClass || tree.symbol.isStaticOwner) promote(tree)