Skip to content

Commit e0db77b

Browse files
committed
Check that classOf gets applied to class types
1 parent 61cb4b6 commit e0db77b

File tree

4 files changed

+14
-8
lines changed

4 files changed

+14
-8
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -607,6 +607,10 @@ trait Applications extends Compatibility { self: Typer =>
607607
case pt: PolyType =>
608608
if (typedArgs.length <= pt.paramBounds.length)
609609
typedArgs = typedArgs.zipWithConserve(pt.paramBounds)(adaptTypeArg)
610+
if (typedFn.symbol == defn.Predef_classOf && typedArgs.nonEmpty) {
611+
val arg = typedArgs.head
612+
checkClassType(arg.tpe, arg.pos, traitReq = false, stablePrefixReq = false)
613+
}
610614
case _ =>
611615
}
612616
assignType(cpy.TypeApply(tree)(typedFn, typedArgs), typedFn, typedArgs)

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

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -344,16 +344,17 @@ trait Checking {
344344
ctx.error(i"$tp cannot be instantiated since it${rstatus.msg}", pos)
345345
}
346346

347-
/** Check that `tp` is a class type with a stable prefix. Also, if `traitReq` is
348-
* true check that `tp` is a trait.
349-
* Stability checking is disabled in phases after RefChecks.
347+
/** Check that `tp` is a class type.
348+
* Also, if `traitReq` is true, check that `tp` is a trait.
349+
* Also, if `stablePrefixReq` is true and phase is not after RefChecks,
350+
* check that class prefix is stable.
350351
* @return `tp` itself if it is a class or trait ref, ObjectType if not.
351352
*/
352-
def checkClassTypeWithStablePrefix(tp: Type, pos: Position, traitReq: Boolean)(implicit ctx: Context): Type =
353+
def checkClassType(tp: Type, pos: Position, traitReq: Boolean, stablePrefixReq: Boolean)(implicit ctx: Context): Type =
353354
tp.underlyingClassRef(refinementOK = false) match {
354355
case tref: TypeRef =>
355-
if (ctx.phase <= ctx.refchecksPhase) checkStable(tref.prefix, pos)
356356
if (traitReq && !(tref.symbol is Trait)) ctx.error(d"$tref is not a trait", pos)
357+
if (stablePrefixReq && ctx.phase <= ctx.refchecksPhase) checkStable(tref.prefix, pos)
357358
tp
358359
case _ =>
359360
ctx.error(d"$tp is not a class type", pos)
@@ -456,7 +457,7 @@ trait NoChecking extends Checking {
456457
override def checkNonCyclic(sym: Symbol, info: TypeBounds, reportErrors: Boolean)(implicit ctx: Context): Type = info
457458
override def checkValue(tree: Tree, proto: Type)(implicit ctx: Context): tree.type = tree
458459
override def checkStable(tp: Type, pos: Position)(implicit ctx: Context): Unit = ()
459-
override def checkClassTypeWithStablePrefix(tp: Type, pos: Position, traitReq: Boolean)(implicit ctx: Context): Type = tp
460+
override def checkClassType(tp: Type, pos: Position, traitReq: Boolean, stablePrefixReq: Boolean)(implicit ctx: Context): Type = tp
460461
override def checkImplicitParamsNotSingletons(vparamss: List[List[ValDef]])(implicit ctx: Context): Unit = ()
461462
override def checkFeasible(tp: Type, pos: Position, where: => String = "")(implicit ctx: Context): Type = tp
462463
override def checkNoDoubleDefs(cls: Symbol)(implicit ctx: Context): Unit = ()

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

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -598,7 +598,8 @@ class Namer { typer: Typer =>
598598
val ptype = parentType(parent)(ctx.superCallContext)
599599
if (cls.isRefinementClass) ptype
600600
else {
601-
val pt = checkClassTypeWithStablePrefix(ptype, parent.pos, traitReq = parent ne parents.head)
601+
val pt = checkClassType(ptype, parent.pos,
602+
traitReq = parent ne parents.head, stablePrefixReq = true)
602603
if (pt.derivesFrom(cls)) {
603604
val addendum = parent match {
604605
case Select(qual: Super, _) if ctx.scala2Mode =>

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -382,7 +382,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
382382
case TypeApplications.EtaExpansion(tycon) => tpt1 = tpt1.withType(tycon)
383383
case _ =>
384384
}
385-
checkClassTypeWithStablePrefix(tpt1.tpe, tpt1.pos, traitReq = false)
385+
checkClassType(tpt1.tpe, tpt1.pos, traitReq = false, stablePrefixReq = true)
386386
assignType(cpy.New(tree)(tpt1), tpt1)
387387
// todo in a later phase: checkInstantiatable(cls, tpt1.pos)
388388
}

0 commit comments

Comments
 (0)