Skip to content

Commit 6edb091

Browse files
committed
Fix handling of default argument in curried supercalls
Default arguments in a parameter list of a supercall that follows the first one were sometimes handled incorrectly. In this case, the supercall can a block which contains bindings of earlier arguments that are passed to the default getter.
1 parent 7a446fa commit 6edb091

File tree

4 files changed

+25
-7
lines changed

4 files changed

+25
-7
lines changed

compiler/src/dotty/tools/dotc/ast/TreeInfo.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -85,6 +85,12 @@ trait TreeInfo[T >: Untyped <: Type] { self: Trees.Instance[T] =>
8585
case _ => tree
8686
}
8787

88+
/** If this is a block, its expression part */
89+
def stripBlock(tree: Tree): Tree = unsplice(tree) match {
90+
case Block(_, expr) => stripBlock(expr)
91+
case _ => tree
92+
}
93+
8894
/** The number of arguments in an application */
8995
def numArgs(tree: Tree): Int = unsplice(tree) match {
9096
case Apply(fn, args) => numArgs(fn) + args.length

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

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -168,15 +168,19 @@ class Mixin extends MiniPhase with SymTransformer { thisPhase =>
168168
* to be used as initializers of trait parameters if the target of the call
169169
* is a trait.
170170
*/
171-
def transformConstructor(tree: Tree): (Tree, List[Tree]) = {
172-
val Apply(sel @ Select(New(_), nme.CONSTRUCTOR), args) = tree
173-
val (callArgs, initArgs) = if (tree.symbol.owner.is(Trait)) (Nil, args) else (args, Nil)
174-
(superRef(tree.symbol, tree.pos).appliedToArgs(callArgs), initArgs)
171+
def transformConstructor(tree: Tree): (Tree, List[Tree]) = tree match {
172+
case Block(stats, expr) =>
173+
val (scall, inits) = transformConstructor(expr)
174+
(cpy.Block(tree)(stats, scall), inits)
175+
case _ =>
176+
val Apply(sel @ Select(New(_), nme.CONSTRUCTOR), args) = tree
177+
val (callArgs, initArgs) = if (tree.symbol.owner.is(Trait)) (Nil, args) else (args, Nil)
178+
(superRef(tree.symbol, tree.pos).appliedToArgs(callArgs), initArgs)
175179
}
176180

177181
val superCallsAndArgs = (
178-
for (p <- impl.parents if p.symbol.isConstructor)
179-
yield p.symbol.owner -> transformConstructor(p)
182+
for (p <- impl.parents; constr = stripBlock(p).symbol if constr.isConstructor)
183+
yield constr.owner -> transformConstructor(p)
180184
).toMap
181185
val superCalls = superCallsAndArgs.mapValues(_._1)
182186
val initArgs = superCallsAndArgs.mapValues(_._2)

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ object ProtoTypes {
402402
}
403403

404404
class UnapplyFunProto(argType: Type, typer: Typer)(implicit ctx: Context) extends FunProto(
405-
untpd.TypedSplice(dummyTreeOfType(argType))(ctx) :: Nil, WildcardType)(typer, new FunProtoState()) // TODO: Investigate Dotty failure with default param
405+
untpd.TypedSplice(dummyTreeOfType(argType))(ctx) :: Nil, WildcardType)(typer)
406406

407407
/** A prototype for expressions [] that are type-parameterized:
408408
*

tests/pos/default-super.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
class A(x: Int)(y: String = "hi")
2+
3+
object Test {
4+
def f() = 22
5+
6+
class B extends A(f())()
7+
8+
}

0 commit comments

Comments
 (0)