Skip to content

Commit e6e15e9

Browse files
oderskymichelou
authored andcommitted
Fix unpickler logic and beef up test
1 parent 3e82c33 commit e6e15e9

File tree

4 files changed

+98
-17
lines changed

4 files changed

+98
-17
lines changed

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 37 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1163,6 +1163,36 @@ class TreeUnpickler(reader: TastyReader,
11631163
readPathTerm()
11641164
}
11651165

1166+
/** Adapt constructor calls where class has only using clauses from old to new scheme.
1167+
* or class has mixed using clauses and other clauses.
1168+
* Old: leading (), new: nothing, or trailing () if all clauses are using clauses.
1169+
* This is neccessary so that we can read pre-3.2 Tasty correctly. There,
1170+
* constructor calls use the old scheme, but constructor definitions already
1171+
* use the new scheme, since they are reconstituted with normalizeIfConstructor.
1172+
*/
1173+
def constructorApply(fn: Tree, args: List[Tree]): Tree =
1174+
if fn.tpe.widen.isContextualMethod && args.isEmpty then
1175+
fn.withAttachment(SuppressedApplyToNone, ())
1176+
else
1177+
val fn1 = fn match
1178+
case Apply(fn1, Nil) if fn.removeAttachment(InsertedApplyToNone).isDefined =>
1179+
// We thought we inserted a final `()` but hit a user-written `()` instead.
1180+
// Remove the inserted `()`.
1181+
fn1
1182+
case _ =>
1183+
fn
1184+
val res = tpd.Apply(fn1, args)
1185+
if fn.removeAttachment(SuppressedApplyToNone).isEmpty then
1186+
res
1187+
else res.tpe.widen match
1188+
case mt @ MethodType(params) =>
1189+
if params.isEmpty then
1190+
// Assume it's the final synthesized `()` parameter
1191+
res.appliedToNone.withAttachment(InsertedApplyToNone, ())
1192+
else if mt.isContextualMethod then
1193+
res.withAttachment(SuppressedApplyToNone, ())
1194+
else res
1195+
11661196
def readLengthTerm(): Tree = {
11671197
val end = readEnd()
11681198
val result =
@@ -1174,22 +1204,8 @@ class TreeUnpickler(reader: TastyReader,
11741204
case APPLY =>
11751205
val fn = readTerm()
11761206
val args = until(end)(readTerm())
1177-
// Adapt constructor calls where class has only using clauses from old to new scheme.
1178-
// Old: leading (), new: trailing ().
1179-
// This is neccessary so that we can read pre-3.2 Tasty correctly. There,
1180-
// constructor calls use the old scheme, but constructor definitions already
1181-
// use the new scheme, since they are reconstituted with normalizeIfConstructor.
1182-
if fn.symbol.isConstructor && fn.tpe.widen.isContextualMethod && args.isEmpty then
1183-
fn.withAttachment(SuppressedApplyToNone, ())
1184-
else
1185-
val res = tpd.Apply(fn, args)
1186-
if fn.removeAttachment(SuppressedApplyToNone).isEmpty then
1187-
res
1188-
else res.tpe.widen match
1189-
case MethodType(Nil) =>
1190-
res.appliedToNone
1191-
case mt: MethodType if mt.isContextualMethod =>
1192-
res.withAttachment(SuppressedApplyToNone, ())
1207+
if fn.symbol.isConstructor then constructorApply(fn, args)
1208+
else tpd.Apply(fn, args)
11931209
case TYPEAPPLY =>
11941210
tpd.TypeApply(readTerm(), until(end)(readTpt()))
11951211
case TYPED =>
@@ -1581,4 +1597,9 @@ object TreeUnpickler {
15811597
* call that has otherwise only using clauses was suppressed.
15821598
*/
15831599
val SuppressedApplyToNone: Property.Key[Unit] = Property.Key()
1600+
1601+
/** An attachment key indicating that an trailing () in a constructor
1602+
* call that has otherwise only using clauses was inserted.
1603+
*/
1604+
val InsertedApplyToNone: Property.Key[Unit] = Property.Key()
15841605
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
Bar
2+
Bar
3+
Bar
4+
Bar
5+
()
6+
Bat
7+
Bat
8+
Bat
9+
Bat
10+
()
11+
Bax
12+
Bax
13+
Bax
14+
Bax
15+
()
16+
Baz
17+
Baz
18+
Baz
19+
Baz
20+
()
Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,32 @@
1-
class Bar(using x: Int)(y: String)
1+
class Bar(using x: Int)(y: String):
2+
override def toString = "Bar"
23
object Bar:
34
given Int = 1
45
inline def foo =
56
println(new Bar()(""))
67
println(Bar()(""))
8+
9+
class Bat(using x: Int):
10+
override def toString = "Bat"
11+
object Bat:
12+
given Int = 1
13+
inline def foo =
14+
println(new Bat())
15+
println(Bat())
16+
17+
class Bax(using x: Int)():
18+
override def toString = "Bax"
19+
object Bax:
20+
given Int = 1
21+
inline def foo =
22+
println(new Bax())
23+
println(Bax())
24+
25+
class Baz(using x: Int)(using y: String):
26+
override def toString = "Baz"
27+
object Baz:
28+
given Int = 1
29+
given String = "x"
30+
inline def foo =
31+
println(new Baz())
32+
println(Baz())
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,19 @@
11
@main def Test =
22
given Int = 1
3+
given String = "x"
4+
35
println(new Bar(""))
46
println(Bar(""))
57
println(Bar.foo)
8+
9+
println(new Bat())
10+
println(Bat())
11+
println(Bat.foo)
12+
13+
println(new Bax())
14+
println(Bax())
15+
println(Bax.foo)
16+
17+
println(new Baz())
18+
println(Baz())
19+
println(Baz.foo)

0 commit comments

Comments
 (0)