@@ -1173,6 +1173,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
1173
1173
ctx.featureWarning(nme.dynamics.toString, " extension of type scala.Dynamic" , isScala2Feature = true ,
1174
1174
cls, isRequired, cdef.pos)
1175
1175
}
1176
+ checkPhantomInheritance(cdef1, parents1)
1176
1177
cdef1
1177
1178
1178
1179
// todo later: check that
@@ -1218,13 +1219,36 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
1218
1219
1219
1220
/** Ensure that first parent tree refers to a real class. */
1220
1221
def ensureFirstIsClass (parents : List [Tree ], pos : Position )(implicit ctx : Context ): List [Tree ] = parents match {
1222
+ case p :: ps if p.tpe.classSymbol.derivesFrom(defn.PhantomAnyClass ) => parents // TODO add PhantomAny as first parent
1221
1223
case p :: ps if p.tpe.classSymbol.isRealClass => parents
1222
1224
case _ =>
1223
1225
// add synthetic class type
1224
1226
val first :: _ = ensureFirstIsClass(parents.tpes)
1225
1227
TypeTree (checkFeasible(first, pos, d " \n in inferred parent $first" )).withPos(pos) :: parents
1226
1228
}
1227
1229
1230
+ /** Check that a class definition does not inherit from Any and PhantomAny at the same time */
1231
+ private def checkPhantomInheritance (cdef : untpd.TypeDef , parents : List [Tree ])(implicit ctx : Context ): Unit = {
1232
+ /** Returns true iff it extends Any and PhantomAny at the same time.
1233
+ * It assumes that the parents do not have conflicts
1234
+ */
1235
+ @ tailrec def hasPhantomParentsConflicts (ls : List [Tree ], seenNonPhantom : Boolean , seenPhantom : Boolean ): Boolean = ls match {
1236
+ case _ if seenNonPhantom && seenPhantom => true
1237
+ case x :: xs =>
1238
+ if (x.tpe.derivesFrom(defn.PhantomAnyClass )) hasPhantomParentsConflicts(xs, seenNonPhantom, true )
1239
+ else hasPhantomParentsConflicts(xs, true , seenPhantom)
1240
+ case Nil => false
1241
+ }
1242
+
1243
+ if (hasPhantomParentsConflicts(parents, false , false )) {
1244
+ val perfix =
1245
+ if (cdef.symbol.flags.is(Flags .Trait )) " A trait"
1246
+ else if (cdef.symbol.flags.is(Flags .Abstract )) " An abstract class"
1247
+ else " A class"
1248
+ ctx.error(perfix + " cannot extend both Any and PhantomAny." , cdef.pos)
1249
+ }
1250
+ }
1251
+
1228
1252
/** If this is a real class, make sure its first parent is a
1229
1253
* constructor call. Cannot simply use a type. Overridden in ReTyper.
1230
1254
*/
0 commit comments