From 023c7bcb8a582a64455d23363e13ab84707ffc8b Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 11 Feb 2015 19:20:46 +0100 Subject: 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. --- src/dotty/tools/dotc/Compiler.scala | 2 +- src/dotty/tools/dotc/transform/TreeChecker.scala | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+), 1 deletion(-) (limited to 'src') 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) -- cgit v1.2.3