diff options
author | Paul Phillips <paulp@improving.org> | 2011-12-19 22:37:58 -0800 |
---|---|---|
committer | Paul Phillips <paulp@improving.org> | 2011-12-19 23:22:35 -0800 |
commit | bba3b00cf737528de9dcb4823806d6928a00474e (patch) | |
tree | cc1c6db76a3c72d22bb0dd5b10ac4921bdeb08b0 /src/compiler/scala/tools/nsc/typechecker/Typers.scala | |
parent | 6226468fdf81d46f005b97fb49c4ec08c856ea3f (diff) | |
download | scala-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.scala | 34 |
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 { |