diff options
author | Jason Zaugg <jzaugg@gmail.com> | 2014-01-13 12:45:46 +0100 |
---|---|---|
committer | Jason Zaugg <jzaugg@gmail.com> | 2014-01-14 22:44:25 +0100 |
commit | e57af7dae72cae7d071f848edaf1fdbe32939ed8 (patch) | |
tree | 2ede778dc5115d77a7191b1d2899a92020ab0df9 /src | |
parent | e089cafb5fd02e2457bafde3252da3a771d3180e (diff) | |
download | scala-e57af7dae72cae7d071f848edaf1fdbe32939ed8.tar.gz scala-e57af7dae72cae7d071f848edaf1fdbe32939ed8.tar.bz2 scala-e57af7dae72cae7d071f848edaf1fdbe32939ed8.zip |
SI-8133 Fix regression with package objects, overloading
Regressed in f5c336d56, a refactoring of `typedIdent`. In that
commit, an (ostensibly) accidental change arrived, equivalent to:
- val pre1 = if (qual == EmptyTree) NoPrefix else if (sym.isTopLevel) sym.owner.thisType else qual.tpe
+ val pre1 = if (sym.isTopLevel) sym.owner.thisType else if (qual == EmptyTree) NoPrefix else qual.tpe
Here, `qual` is a tree returned in the successful result of
`Context#lookup`.
This change itself looks innocuous (top level symbols can be prefixed
with a qualifier or not, right?), but it exposed us to a bug in
`makeAccessible`. It is responsible for rewriting, e.g,
`scala.List` to `scala.package.List`. It has a few cases, but one
of them relies relies on typechecking `Ident(nme.PACKAGE)`, and
hoping that it will bind to the right place. That's fraught with
danger, and breaks in the enclosed tests.
This commit binds that Ident symbolically, and in the process
factors a tiny bit of code in common with `TreeGen`. (More work
is still needed here!)
In the next commit, I'm going to revert the change to `pre1`. That
would have also fixed the regression, albeit symptomatically.
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/typechecker/Typers.scala | 2 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/Mirrors.scala | 9 | ||||
-rw-r--r-- | src/reflect/scala/reflect/internal/TreeGen.scala | 6 |
3 files changed, 11 insertions, 6 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Typers.scala b/src/compiler/scala/tools/nsc/typechecker/Typers.scala index 6b5afce993..0e2efe2efa 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Typers.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Typers.scala @@ -555,7 +555,7 @@ trait Typers extends Adaptations with Tags with TypersTracking with PatternTyper } val qual = typedQualifier { atPos(tree.pos.makeTransparent) { tree match { - case Ident(_) => Ident(nme.PACKAGEkw) + case Ident(_) => Ident(rootMirror.getPackageObjectWithMember(pre, sym)) case Select(qual, _) => Select(qual, nme.PACKAGEkw) case SelectFromTypeTree(qual, _) => Select(qual, nme.PACKAGEkw) } diff --git a/src/reflect/scala/reflect/internal/Mirrors.scala b/src/reflect/scala/reflect/internal/Mirrors.scala index 9c5a593ca5..6cf4944d18 100644 --- a/src/reflect/scala/reflect/internal/Mirrors.scala +++ b/src/reflect/scala/reflect/internal/Mirrors.scala @@ -186,6 +186,15 @@ trait Mirrors extends api.Mirrors { def getPackageObjectIfDefined(fullname: TermName): Symbol = wrapMissing(getPackageObject(fullname)) + + final def getPackageObjectWithMember(pre: Type, sym: Symbol): Symbol = { + // The owner of a symbol which requires package qualification may be the + // package object iself, but it also could be any superclass of the package + // object. In the latter case, we must go through the qualifier's info + // to obtain the right symbol. + if (sym.owner.isModuleClass) sym.owner.sourceModule // fast path, if the member is owned by a module class, that must be linked to the package object + else pre member nme.PACKAGE // otherwise we have to findMember + } override def staticPackage(fullname: String): ModuleSymbol = ensurePackageSymbol(fullname.toString, getModuleOrClass(newTermNameCached(fullname)), allowModules = false) diff --git a/src/reflect/scala/reflect/internal/TreeGen.scala b/src/reflect/scala/reflect/internal/TreeGen.scala index f6d21ec9bd..11b3707e48 100644 --- a/src/reflect/scala/reflect/internal/TreeGen.scala +++ b/src/reflect/scala/reflect/internal/TreeGen.scala @@ -191,11 +191,7 @@ abstract class TreeGen extends macros.TreeBuilder { ) val pkgQualifier = if (needsPackageQualifier) { - // The owner of a symbol which requires package qualification may be the - // package object iself, but it also could be any superclass of the package - // object. In the latter case, we must go through the qualifier's info - // to obtain the right symbol. - val packageObject = if (sym.owner.isModuleClass) sym.owner.sourceModule else qual.tpe member nme.PACKAGE + val packageObject = rootMirror.getPackageObjectWithMember(qual.tpe, sym) Select(qual, nme.PACKAGE) setSymbol packageObject setType singleType(qual.tpe, packageObject) } else qual |