aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-02-19 13:49:15 +0100
committerMartin Odersky <odersky@gmail.com>2016-02-20 10:19:58 +0100
commitc6064ed02c4d895b1d0df269fc018265b0d55625 (patch)
tree224e7a2fcbb0bdf829a7bcbfacad09ff03fcc00b /src/dotty/tools
parent419ee6cd11214c91e55bb74fb77b8e84760a780e (diff)
downloaddotty-c6064ed02c4d895b1d0df269fc018265b0d55625.tar.gz
dotty-c6064ed02c4d895b1d0df269fc018265b0d55625.tar.bz2
dotty-c6064ed02c4d895b1d0df269fc018265b0d55625.zip
Check that classOf gets applied to class types
Diffstat (limited to 'src/dotty/tools')
-rw-r--r--src/dotty/tools/dotc/typer/Applications.scala4
-rw-r--r--src/dotty/tools/dotc/typer/Checking.scala13
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala3
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala2
4 files changed, 14 insertions, 8 deletions
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)
}