aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/typer/RefChecks.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-07-02 14:36:36 +0200
committerMartin Odersky <odersky@gmail.com>2015-07-02 14:37:12 +0200
commitf57a6d9db6b8119bef1a78aabef4a527a0f9905c (patch)
tree7ecdb4b69efc356ef13d2e6196937510fa8245bd /src/dotty/tools/dotc/typer/RefChecks.scala
parent257bf52c3d205359896e3c391274091b3fab732e (diff)
downloaddotty-f57a6d9db6b8119bef1a78aabef4a527a0f9905c.tar.gz
dotty-f57a6d9db6b8119bef1a78aabef4a527a0f9905c.tar.bz2
dotty-f57a6d9db6b8119bef1a78aabef4a527a0f9905c.zip
Check value class member restrictions
According to SIP 15 a value class C must obey the following restrictions: C may not have secondary constructors. C may not declare fields (other than the parameter of a value class). C may not contain object definitions. C may not have initialization statements. These are enforced by this commit. We are still missing restrictions on value class paremeters. We should review what the right set of conditions is (probably we want to admit non-vals, and maybe even multiple parameters).
Diffstat (limited to 'src/dotty/tools/dotc/typer/RefChecks.scala')
-rw-r--r--src/dotty/tools/dotc/typer/RefChecks.scala16
1 files changed, 14 insertions, 2 deletions
diff --git a/src/dotty/tools/dotc/typer/RefChecks.scala b/src/dotty/tools/dotc/typer/RefChecks.scala
index 6a31b66aa..bb22e2045 100644
--- a/src/dotty/tools/dotc/typer/RefChecks.scala
+++ b/src/dotty/tools/dotc/typer/RefChecks.scala
@@ -655,7 +655,17 @@ object RefChecks {
}
/** Verify classes extending AnyVal meet the requirements */
- private def checkDerivedValueClass(clazz: Symbol)(implicit ctx: Context) =
+ private def checkDerivedValueClass(clazz: Symbol, stats: List[Tree])(implicit ctx: Context) = {
+ def checkValueClassMember(stat: Tree) = stat match {
+ case _: ValDef if !stat.symbol.is(ParamAccessor) =>
+ ctx.error(s"value class may not define non-parameter field", stat.pos)
+ case _: DefDef if stat.symbol.isConstructor =>
+ ctx.error(s"value class may not define secondary constructor", stat.pos)
+ case _: MemberDef | _: Import | EmptyTree =>
+ // ok
+ case _ =>
+ ctx.error(s"value class may not contain initialization statements", stat.pos)
+ }
if (isDerivedValueClass(clazz)) {
if (clazz.is(Trait))
ctx.error("Only classes (not traits) are allowed to extend AnyVal", clazz.pos)
@@ -663,7 +673,9 @@ object RefChecks {
ctx.error("`abstract' modifier cannot be used with value classes", clazz.pos)
if (!clazz.isStatic)
ctx.error("value class cannot be an inner class", clazz.pos)
+ stats.foreach(checkValueClassMember)
}
+ }
type LevelAndIndex = immutable.Map[Symbol, (LevelInfo, Int)]
@@ -780,7 +792,7 @@ class RefChecks extends MiniPhase { thisTransformer =>
checkParents(cls)
checkCompanionNameClashes(cls)
checkAllOverrides(cls)
- checkDerivedValueClass(cls)
+ checkDerivedValueClass(cls, tree.body)
tree
}