aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-02-11 19:20:46 +0100
committerMartin Odersky <odersky@gmail.com>2015-02-11 19:22:56 +0100
commit023c7bcb8a582a64455d23363e13ab84707ffc8b (patch)
tree6221a9787dc95832b76f7a7e5fcbc45d87338f47 /src/dotty/tools/dotc
parentf1aa075b818cd7ff110ec3316a7713154c15daf8 (diff)
downloaddotty-023c7bcb8a582a64455d23363e13ab84707ffc8b.tar.gz
dotty-023c7bcb8a582a64455d23363e13ab84707ffc8b.tar.bz2
dotty-023c7bcb8a582a64455d23363e13ab84707ffc8b.zip
Added test to TreeChecker that guards against orphan parameters.
Currently, tests fail. The failures I checked are all related to tailcalls. Not sure whether there are others. This is a blocker for serialization. Orphan parameters cannot be serialized. Maybe rethink the position of tailcalls? It looks to me that the repeated trouble it gives us is more than the effort required to put an efficient tailcall recognition after pattern matching in place. But I might be wrong.
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r--src/dotty/tools/dotc/Compiler.scala2
-rw-r--r--src/dotty/tools/dotc/transform/TreeChecker.scala19
2 files changed, 20 insertions, 1 deletions
diff --git a/src/dotty/tools/dotc/Compiler.scala b/src/dotty/tools/dotc/Compiler.scala
index 721b52b2e..403aa1157 100644
--- a/src/dotty/tools/dotc/Compiler.scala
+++ b/src/dotty/tools/dotc/Compiler.scala
@@ -41,7 +41,7 @@ class Compiler {
List(new FirstTransform,
new SyntheticMethods),
List(new SuperAccessors),
- // pickling goes here
+ //List(new Pickler), // Pickler needs to come last in a group since it should not pickle trees generated later
List(new RefChecks,
new ElimRepeated,
new ElimLocals,
diff --git a/src/dotty/tools/dotc/transform/TreeChecker.scala b/src/dotty/tools/dotc/transform/TreeChecker.scala
index 1aa681f33..7552f1f54 100644
--- a/src/dotty/tools/dotc/transform/TreeChecker.scala
+++ b/src/dotty/tools/dotc/transform/TreeChecker.scala
@@ -139,9 +139,28 @@ class TreeChecker {
assert(isSubType(tree1.tpe, tree.typeOpt), divergenceMsg(tree1.tpe, tree.typeOpt))
tree1
}
+ checkNoOrphans(res.tpe)
phasesToCheck.foreach(_.checkPostCondition(res))
res
}
+
+ /** Check that PolyParams and MethodParams refer to an enclosing type */
+ def checkNoOrphans(tp: Type)(implicit ctx: Context) = new TypeMap() {
+ val definedBinders = mutable.Set[Type]()
+ def apply(tp: Type): Type = {
+ tp match {
+ case tp: BindingType =>
+ definedBinders += tp
+ mapOver(tp)
+ definedBinders -= tp
+ case tp: ParamType =>
+ assert(definedBinders.contains(tp.binder), s"orphan param: $tp")
+ case _ =>
+ mapOver(tp)
+ }
+ tp
+ }
+ }.apply(tp)
override def typedIdent(tree: untpd.Ident, pt: Type)(implicit ctx: Context): Tree = {
assert(tree.isTerm || !ctx.isAfterTyper, tree.show + " at " + ctx.phase)