Skip to content

Commit ed4e6bb

Browse files
committed
Fix 2403: Tweak places where we look for new definition
Given a sequence of nested scope (inner to outer), typedIdent has to decode when to look for definitions. Originally his was the lawas packagst scope before the owner changes. A recent fix changed it to the first scope after the owner changed. But that is wrong for package scopes because for them we first have to analyze any neted imports before considering the package scope. This commit fixes the problem by treating package scopes specially. Also, the ambiguous import message was improved.
1 parent cc4533d commit ed4e6bb

File tree

3 files changed

+27
-10
lines changed

3 files changed

+27
-10
lines changed

compiler/src/dotty/tools/dotc/reporting/diagnostic/messages.scala

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1222,17 +1222,24 @@ object messages {
12221222
case class AmbiguousImport(name: Names.Name, newPrec: Int, prevPrec: Int, prevCtx: Context)(implicit ctx: Context)
12231223
extends Message(AmbiguousImportID) {
12241224

1225-
import typer.Typer.BindingPrec._
1225+
import typer.Typer.BindingPrec
12261226

12271227
/** A string which explains how something was bound; Depending on `prec` this is either
12281228
* imported by <tree>
12291229
* or defined in <symbol>
12301230
*/
1231-
private def bindingString(prec: Int, whereFound: Context, qualifier: String = "") =
1232-
if (isImportPrec(prec)) {
1233-
ex"""imported$qualifier by ${hl"${whereFound.importInfo}"}"""
1231+
private def bindingString(prec: Int, whereFound: Context, qualifier: String = "") = {
1232+
val howVisible = prec match {
1233+
case BindingPrec.definition => "defined"
1234+
case BindingPrec.namedImport => "imported by name"
1235+
case BindingPrec.wildImport => "imported"
1236+
case BindingPrec.packageClause => "found"
1237+
}
1238+
if (BindingPrec.isImportPrec(prec)) {
1239+
ex"""$howVisible$qualifier by ${hl"${whereFound.importInfo}"}"""
12341240
} else
1235-
ex"""defined$qualifier in ${hl"${whereFound.owner.toString}"}"""
1241+
ex"""$howVisible$qualifier in ${hl"${whereFound.owner}"}"""
1242+
}
12361243

12371244

12381245
val msg =

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 14 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -244,11 +244,21 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
244244
else {
245245
var result: Type = NoType
246246

247-
// find definition
248-
if ((lastCtx eq ctx) || (ctx.scope ne lastCtx.scope) || (ctx.owner ne lastCtx.owner)) {
247+
val curOwner = ctx.owner
248+
249+
// Can this scope contain new definitions? This is usually the first
250+
// context where either the scope or the owner changes wrt the
251+
// context immediately nested in it. But for package contexts, it's
252+
// the opposite: the last context before the package changes. This distinction
253+
// is made so that top-level imports following a package clause are
254+
// logically nested in that package clause.
255+
val isNewDefScope =
256+
if (curOwner is Package) curOwner ne ctx.outer.owner
257+
else (ctx.scope ne lastCtx.scope) || (curOwner ne lastCtx.owner)
258+
259+
if (isNewDefScope) {
249260
val defDenot = ctx.denotNamed(name)
250261
if (qualifies(defDenot)) {
251-
val curOwner = ctx.owner
252262
val found =
253263
if (isSelfDenot(defDenot)) curOwner.enclosingClass.thisType
254264
else curOwner.thisType.select(name, defDenot)
@@ -297,7 +307,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
297307
}
298308

299309
// begin findRef
300-
loop(ctx)(ctx)
310+
loop(NoContext)(ctx)
301311
}
302312

303313
// begin typedIdent

tests/neg/i1641.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ package bar { object bippy extends (Double => String) { def apply(x: Double): St
22
package object println { def bippy(x: Int, y: Int, z: Int) = "(Int, Int, Int)" }
33
object Test {
44
def main(args: Array[String]): Unit = {
5-
println(bar.bippy(5.5)) // error
5+
println(bar.bippy(5.5))
66
println(bar.bippy(1, 2, 3)) // error
77
}
88
}

0 commit comments

Comments
 (0)