Skip to content

Commit dcf42cf

Browse files
committed
Require @publicInBinary on overrides
1 parent eb4962b commit dcf42cf

File tree

6 files changed

+21
-7
lines changed

6 files changed

+21
-7
lines changed

compiler/src/dotty/tools/dotc/core/SymDenotations.scala

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,10 +1033,7 @@ object SymDenotations {
10331033

10341034
/** Is this a member that will become public in the generated binary */
10351035
def hasPublicInBinary(using Context): Boolean =
1036-
isTerm && (
1037-
hasAnnotation(defn.PublicInBinaryAnnot) ||
1038-
allOverriddenSymbols.exists(sym => sym.hasAnnotation(defn.PublicInBinaryAnnot))
1039-
)
1036+
isTerm && hasAnnotation(defn.PublicInBinaryAnnot)
10401037

10411038
/** ()T and => T types should be treated as equivalent for this symbol.
10421039
* Note: For the moment, we treat Scala-2 compiled symbols as loose matching,

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -580,6 +580,8 @@ object RefChecks {
580580
overrideError("may not override non-experimental member")
581581
else if other.hasAnnotation(defn.DeprecatedOverridingAnnot) then
582582
overrideDeprecation("", member, other, "removed or renamed")
583+
else if !member.hasAnnotation(defn.PublicInBinaryAnnot) && other.hasAnnotation(defn.PublicInBinaryAnnot) then
584+
overrideError("also needs to be declared with @publicInBinary")
583585
end checkOverride
584586

585587
checker.checkAll(checkOverride)

library/src/scala/annotation/publicInBinary.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package scala.annotation
22

3-
/** A binary API is a definition that is annotated with `@publicInBinary` or overrides a definition annotated with `@publicInBinary`.
3+
/** A binary API is a definition that is annotated with `@publicInBinary`.
44
* This annotation can be placed on `def`, `val`, `lazy val`, `var`, class constructors, `object`, and `given` definitions.
55
* A binary API will be publicly available in the bytecode. Tools like TASTy MiMa will take this into account to check
66
* compatibility.
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
-- [E164] Declaration Error: tests/neg/publicInBinaryOverride.scala:8:15 -----------------------------------------------
2+
8 | override def f(): Unit = () // error
3+
| ^
4+
| error overriding method f in class A of type (): Unit;
5+
| method f of type (): Unit also needs to be declared with @publicInBinary
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
import scala.annotation.publicInBinary
2+
3+
class A:
4+
@publicInBinary def f(): Unit = ()
5+
@publicInBinary def g(): Unit = ()
6+
7+
class B extends A:
8+
override def f(): Unit = () // error
9+
@publicInBinary override def g(): Unit = ()

tests/run/publicInBinary/Lib_1.scala

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,14 +21,15 @@ class Foo(@publicInBinary private[Foo] val paramVal: Int, @publicInBinary privat
2121
paramVal + paramVar + protectedVal + packagePrivateVal + protectedVar + packagePrivateVar
2222

2323
class Bar() extends Foo(3, 3):
24+
@publicInBinary
2425
override protected val protectedVal: Int = 2
25-
26+
@publicInBinary
2627
override private[foo] val packagePrivateVal: Int = 2
2728

2829
inline def bar: Int = protectedVal + packagePrivateVal
2930

3031
class Baz() extends Foo(4, 4):
31-
@publicInBinary // TODO warn? Not needed because Foo.protectedVal is already @publicInBinary
32+
@publicInBinary
3233
override protected val protectedVal: Int = 2
3334

3435
@publicInBinary

0 commit comments

Comments
 (0)