Skip to content

Commit 11f64e1

Browse files
committed
Code improvements
1 parent d152232 commit 11f64e1

File tree

3 files changed

+84
-87
lines changed

3 files changed

+84
-87
lines changed

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

+7-7
Original file line numberDiff line numberDiff line change
@@ -533,16 +533,16 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
533533
case OrType(tp1, tp2) => isNullable(tp1) || isNullable(tp2)
534534
case _ => false
535535
}
536-
def isPhantom(tp: Type): Boolean = tp.dealias match {
536+
def isPhantomType(tp: Type): Boolean = tp.dealias match {
537537
case tp: TypeRef => tp.symbol.isPhantomClass
538-
case tp: RefinedOrRecType => isPhantom(tp.parent)
539-
case AndType(tp1, tp2) => isPhantom(tp1) && isPhantom(tp2)
540-
case OrType(tp1, tp2) => isPhantom(tp1) || isPhantom(tp2)
538+
case tp: RefinedOrRecType => isPhantomType(tp.parent)
539+
case AndType(tp1, tp2) => isPhantomType(tp1) || isPhantomType(tp2)
540+
case OrType(tp1, tp2) => isPhantomType(tp1) || isPhantomType(tp2)
541541
case _ => false
542542
}
543-
if (tp1.symbol eq NothingClass) tp2.isInstanceOf[ValueType] && !isPhantom(tp2)
544-
else if (tp1.symbol eq NullClass) isNullable(tp2) && !isPhantom(tp2)
545-
else if (tp1.symbol eq PhantomNothingClass) tp2.isInstanceOf[ValueType] && isPhantom(tp2)
543+
if (tp1.symbol eq NothingClass) tp2.isInstanceOf[ValueType] && !isPhantomType(tp2)
544+
else if (tp1.symbol eq NullClass) isNullable(tp2) && !isPhantomType(tp2)
545+
else if (tp1.symbol eq PhantomNothingClass) tp2.isInstanceOf[ValueType] && isPhantomType(tp2)
546546
else false
547547
}
548548
case tp1: SingletonType =>

src/dotty/tools/dotc/transform/PhantomDeclErasure.scala

+3-2
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,7 @@ class PhantomDeclErasure extends MiniPhaseTransform with InfoTransformer {
5050
super.checkPostCondition(tree)
5151
}
5252

53-
// Transform trees
53+
/* Tree transform */
5454

