Skip to content

Commit c6064ed

Browse files
committed
Check that classOf gets applied to class types
1 parent 419ee6c commit c6064ed

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
@@ -617,6 +617,10 @@ trait Applications extends Compatibility { self: Typer =>
617617
case pt: PolyType =>
618618
if (typedArgs.length <= pt.paramBounds.length && !isNamed)
619619
typedArgs = typedArgs.zipWithConserve(pt.paramBounds)(adaptTypeArg)
620+
if (typedFn.symbol == defn.Predef_classOf && typedArgs.nonEmpty) {
621+
val arg = typedArgs.head
622+
checkClassType(arg.tpe, arg.pos, traitReq = false, stablePrefixReq = false)
623+
}
620624
case _ =>
621625
}
622626
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
@@ -394,16 +394,17 @@ trait Checking {
394394
ctx.error(i"$tp cannot be instantiated since it${rstatus.msg}", pos)
395395
}
396396

397-
/** Check that `tp` is a class type with a stable prefix. Also, if `traitReq` is
398-
* true check that `tp` is a trait.
399-
* Stability checking is disabled in phases after RefChecks.
397+
/** Check that `tp` is a class type.
398+
* Also, if `traitReq` is true, check that `tp` is a trait.
399+
* Also, if `stablePrefixReq` is true and phase is not after RefChecks,
400+
* check that class prefix is stable.
400401
* @return `tp` itself if it is a class or trait ref, ObjectType if not.
401402
*/
402-
def checkClassTypeWithStablePrefix(tp: Type, pos: Position, traitReq: Boolean)(implicit ctx: Context): Type =
403+
def checkClassType(tp: Type, pos: Position, traitReq: Boolean, stablePrefixReq: Boolean)(implicit ctx: Context): Type =
403404
tp.underlyingClassRef(refinementOK = false) match {
404405
case tref: TypeRef =>
405-
if (ctx.phase <= ctx.refchecksPhase) checkStable(tref.prefix, pos)
406406
if (traitReq && !(tref.symbol is Trait)) ctx.error(d"$tref is not a trait", pos)
407+
if (stablePrefixReq && ctx.phase <= ctx.refchecksPhase) checkStable(tref.prefix, pos)
407408
tp
408409
case _ =>
409410
ctx.error(d"$tp is not a class type", pos)
@@ -506,7 +507,7 @@ trait NoChecking extends Checking {
506507
override def checkNonCyclic(sym: Symbol, info: TypeBounds, reportErrors: Boolean)(implicit ctx: Context): Type = info
507508
override def checkValue(tree: Tree, proto: Type)(implicit ctx: Context): tree.type = tree
508509
override def checkStable(tp: Type, pos: Position)(implicit ctx: Context): Unit = ()
509-
override def checkClassTypeWithStablePrefix(tp: Type, pos: Position, traitReq: Boolean)(implicit ctx: Context): Type = tp
510+
override def checkClassType(tp: Type, pos: Position, traitReq: Boolean, stablePrefixReq: Boolean)(implicit ctx: Context): Type = tp
510511
override def checkImplicitParamsNotSingletons(vparamss: List[List[ValDef]])(implicit ctx: Context): Unit = ()
511512
override def checkFeasible(tp: Type, pos: Position, where: => String = "")(implicit ctx: Context): Type = tp
512513
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
@@ -603,7 +603,8 @@ class Namer { typer: Typer =>
603603
val ptype = parentType(parent)(ctx.superCallContext)
604604
if (cls.isRefinementClass) ptype
605605
else {
606-
val pt = checkClassTypeWithStablePrefix(ptype, parent.pos, traitReq = parent ne parents.head)
606+
val pt = checkClassType(ptype, parent.pos,
607+
traitReq = parent ne parents.head, stablePrefixReq = true)
607608
if (pt.derivesFrom(cls)) {
608609
val addendum = parent match {
609610
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
@@ -383,7 +383,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
383383
case TypeApplications.EtaExpansion(tycon) => tpt1 = tpt1.withType(tycon)
384384
case _ =>
385385
}
386-
checkClassTypeWithStablePrefix(tpt1.tpe, tpt1.pos, traitReq = false)
386+
checkClassType(tpt1.tpe, tpt1.pos, traitReq = false, stablePrefixReq = true)
387387
assignType(cpy.New(tree)(tpt1), tpt1)
388388
// todo in a later phase: checkInstantiatable(cls, tpt1.pos)
389389
}

0 commit comments

Comments
 (0)