Skip to content

Commit de1fb42

Browse files
committed
Fix #1688: don't allow override of synthetic or primitive classes
1 parent 64a23e0 commit de1fb42

File tree

5 files changed

+56
-5
lines changed

5 files changed

+56
-5
lines changed

src/dotty/tools/dotc/Compiler.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ class Compiler {
5050
new CheckReentrant), // Internal use only: Check that compiled program has no data races involving global vars
5151
List(new RefChecks, // Various checks mostly related to abstract members and overriding
5252
new CheckStatic, // Check restrictions that apply to @static members
53+
new CheckIllegalOverrides, // Check restrictions that apply to phantom types and value classes
5354
new ElimRepeated, // Rewrite vararg parameters and arguments
5455
new NormalizeFlags, // Rewrite some definition flags
5556
new ExtensionMethods, // Expand methods of value classes with extension methods

src/dotty/tools/dotc/core/Definitions.scala

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -633,9 +633,9 @@ class Definitions {
633633
name.startsWith(prefix) && name.drop(prefix.length).forall(_.isDigit)
634634
}
635635

636-
def isBottomClass(cls: Symbol) =
636+
def isBottomClass(cls: Symbol) =
637637
cls == NothingClass || cls == NullClass
638-
def isBottomType(tp: Type) =
638+
def isBottomType(tp: Type) =
639639
tp.derivesFrom(NothingClass) || tp.derivesFrom(NullClass)
640640

641641
def isFunctionClass(cls: Symbol) = isVarArityClass(cls, tpnme.Function)
@@ -772,7 +772,8 @@ class Definitions {
772772
SingletonClass,
773773
EqualsPatternClass,
774774
EmptyPackageVal,
775-
OpsPackageClass)
775+
OpsPackageClass
776+
)
776777

777778
/** Lists core methods that don't have underlying bytecode, but are synthesized on-the-fly in every reflection universe */
778779
lazy val syntheticCoreMethods = AnyMethods ++ ObjectMethods ++ List(String_+, throwMethod)
@@ -785,8 +786,8 @@ class Definitions {
785786
if (!_isInitialized) {
786787
// force initialization of every symbol that is synthesized or hijacked by the compiler
787788
val forced = syntheticCoreClasses ++ syntheticCoreMethods ++ ScalaValueClasses()
788-
789-
// Enter all symbols from the scalaShadowing package in the scala package
789+
790+
// Enter all symbols from the scalaShadowing package in the scala package
790791
for (m <- ScalaShadowingPackageClass.info.decls)
791792
ScalaPackageClass.enter(m)
792793

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
package dotty.tools.dotc
2+
package transform
3+
4+
import TreeTransforms._
5+
import core._
6+
import Contexts._, Definitions._, Decorators._
7+
8+
/** Checks if the user is trying to illegally override synthetic classes
9+
* or objects
10+
*/
11+
class CheckIllegalOverrides extends MiniPhaseTransform {
12+
import ast.tpd._
13+
14+
override def phaseName = "checkPhantom"
15+
16+
override def transformTypeDef(tree: TypeDef)(implicit ctx: Context, info: TransformerInfo) = {
17+
val defn = ctx.definitions
18+
val tpe = tree.tpe
19+
val fullName = tree.symbol.showFullName
20+
21+
val syntheticClasses = defn.syntheticCoreClasses.map(_.showFullName)
22+
val primitives = defn.ScalaValueClasses().map(_.showFullName)
23+
val boxedPrimitives = defn.ScalaBoxedClasses().map(_.showFullName)
24+
25+
val illegalOverride =
26+
if (syntheticClasses.contains(fullName))
27+
Some("synthetic")
28+
else if (primitives.contains(fullName))
29+
Some("primitive")
30+
else if (boxedPrimitives.contains(fullName))
31+
Some("boxed primitive")
32+
else
33+
None
34+
35+
illegalOverride.foreach { overriden =>
36+
ctx.error(i"Cannot define symbol overriding $overriden class `$tpe`", tree.pos)
37+
}
38+
39+
tree
40+
}
41+
}

tests/neg/i1688.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
package scala
2+
3+
sealed trait Null // error
4+
5+
trait Char // error

tests/neg/i1688b.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
package java.lang
2+
3+
trait Byte // error

0 commit comments

Comments
 (0)