Skip to content

Commit

Permalink
Allow ambiguous references under Scala-2 mode
Browse files Browse the repository at this point in the history
And offer an automatic rewrite rule.
  • Loading branch information
odersky authored and anatoliykmetyuk committed Apr 2, 2020
1 parent 44b6d43 commit 617b95c
Show file tree
Hide file tree
Showing 4 changed files with 48 additions and 6 deletions.
13 changes: 8 additions & 5 deletions compiler/src/dotty/tools/dotc/typer/Typer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -125,9 +125,6 @@ class Typer extends Namer
val refctx = ctx
val noImports = ctx.mode.is(Mode.InPackageClauseName)

def ambiguous(newPrec: BindingPrec, prevPrec: BindingPrec, prevCtx: Context)(using Context) =
refctx.error(AmbiguousReference(name, newPrec, prevPrec, prevCtx), posd.sourcePos)

/** A symbol qualifies if it really exists and is not a package class.
* In addition, if we are in a constructor of a pattern, we ignore all definitions
* which are methods and not accessors (note: if we don't do that
Expand Down Expand Up @@ -173,7 +170,7 @@ class Typer extends Namer
found
else
if !scala2pkg && !previous.isError && !found.isError then
ambiguous(newPrec, prevPrec, prevCtx)
refctx.error(AmbiguousReference(name, newPrec, prevPrec, prevCtx), posd.sourcePos)
previous

/** Recurse in outer context. If final result is same as `previous`, check that it
Expand Down Expand Up @@ -317,7 +314,13 @@ class Typer extends Namer
if scope.lookup(name).exists then
val symsMatch = scope.lookupAll(name).exists(denot.containsSym)
if !symsMatch then
ambiguous(Definition, Inheritance, prevCtx)(using outer)
refctx.errorOrMigrationWarning(
AmbiguousReference(name, Definition, Inheritance, prevCtx)(using outer),
posd.sourcePos)
if ctx.scala2CompatMode then
patch(Span(posd.span.start),
if prevCtx.owner == refctx.owner.enclosingClass then "this."
else s"${prevCtx.owner.name}.this.")
else
checkNoOuterDefs(denot, outer, prevCtx)

Expand Down
8 changes: 8 additions & 0 deletions tests/neg/ambiref.check
Original file line number Diff line number Diff line change
Expand Up @@ -22,3 +22,11 @@ longer explanation available when compiling with `-explain`
| and inherited subsequently in anonymous class D {...}

longer explanation available when compiling with `-explain`
-- [E049] Reference Error: tests/neg/ambiref.scala:25:16 ---------------------------------------------------------------
25 | println(y) // error
| ^
| Reference to y is ambiguous,
| it is both defined in method c
| and inherited subsequently in class E

longer explanation available when compiling with `-explain`
10 changes: 9 additions & 1 deletion tests/neg/ambiref.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,14 @@ object test2:
println(y) // error

object test3:
def c(y: Float) =
class D:
val y = 2
class E extends D:
class F:
println(y) // error

object test4:

class C:
val x = 0
Expand All @@ -26,7 +34,7 @@ object test3:
def x(y: Int) = 3
val y: Int = this.x // OK
val z: Int = x // OK
end test3
end test4

val global = 0
class C:
Expand Down
23 changes: 23 additions & 0 deletions tests/pos-scala2/rewrites.scala
Original file line number Diff line number Diff line change
Expand Up @@ -34,3 +34,26 @@ class Stream[+A] {

}

object test2 {
def c(y: Float) = {
class D {
val y = 2
}
new D {
println(y)
}
}
}

object test3 {
def c(y: Float) = {
class D {
val y = 2
}
class E extends D {
class F {
println(y)
}
}
}
}

0 comments on commit 617b95c

Please sign in to comment.