aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer/Checking.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-11-24 12:36:31 +0100
committerMartin Odersky <odersky@gmail.com>2014-11-24 14:57:49 +0100
commite26fb448e6b6e62e38fbda0f564a13fc0b149c9f (patch)
tree26ee7c34727e1841994c1d2600f8bdcdbd1c4e0b /src/dotty/tools/dotc/typer/Checking.scala
parent917f58fe1de3f0237c9133ccda462f8af52124f8 (diff)
downloaddotty-e26fb448e6b6e62e38fbda0f564a13fc0b149c9f.tar.gz
dotty-e26fb448e6b6e62e38fbda0f564a13fc0b149c9f.tar.bz2
dotty-e26fb448e6b6e62e38fbda0f564a13fc0b149c9f.zip
Updated refinement checking.
Toucher checks, but only deprecated warnings instead of errors.
Diffstat (limited to 'src/dotty/tools/dotc/typer/Checking.scala')
-rw-r--r--src/dotty/tools/dotc/typer/Checking.scala48
1 files changed, 48 insertions, 0 deletions
diff --git a/src/dotty/tools/dotc/typer/Checking.scala b/src/dotty/tools/dotc/typer/Checking.scala
index 2ff2e9e3b..06722492f 100644
--- a/src/dotty/tools/dotc/typer/Checking.scala
+++ b/src/dotty/tools/dotc/typer/Checking.scala
@@ -152,6 +152,54 @@ object Checking {
else info
}
}
+
+ /** Check that refinement satisfies the following two conditions
+ * 1. No part of it refers to a symbol that's defined in the same refinement
+ * at a textually later point.
+ * 2. All references to the refinement itself via `this` are followed by
+ * selections.
+ * Note: It's not yet clear what exactly we want to allow and what we want to rule out.
+ * This depends also on firming up the DOT calculus. For the moment we only issue
+ * deprecated warnings, not errors.
+ */
+ def checkRefinementNonCyclic(refinement: Tree, refineCls: ClassSymbol)(implicit ctx: Context): Unit = {
+ def flag(what: String, tree: Tree) =
+ ctx.deprecationWarning(i"$what reference in refinement is deprecated", tree.pos)
+ def forwardRef(tree: Tree) = flag("forward", tree)
+ def selfRef(tree: Tree) = flag("self", tree)
+ val checkTree = new TreeAccumulator[Unit] {
+ def checkRef(tree: Tree, sym: Symbol) =
+ if (sym.maybeOwner == refineCls && tree.pos.start <= sym.pos.end) forwardRef(tree)
+ def apply(x: Unit, tree: Tree) = tree match {
+ case tree @ Select(This(_), _) =>
+ checkRef(tree, tree.symbol)
+ case tree: RefTree =>
+ checkRef(tree, tree.symbol)
+ foldOver(x, tree)
+ case tree: This =>
+ selfRef(tree)
+ case tree: TypeTree =>
+ val checkType = new TypeAccumulator[Unit] {
+ def apply(x: Unit, tp: Type): Unit = tp match {
+ case tp: NamedType =>
+ checkRef(tree, tp.symbol)
+ tp.prefix match {
+ case pre: ThisType =>
+ case pre => foldOver(x, pre)
+ }
+ case tp: ThisType if tp.cls == refineCls =>
+ selfRef(tree)
+ case _ =>
+ foldOver(x, tp)
+ }
+ }
+ checkType((), tree.tpe)
+ case _ =>
+ foldOver(x, tree)
+ }
+ }
+ checkTree((), refinement)
+ }
}
trait Checking {