aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/transform/TreeChecker.scala
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/transform/TreeChecker.scala
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/transform/TreeChecker.scala')
-rw-r--r--src/dotty/tools/dotc/transform/TreeChecker.scala19
1 files changed, 19 insertions, 0 deletions
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)