Skip to content

Commit 20754c2

Browse files
Remove atNextPhase and use atPhase only where necessary
1 parent b828c69 commit 20754c2

File tree

1 file changed

+47
-41
lines changed

1 file changed

+47
-41
lines changed

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

Lines changed: 47 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -115,30 +115,34 @@ class ElimRepeated extends MiniPhase with InfoTransformer { thisPhase =>
115115
* Also transform trees inside method annotation.
116116
*/
117117
override def transformDefDef(tree: DefDef)(using Context): Tree =
118-
atPhase(thisPhase) {
119-
val sym = tree.symbol
120-
val hasAnnotation = hasVarargsAnnotation(sym)
121-
if hasRepeatedParams(sym) then
122-
val isOverride = overridesJava(sym)
123-
if isOverride || hasAnnotation || parentHasAnnotation(sym) then
124-
// java varargs are more restrictive than scala's
125-
// see https://github.com/scala/bug/issues/11714
126-
if !isValidJavaVarArgs(sym.info) then
127-
ctx.error("""To generate java-compatible varargs:
128-
| - there must be a single repeated parameter
129-
| - it must be the last argument in the last parameter list
130-
|""".stripMargin,
131-
sym.sourcePos)
132-
tree
133-
else
134-
addVarArgsForwarder(tree, isOverride)
135-
else
118+
val sym = tree.symbol
119+
val hasAnnotation = hasVarargsAnnotation(sym)
120+
121+
// atPhase(thisPhase) is used where necessary to see the repeated
122+
// parameters before their elimination
123+
val hasRepeatedParam = atPhase(thisPhase)(hasRepeatedParams(sym))
124+
if hasRepeatedParam then
125+
val isOverride = atPhase(thisPhase)(overridesJava(sym))
126+
if isOverride || hasAnnotation || parentHasAnnotation(sym) then
127+
// java varargs are more restrictive than scala's
128+
// see https://github.com/scala/bug/issues/11714
129+
val validJava = atPhase(thisPhase)(isValidJavaVarArgs(sym.info))
130+
if !validJava then
131+
ctx.error("""To generate java-compatible varargs:
132+
| - there must be a single repeated parameter
133+
| - it must be the last argument in the last parameter list
134+
|""".stripMargin,
135+
sym.sourcePos)
136136
tree
137+
else
138+
// non-overrides cannot be synthetic otherwise javac refuses to call them
139+
addVarArgsForwarder(tree, isBridge = isOverride)
137140
else
138-
if hasAnnotation then
139-
ctx.error("A method without repeated parameters cannot be annotated with @varargs", sym.sourcePos)
140141
tree
141-
}
142+
else
143+
if hasAnnotation then
144+
ctx.error("A method without repeated parameters cannot be annotated with @varargs", sym.sourcePos)
145+
tree
142146

143147
/** Is there a repeated parameter in some parameter list? */
144148
private def hasRepeatedParams(sym: Symbol)(using Context): Boolean =
@@ -175,23 +179,30 @@ class ElimRepeated extends MiniPhase with InfoTransformer { thisPhase =>
175179
* forwards it to `ddef`.
176180
*/
177181
private def addVarArgsForwarder(ddef: DefDef, isBridge: Boolean)(using ctx: Context): Tree =
178-
val original = ddef.symbol.asTerm
179-
// For simplicity we always set the varargs flag
180-
// although it's not strictly necessary for overrides
181-
// (but it is for non-overrides)
182-
val flags = ddef.symbol.flags | JavaVarargs
182+
val original = ddef.symbol
183183

184184
// The java-compatible forwarder symbol
185-
val sym = original.copy(
186-
// non-overrides cannot be synthetic otherwise javac refuses to call them
185+
val sym = atPhase(thisPhase) {
186+
// Capture the flags before they get modified by #transform.
187+
// For simplicity we always set the varargs flag,
188+
// although it's not strictly necessary for overrides.
189+
val flags = original.flags | JavaVarargs
190+
original.copy(
187191
flags = if isBridge then flags | Artifact else flags,
188192
info = toJavaVarArgs(ddef.symbol.info)
189193
).asTerm
194+
}
190195

191-
currentClass.info.member(sym.name).alternatives.find { s =>
192-
s.matches(sym) &&
193-
!(isBridge && s.asSymDenotation.is(JavaDefined))
194-
} match
196+
// Find a method that would conflict with the forwarder if the latter existed.
197+
// This needs to be done at thisPhase so that parent @varargs don't conflict.
198+
val conflict = atPhase(thisPhase) {
199+
currentClass.info.member(sym.name).alternatives.find { s =>
200+
s.matches(sym) &&
201+
!(isBridge && s.asSymDenotation.is(JavaDefined))
202+
}
203+
}
204+
205+
conflict match
195206
case Some(conflict) =>
196207
ctx.error(s"@varargs produces a forwarder method that conflicts with ${conflict.showDcl}", original.sourcePos)
197208
ddef
@@ -201,15 +212,10 @@ class ElimRepeated extends MiniPhase with InfoTransformer { thisPhase =>
201212
// Can't call `.argTypes` here because the underlying array type is of the
202213
// form `Array[? <: SomeType]`, so we need `.argInfos` to get the `TypeBounds`.
203214
val elemtp = vararg.tpe.widen.argInfos.head
204-
205-
// The generation of the forwarding call needs to be deferred, otherwise
206-
// generic and curried methods won't pass the tree checker.
207-
atNextPhase {
208-
ref(original.termRef)
209-
.appliedToTypes(trefs)
210-
.appliedToArgss(init)
211-
.appliedToArgs(last :+ tpd.wrapArray(vararg, elemtp))
212-
}
215+
ref(original.termRef)
216+
.appliedToTypes(trefs)
217+
.appliedToArgss(init)
218+
.appliedToArgs(last :+ tpd.wrapArray(vararg, elemtp))
213219
})
214220
Thicket(ddef, bridgeDef)
215221

0 commit comments

Comments
 (0)