Skip to content

Commit f5c8d52

Browse files
authored
Merge pull request #8624 from dotty-staging/tasty/single-methodtype-tag
Remove variants of METHODtype tasty tag
2 parents 3d17b02 + c77f8e2 commit f5c8d52

File tree

4 files changed

+58
-71
lines changed

4 files changed

+58
-71
lines changed

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -86,11 +86,10 @@ class TastyPrinter(bytes: Array[Byte])(implicit ctx: Context) {
8686
printName(); printTree(); printTrees()
8787
case RETURN | HOLE =>
8888
printNat(); printTrees()
89-
case METHODtype | ERASEDMETHODtype |
90-
GIVENMETHODtype | ERASEDGIVENMETHODtype | IMPLICITMETHODtype |
91-
POLYtype | TYPELAMBDAtype =>
89+
case METHODtype | POLYtype | TYPELAMBDAtype =>
9290
printTree()
93-
until(end) { printName(); printTree() }
91+
while (currentAddr.index < end.index && !isModifierTag(nextByte)) { printTree(); printName(); }
92+
printTrees()
9493
case PARAMtype =>
9594
printNat(); printNat()
9695
case _ =>

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

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -259,7 +259,7 @@ class TreePickler(pickler: TastyPickler) {
259259
writeByte(BYNAMEtype)
260260
pickleType(tpe.underlying)
261261
case tpe: HKTypeLambda =>
262-
pickleMethodic(TYPELAMBDAtype, tpe)
262+
pickleMethodic(TYPELAMBDAtype, tpe, EmptyFlags)
263263
case tpe: MatchType =>
264264
writeByte(MATCHtype)
265265
withLength {
@@ -268,26 +268,27 @@ class TreePickler(pickler: TastyPickler) {
268268
tpe.cases.foreach(pickleType(_))
269269
}
270270
case tpe: PolyType if richTypes =>
271-
pickleMethodic(POLYtype, tpe)
271+
pickleMethodic(POLYtype, tpe, EmptyFlags)
272272
case tpe: MethodType if richTypes =>
273-
val tag = methodTypeTag(
274-
isContextual = tpe.isContextualMethod,
275-
isImplicit = tpe.isImplicitMethod && !tpe.isContextualMethod,
276-
isErased = tpe.isErasedMethod)
277-
pickleMethodic(tag, tpe)
273+
var mods = EmptyFlags
274+
if tpe.isContextualMethod then mods |= Given
275+
else if tpe.isImplicitMethod then mods |= Implicit
276+
if tpe.isErasedMethod then mods |= Erased
277+
pickleMethodic(METHODtype, tpe, mods)
278278
case tpe: ParamRef =>
279279
assert(pickleParamRef(tpe), s"orphan parameter reference: $tpe")
280280
case tpe: LazyRef =>
281281
pickleType(tpe.ref)
282282
}
283283

284-
def pickleMethodic(tag: Int, tpe: LambdaType)(implicit ctx: Context): Unit = {
284+
def pickleMethodic(tag: Int, tpe: LambdaType, mods: FlagSet)(implicit ctx: Context): Unit = {
285285
writeByte(tag)
286286
withLength {
287287
pickleType(tpe.resultType, richTypes = true)
288288
tpe.paramNames.lazyZip(tpe.paramInfos).foreach { (name, tpe) =>
289-
pickleName(name); pickleType(tpe)
289+
pickleType(tpe); pickleName(name)
290290
}
291+
if (mods != EmptyFlags) pickleFlags(mods, tpe.isTermLambda)
291292
}
292293
}
293294

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

Lines changed: 37 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -210,17 +210,30 @@ class TreeUnpickler(reader: TastyReader,
210210

211211
// ------ Reading types -----------------------------------------------------
212212

213-
/** Read names in an interleaved sequence of (parameter) names and types/bounds */
214-
def readParamNames(end: Addr): List[Name] =
215-
until(end) {
216-
val name = readName()
217-
skipTree()
218-
name
219-
}
220-
221-
/** Read types or bounds in an interleaved sequence of (parameter) names and types/bounds */
222-
def readParamTypes[T <: Type](end: Addr)(implicit ctx: Context): List[T] =
223-
until(end) { readNat(); readType().asInstanceOf[T] }
213+
/** Read names in an interleaved sequence of types/bounds and (parameter) names,
214+
* possibly followed by a sequence of modifiers.
215+
*/
216+
def readParamNamesAndMods(end: Addr): (List[Name], FlagSet) =
217+
val names =
218+
collectWhile(currentAddr != end && !isModifierTag(nextByte)) {
219+
skipTree()
220+
readName()
221+
}
222+
var mods = EmptyFlags
223+
while currentAddr != end do // avoid boxing the mods
224+
readByte() match
225+
case IMPLICIT => mods |= Implicit
226+
case ERASED => mods |= Erased
227+
case GIVEN => mods |= Given
228+
(names, mods)
229+
230+
/** Read `n` parameter types or bounds which are interleaved with names */
231+
def readParamTypes[T <: Type](n: Int)(implicit ctx: Context): List[T] =
232+
if n == 0 then Nil
233+
else
234+
val t = readType().asInstanceOf[T]
235+
readNat() // skip name
236+
t :: readParamTypes(n - 1)
224237

225238
/** Read reference to definition and return symbol created at that definition */
226239
def readSymRef()(implicit ctx: Context): Symbol = symbolAt(readAddr())
@@ -290,14 +303,14 @@ class TreeUnpickler(reader: TastyReader,
290303
val end = readEnd()
291304

292305
def readMethodic[N <: Name, PInfo <: Type, LT <: LambdaType]
293-
(companion: LambdaTypeCompanion[N, PInfo, LT], nameMap: Name => N): LT = {
306+
(companionOp: FlagSet => LambdaTypeCompanion[N, PInfo, LT], nameMap: Name => N): LT = {
294307
val result = typeAtAddr.getOrElse(start, {
295308
val nameReader = fork
296309
nameReader.skipTree() // skip result
297310
val paramReader = nameReader.fork
298-
val paramNames = nameReader.readParamNames(end).map(nameMap)
299-
companion(paramNames)(
300-
pt => registeringType(pt, paramReader.readParamTypes[PInfo](end)),
311+
val (paramNames, mods) = nameReader.readParamNamesAndMods(end)
312+
companionOp(mods)(paramNames.map(nameMap))(
313+
pt => registeringType(pt, paramReader.readParamTypes[PInfo](paramNames.length)),
301314
pt => readType())
302315
})
303316
goto(end)
@@ -361,19 +374,17 @@ class TreeUnpickler(reader: TastyReader,
361374
case MATCHtype =>
362375
MatchType(readType(), readType(), until(end)(readType()))
363376
case POLYtype =>
364-
readMethodic(PolyType, _.toTypeName)
377+
readMethodic(_ => PolyType, _.toTypeName)
365378
case METHODtype =>
366-
readMethodic(MethodType, _.toTermName)
367-
case ERASEDMETHODtype =>
368-
readMethodic(ErasedMethodType, _.toTermName)
369-
case GIVENMETHODtype =>
370-
readMethodic(ContextualMethodType, _.toTermName)
371-
case ERASEDGIVENMETHODtype =>
372-
readMethodic(ErasedContextualMethodType, _.toTermName)
373-
case IMPLICITMETHODtype =>
374-
readMethodic(ImplicitMethodType, _.toTermName)
379+
def methodTypeCompanion(mods: FlagSet): MethodTypeCompanion =
380+
if mods.is(Implicit) then ImplicitMethodType
381+
else if mods.isAllOf(Erased | Given) then ErasedContextualMethodType
382+
else if mods.is(Given) then ContextualMethodType
383+
else if mods.is(Erased) then ErasedMethodType
384+
else MethodType
385+
readMethodic(methodTypeCompanion, _.toTermName)
375386
case TYPELAMBDAtype =>
376-
readMethodic(HKTypeLambda, _.toTypeName)
387+
readMethodic(_ => HKTypeLambda, _.toTypeName)
377388
case PARAMtype =>
378389
readTypeRef() match {
379390
case binder: LambdaType => binder.paramRefs(readNat())

tasty/src/dotty/tools/tasty/TastyFormat.scala

Lines changed: 8 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -160,17 +160,12 @@ Standard-Section: "ASTs" TopLevelStat*
160160
BIND Length boundName_NameRef bounds_Type -- boundName @ bounds, for type-variables defined in a type pattern
161161
BYNAMEtype underlying_Type -- => underlying
162162
PARAMtype Length binder_ASTRef paramNum_Nat -- A reference to parameter # paramNum in lambda type `binder`
163-
POLYtype Length result_Type NamesTypes -- A polymorphic method type `[NamesTypes]result`, used in refinements
164-
METHODtype Length result_Type NamesTypes -- A method type `(NamesTypes)result`, needed for refinements
165-
ERASEDMETHODtype Length result_Type NamesTypes -- A method type `erased (NamesTypes)result`, needed for refinements
166-
GIVENMETHODtype Length result_Type NamesTypes -- A method type `(using NamesTypes)result`, needed for refinements
167-
ERASEDGIVENMETHODtype Length result_Type NamesTypes -- A method type `(using erased NamesTypes)result`, needed for refinements
168-
IMPLICITMETHODtype Length result_Type NamesTypes -- A method type `(implicit NamesTypes)result`, needed for refinements
169-
// TODO: remove ERASEDIMPLICITMETHODtype
170-
TYPELAMBDAtype Length result_Type NamesTypes -- A type lambda `[NamesTypes] => result`
163+
POLYtype Length result_Type TypesNames -- A polymorphic method type `[TypesNames]result`, used in refinements
164+
METHODtype Length result_Type TypesNames Modifier* -- A method type `(Modifier* TypesNames)result`, needed for refinements, with optional modifiers for the parameters
165+
TYPELAMBDAtype Length result_Type TypesNames -- A type lambda `[TypesNames] => result`
171166
SHAREDtype type_ASTRef -- link to previously serialized type
172-
NamesTypes = NameType*
173-
NameType = paramName_NameRef typeOrBounds_ASTRef -- `termName : type` or `typeName bounds`
167+
TypesNames = TypeName*
168+
TypeName = typeOrBounds_ASTRef paramName_NameRef -- (`termName`: `type`) or (`typeName` `bounds`)
174169
175170
Modifier = PRIVATE -- private
176171
INTERNAL -- package private (not yet used)
@@ -254,7 +249,7 @@ Standard Section: "Comments" Comment*
254249
object TastyFormat {
255250

256251
final val header: Array[Int] = Array(0x5C, 0xA1, 0xAB, 0x1F)
257-
val MajorVersion: Int = 20
252+
val MajorVersion: Int = 21
258253
val MinorVersion: Int = 0
259254

260255
/** Tags used to serialize names, should update [[nameTagToString]] if a new constant is added */
@@ -305,6 +300,7 @@ object TastyFormat {
305300
case DEFAULTGETTER => "DEFAULTGETTER"
306301
case SUPERACCESSOR => "SUPERACCESSOR"
307302
case INLINEACCESSOR => "INLINEACCESSOR"
303+
case BODYRETAINER => "BODYRETAINER"
308304
case OBJECTCLASS => "OBJECTCLASS"
309305
case SIGNED => "SIGNED"
310306
case id => s"NotANameTag($id)"
@@ -460,23 +456,10 @@ object TastyFormat {
460456
final val TYPEREFin = 175
461457

462458
final val METHODtype = 180
463-
final val ERASEDMETHODtype = 181
464-
final val GIVENMETHODtype = 182
465-
final val ERASEDGIVENMETHODtype = 183
466-
final val IMPLICITMETHODtype = 184
467459

468460
final val MATCHtype = 190
469461
final val MATCHtpt = 191
470462

471-
def methodTypeTag(isContextual: Boolean, isImplicit: Boolean, isErased: Boolean): Int = {
472-
val implicitOffset =
473-
if (isContextual) 2
474-
else if (isImplicit) { assert(!isErased); 4 }
475-
else 0
476-
val erasedOffset = if (isErased) 1 else 0
477-
METHODtype + erasedOffset + implicitOffset
478-
}
479-
480463
final val HOLE = 255
481464

482465
final val firstNatTreeTag = SHAREDterm
@@ -680,10 +663,6 @@ object TastyFormat {
680663
case BYNAMEtpt => "BYNAMEtpt"
681664
case POLYtype => "POLYtype"
682665
case METHODtype => "METHODtype"
683-
case ERASEDMETHODtype => "ERASEDMETHODtype"
684-
case GIVENMETHODtype => "GIVENMETHODtype"
685-
case ERASEDGIVENMETHODtype => "ERASEDGIVENMETHODtype"
686-
case IMPLICITMETHODtype => "IMPLICITMETHODtype"
687666
case TYPELAMBDAtype => "TYPELAMBDAtype"
688667
case LAMBDAtpt => "LAMBDAtpt"
689668
case MATCHtype => "MATCHtype"
@@ -702,10 +681,7 @@ object TastyFormat {
702681
case VALDEF | DEFDEF | TYPEDEF | TYPEPARAM | PARAM | NAMEDARG | RETURN | BIND |
703682
SELFDEF | REFINEDtype | TERMREFin | TYPEREFin | HOLE => 1
704683
case RENAMED | PARAMtype => 2
705-
case POLYtype | TYPELAMBDAtype |
706-
METHODtype | ERASEDMETHODtype |
707-
GIVENMETHODtype | ERASEDGIVENMETHODtype |
708-
IMPLICITMETHODtype => -1
684+
case POLYtype | TYPELAMBDAtype | METHODtype => -1
709685
case _ => 0
710686
}
711687
}

0 commit comments

Comments
 (0)