aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/dotty/tools/dotc/typer/RefChecks.scala14
-rw-r--r--test/dotc/tests.scala1
-rw-r--r--tests/neg/valueClasses.scala10
3 files changed, 24 insertions, 1 deletions
diff --git a/src/dotty/tools/dotc/typer/RefChecks.scala b/src/dotty/tools/dotc/typer/RefChecks.scala
index 067694bfd..bb411c6b5 100644
--- a/src/dotty/tools/dotc/typer/RefChecks.scala
+++ b/src/dotty/tools/dotc/typer/RefChecks.scala
@@ -708,7 +708,19 @@ object RefChecks {
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)
+ ctx.error(s"value class may not be a ${if (clazz.owner.isTerm) "local class" else "member of another class"}", clazz.pos)
+ else {
+ val clParamAccessors = clazz.asClass.paramAccessors.filter(sym => sym.isTerm && !sym.is(Method))
+ clParamAccessors match {
+ case List(param) =>
+ if (param.is(Mutable))
+ ctx.error("value class parameter must not be a var", param.pos)
+ if (param.is(PrivateLocal))
+ ctx.error("value class parameter must not be private[this]", param.pos)
+ case _ =>
+ ctx.error("value class needs to have exactly one val parameter", clazz.pos)
+ }
+ }
stats.foreach(checkValueClassMember)
}
}
diff --git a/test/dotc/tests.scala b/test/dotc/tests.scala
index 12b830738..70af32bd3 100644
--- a/test/dotc/tests.scala
+++ b/test/dotc/tests.scala
@@ -185,6 +185,7 @@ class tests extends CompilerTest {
@Test def neg_validateRefchecks = compileFile(negDir, "validate-refchecks", xerrors = 2)
@Test def neg_skolemize = compileFile(negDir, "skolemize", xerrors = 2)
@Test def neg_nested_bounds = compileFile(negDir, "nested_bounds", xerrors = 1)
+ @Test def neg_valueClasses = compileFile(negDir, "valueClasses", xerrors = 4)
@Test def run_all = runFiles(runDir)
diff --git a/tests/neg/valueClasses.scala b/tests/neg/valueClasses.scala
new file mode 100644
index 000000000..ae90ef63c
--- /dev/null
+++ b/tests/neg/valueClasses.scala
@@ -0,0 +1,10 @@
+class A1 {
+ class A2(x: Int) extends AnyVal // error: value class may not be a member of another class
+}
+class B1 {
+ def test = {
+ class B2(x: Int) extends AnyVal // error: value class may not be a local class
+ }
+}
+class C(private[this] val u: Int) extends AnyVal // error: value class parameter must not be private[this]
+class D(u: Int) extends AnyVal // error: value class parameter must not be private[this]