Skip to content

Commit e208878

Browse files
authored
Merge pull request #3201 from dotty-staging/fix-#3171
Fix #3171: Fix handling default getters in secondary constructors
2 parents 1f5343c + fea3bf9 commit e208878

File tree

4 files changed

+39
-9
lines changed

4 files changed

+39
-9
lines changed

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

Lines changed: 18 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -149,7 +149,7 @@ object desugar {
149149
* def f$default$1[T] = 1
150150
* def f$default$2[T](x: Int) = x + "m"
151151
*/
152-
def defDef(meth: DefDef, isPrimaryConstructor: Boolean = false)(implicit ctx: Context): Tree = {
152+
private def defDef(meth: DefDef, isPrimaryConstructor: Boolean = false)(implicit ctx: Context): Tree = {
153153
val DefDef(name, tparams, vparamss, tpt, rhs) = meth
154154
val mods = meth.mods
155155
val epbuf = new ListBuffer[ValDef]
@@ -254,11 +254,17 @@ object desugar {
254254
.withFlags((mods.flags & AccessFlags).toCommonFlags)
255255
.withMods(Nil)
256256

257-
val (constr1, defaultGetters) = defDef(constr0, isPrimaryConstructor = true) match {
258-
case meth: DefDef => (meth, Nil)
259-
case Thicket((meth: DefDef) :: defaults) => (meth, defaults)
257+
var defaultGetters: List[Tree] = Nil
258+
259+
def decompose(ddef: Tree): DefDef = ddef match {
260+
case meth: DefDef => meth
261+
case Thicket((meth: DefDef) :: defaults) =>
262+
defaultGetters = defaults
263+
meth
260264
}
261265

266+
val constr1 = decompose(defDef(constr0, isPrimaryConstructor = true))
267+
262268
// The original type and value parameters in the constructor already have the flags
263269
// needed to be type members (i.e. param, and possibly also private and local unless
264270
// prefixed by type or val). `tparams` and `vparamss` are the type parameters that
@@ -299,9 +305,11 @@ object desugar {
299305
// to auxiliary constructors
300306
val normalizedBody = impl.body map {
301307
case ddef: DefDef if ddef.name.isConstructorName =>
302-
addEvidenceParams(
303-
cpy.DefDef(ddef)(tparams = constrTparams),
304-
evidenceParams(constr1).map(toDefParam))
308+
decompose(
309+
defDef(
310+
addEvidenceParams(
311+
cpy.DefDef(ddef)(tparams = constrTparams),
312+
evidenceParams(constr1).map(toDefParam))))
305313
case stat =>
306314
stat
307315
}
@@ -680,7 +688,9 @@ object desugar {
680688
def defTree(tree: Tree)(implicit ctx: Context): Tree = tree match {
681689
case tree: ValDef => valDef(tree)
682690
case tree: TypeDef => if (tree.isClassDef) classDef(tree) else tree
683-
case tree: DefDef => defDef(tree)
691+
case tree: DefDef =>
692+
if (tree.name.isConstructorName) tree // was already handled by enclosing classDef
693+
else defDef(tree)
684694
case tree: ModuleDef => moduleDef(tree)
685695
case tree: PatDef => patDef(tree)
686696
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -625,7 +625,7 @@ trait Checking {
625625
else doubleDefError(decl, other)
626626
}
627627
if ((decl is HasDefaultParams) && (other is HasDefaultParams)) {
628-
ctx.error(em"two or more overloaded variants of $decl have default arguments")
628+
ctx.error(em"two or more overloaded variants of $decl have default arguments", decl.pos)
629629
decl resetFlag HasDefaultParams
630630
}
631631
}

tests/neg/i3171.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
object Test {
2+
class C(x: Int = 1, y: Int) {
3+
def this(x: Int = 1)(y: String) = // error: two or more overloaded methods have default getters
4+
this(x, y.toInt)
5+
}
6+
7+
def test: Unit = {
8+
new C()("1") // error: missing argument
9+
}
10+
}

tests/pos/i3171.scala

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
object Test {
2+
class C(x: Int, y: Int) {
3+
def this(x: Int = 1)(y: String) =
4+
this(x, y.toInt)
5+
}
6+
7+
def test: Unit = {
8+
new C()("1")
9+
}
10+
}

0 commit comments

Comments
 (0)