diff options
author | Josh Suereth <joshua.suereth@gmail.com> | 2011-12-20 20:24:15 -0500 |
---|---|---|
committer | Josh Suereth <joshua.suereth@gmail.com> | 2011-12-20 20:24:15 -0500 |
commit | ee5dd43598a7be8dd25e5b904a394710e1325d5d (patch) | |
tree | dc8c2a49b94380d5bfab1f06a34bf28fe1199355 /src/compiler | |
parent | 38ad3cab7b547e2c1e083e8d795a763ff7bb6f6d (diff) | |
parent | 178d49df450904330c06cfea9955f120ba04d34c (diff) | |
download | scala-ee5dd43598a7be8dd25e5b904a394710e1325d5d.tar.gz scala-ee5dd43598a7be8dd25e5b904a394710e1325d5d.tar.bz2 scala-ee5dd43598a7be8dd25e5b904a394710e1325d5d.zip |
Merge branch 'master' into xsbt
Diffstat (limited to 'src/compiler')
3 files changed, 35 insertions, 20 deletions
diff --git a/src/compiler/scala/reflect/internal/Definitions.scala b/src/compiler/scala/reflect/internal/Definitions.scala index 4d71d2a769..6ee9347aab 100644 --- a/src/compiler/scala/reflect/internal/Definitions.scala +++ b/src/compiler/scala/reflect/internal/Definitions.scala @@ -232,6 +232,16 @@ trait Definitions extends reflect.api.StandardDefinitions { def Predef_identity = getMember(PredefModule, nme.identity) def Predef_conforms = getMember(PredefModule, nme.conforms) def Predef_wrapRefArray = getMember(PredefModule, nme.wrapRefArray) + + /** Is `sym` a member of Predef with the given name? + * Note: DON't replace this by sym == Predef_conforms/etc, as Predef_conforms is a `def` + * which does a member lookup (it can't be a lazy val because we might reload Predef + * during resident compilations). + */ + def isPredefMemberNamed(sym: Symbol, name: Name) = ( + (sym.name == name) && (sym.owner == PredefModule.moduleClass) + ) + lazy val ConsoleModule: Symbol = getModule("scala.Console") lazy val ScalaRunTimeModule: Symbol = getModule("scala.runtime.ScalaRunTime") lazy val SymbolModule: Symbol = getModule("scala.Symbol") diff --git a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala index 92be241951..d54cb248cf 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Implicits.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Implicits.scala @@ -740,7 +740,7 @@ trait Implicits { ) private def isIneligible(info: ImplicitInfo) = ( info.isCyclicOrErroneous - || isView && isConforms(info.sym) + || isView && isPredefMemberNamed(info.sym, nme.conforms) || isShadowed(info.name) ) @@ -760,15 +760,6 @@ trait Implicits { */ private def checkValid(sym: Symbol) = isValid(sym) || { invalidImplicits += sym ; false } - /** Is `sym` the standard conforms method in Predef? - * Note: DON't replace this by sym == Predef_conforms, as Predef_conforms is a `def` - * which does a member lookup (it can't be a lazy val because we might reload Predef - * during resident compilations). - */ - private def isConforms(sym: Symbol) = ( - (sym.name == nme.conforms) && (sym.owner == PredefModule.moduleClass) - ) - /** Preventing a divergent implicit from terminating implicit search, * so that if there is a best candidate it can still be selected. */ 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 { |