Skip to content

Commit 24a5fbe

Browse files
committed
Merge pull request #1092 from dotty-staging/value-class-checks
Add checks for value classes
2 parents 5e80233 + 71698fa commit 24a5fbe

File tree

3 files changed

+24
-1
lines changed

3 files changed

+24
-1
lines changed

src/dotty/tools/dotc/typer/RefChecks.scala

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -708,7 +708,19 @@ object RefChecks {
708708
if (clazz.is(Abstract))
709709
ctx.error("`abstract' modifier cannot be used with value classes", clazz.pos)
710710
if (!clazz.isStatic)
711-
ctx.error("value class cannot be an inner class", clazz.pos)
711+
ctx.error(s"value class may not be a ${if (clazz.owner.isTerm) "local class" else "member of another class"}", clazz.pos)
712+
else {
713+
val clParamAccessors = clazz.asClass.paramAccessors.filter(sym => sym.isTerm && !sym.is(Method))
714+
clParamAccessors match {
715+
case List(param) =>
716+
if (param.is(Mutable))
717+
ctx.error("value class parameter must not be a var", param.pos)
718+
if (param.is(PrivateLocal))
719+
ctx.error("value class parameter must not be private[this]", param.pos)
720+
case _ =>
721+
ctx.error("value class needs to have exactly one val parameter", clazz.pos)
722+
}
723+
}
712724
stats.foreach(checkValueClassMember)
713725
}
714726
}

test/dotc/tests.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -185,6 +185,7 @@ class tests extends CompilerTest {
185185
@Test def neg_validateRefchecks = compileFile(negDir, "validate-refchecks", xerrors = 2)
186186
@Test def neg_skolemize = compileFile(negDir, "skolemize", xerrors = 2)
187187
@Test def neg_nested_bounds = compileFile(negDir, "nested_bounds", xerrors = 1)
188+
@Test def neg_valueClasses = compileFile(negDir, "valueClasses", xerrors = 4)
188189

189190
@Test def run_all = runFiles(runDir)
190191

tests/neg/valueClasses.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
class A1 {
2+
class A2(x: Int) extends AnyVal // error: value class may not be a member of another class
3+
}
4+
class B1 {
5+
def test = {
6+
class B2(x: Int) extends AnyVal // error: value class may not be a local class
7+
}
8+
}
9+
class C(private[this] val u: Int) extends AnyVal // error: value class parameter must not be private[this]
10+
class D(u: Int) extends AnyVal // error: value class parameter must not be private[this]

0 commit comments

Comments
 (0)