5555
override def transformStats(trees: List[tpd.Tree])(implicit ctx: Context, info: TransformerInfo): List[tpd.Tree] = {
5656
val newTrees = trees.filter {
@@ -61,7 +61,7 @@ class PhantomDeclErasure extends MiniPhaseTransform with InfoTransformer {
6161
super.transformStats(newTrees)
6262
}
6363

64-
// Transform symbols
64+
/* Symbol transform */
6565

6666
def transformInfo(tp: Type, sym: Symbol)(implicit ctx: Context): Type = erasedPhantoms(tp)
6767

@@ -85,4 +85,5 @@ class PhantomDeclErasure extends MiniPhaseTransform with InfoTransformer {
8585
case tp: ClassInfo => tp.cls.derivesFrom(defn.PhantomAnyClass)
8686
case _ => false
8787
}
88+
8889
}

src/dotty/tools/dotc/transform/PhantomRefErasure.scala

+74-78
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,74 @@ class PhantomRefErasure extends MiniPhaseTransform with InfoTransformer {
2626
override def runsAfter: Set[Class[_ <: Phase]] =
2727
Set(classOf[InterceptedMethods], classOf[Splitter], classOf[ElimRepeated])
2828

29+
/* Before transform checks: errors and warnings */
30+
31+
private def checkStats(trees: List[Tree])(implicit ctx: Context): Unit = ctx.owner match {
32+
case cls: ClassSymbol if cls.classDenot.classSymbol.isPhantomClass =>
33+
trees.foreach {
34+
case _: TypeDef => // OK
35+
case _: ValOrDefDef => // OK
36+
case tree =>
37+
ctx.error(s"Phantom classes can not have expressions in statement position.", tree.pos)
38+
}
39+
40+
case _ =>
41+
def checkTree(tree: Tree, pos: Position): Unit = tree match {
42+
case _: TypeDef => // OK
43+
case _: ValOrDefDef => // OK
44+
case Apply(Select(_: This, name), _) if name == nme.CONSTRUCTOR => // OK
45+
case _ if tree.tpe.derivesFrom(defn.PhantomAnyClass) =>
46+
ctx.error(s"Expression returning a phantom type can not be in statement position.", pos)
47+
case _ => // OK
48+
}
49+
trees.foreach(tree => checkTree(tree, tree.pos))
50+
}
51+
52+
private def checkDefDef(ddef: DefDef)(implicit ctx: Context): Unit = {
53+
def valOrDefDefDeclKeyword(flags: FlagSet): String = {
54+
if (!flags.is(Flags.Accessor)) "def"
55+
else if (flags.is(Flags.Mutable)) "var"
56+
else if (flags.is(Flags.Lazy)) "lazy val"
57+
else "val"
58+
}
59+
60+
def classDeclKeyword(flags: FlagSet): String = {
61+
if (flags.is(Flags.Trait)) "trait"
62+
else if (flags.is(Flags.Abstract)) "abstract class"
63+
else "class"
64+
}
65+
66+
val flags = ddef.symbol.flags
67+
if (ddef.tpt.tpe.derivesFrom(defn.PhantomAnyClass)) {
68+
if (flags.is(Flags.Mutable) || flags.is(Flags.Lazy))
69+
ctx.error(s"Can not define '${valOrDefDefDeclKeyword(flags)}' with phantom type.", ddef.pos)
70+
} else if (ddef.name != nme.CONSTRUCTOR) {
71+
ddef.symbol.owner match {
72+
case cls: ClassSymbol if cls.classSymbol.derivesFrom(defn.PhantomAnyClass) =>
73+
val defKey = valOrDefDefDeclKeyword(flags)
74+
val classKey = classDeclKeyword(ddef.symbol.owner.flags)
75+
ctx.error(s"Can not define '$defKey' with non phantom type in a phantom '$classKey'.", ddef.pos)
76+
77+
case _ => // OK
78+
}
79+
}
80+
81+
for (vparams <- ddef.vparamss) {
82+
val numPhantoms = vparams.count(_.tpt.typeOpt.derivesFrom(defn.PhantomAnyClass))
83+
if (numPhantoms != 0 && numPhantoms != vparams.size)
84+
ctx.error("Lists of parameters with runtime and phantom types are not allowed.", vparams.head.pos)
85+
else if (ddef.name == nme.CONSTRUCTOR && numPhantoms != vparams.size) {
86+
ctx.owner match {
87+
case cls: ClassSymbol if cls.classDenot.classSymbol.derivesFrom(defn.PhantomAnyClass) =>
88+
ctx.error("Phantom class constructors can not have non phantom parameters.", vparams.head.pos)
89+
case _ =>
90+
}
91+
}
92+
}
93+
}
94+
95+
/* After transform checks */
96+
2997
/** Check what the phase achieves, to be called at any point after it is finished.
3098
*/
3199
override def checkPostCondition(tree: Tree)(implicit ctx: Context): Unit = {
@@ -40,7 +108,7 @@ class PhantomRefErasure extends MiniPhaseTransform with InfoTransformer {
40108
super.checkPostCondition(tree)
41109
}
42110

43-
// Transform trees
111+
/* Tree transform */
44112

45113
override def transformStats(trees: List[Tree])(implicit ctx: Context, info: TransformerInfo): List[Tree] = {
46114
checkStats(trees)
@@ -78,29 +146,10 @@ class PhantomRefErasure extends MiniPhaseTransform with InfoTransformer {
78146
}
79147

80148
override def transformDefDef(ddef: DefDef)(implicit ctx: Context, info: TransformerInfo): Tree = {
81-
def filterPhantom(vparamss: List[List[ValDef]]): List[List[ValDef]] = {
82-
vparamss.filter { vparams =>
83-
val phantoms = vparams.filter(_.tpt.typeOpt.derivesFrom(defn.PhantomAnyClass))
84-
if (phantoms.size != vparams.size) {
85-
if (phantoms.nonEmpty)
86-
ctx.error("Lists of parameters with runtime and phantom types are not allowed.", vparams.head.pos)
87-
else if (ddef.name == nme.CONSTRUCTOR) {
88-
ctx.owner match {
89-
case cls: ClassSymbol if cls.classDenot.classSymbol.derivesFrom(defn.PhantomAnyClass) =>
90-
ctx.error("Phantom class constructors can not have non phantom parameters.", vparams.head.pos)
91-
case _ =>
92-
}
93-
}
94-
}
95-
96-
phantoms.isEmpty
97-
}
98-
}
99-
val newVparamss = filterPhantom(ddef.vparamss)
100-
val ddef1 =
101-
if (ddef.vparamss.length == newVparamss.length) ddef
102-
else cpy.DefDef(ddef)(vparamss = newVparamss)
103-
super.transformDefDef(ddef1)
149+
checkDefDef(ddef)
150+
val newVparamss = ddef.vparamss.map(_.filter(vparam => !vparam.tpt.typeOpt.derivesFrom(defn.PhantomAnyClass)))
151+
if (newVparamss == ddef.vparamss) ddef
152+
else cpy.DefDef(ddef)(vparamss = newVparamss)
104153
}
105154

106155
private def filterStats(trees: List[Tree])(implicit ctx: Context): List[Tree] = {
@@ -111,60 +160,7 @@ class PhantomRefErasure extends MiniPhaseTransform with InfoTransformer {
111160
flatStats.filter(!_.tpe.derivesFrom(defn.PhantomAnyClass))
112161
}
113162

114-
private def checkStats(trees: List[Tree])(implicit ctx: Context): Unit = ctx.owner match {
115-
case cls: ClassSymbol if cls.classDenot.classSymbol.derivesFrom(defn.PhantomAnyClass) =>
116-
trees.foreach {
117-
case tree: TypeDef => // OK
118-
case tree: ValDef => // OK
119-
case tree: DefDef => checkDefDef(tree)
120-
case tree =>
121-
ctx.error(s"Phantom classes can not have expressions in statement position.", tree.pos)
122-
}
123-
124-
case _ =>
125-
def checkTree(tree: Tree, pos: Position): Unit = tree match {
126-
case _: TypeDef => // OK
127-
case _: ValDef => // OK
128-
case tree: DefDef => checkDefDef(tree)
129-
case Apply(Select(_: This, name), _) if name == nme.CONSTRUCTOR => // OK
130-
case _ if tree.tpe.derivesFrom(defn.PhantomAnyClass) =>
131-
ctx.error(s"Expression returning a phantom type can not be in statement position.", pos)
132-
case _ =>
133-
}
134-
trees.foreach(tree => checkTree(tree, tree.pos))
135-
}
136-
137-
private def checkDefDef(ddef: DefDef)(implicit ctx: Context): Unit = {
138-
def valOrDefDefDeclKeyword(flags: FlagSet): String = {
139-
if (!flags.is(Flags.Accessor)) "def"
140-
else if (flags.is(Flags.Mutable)) "var"
141-
else if (flags.is(Flags.Lazy)) "lazy val"
142-
else "val"
143-
}
144-
145-
def classDeclKeyword(flags: FlagSet): String = {
146-
if (flags.is(Flags.Trait)) "trait"
147-
else if (flags.is(Flags.Abstract)) "abstract class"
148-
else "class"
149-
}
150-
151-
val flags = ddef.symbol.flags
152-
if (ddef.tpt.tpe.derivesFrom(defn.PhantomAnyClass)) {
153-
if (flags.is(Flags.Mutable) || flags.is(Flags.Lazy))
154-
ctx.error(s"Can not define '${valOrDefDefDeclKeyword(flags)}' with phantom type.", ddef.pos)
155-
} else if (ddef.name != nme.CONSTRUCTOR) {
156-
ddef.symbol.owner match {
157-
case cls: ClassSymbol if cls.classSymbol.derivesFrom(defn.PhantomAnyClass) =>
158-
val defKey = valOrDefDefDeclKeyword(flags)
159-
val classKey = classDeclKeyword(ddef.symbol.owner.flags)
160-
ctx.error(s"Can not define '$defKey' with non phantom type in a phantom '$classKey'.", ddef.pos)
161-
162-
case _ => // OK
163-
}
164-
}
165-
}
166-
167-
// Transform symbols
163+
/* Symbol transform */
168164

169165
def transformInfo(tp: Type, sym: Symbol)(implicit ctx: Context): Type = erasedPhantoms(tp)
170166

0 commit comments

Comments
 (0)