summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
diff options
context:
space:
mode:
authorJason Zaugg <jzaugg@gmail.com>2012-12-18 14:50:55 +0100
committerJason Zaugg <jzaugg@gmail.com>2012-12-18 14:50:55 +0100
commit5b2990c5119ae58d2c9d90d6b4822d906559aeef (patch)
tree781534b812df3dec35194ba31df7c7d8f324b59a /src/compiler/scala/tools/nsc/typechecker/Contexts.scala
parente14917528e1c080a7f10785e21de36f3a7769718 (diff)
downloadscala-5b2990c5119ae58d2c9d90d6b4822d906559aeef.tar.gz
scala-5b2990c5119ae58d2c9d90d6b4822d906559aeef.tar.bz2
scala-5b2990c5119ae58d2c9d90d6b4822d906559aeef.zip
SI-6745 Fix <init> lookup
We should only consult the decls of the enclosing class. Members of the self type, enclosing scopes, or imports should not be considered.
Diffstat (limited to 'src/compiler/scala/tools/nsc/typechecker/Contexts.scala')
-rw-r--r--src/compiler/scala/tools/nsc/typechecker/Contexts.scala45
1 files changed, 33 insertions, 12 deletions
diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
index c0d2f44c7b..01c8030f64 100644
--- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
+++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala
@@ -802,6 +802,12 @@ trait Contexts { self: Analyzer =>
case _ => LookupSucceeded(qual, sym)
}
)
+ def finishDefSym(sym: Symbol, pre0: Type): NameLookup =
+ if (requiresQualifier(sym))
+ finish(gen.mkAttributedQualifier(pre0), sym)
+ else
+ finish(EmptyTree, sym)
+
def isPackageOwnedInDifferentUnit(s: Symbol) = (
s.isDefinedInPackage && (
!currentRun.compiles(s)
@@ -825,17 +831,36 @@ trait Contexts { self: Analyzer =>
found1
}
+
+ def lookupInScope(scope: Scope) =
+ (scope lookupUnshadowedEntries name filter (e => qualifies(e.sym))).toList
+
+ def newOverloaded(owner: Symbol, pre: Type, entries: List[ScopeEntry]) =
+ logResult(s"!!! lookup overloaded")(owner.newOverloaded(pre, entries map (_.sym)))
+
+ // Constructor lookup should only look in the decls of the enclosing class
+ // not in the self-type, nor in the enclosing context, nor in imports (SI-4460, SI-6745)
+ if (name == nme.CONSTRUCTOR) return {
+ val enclClassSym = cx.enclClass.owner
+ val scope = cx.enclClass.prefix.baseType(enclClassSym).decls
+ val constructorSym = lookupInScope(scope) match {
+ case Nil => NoSymbol
+ case hd :: Nil => hd.sym
+ case entries => newOverloaded(enclClassSym, cx.enclClass.prefix, entries)
+ }
+ finishDefSym(constructorSym, cx.enclClass.prefix)
+ }
+
// cx.scope eq null arises during FixInvalidSyms in Duplicators
while (defSym == NoSymbol && (cx ne NoContext) && (cx.scope ne null)) {
- pre = cx.enclClass.prefix
- val entries = (cx.scope lookupUnshadowedEntries name filter (e => qualifies(e.sym))).toList
- defSym = entries match {
- case Nil => searchPrefix
- case hd :: tl =>
+ pre = cx.enclClass.prefix
+ defSym = lookupInScope(cx.scope) match {
+ case Nil => searchPrefix
+ case entries @ (hd :: tl) =>
// we have a winner: record the symbol depth
symbolDepth = (cx.depth - cx.scope.nestingLevel) + hd.depth
if (tl.isEmpty) hd.sym
- else logResult(s"!!! lookup overloaded")(cx.owner.newOverloaded(pre, entries map (_.sym)))
+ else newOverloaded(cx.owner, pre, entries)
}
if (!defSym.exists)
cx = cx.outer // push further outward
@@ -873,12 +898,8 @@ trait Contexts { self: Analyzer =>
}
// At this point only one or the other of defSym and impSym might be set.
- if (defSym.exists) {
- if (requiresQualifier(defSym))
- finish(gen.mkAttributedQualifier(pre), defSym)
- else
- finish(EmptyTree, defSym)
- }
+ if (defSym.exists)
+ finishDefSym(defSym, pre)
else if (impSym.exists) {
// We continue walking down the imports as long as the tail is non-empty, which gives us:
// imports == imp1 :: imp2 :: _