Skip to content

Commit 176b23c

Browse files
committed
Use the @ErasedParam annotation as a marker for erased parameter
... instead of storing a separate boolean list. This has already been done, and will require no change to the TASTY format.
1 parent 08236ac commit 176b23c

File tree

7 files changed

+36
-65
lines changed

7 files changed

+36
-65
lines changed

compiler/src/dotty/tools/dotc/core/Types.scala

+20-17
Original file line numberDiff line numberDiff line change
@@ -3619,7 +3619,7 @@ object Types {
36193619

36203620
def companion: LambdaTypeCompanion[ThisName, PInfo, This]
36213621

3622-
def erasedParams = List.fill(paramInfos.size)(false)
3622+
def erasedParams(using Context) = List.fill(paramInfos.size)(false)
36233623

36243624
/** The type `[tparams := paramRefs] tp`, where `tparams` can be
36253625
* either a list of type parameter symbols or a list of lambda parameters
@@ -3910,25 +3910,26 @@ object Types {
39103910

39113911
final override def isImplicitMethod: Boolean =
39123912
companion.eq(ImplicitMethodType) ||
3913-
companion.isInstanceOf[ErasedImplicitMethodType] ||
3913+
companion.eq(ErasedImplicitMethodType) ||
39143914
isContextualMethod
39153915
final override def hasErasedParams: Boolean =
39163916
companion.isInstanceOf[ErasedMethodCompanion]
39173917
final override def isContextualMethod: Boolean =
39183918
companion.eq(ContextualMethodType) ||
3919-
companion.isInstanceOf[ErasedContextualMethodType]
3919+
companion.eq(ErasedContextualMethodType)
39203920

3921-
override def erasedParams: List[Boolean] = companion match
3922-
case c: ErasedMethodCompanion => c.erasedParams
3921+
override def erasedParams(using Context): List[Boolean] = companion match
3922+
case c: ErasedMethodCompanion => c.erasedParams(paramInfos)
39233923
case _ => super.erasedParams
39243924

39253925
// Mark erased classes as erased parameters as well.
39263926
def markErasedClasses(using Context): MethodType =
39273927
val isErasedClass = paramInfos.map(_.isErasedClass)
39283928
if isErasedClass.contains(true) then companion match
39293929
case c: ErasedMethodCompanion =>
3930-
val erasedParams = c.erasedParams.zipWithConserve(isErasedClass) { (a, b) => a || b }
3931-
if erasedParams == c.erasedParams then this
3930+
val baseErasedParams = c.erasedParams(paramInfos)
3931+
val erasedParams = baseErasedParams.zipWithConserve(isErasedClass) { (a, b) => a || b }
3932+
if erasedParams == baseErasedParams then this
39323933
else MethodType.companion(
39333934
isContextual = isContextualMethod,
39343935
isImplicit = isImplicitMethod,
@@ -4055,22 +4056,24 @@ object Types {
40554056
def companion(isContextual: Boolean = false, isImplicit: Boolean = false, erasedParams: List[Boolean] = Nil): MethodTypeCompanion =
40564057
val hasErased = erasedParams.contains(true)
40574058
if (isContextual)
4058-
if (hasErased) ErasedContextualMethodType(erasedParams) else ContextualMethodType
4059+
if (hasErased) ErasedContextualMethodType else ContextualMethodType
40594060
else if (isImplicit)
4060-
if (hasErased) ErasedImplicitMethodType(erasedParams) else ImplicitMethodType
4061+
if (hasErased) ErasedImplicitMethodType else ImplicitMethodType
40614062
else
4062-
if (hasErased) ErasedMethodType(erasedParams) else MethodType
4063+
if (hasErased) ErasedMethodType else MethodType
40634064
}
4064-
private def erasedMt(t: String, erasedParams: List[Boolean]) =
4065-
s"Erased${t}(${erasedParams.map(if _ then "erased _" else "_").mkString(", ")})"
4066-
sealed abstract class ErasedMethodCompanion(prefixString: String, val erasedParams: List[Boolean])
4067-
extends MethodTypeCompanion(erasedMt(prefixString, erasedParams))
4065+
sealed abstract class ErasedMethodCompanion(prefixString: String)
4066+
extends MethodTypeCompanion("Erased" + prefixString) {
40684067

4069-
class ErasedMethodType(erasedParams: List[Boolean]) extends ErasedMethodCompanion("MethodType", erasedParams)
4068+
def erasedParams(paramsInfo: List[Type])(using Context) =
4069+
paramsInfo.map(_.hasAnnotation(defn.ErasedParamAnnot))
4070+
}
4071+
4072+
object ErasedMethodType extends ErasedMethodCompanion("MethodType")
40704073
object ContextualMethodType extends MethodTypeCompanion("ContextualMethodType")
4071-
class ErasedContextualMethodType(erasedParams: List[Boolean]) extends ErasedMethodCompanion("ContextualMethodType", erasedParams)
4074+
object ErasedContextualMethodType extends ErasedMethodCompanion("ContextualMethodType")
40724075
object ImplicitMethodType extends MethodTypeCompanion("ImplicitMethodType")
4073-
class ErasedImplicitMethodType(erasedParams: List[Boolean]) extends ErasedMethodCompanion("ImplicitMethodType", erasedParams)
4076+
object ErasedImplicitMethodType extends ErasedMethodCompanion("ImplicitMethodType")
40744077

40754078
/** A ternary extractor for MethodType */
40764079
object MethodTpe {

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

+1-8
Original file line numberDiff line numberDiff line change
@@ -137,14 +137,7 @@ class TastyPrinter(bytes: Array[Byte]) {
137137
printTree()
138138
while (currentAddr.index < end.index && !isModifierTag(nextByte)) { printTree(); printName(); }
139139
// read tags
140-
until(end) {
141-
val tag = readByte()
142-
newLine()
143-
sb.append(" ").append(astTagToString(tag))
144-
if tag == ERASED then // ERASED comes with erased parameter flags
145-
val erasedParams = readBits().map(b => if b then "erased _" else "_")
146-
sb.append(s"(${erasedParams.mkString(", ")})")
147-
}
140+
printTrees()
148141
case PARAMtype =>
149142
printNat(); printNat()
150143
case _ =>

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

+1-5
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import config.Config
1919
import collection.mutable
2020
import reporting.{Profile, NoProfile}
2121
import dotty.tools.tasty.TastyFormat.ASTsSection
22-
import dotty.tools.dotc.transform.TypeUtils.isErasedClass
2322

2423
object TreePickler:
2524
class StackSizeExceeded(val mdef: tpd.MemberDef) extends Exception
@@ -304,10 +303,7 @@ class TreePickler(pickler: TastyPickler) {
304303
tpe.paramNames.lazyZip(tpe.paramInfos).foreach { (name, tpe) =>
305304
pickleType(tpe); pickleName(name)
306305
}
307-
if (mods != EmptyFlags) pickleFlags(mods &~ Flags.Erased, tpe.isTermLambda)
308-
if mods.is(Erased) then
309-
writeByte(ERASED)
310-
writeBits(tpe.erasedParams)
306+
if (mods != EmptyFlags) pickleFlags(mods, tpe.isTermLambda)
311307
}
312308
}
313309

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

+13-16
Original file line numberDiff line numberDiff line change
@@ -233,24 +233,21 @@ class TreeUnpickler(reader: TastyReader,
233233
// ------ Reading types -----------------------------------------------------
234234

235235
/** Read names in an interleaved sequence of types/bounds and (parameter) names,
236-
* possibly followed by a sequence of modifiers and a list of erased parameter flags.
236+
* possibly followed by a sequence of modifiers.
237237
*/
238-
def readParamNamesAndMods(end: Addr): (List[Name], FlagSet, List[Boolean]) =
238+
def readParamNamesAndMods(end: Addr): (List[Name], FlagSet) =
239239
val names =
240240
collectWhile(currentAddr != end && !isModifierTag(nextByte)) {
241241
skipTree()
242242
readName()
243243
}
244244
var mods = EmptyFlags
245-
var erasedParams: List[Boolean] = Nil
246245
while currentAddr != end do // avoid boxing the mods
247246
readByte() match
248247
case IMPLICIT => mods |= Implicit
249-
case ERASED =>
250-
mods |= Erased
251-
erasedParams = readBits()
248+
case ERASED => mods |= Erased
252249
case GIVEN => mods |= Given
253-
(names, mods, erasedParams)
250+
(names, mods)
254251

255252
/** Read `n` parameter types or bounds which are interleaved with names */
256253
def readParamTypes[T <: Type](n: Int)(using Context): List[T] =
@@ -326,13 +323,13 @@ class TreeUnpickler(reader: TastyReader,
326323
val end = readEnd()
327324

328325
def readMethodic[N <: Name, PInfo <: Type, LT <: LambdaType]
329-
(companionOp: (FlagSet, List[Boolean]) => LambdaTypeCompanion[N, PInfo, LT], nameMap: Name => N): LT = {
326+
(companionOp: FlagSet => LambdaTypeCompanion[N, PInfo, LT], nameMap: Name => N): LT = {
330327
val result = typeAtAddr.getOrElse(start, {
331328
val nameReader = fork
332329
nameReader.skipTree() // skip result
333330
val paramReader = nameReader.fork
334-
val (paramNames, mods, erasedParams) = nameReader.readParamNamesAndMods(end)
335-
companionOp(mods, erasedParams)(paramNames.map(nameMap))(
331+
val (paramNames, mods) = nameReader.readParamNamesAndMods(end)
332+
companionOp(mods)(paramNames.map(nameMap))(
336333
pt => registeringType(pt, paramReader.readParamTypes[PInfo](paramNames.length)),
337334
pt => readType())
338335
})
@@ -401,19 +398,19 @@ class TreeUnpickler(reader: TastyReader,
401398
case MATCHCASEtype =>
402399
defn.MatchCaseClass.typeRef.appliedTo(readType(), readType())
403400
case POLYtype =>
404-
readMethodic((_, _) => PolyType, _.toTypeName)
401+
readMethodic(_ => PolyType, _.toTypeName)
405402
case METHODtype =>
406-
def methodTypeCompanion(mods: FlagSet, erasedParams: List[Boolean]): MethodTypeCompanion =
403+
def methodTypeCompanion(mods: FlagSet): MethodTypeCompanion =
407404
if mods.is(Erased) then
408-
if mods.is(Implicit) then ErasedImplicitMethodType(erasedParams)
409-
else if mods.is(Given) then ErasedContextualMethodType(erasedParams)
410-
else ErasedMethodType(erasedParams)
405+
if mods.is(Implicit) then ErasedImplicitMethodType
406+
else if mods.is(Given) then ErasedContextualMethodType
407+
else ErasedMethodType
411408
else if mods.is(Implicit) then ImplicitMethodType
412409
else if mods.is(Given) then ContextualMethodType
413410
else MethodType
414411
readMethodic(methodTypeCompanion, _.toTermName)
415412
case TYPELAMBDAtype =>
416-
readMethodic((_, _) => HKTypeLambda, _.toTypeName)
413+
readMethodic(_ => HKTypeLambda, _.toTypeName)
417414
case PARAMtype =>
418415
readTypeRef() match {
419416
case binder: LambdaType => binder.paramRefs(readNat())

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -74,7 +74,7 @@ object ContextFunctionResults:
7474
tp.derivedLambdaType(resType = integrateContextResults(tp.resType, crCount))
7575
case defn.ContextFunctionType(argTypes, resType, erasedParams) =>
7676
val methodType: MethodTypeCompanion =
77-
if erasedParams.contains(true) then ErasedMethodType(erasedParams) else MethodType
77+
if erasedParams.contains(true) then ErasedMethodType else MethodType
7878
methodType(argTypes, integrateContextResults(resType, crCount - 1))
7979

8080
/** The total number of parameters of method `sym`, not counting

tasty/src/dotty/tools/tasty/TastyBuffer.scala

-9
Original file line numberDiff line numberDiff line change
@@ -63,15 +63,6 @@ class TastyBuffer(initialSize: Int) {
6363
length += n
6464
}
6565

66-
/** Write a list of bits, packed into an array of bytes, prefixed by its length. */
67-
def writeBits(data: List[Boolean]): Unit = {
68-
val bytes = data.grouped(8)
69-
.map(bits => bits.zipWithIndex.collect { case (true, i) => (1<<i).toByte }.sum)
70-
.toArray
71-
writeInt(data.length)
72-
writeBytes(bytes, bytes.length)
73-
}
74-
7566
/** Write a natural number in big endian format, base 128.
7667
* All but the last digits have bit 0x80 set.
7768
*/

tasty/src/dotty/tools/tasty/TastyReader.scala

-9
Original file line numberDiff line numberDiff line change
@@ -57,15 +57,6 @@ class TastyReader(val bytes: Array[Byte], start: Int, end: Int, val base: Int =
5757
result
5858
}
5959

60-
/** Read a list of packed booleans, prefixed by the length. */
61-
def readBits(): List[Boolean] = {
62-
val length = readInt()
63-
val lengthBytes = (length + 7) / 8 // number of bytes followed, this is ceil(length / 8)
64-
List.fill(lengthBytes) { readByte() }
65-
.flatMap(byte => List.tabulate(8) { i => (byte & (1 << i)) > 0 })
66-
.take(length) // we got lengthBytes * 8 bits here, with some extra bits, just cut them off.
67-
}
68-
6960
/** Read a natural number fitting in an Int in big endian format, base 128.
7061
* All but the last digits have bit 0x80 set.
7162
*/

0 commit comments

Comments
 (0)