From 257bf52c3d205359896e3c391274091b3fab732e Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Thu, 2 Jul 2015 14:07:57 +0200 Subject: Check that value classes are static --- src/dotty/tools/dotc/typer/RefChecks.scala | 10 ++++++---- test/dotc/tests.scala | 2 ++ tests/neg/i705-inner-value-class.scala | 15 +++++++++++++++ 3 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 tests/neg/i705-inner-value-class.scala diff --git a/src/dotty/tools/dotc/typer/RefChecks.scala b/src/dotty/tools/dotc/typer/RefChecks.scala index d9b62badc..6a31b66aa 100644 --- a/src/dotty/tools/dotc/typer/RefChecks.scala +++ b/src/dotty/tools/dotc/typer/RefChecks.scala @@ -655,12 +655,14 @@ object RefChecks { } /** Verify classes extending AnyVal meet the requirements */ - private def checkAnyValSubclass(clazz: Symbol)(implicit ctx: Context) = + private def checkDerivedValueClass(clazz: Symbol)(implicit ctx: Context) = if (isDerivedValueClass(clazz)) { if (clazz.is(Trait)) ctx.error("Only classes (not traits) are allowed to extend AnyVal", clazz.pos) - else if (clazz.is(Abstract)) + if (clazz.is(Abstract)) 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) } type LevelAndIndex = immutable.Map[Symbol, (LevelInfo, Int)] @@ -708,7 +710,7 @@ import RefChecks._ * - only one overloaded alternative defines default arguments * - applyDynamic methods are not overloaded * - all overrides conform to rules laid down by `checkAllOverrides`. - * - any value classes conform to rules laid down by `checkAnyValSubClass`. + * - any value classes conform to rules laid down by `checkDerivedValueClass`. * - this(...) constructor calls do not forward reference other definitions in their block (not even lazy vals). * - no forward reference in a local block jumps over a non-lazy val definition. * - a class and its companion object do not both define a class or module with the same name. @@ -778,7 +780,7 @@ class RefChecks extends MiniPhase { thisTransformer => checkParents(cls) checkCompanionNameClashes(cls) checkAllOverrides(cls) - checkAnyValSubclass(cls) + checkDerivedValueClass(cls) tree } diff --git a/test/dotc/tests.scala b/test/dotc/tests.scala index 1aa35e3ee..1cdd9f38a 100644 --- a/test/dotc/tests.scala +++ b/test/dotc/tests.scala @@ -133,6 +133,8 @@ class tests extends CompilerTest { @Test def neg_i0248_inherit_refined = compileFile(negDir, "i0248-inherit-refined", xerrors = 4) @Test def neg_i0281 = compileFile(negDir, "i0281-null-primitive-conforms", xerrors = 3) @Test def neg_i583 = compileFile(negDir, "i0583-skolemize", xerrors = 2) + @Test def neg_finalSealed = compileFile(negDir, "final-sealed", xerrors = 2) + @Test def neg_i705 = compileFile(negDir, "i705-inner-value-class", xerrors = 3) @Test def neg_moduleSubtyping = compileFile(negDir, "moduleSubtyping", xerrors = 4) @Test def neg_escapingRefs = compileFile(negDir, "escapingRefs", xerrors = 2) @Test def neg_instantiateAbstract = compileFile(negDir, "instantiateAbstract", xerrors = 8) diff --git a/tests/neg/i705-inner-value-class.scala b/tests/neg/i705-inner-value-class.scala new file mode 100644 index 000000000..6dec7b0f9 --- /dev/null +++ b/tests/neg/i705-inner-value-class.scala @@ -0,0 +1,15 @@ +class Foo { + class B(val a: Int) extends AnyVal // error +} + +object Test { + class B(val a: Int) extends AnyVal // ok + def f = { + class C(val a: Int) extends AnyVal // error + new C(1) + } + class B1(val b: Int) extends B(b) +// class D extends B( { class E(val a: Int) extends AnyVal; new E(1) } ) // error +} + + -- cgit v1.2.3