Skip to content

Commit 86e001e

Browse files
authored
Merge pull request scala#6279 from retronym/topic/names-default-nest
Fix lookup of default getter in scope
2 parents 79e5101 + da14e9c commit 86e001e

File tree

3 files changed

+30
-32
lines changed

3 files changed

+30
-32
lines changed

src/compiler/scala/tools/nsc/typechecker/Contexts.scala

Lines changed: 14 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1065,8 +1065,11 @@ trait Contexts { self: Analyzer =>
10651065
found1
10661066
}
10671067

1068-
def lookupInScope(scope: Scope) =
1069-
(scope lookupUnshadowedEntries name filter (e => qualifies(e.sym))).toList
1068+
def lookupInScope(scope: Scope) = {
1069+
val entries = scope lookupUnshadowedEntries name
1070+
val result = entries.filter(e => qualifies(e.sym)).toList
1071+
result
1072+
}
10701073

10711074
def newOverloaded(owner: Symbol, pre: Type, entries: List[ScopeEntry]) =
10721075
logResult(s"overloaded symbol in $pre")(owner.newOverloaded(pre, entries map (_.sym)))
@@ -1198,29 +1201,14 @@ trait Contexts { self: Analyzer =>
11981201
else finish(EmptyTree, NoSymbol)
11991202
}
12001203

1201-
/**
1202-
* Find a symbol in this context or one of its outers.
1203-
*
1204-
* Used to find symbols are owned by methods (or fields), they can't be
1205-
* found in some scope.
1206-
*
1207-
* Examples: companion module of classes owned by a method, default getter
1208-
* methods of nested methods. See NamesDefaults.scala
1209-
*/
1210-
def lookup(name: Name, expectedOwner: Symbol) = {
1211-
var res: Symbol = NoSymbol
1212-
var ctx = this
1213-
while (res == NoSymbol && ctx.outer != ctx) {
1214-
val s = ctx.scope lookup name
1215-
if (s != NoSymbol && s.owner == expectedOwner)
1216-
res = s
1217-
else
1218-
ctx = ctx.outer
1219-
}
1220-
res
1204+
final def lookupCompanionInIncompleteOwner(original: Symbol): Symbol = {
1205+
// Must have both a class and module symbol, so that `{ class C; def C }` or `{ type T; object T }` are not companions.
1206+
def isCompanion(sym: Symbol): Boolean =
1207+
(original.isModule && sym.isClass || sym.isModule && original.isClass) && sym.isCoDefinedWith(original)
1208+
lookupSibling(original, original.name.companionName).filter(isCompanion)
12211209
}
12221210

1223-
final def lookupCompanionInIncompleteOwner(original: Symbol): Symbol = {
1211+
final def lookupSibling(original: Symbol, name: Name): Symbol = {
12241212
/* Search scopes in current and enclosing contexts for the definition of `symbol` */
12251213
def lookupScopeEntry(symbol: Symbol): ScopeEntry = {
12261214
var res: ScopeEntry = null
@@ -1235,15 +1223,12 @@ trait Contexts { self: Analyzer =>
12351223
res
12361224
}
12371225

1238-
// 1) Must be owned by the same Scope, to ensure that in
1239-
// `{ class C; { ...; object C } }`, the class is not seen as a companion of the object.
1240-
// 2) Must be a class and module symbol, so that `{ class C; def C }` or `{ type T; object T }` are not companions.
1226+
// Must be owned by the same Scope, to ensure that in
1227+
// `{ class C; { ...; object C } }`, the class is not seen as a companion of the object.
12411228
lookupScopeEntry(original) match {
12421229
case null => NoSymbol
12431230
case entry =>
1244-
def isCompanion(sym: Symbol): Boolean =
1245-
(original.isModule && sym.isClass || sym.isModule && original.isClass) && sym.isCoDefinedWith(original)
1246-
entry.owner.lookupNameInSameScopeAs(original, original.name.companionName).filter(isCompanion)
1231+
entry.owner.lookupNameInSameScopeAs(original, name)
12471232
}
12481233
}
12491234

src/compiler/scala/tools/nsc/typechecker/NamesDefaults.scala

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -479,9 +479,8 @@ trait NamesDefaults { self: Analyzer =>
479479
if (param.owner.owner.isClass) {
480480
param.owner.owner.info.member(defGetterName)
481481
} else {
482-
// the owner of the method is another method. find the default
483-
// getter in the context.
484-
context.lookup(defGetterName, param.owner.owner)
482+
// the owner of the method is another method. find the default getter in the context.
483+
context.lookupSibling(param.owner, defGetterName)
485484
}
486485
}
487486
} else NoSymbol
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
object Test {
2+
def multinest = {
3+
def baz = {bar()}
4+
def bar(x: String = "a"): Any = {
5+
def bar(x: String = "b") = x
6+
bar() + x
7+
};
8+
bar$default$1(0)
9+
assert(baz == "ba", baz)
10+
}
11+
def main(args: Array[String]) {
12+
multinest
13+
}
14+
}

0 commit comments

Comments
 (0)