Skip to content

Commit ac9d155

Browse files
Remove Override flag from varargs forwarders when there is no forwarder
to override
1 parent 19cf871 commit ac9d155

File tree

2 files changed

+33
-5
lines changed

2 files changed

+33
-5
lines changed

compiler/src/dotty/tools/dotc/transform/ElimRepeated.scala

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@ class ElimRepeated extends MiniPhase with InfoTransformer { thisPhase =>
4343
val hasAnnotation = hasVarargsAnnotation(sym)
4444
val hasRepeatedParam = hasRepeatedParams(sym)
4545
if hasRepeatedParam then
46-
if isJavaVarargsOverride || hasAnnotation || parentHasAnnotation(sym) then
46+
val parentHasAnnotation = parentHasVarargsAnnotation(sym)
47+
if isJavaVarargsOverride || hasAnnotation || parentHasAnnotation then
4748
// java varargs are more restrictive than scala's
4849
// see https://github.com/scala/bug/issues/11714
4950
val validJava = isValidJavaVarArgs(sym.info)
@@ -54,7 +55,7 @@ class ElimRepeated extends MiniPhase with InfoTransformer { thisPhase =>
5455
|""".stripMargin,
5556
sym.sourcePos)
5657
else
57-
addVarArgsForwarder(sym, isJavaVarargsOverride, hasAnnotation)
58+
addVarArgsForwarder(sym, isJavaVarargsOverride, hasAnnotation, parentHasAnnotation)
5859
else if hasAnnotation then
5960
report.error("A method without repeated parameters cannot be annotated with @varargs", sym.sourcePos)
6061
end
@@ -79,7 +80,7 @@ class ElimRepeated extends MiniPhase with InfoTransformer { thisPhase =>
7980

8081
private def hasVarargsAnnotation(sym: Symbol)(using Context) = sym.hasAnnotation(defn.VarargsAnnot)
8182

82-
private def parentHasAnnotation(sym: Symbol)(using Context) = sym.allOverriddenSymbols.exists(hasVarargsAnnotation)
83+
private def parentHasVarargsAnnotation(sym: Symbol)(using Context) = sym.allOverriddenSymbols.exists(hasVarargsAnnotation)
8384

8485
private def isVarargsMethod(sym: Symbol)(using Context) =
8586
hasVarargsAnnotation(sym) ||
@@ -266,7 +267,7 @@ class ElimRepeated extends MiniPhase with InfoTransformer { thisPhase =>
266267
* The solution is to add a method that converts its argument from `Array[? <: T]` to `Seq[T]` and
267268
* forwards it to the original method.
268269
*/
269-
private def addVarArgsForwarder(original: Symbol, isBridge: Boolean, hasAnnotation: Boolean)(using Context): Unit =
270+
private def addVarArgsForwarder(original: Symbol, isBridge: Boolean, hasAnnotation: Boolean, parentHasAnnotation: Boolean)(using Context): Unit =
270271
val owner = original.owner
271272
if !owner.isClass then
272273
report.error("inner methods cannot be annotated with @varargs", original.sourcePos)
@@ -281,7 +282,10 @@ class ElimRepeated extends MiniPhase with InfoTransformer { thisPhase =>
281282
// The java-compatible forwarder symbol
282283
val forwarder =
283284
original.copy(
284-
flags = if isBridge then flags | Artifact else flags,
285+
flags =
286+
if isBridge then flags | Artifact
287+
else if hasAnnotation && !parentHasAnnotation then flags &~ Override
288+
else flags,
285289
info = toJavaVarArgs(original.info)
286290
).asTerm
287291

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
import scala.annotation.varargs
2+
3+
abstract class NoAnnot {
4+
// java varargs forwarder: no
5+
def f(args: String*): Unit
6+
}
7+
class B1 extends NoAnnot {
8+
// java varargs forwarder: no
9+
override def f(args: String*) = ()
10+
}
11+
class B2 extends NoAnnot {
12+
// java varargs forwarder: yes, but it doesn't override anything
13+
@varargs
14+
override def f(args: String*) = ()
15+
}
16+
class C1 extends B2 {
17+
// java varargs forwarder: yes, overrides parent forwarder
18+
override def f(args: String*) = ()
19+
}
20+
class C2 extends B2 {
21+
// java varargs forwarder: yes, overrides parent forwarder
22+
@varargs
23+
override def f(args: String*) = ()
24+
}

0 commit comments

Comments
 (0)