From ca6b46f9049294cd00973afb53c1488a2c8b671e Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Wed, 8 Mar 2023 15:15:44 +0100 Subject: [PATCH 1/2] Include top-level symbols from same file in outer ambiguity error --- spec/02-identifiers-names-and-scopes.md | 13 ++++++++----- .../scala/tools/nsc/typechecker/Contexts.scala | 2 +- test/files/jvm/protectedacc.scala | 4 ++-- test/files/neg/t11921b.check | 9 ++++++++- test/files/neg/t11921b.scala | 9 ++++++++- 5 files changed, 27 insertions(+), 10 deletions(-) diff --git a/spec/02-identifiers-names-and-scopes.md b/spec/02-identifiers-names-and-scopes.md index 8ae89aec1178..213c2bee96df 100644 --- a/spec/02-identifiers-names-and-scopes.md +++ b/spec/02-identifiers-names-and-scopes.md @@ -17,11 +17,14 @@ which are collectively called _bindings_. Bindings of each kind are assigned a precedence which determines whether one binding can shadow another: -1. Definitions and declarations in lexical scope that are not [top-level](09-top-level-definitions.html) - have the highest precedence. -1. Definitions and declarations that are either inherited, - or made available by a package clause and also defined in the same compilation unit as the reference to them, - have the next highest precedence. + +1. Definitions and declarations that are local, inherited, or made + available by a package clause and also defined in the same compilation unit + as the reference to them, have the highest precedence. 1. Explicit imports have the next highest precedence. 1. Wildcard imports have the next highest precedence. 1. Bindings made available by a package clause, diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 6ff69b02252b..2f9f1b4e678b 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -1612,7 +1612,7 @@ trait Contexts { self: Analyzer => val wasFoundInSuper = foundInSuper val foundCompetingSymbol: () => Boolean = if (foreignDefined) () => !foreignDefined - else () => !defSym.isTopLevel && !defSym.owner.isPackageObjectOrClass && !foundInSuper && !foreignDefined + else () => !defSym.owner.isPackageObjectOrClass && !foundInSuper && !foreignDefined while ((cx ne NoContext) && cx.depth >= symbolDepth) cx = cx.outer if (wasFoundInSuper) while ((cx ne NoContext) && (cx.owner eq cx0.owner)) cx = cx.outer diff --git a/test/files/jvm/protectedacc.scala b/test/files/jvm/protectedacc.scala index 43d218fa89fd..51a50bed421c 100644 --- a/test/files/jvm/protectedacc.scala +++ b/test/files/jvm/protectedacc.scala @@ -47,7 +47,7 @@ package p { abstract class PolyA[a] { protected def m(x: a): Unit; - class B { + class BB { trait Node { def s: String = ""; @@ -134,7 +134,7 @@ package p { abstract class X[T] extends PolyA[T] { - trait Inner extends B { + trait Inner extends BB { def self: T; def self2: Node; def getB: Inner; diff --git a/test/files/neg/t11921b.check b/test/files/neg/t11921b.check index 0e2e2391d349..045f13ffb9a2 100644 --- a/test/files/neg/t11921b.check +++ b/test/files/neg/t11921b.check @@ -29,6 +29,13 @@ Such references are ambiguous in Scala 3. To continue using the inherited symbol Or use `-Wconf:msg=legacy-binding:s` to silence this warning. println(y) // error ^ +t11921b.scala:65: warning: reference to global is ambiguous; +it is both defined in the enclosing package and inherited in the enclosing object D as value global (defined in class C) +In Scala 2, symbols inherited from a superclass shadow symbols defined in an outer scope. +Such references are ambiguous in Scala 3. To continue using the inherited symbol, write `this.global`. +Or use `-Wconf:msg=legacy-binding:s` to silence this warning. + println(global) // error + ^ t11921b.scala:75: warning: reference to x is ambiguous; it is both defined in the enclosing object Uhu and inherited in the enclosing class C as value x (defined in class A, inherited through parent class B) In Scala 2, symbols inherited from a superclass shadow symbols defined in an outer scope. @@ -50,5 +57,5 @@ Such references are ambiguous in Scala 3. To continue using the inherited symbol Or use `-Wconf:msg=legacy-binding:s` to silence this warning. def v = t(lo) // error ^ -7 warnings +8 warnings 1 error diff --git a/test/files/neg/t11921b.scala b/test/files/neg/t11921b.scala index 93447b5e0a5f..ef3b53ae4724 100644 --- a/test/files/neg/t11921b.scala +++ b/test/files/neg/t11921b.scala @@ -62,7 +62,7 @@ class C { val global = 42 } object D extends C { - println(global) // OK, since global is defined in package (https://github.com/scala/scala/pull/10220/files#r1109773904) + println(global) // error } object test5 { @@ -136,3 +136,10 @@ object test10 { def v = t(lo) // error } } + +package scala { + trait P { trait Option[+A] } + class C extends P { + def t = new Option[String] {} // OK, competing scala.Option is not defined in the same compilation unit + } +} From b8c58b1abe017ce739a6e592b1d3603baadecf73 Mon Sep 17 00:00:00 2001 From: Lukas Rytz Date: Tue, 2 May 2023 10:06:09 +0200 Subject: [PATCH 2/2] Demote the new ambiguity: nothing in 2.13.11, warn (not err) under Xsource:3 --- src/compiler/scala/tools/nsc/typechecker/Contexts.scala | 9 +++++---- test/files/neg/t11921-alias.scala | 2 +- test/files/neg/t11921.scala | 2 +- test/files/neg/t11921b.scala | 2 +- test/files/neg/t11921c.scala | 2 +- test/files/pos/t11921b.scala | 2 +- test/files/pos/t11921c.scala | 1 + 7 files changed, 11 insertions(+), 9 deletions(-) diff --git a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala index 2f9f1b4e678b..64b902efe302 100644 --- a/src/compiler/scala/tools/nsc/typechecker/Contexts.scala +++ b/src/compiler/scala/tools/nsc/typechecker/Contexts.scala @@ -1377,16 +1377,17 @@ trait Contexts { self: Analyzer => sm"""|it is both defined in the enclosing ${outer1.owner} and inherited in the enclosing $classDesc as $inherited1 (defined in ${inherited1.ownsString}$inherit) |In Scala 2, symbols inherited from a superclass shadow symbols defined in an outer scope. |Such references are ambiguous in Scala 3. To continue using the inherited symbol, write `this.${outer1.name}`.""" - if (currentRun.isScala3) - Some(LookupAmbiguous(message)) - else { + // For now (2.13.11), warn under Xsource:3. We'll consider warning by default (and erring in Xsource:3) in 2.13.12 + if (currentRun.isScala3) { // passing the message to `typedIdent` as attachment, we don't have the position here to report the warning inherited.updateAttachment(LookupAmbiguityWarning( sm"""|reference to ${outer1.name} is ambiguous; |$message |Or use `-Wconf:msg=legacy-binding:s` to silence this warning.""")) + // Some(LookupAmbiguous(message)) // to make it an error in 2.13.12 + None + } else None - } } } else Some(LookupAmbiguous(s"it is both defined in ${outer.owner} and available as ${inherited.fullLocationString}")) diff --git a/test/files/neg/t11921-alias.scala b/test/files/neg/t11921-alias.scala index f238796da174..fab5ae9badc2 100644 --- a/test/files/neg/t11921-alias.scala +++ b/test/files/neg/t11921-alias.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +// scalac: -Werror -Xsource:3 object t1 { class C[T] { type TT = T } diff --git a/test/files/neg/t11921.scala b/test/files/neg/t11921.scala index 01269d3895f1..91093f3e7443 100644 --- a/test/files/neg/t11921.scala +++ b/test/files/neg/t11921.scala @@ -1,4 +1,4 @@ - +// scalac: -Xsource:3 class C { def lazyMap[A, B](coll: Iterable[A], f: A => B) = diff --git a/test/files/neg/t11921b.scala b/test/files/neg/t11921b.scala index ef3b53ae4724..887b7280698c 100644 --- a/test/files/neg/t11921b.scala +++ b/test/files/neg/t11921b.scala @@ -1,4 +1,4 @@ -// scalac: -Werror +// scalac: -Werror -Xsource:3 object test1 { diff --git a/test/files/neg/t11921c.scala b/test/files/neg/t11921c.scala index f528773d7554..3b38fa6c9520 100644 --- a/test/files/neg/t11921c.scala +++ b/test/files/neg/t11921c.scala @@ -1,4 +1,4 @@ -// scalac: -Wconf:msg=legacy-binding:s +// scalac: -Wconf:msg=legacy-binding:s -Xsource:3 class C { def lazyMap[A, B](coll: Iterable[A], f: A => B) = diff --git a/test/files/pos/t11921b.scala b/test/files/pos/t11921b.scala index b6c0ea293d04..38870f0cb53b 100644 --- a/test/files/pos/t11921b.scala +++ b/test/files/pos/t11921b.scala @@ -1,4 +1,4 @@ -// scalac: -Werror -Wconf:msg=legacy-binding:s +// scalac: -Werror -Wconf:msg=legacy-binding:s -Xsource:3 object test1 { diff --git a/test/files/pos/t11921c.scala b/test/files/pos/t11921c.scala index d73c4c31536e..d78439424f4e 100644 --- a/test/files/pos/t11921c.scala +++ b/test/files/pos/t11921c.scala @@ -1,3 +1,4 @@ +// scalac: -Xsource:3 // test/scaladoc/resources/t5784.scala