aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorodersky <odersky@gmail.com>2015-06-26 22:41:27 +0200
committerodersky <odersky@gmail.com>2015-06-26 22:41:27 +0200
commit68b4e6ce51ee8b4981d8a8369d84a45bba8a237c (patch)
tree129c3450020e6f713f7011c2f0c3b75480822918
parent5e6a9a28241ea8c64617bf90f9c331a352409035 (diff)
parentef0184826b784fda9e2e1ef9aab31cab692cf3d2 (diff)
downloaddotty-68b4e6ce51ee8b4981d8a8369d84a45bba8a237c.tar.gz
dotty-68b4e6ce51ee8b4981d8a8369d84a45bba8a237c.tar.bz2
dotty-68b4e6ce51ee8b4981d8a8369d84a45bba8a237c.zip
Merge pull request #697 from dotty-staging/fix/erasure-thistypes-vcs
Fix erasure of this types and refactor value class erasure
-rw-r--r--src/dotty/tools/dotc/config/Config.scala12
-rw-r--r--src/dotty/tools/dotc/core/TypeErasure.scala27
-rw-r--r--src/dotty/tools/dotc/core/TyperState.scala2
-rw-r--r--src/dotty/tools/dotc/core/Types.scala2
-rw-r--r--src/dotty/tools/dotc/transform/Erasure.scala28
-rw-r--r--src/dotty/tools/dotc/transform/ExtensionMethods.scala4
-rw-r--r--tests/pending/run/unittest_collection.check1
-rw-r--r--tests/run/unittest_collection.scala (renamed from tests/pending/run/unittest_collection.scala)0
8 files changed, 40 insertions, 36 deletions
diff --git a/src/dotty/tools/dotc/config/Config.scala b/src/dotty/tools/dotc/config/Config.scala
index 9e9974bdc..97893647c 100644
--- a/src/dotty/tools/dotc/config/Config.scala
+++ b/src/dotty/tools/dotc/config/Config.scala
@@ -32,8 +32,16 @@ object Config {
*/
final val checkConstraintsPropagated = false
- /** Check that constraints of globally committable typer states are closed */
- final val checkConstraintsClosed = true
+ /** Check that constraints of globally committable typer states are closed.
+ * NOTE: When enabled, the check can cause CyclicReference errors because
+ * it traverses all elements of a type. Such failures were observed when
+ * compiling all of dotty together (source seems to be in GenBCode which
+ * accesses javac's settings.)
+ *
+ * It is recommended to turn this option on only when chasing down
+ * a PolyParam instantiation error. See comment in Types.TypeVar.instantiate.
+ */
+ final val debugCheckConstraintsClosed = false
/** Check that no type appearing as the info of a SymDenotation contains
* skolem types.
diff --git a/src/dotty/tools/dotc/core/TypeErasure.scala b/src/dotty/tools/dotc/core/TypeErasure.scala
index abe5418d4..9b41eb982 100644
--- a/src/dotty/tools/dotc/core/TypeErasure.scala
+++ b/src/dotty/tools/dotc/core/TypeErasure.scala
@@ -110,15 +110,20 @@ object TypeErasure {
private def erasureCtx(implicit ctx: Context) =
if (ctx.erasedTypes) ctx.withPhase(ctx.erasurePhase).addMode(Mode.FutureDefsOK) else ctx
- /** The standard erasure of a Scala type.
+ /** The standard erasure of a Scala type. Value classes are erased as normal classes.
+ *
+ * @param tp The type to erase.
+ */
+ def erasure(tp: Type)(implicit ctx: Context): Type =
+ erasureFn(isJava = false, semiEraseVCs = false, isConstructor = false, wildcardOK = false)(tp)(erasureCtx)
+
+ /** The value class erasure of a Scala type, where value classes are semi-erased to
+ * ErasedValueType (they will be fully erased in [[ElimErasedValueType]]).
*
* @param tp The type to erase.
- * @param semiEraseVCs If true, value classes are semi-erased to ErasedValueType
- * (they will be fully erased in [[ElimErasedValueType]]).
- * If false, they are erased like normal classes.
*/
- def erasure(tp: Type, semiEraseVCs: Boolean = false)(implicit ctx: Context): Type =
- erasureFn(isJava = false, semiEraseVCs, isConstructor = false, wildcardOK = false)(tp)(erasureCtx)
+ def valueErasure(tp: Type)(implicit ctx: Context): Type =
+ erasureFn(isJava = false, semiEraseVCs = true, isConstructor = false, wildcardOK = false)(tp)(erasureCtx)
def sigName(tp: Type, isJava: Boolean)(implicit ctx: Context): TypeName = {
val seqClass = if (isJava) defn.ArrayClass else defn.SeqClass
@@ -141,7 +146,7 @@ object TypeErasure {
case tp: ThisType =>
tp
case tp =>
- erasure(tp, semiEraseVCs = true)
+ valueErasure(tp)
}
/** The symbol's erased info. This is the type's erasure, except for the following symbols:
@@ -315,12 +320,8 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
val parent = tp.parent
if (parent isRef defn.ArrayClass) eraseArray(tp)
else this(parent)
- case tp: TermRef =>
+ case _: TermRef | _: ThisType =>
this(tp.widen)
- case tp: ThisType =>
- def thisTypeErasure(tpToErase: Type) =
- erasureFn(isJava, semiEraseVCs = false, isConstructor, wildcardOK)(tpToErase)
- thisTypeErasure(tp.cls.typeRef)
case SuperType(thistpe, supertpe) =>
SuperType(this(thistpe), this(supertpe))
case ExprType(rt) =>
@@ -396,7 +397,7 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
private def eraseDerivedValueClassRef(tref: TypeRef)(implicit ctx: Context): Type = {
val cls = tref.symbol.asClass
val underlying = underlyingOfValueClass(cls)
- ErasedValueType(cls, erasure(underlying, semiEraseVCs = true))
+ ErasedValueType(cls, valueErasure(underlying))
}
diff --git a/src/dotty/tools/dotc/core/TyperState.scala b/src/dotty/tools/dotc/core/TyperState.scala
index ba7a6a806..5617f568a 100644
--- a/src/dotty/tools/dotc/core/TyperState.scala
+++ b/src/dotty/tools/dotc/core/TyperState.scala
@@ -87,7 +87,7 @@ extends TyperState(r) {
override def constraint = myConstraint
override def constraint_=(c: Constraint)(implicit ctx: Context) = {
- if (Config.checkConstraintsClosed && isGlobalCommittable) c.checkClosed()
+ if (Config.debugCheckConstraintsClosed && isGlobalCommittable) c.checkClosed()
myConstraint = c
}
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 1270466e9..d6bb9c3c5 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -2460,6 +2460,8 @@ object Types {
if (ctx.typerState.isGlobalCommittable)
assert(!inst.isInstanceOf[PolyParam], i"bad inst $this := $inst, constr = ${ctx.typerState.constraint}")
+ // If this fails, you might want to turn on Config.debugCheckConstraintsClosed
+ // to help find the root of the problem.
instantiateWith(inst)
}
diff --git a/src/dotty/tools/dotc/transform/Erasure.scala b/src/dotty/tools/dotc/transform/Erasure.scala
index ad261c16b..8b4c6a87d 100644
--- a/src/dotty/tools/dotc/transform/Erasure.scala
+++ b/src/dotty/tools/dotc/transform/Erasure.scala
@@ -268,35 +268,29 @@ object Erasure extends TypeTestsCasts{
class Typer extends typer.ReTyper with NoChecking {
import Boxing._
- def erasedType(tree: untpd.Tree, semiEraseVCs: Boolean)(implicit ctx: Context): Type =
- tree.typeOpt match {
- case tp: TermRef if tree.isTerm => erasedRef(tp)
- case tp => erasure(tp, semiEraseVCs)
- }
+ def erasedType(tree: untpd.Tree)(implicit ctx: Context): Type = {
+ val tp = tree.typeOpt
+ if (tree.isTerm) erasedRef(tp) else valueErasure(tp)
+ }
- def promote(tree: untpd.Tree, semiEraseVCs: Boolean)(implicit ctx: Context): tree.ThisTree[Type] = {
+ override def promote(tree: untpd.Tree)(implicit ctx: Context): tree.ThisTree[Type] = {
assert(tree.hasType)
- val erased = erasedType(tree, semiEraseVCs)
+ val erased = erasedType(tree)
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)
- }
+ override def typedTypeTree(tree: untpd.TypeTree, pt: Type)(implicit ctx: Context): TypeTree =
+ tree.withType(erasure(tree.tpe))
/** 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, semiEraseVCs = true)
+ val tpt1 = promote(tpt)
val expr1 = typed(expr, tpt1.tpe)
assignType(untpd.cpy.Typed(tree)(expr1, tpt1), tpt1)
}
@@ -384,7 +378,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, semiEraseVCs = false))
+ untpd.Ident(tree.name).withPos(tree.pos).withType(erasedType(tree))
override def typedThis(tree: untpd.This)(implicit ctx: Context): Tree =
if (tree.symbol == ctx.owner.enclosingClass || tree.symbol.isStaticOwner) promote(tree)
@@ -460,7 +454,7 @@ object Erasure extends TypeTestsCasts{
if (pt.isValueType) pt else {
if (tree.typeOpt.derivesFrom(ctx.definitions.UnitClass))
tree.typeOpt
- else erasure(tree.typeOpt, semiEraseVCs = true)
+ else valueErasure(tree.typeOpt)
}
}
diff --git a/src/dotty/tools/dotc/transform/ExtensionMethods.scala b/src/dotty/tools/dotc/transform/ExtensionMethods.scala
index 503016d8b..f50e3324d 100644
--- a/src/dotty/tools/dotc/transform/ExtensionMethods.scala
+++ b/src/dotty/tools/dotc/transform/ExtensionMethods.scala
@@ -14,7 +14,7 @@ import core._
import Phases.Phase
import Types._, Contexts._, Constants._, Names._, NameOps._, Flags._, DenotTransformers._
import SymDenotations._, Symbols._, StdNames._, Annotations._, Trees._, Scopes._, Denotations._
-import TypeErasure.{ erasure, ErasedValueType }
+import TypeErasure.{ erasure, valueErasure, ErasedValueType }
import TypeUtils._
import util.Positions._
import Decorators._
@@ -65,7 +65,7 @@ class ExtensionMethods extends MiniPhaseTransform with DenotTransformer with Ful
}
}
- val underlying = erasure(underlyingOfValueClass(valueClass), semiEraseVCs = true)
+ val underlying = valueErasure(underlyingOfValueClass(valueClass))
val evt = ErasedValueType(valueClass, underlying)
val u2evtSym = ctx.newSymbol(moduleSym, nme.U2EVT, Synthetic | Method,
MethodType(List(nme.x_0), List(underlying), evt))
diff --git a/tests/pending/run/unittest_collection.check b/tests/pending/run/unittest_collection.check
deleted file mode 100644
index df1629dd7..000000000
--- a/tests/pending/run/unittest_collection.check
+++ /dev/null
@@ -1 +0,0 @@
-warning: there was one deprecation warning; re-run with -deprecation for details
diff --git a/tests/pending/run/unittest_collection.scala b/tests/run/unittest_collection.scala
index d10845475..d10845475 100644
--- a/tests/pending/run/unittest_collection.scala
+++ b/tests/run/unittest_collection.scala