aboutsummaryrefslogtreecommitdiff
path: root/compiler/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2017-03-12 11:53:51 +0100
committerMartin Odersky <odersky@gmail.com>2017-03-14 12:05:29 +0100
commit81086afc724aaa4b574dfcf6318905773fc5b2f1 (patch)
tree2c3f5161c147b2d2c6999a78d06a4d1d28d7c5c6 /compiler/src
parent41afff188c25866f92fc64cbf5da195bc85c8c9a (diff)
downloaddotty-81086afc724aaa4b574dfcf6318905773fc5b2f1.tar.gz
dotty-81086afc724aaa4b574dfcf6318905773fc5b2f1.tar.bz2
dotty-81086afc724aaa4b574dfcf6318905773fc5b2f1.zip
Check there are no forward dependencies to method parameters
Diffstat (limited to 'compiler/src')
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Checking.scala20
-rw-r--r--compiler/src/dotty/tools/dotc/typer/Typer.scala1
2 files changed, 20 insertions, 1 deletions
diff --git a/compiler/src/dotty/tools/dotc/typer/Checking.scala b/compiler/src/dotty/tools/dotc/typer/Checking.scala
index f822f8893..b43391592 100644
--- a/compiler/src/dotty/tools/dotc/typer/Checking.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Checking.scala
@@ -441,7 +441,6 @@ object Checking {
case List(param) =>
if (param.is(Mutable))
ctx.error("value class parameter must not be a var", param.pos)
-
case _ =>
ctx.error("value class needs to have exactly one val parameter", clazz.pos)
}
@@ -625,6 +624,24 @@ trait Checking {
case _ =>
}
}
+
+ /** Check that method parameter types do not reference their own parameter
+ * or later parameters in the same parameter section.
+ */
+ def checkNoForwardDependencies(vparams: List[ValDef])(implicit ctx: Context): Unit = vparams match {
+ case vparam :: vparams1 =>
+ val check = new TreeTraverser {
+ def traverse(tree: Tree)(implicit ctx: Context) = tree match {
+ case id: Ident if vparams.exists(_.symbol == id.symbol) =>
+ ctx.error("illegal forward reference to method parameter", id.pos)
+ case _ =>
+ traverseChildren(tree)
+ }
+ }
+ check.traverse(vparam.tpt)
+ checkNoForwardDependencies(vparams1)
+ case Nil =>
+ }
}
trait NoChecking extends Checking {
@@ -642,4 +659,5 @@ trait NoChecking extends Checking {
override def checkNotSingleton(tpt: Tree, where: String)(implicit ctx: Context): Tree = tpt
override def checkDerivedValueClass(clazz: Symbol, stats: List[Tree])(implicit ctx: Context) = ()
override def checkTraitInheritance(parentSym: Symbol, cls: ClassSymbol, pos: Position)(implicit ctx: Context) = ()
+ override def checkNoForwardDependencies(vparams: List[ValDef])(implicit ctx: Context): Unit = ()
}
diff --git a/compiler/src/dotty/tools/dotc/typer/Typer.scala b/compiler/src/dotty/tools/dotc/typer/Typer.scala
index 4bf87dd81..d4a9744e4 100644
--- a/compiler/src/dotty/tools/dotc/typer/Typer.scala
+++ b/compiler/src/dotty/tools/dotc/typer/Typer.scala
@@ -1229,6 +1229,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
completeAnnotations(ddef, sym)
val tparams1 = tparams mapconserve (typed(_).asInstanceOf[TypeDef])
val vparamss1 = vparamss nestedMapconserve (typed(_).asInstanceOf[ValDef])
+ vparamss1.foreach(checkNoForwardDependencies)
if (sym is Implicit) checkImplicitParamsNotSingletons(vparamss1)
var tpt1 = checkSimpleKinded(typedType(tpt))