From c6064ed02c4d895b1d0df269fc018265b0d55625 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Fri, 19 Feb 2016 13:49:15 +0100 Subject: Check that classOf gets applied to class types --- src/dotty/tools/dotc/typer/Applications.scala | 4 ++++ src/dotty/tools/dotc/typer/Checking.scala | 13 +++++++------ src/dotty/tools/dotc/typer/Namer.scala | 3 ++- src/dotty/tools/dotc/typer/Typer.scala | 2 +- 4 files changed, 14 insertions(+), 8 deletions(-) (limited to 'src/dotty/tools') diff --git a/src/dotty/tools/dotc/typer/Applications.scala b/src/dotty/tools/dotc/typer/Applications.scala index 098385d4b..3b8c56ea6 100644 --- a/src/dotty/tools/dotc/typer/Applications.scala +++ b/src/dotty/tools/dotc/typer/Applications.scala @@ -617,6 +617,10 @@ trait Applications extends Compatibility { self: Typer => case pt: PolyType => if (typedArgs.length <= pt.paramBounds.length && !isNamed) typedArgs = typedArgs.zipWithConserve(pt.paramBounds)(adaptTypeArg) + if (typedFn.symbol == defn.Predef_classOf && typedArgs.nonEmpty) { + val arg = typedArgs.head + checkClassType(arg.tpe, arg.pos, traitReq = false, stablePrefixReq = false) + } case _ => } assignType(cpy.TypeApply(tree)(typedFn, typedArgs), typedFn, typedArgs) diff --git a/src/dotty/tools/dotc/typer/Checking.scala b/src/dotty/tools/dotc/typer/Checking.scala index b71a3ab2a..0ca121925 100644 --- a/src/dotty/tools/dotc/typer/Checking.scala +++ b/src/dotty/tools/dotc/typer/Checking.scala @@ -394,16 +394,17 @@ trait Checking { ctx.error(i"$tp cannot be instantiated since it${rstatus.msg}", pos) } - /** Check that `tp` is a class type with a stable prefix. Also, if `traitReq` is - * true check that `tp` is a trait. - * Stability checking is disabled in phases after RefChecks. + /** Check that `tp` is a class type. + * Also, if `traitReq` is true, check that `tp` is a trait. + * Also, if `stablePrefixReq` is true and phase is not after RefChecks, + * check that class prefix is stable. * @return `tp` itself if it is a class or trait ref, ObjectType if not. */ - def checkClassTypeWithStablePrefix(tp: Type, pos: Position, traitReq: Boolean)(implicit ctx: Context): Type = + def checkClassType(tp: Type, pos: Position, traitReq: Boolean, stablePrefixReq: Boolean)(implicit ctx: Context): Type = tp.underlyingClassRef(refinementOK = false) match { case tref: TypeRef => - if (ctx.phase <= ctx.refchecksPhase) checkStable(tref.prefix, pos) if (traitReq && !(tref.symbol is Trait)) ctx.error(d"$tref is not a trait", pos) + if (stablePrefixReq && ctx.phase <= ctx.refchecksPhase) checkStable(tref.prefix, pos) tp case _ => ctx.error(d"$tp is not a class type", pos) @@ -506,7 +507,7 @@ trait NoChecking extends Checking { override def checkNonCyclic(sym: Symbol, info: TypeBounds, reportErrors: Boolean)(implicit ctx: Context): Type = info override def checkValue(tree: Tree, proto: Type)(implicit ctx: Context): tree.type = tree override def checkStable(tp: Type, pos: Position)(implicit ctx: Context): Unit = () - override def checkClassTypeWithStablePrefix(tp: Type, pos: Position, traitReq: Boolean)(implicit ctx: Context): Type = tp + override def checkClassType(tp: Type, pos: Position, traitReq: Boolean, stablePrefixReq: Boolean)(implicit ctx: Context): Type = tp override def checkImplicitParamsNotSingletons(vparamss: List[List[ValDef]])(implicit ctx: Context): Unit = () override def checkFeasible(tp: Type, pos: Position, where: => String = "")(implicit ctx: Context): Type = tp override def checkNoDoubleDefs(cls: Symbol)(implicit ctx: Context): Unit = () diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index 13ed96249..de27333d5 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -603,7 +603,8 @@ class Namer { typer: Typer => val ptype = parentType(parent)(ctx.superCallContext) if (cls.isRefinementClass) ptype else { - val pt = checkClassTypeWithStablePrefix(ptype, parent.pos, traitReq = parent ne parents.head) + val pt = checkClassType(ptype, parent.pos, + traitReq = parent ne parents.head, stablePrefixReq = true) if (pt.derivesFrom(cls)) { val addendum = parent match { case Select(qual: Super, _) if ctx.scala2Mode => diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala index a1d650d2d..1e8e3a524 100644 --- a/src/dotty/tools/dotc/typer/Typer.scala +++ b/src/dotty/tools/dotc/typer/Typer.scala @@ -383,7 +383,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit case TypeApplications.EtaExpansion(tycon) => tpt1 = tpt1.withType(tycon) case _ => } - checkClassTypeWithStablePrefix(tpt1.tpe, tpt1.pos, traitReq = false) + checkClassType(tpt1.tpe, tpt1.pos, traitReq = false, stablePrefixReq = true) assignType(cpy.New(tree)(tpt1), tpt1) // todo in a later phase: checkInstantiatable(cls, tpt1.pos) } -- cgit v1.2.3