diff options
author | Martin Odersky <odersky@gmail.com> | 2015-07-02 14:36:36 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2015-07-02 14:37:12 +0200 |
commit | f57a6d9db6b8119bef1a78aabef4a527a0f9905c (patch) | |
tree | 7ecdb4b69efc356ef13d2e6196937510fa8245bd /src/dotty/tools/dotc/typer/RefChecks.scala | |
parent | 257bf52c3d205359896e3c391274091b3fab732e (diff) | |
download | dotty-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.scala | 16 |
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 } |