@@ -1125,6 +1125,36 @@ class TreeUnpickler(reader: TastyReader,
1125
1125
readPathTerm()
1126
1126
}
1127
1127
1128
+ /** Adapt constructor calls where class has only using clauses from old to new scheme.
1129
+ * or class has mixed using clauses and other clauses.
1130
+ * Old: leading (), new: nothing, or trailing () if all clauses are using clauses.
1131
+ * This is neccessary so that we can read pre-3.2 Tasty correctly. There,
1132
+ * constructor calls use the old scheme, but constructor definitions already
1133
+ * use the new scheme, since they are reconstituted with normalizeIfConstructor.
1134
+ */
1135
+ def constructorApply (fn : Tree , args : List [Tree ]): Tree =
1136
+ if fn.tpe.widen.isContextualMethod && args.isEmpty then
1137
+ fn.withAttachment(SuppressedApplyToNone , ())
1138
+ else
1139
+ val fn1 = fn match
1140
+ case Apply (fn1, Nil ) if fn.removeAttachment(InsertedApplyToNone ).isDefined =>
1141
+ // We thought we inserted a final `()` but hit a user-written `()` instead.
1142
+ // Remove the inserted `()`.
1143
+ fn1
1144
+ case _ =>
1145
+ fn
1146
+ val res = tpd.Apply (fn1, args)
1147
+ if fn.removeAttachment(SuppressedApplyToNone ).isEmpty then
1148
+ res
1149
+ else res.tpe.widen match
1150
+ case mt @ MethodType (params) =>
1151
+ if params.isEmpty then
1152
+ // Assume it's the final synthesized `()` parameter
1153
+ res.appliedToNone.withAttachment(InsertedApplyToNone , ())
1154
+ else if mt.isContextualMethod then
1155
+ res.withAttachment(SuppressedApplyToNone , ())
1156
+ else res
1157
+
1128
1158
def readLengthTerm (): Tree = {
1129
1159
val end = readEnd()
1130
1160
val result =
@@ -1136,22 +1166,8 @@ class TreeUnpickler(reader: TastyReader,
1136
1166
case APPLY =>
1137
1167
val fn = readTerm()
1138
1168
val args = until(end)(readTerm())
1139
- // Adapt constructor calls where class has only using clauses from old to new scheme.
1140
- // Old: leading (), new: trailing ().
1141
- // This is neccessary so that we can read pre-3.2 Tasty correctly. There,
1142
- // constructor calls use the old scheme, but constructor definitions already
1143
- // use the new scheme, since they are reconstituted with normalizeIfConstructor.
1144
- if fn.symbol.isConstructor && fn.tpe.widen.isContextualMethod && args.isEmpty then
1145
- fn.withAttachment(SuppressedApplyToNone , ())
1146
- else
1147
- val res = tpd.Apply (fn, args)
1148
- if fn.removeAttachment(SuppressedApplyToNone ).isEmpty then
1149
- res
1150
- else res.tpe.widen match
1151
- case MethodType (Nil ) =>
1152
- res.appliedToNone
1153
- case mt : MethodType if mt.isContextualMethod =>
1154
- res.withAttachment(SuppressedApplyToNone , ())
1169
+ if fn.symbol.isConstructor then constructorApply(fn, args)
1170
+ else tpd.Apply (fn, args)
1155
1171
case TYPEAPPLY =>
1156
1172
tpd.TypeApply (readTerm(), until(end)(readTpt()))
1157
1173
case TYPED =>
@@ -1544,4 +1560,9 @@ object TreeUnpickler {
1544
1560
* call that has otherwise only using clauses was suppressed.
1545
1561
*/
1546
1562
val SuppressedApplyToNone : Property .Key [Unit ] = Property .Key ()
1563
+
1564
+ /** An attachment key indicating that an trailing () in a constructor
1565
+ * call that has otherwise only using clauses was inserted.
1566
+ */
1567
+ val InsertedApplyToNone : Property .Key [Unit ] = Property .Key ()
1547
1568
}
0 commit comments