Skip to content

Commit ef38642

Browse files
committed
Do not allow extending alias of AnyVal
1 parent 05b102a commit ef38642

File tree

5 files changed

+19
-6
lines changed

5 files changed

+19
-6
lines changed

compiler/src/dotty/tools/dotc/reporting/ErrorMessageID.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -223,6 +223,7 @@ enum ErrorMessageID(val isActive: Boolean = true) extends java.lang.Enum[ErrorMe
223223
case IllegalUnrollPlacementID // errorNumber: 207
224224
case ExtensionHasDefaultID // errorNumber: 208
225225
case FormatInterpolationErrorID // errorNumber: 209
226+
case ValueClassCannotExtendAliasOfAnyValID // errorNumber: 210
226227

227228
def errorNumber = ordinal - 1
228229

compiler/src/dotty/tools/dotc/reporting/messages.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1813,6 +1813,12 @@ class ValueClassParameterMayNotBeCallByName(valueClass: Symbol, param: Symbol)(u
18131813
def explain(using Context) = ""
18141814
}
18151815

1816+
class ValueClassCannotExtendAliasOfAnyVal(valueClass: Symbol, alias: Symbol)(using Context)
1817+
extends SyntaxMsg(ValueClassCannotExtendAliasOfAnyValID) {
1818+
def msg(using Context) = i"""Value class cannot extend from alias $alias of ${hl("AnyVal")} """
1819+
def explain(using Context) = ""
1820+
}
1821+
18161822
class SuperCallsNotAllowedInlineable(symbol: Symbol)(using Context)
18171823
extends SyntaxMsg(SuperCallsNotAllowedInlineableID) {
18181824
def msg(using Context) = i"Super call not allowed in inlineable $symbol"

compiler/src/dotty/tools/dotc/transform/TreeChecker.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ object TreeChecker {
244244
private val everDefinedSyms = MutableSymbolMap[untpd.Tree]()
245245

246246
// don't check value classes after typer, as the constraint about constructors doesn't hold after transform
247-
override def checkDerivedValueClass(clazz: Symbol, stats: List[Tree])(using Context): Unit = ()
247+
override def checkDerivedValueClass(cdef: untpd.TypeDef, clazz: Symbol, stats: List[Tree])(using Context): Unit = ()
248248

249249
def withDefinedSyms[T](trees: List[untpd.Tree])(op: => T)(using Context): T = {
250250
var locally = List.empty[Symbol]

compiler/src/dotty/tools/dotc/typer/Checking.scala

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -743,7 +743,7 @@ object Checking {
743743
}
744744

745745
/** Verify classes extending AnyVal meet the requirements */
746-
def checkDerivedValueClass(clazz: Symbol, stats: List[Tree])(using Context): Unit = {
746+
def checkDerivedValueClass(cdef: untpd.TypeDef, clazz: Symbol, stats: List[Tree])(using Context): Unit = {
747747
def checkValueClassMember(stat: Tree) = stat match {
748748
case _: TypeDef if stat.symbol.isClass =>
749749
report.error(ValueClassesMayNotDefineInner(clazz, stat.symbol), stat.srcPos)
@@ -760,6 +760,10 @@ object Checking {
760760
// enum extending a value class type (AnyVal or an alias of it)
761761
// The error message 'EnumMayNotBeValueClassesID' will take care of generating the error message (See #22236)
762762
if (clazz.isDerivedValueClass && !clazz.isEnumAnonymClass) {
763+
val implTree @ Template(_, _, _, _) = cdef.rhs: @unchecked
764+
val parent = implTree.parents.head
765+
val isExtendingAliasOfAnyVal = parent.tpe.nn.dealias =:= defn.AnyValType && !(parent.tpe.nn =:= defn.AnyValType)
766+
763767
if (clazz.is(Trait))
764768
report.error(CannotExtendAnyVal(clazz), clazz.srcPos)
765769
if clazz.is(Module) then
@@ -770,6 +774,8 @@ object Checking {
770774
report.error(ValueClassesMayNotBeAbstract(clazz), clazz.srcPos)
771775
if (!clazz.isStatic)
772776
report.error(ValueClassesMayNotBeContainted(clazz), clazz.srcPos)
777+
if (isExtendingAliasOfAnyVal)
778+
report.error(ValueClassCannotExtendAliasOfAnyVal(clazz, parent.symbol), clazz.srcPos)
773779
if (isDerivedValueClass(underlyingOfValueClass(clazz.asClass).classSymbol))
774780
report.error(ValueClassesMayNotWrapAnotherValueClass(clazz), clazz.srcPos)
775781
else {
@@ -1307,8 +1313,8 @@ trait Checking {
13071313
else tpt
13081314

13091315
/** Verify classes extending AnyVal meet the requirements */
1310-
def checkDerivedValueClass(clazz: Symbol, stats: List[Tree])(using Context): Unit =
1311-
Checking.checkDerivedValueClass(clazz, stats)
1316+
def checkDerivedValueClass(cdef: untpd.TypeDef, clazz: Symbol, stats: List[Tree])(using Context): Unit =
1317+
Checking.checkDerivedValueClass(cdef, clazz, stats)
13121318

13131319
/** Check that case classes are not inherited by case classes.
13141320
*/
@@ -1689,7 +1695,7 @@ trait NoChecking extends ReChecking {
16891695
override def checkNoTargetNameConflict(stats: List[Tree])(using Context): Unit = ()
16901696
override def checkParentCall(call: Tree, caller: ClassSymbol)(using Context): Unit = ()
16911697
override def checkSimpleKinded(tpt: Tree)(using Context): Tree = tpt
1692-
override def checkDerivedValueClass(clazz: Symbol, stats: List[Tree])(using Context): Unit = ()
1698+
override def checkDerivedValueClass(cdef: untpd.TypeDef, clazz: Symbol, stats: List[Tree])(using Context): Unit = ()
16931699
override def checkCaseInheritance(parentSym: Symbol, caseCls: ClassSymbol, pos: SrcPos)(using Context): Unit = ()
16941700
override def checkNoForwardDependencies(vparams: List[ValDef])(using Context): Unit = ()
16951701
override def checkMembersOK(tp: Type, pos: SrcPos)(using Context): Type = tp

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3243,7 +3243,7 @@ class Typer(@constructorOnly nestingLevel: Int = 0) extends Namer
32433243
checkNonCyclicInherited(cls.thisType, cls.info.parents, cls.info.decls, cdef.srcPos)
32443244

32453245
// check value class constraints
3246-
checkDerivedValueClass(cls, body1)
3246+
checkDerivedValueClass(cdef, cls, body1)
32473247

32483248
val effectiveOwner = cls.owner.skipWeakOwner
32493249
if cls.is(ModuleClass)

0 commit comments

Comments
 (0)