summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/Typers.scala
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-12-19 22:37:58 -0800
committerPaul Phillips <paulp@improving.org>2011-12-19 23:22:35 -0800
commitbba3b00cf737528de9dcb4823806d6928a00474e (patch)
treecc1c6db76a3c72d22bb0dd5b10ac4921bdeb08b0 /src/compiler/scala/tools/nsc/typechecker/Typers.scala
parent6226468fdf81d46f005b97fb49c4ec08c856ea3f (diff)
downloadscala-bba3b00cf737528de9dcb4823806d6928a00474e.tar.gz
scala-bba3b00cf737528de9dcb4823806d6928a00474e.tar.bz2
scala-bba3b00cf737528de9dcb4823806d6928a00474e.zip
Fix for classOf NPE.
Let type parameter be inferred. Closes SI-4871.
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Typers.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Typers.scala34
1 files changed, 24 insertions, 10 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
index 9b03d59216..341e1bc5ea 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala
@@ -2950,6 +2950,11 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
new DeSkolemizeMap mapOver tp
}
+ def typedClassOf(tree: Tree, tpt: Tree) = {
+ checkClassType(tpt, true, false)
+ atPos(tree.pos)(gen.mkClassOf(tpt.tpe))
+ }
+
protected def typedExistentialTypeTree(tree: ExistentialTypeTree, mode: Int): Tree = {
for (wc <- tree.whereClauses)
if (wc.symbol == NoSymbol) { namer.enterSym(wc); wc.symbol setFlag EXISTENTIAL }
@@ -2989,10 +2994,9 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
if (sameLength(tparams, args)) {
val targs = args map (_.tpe)
checkBounds(tree.pos, NoPrefix, NoSymbol, tparams, targs, "")
- if (fun.symbol == Predef_classOf) {
- checkClassType(args.head, true, false)
- atPos(tree.pos) { gen.mkClassOf(targs.head) }
- } else {
+ if (fun.symbol == Predef_classOf)
+ typedClassOf(tree, args.head)
+ else {
if (!isPastTyper && fun.symbol == Any_isInstanceOf && !targs.isEmpty)
checkCheckable(tree.pos, targs.head, "")
val resultpe = restpe.instantiateTypeParams(tparams, targs)
@@ -3769,7 +3773,7 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
reallyExists(sym) &&
((mode & PATTERNmode | FUNmode) != (PATTERNmode | FUNmode) || !sym.isSourceMethod || sym.hasFlag(ACCESSOR))
}
-
+
if (defSym == NoSymbol) {
var defEntry: ScopeEntry = null // the scope entry of defSym, if defined in a local scope
@@ -3900,13 +3904,23 @@ trait Typers extends Modes with Adaptations with PatMatVirtualiser {
}
}
}
- if (defSym.owner.isPackageClass) pre = defSym.owner.thisType
+ if (defSym.owner.isPackageClass)
+ pre = defSym.owner.thisType
+
+ // Inferring classOf type parameter from expected type.
if (defSym.isThisSym) {
typed1(This(defSym.owner) setPos tree.pos, mode, pt)
- } else {
- val tree1 = if (qual == EmptyTree) tree
- else atPos(tree.pos)(Select(qual, name))
- // atPos necessary because qualifier might come from startContext
+ }
+ // Inferring classOf type parameter from expected type. Otherwise an
+ // actual call to the stubbed classOf method is generated, returning null.
+ else if (isPredefMemberNamed(defSym, nme.classOf) && pt.typeSymbol == ClassClass && pt.typeArgs.nonEmpty)
+ typedClassOf(tree, TypeTree(pt.typeArgs.head))
+ else {
+ val tree1 = (
+ if (qual == EmptyTree) tree
+ // atPos necessary because qualifier might come from startContext
+ else atPos(tree.pos)(Select(qual, name))
+ )
val (tree2, pre2) = makeAccessible(tree1, defSym, pre, qual)
// assert(pre.typeArgs isEmpty) // no need to add #2416-style check here, right?
stabilize(tree2, pre2, mode, pt) match {