diff options
author | Martin Odersky <odersky@gmail.com> | 2015-02-11 19:20:46 +0100 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2015-02-11 19:22:56 +0100 |
commit | 023c7bcb8a582a64455d23363e13ab84707ffc8b (patch) | |
tree | 6221a9787dc95832b76f7a7e5fcbc45d87338f47 | |
parent | f1aa075b818cd7ff110ec3316a7713154c15daf8 (diff) | |
download | dotty-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.
-rw-r--r-- | src/dotty/tools/dotc/Compiler.scala | 2 | ||||
-rw-r--r-- | src/dotty/tools/dotc/transform/TreeChecker.scala | 19 | ||||
-rw-r--r-- | test/dotc/tests.scala | 2 |
3 files changed, 21 insertions, 2 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) diff --git a/test/dotc/tests.scala b/test/dotc/tests.scala index a9ce5a18a..8b3965e88 100644 --- a/test/dotc/tests.scala +++ b/test/dotc/tests.scala @@ -15,7 +15,7 @@ class tests extends CompilerTest { implicit val defaultOptions = noCheckOptions ++ List( "-Yno-deep-subtypes", - "-Ycheck:resolveSuper,mixin,restoreScopes", + "-Ycheck:tailrec,resolveSuper,mixin,restoreScopes", "-d", "./out/" ) |