Skip to content

Commit

Permalink
Use Scala2x flags for unpickled Scala 2 stdlib TASTy
Browse files Browse the repository at this point in the history
Also introduce `Scala2Tasty` flag to differentiate between Scala 2
symbols that come from class files and Scala 2 symbols that come from
TASTy.

At this point, the only Scala 2 TASTy is the one from the standard
library. To know that a TASTy contains the definitions of the standard
library, we add the `Scala2StandardLibrary` attribute to the TASTy file.
We mark all unpickled classes from those TASTy files with `Scala2x | Scala2Tasty`.
  • Loading branch information
nicolasstucki committed Oct 12, 2023
1 parent b418baa commit 4e12301
Show file tree
Hide file tree
Showing 7 changed files with 24 additions and 6 deletions.
4 changes: 2 additions & 2 deletions compiler/src/dotty/tools/dotc/core/Flags.scala
Original file line number Diff line number Diff line change
Expand Up @@ -308,8 +308,8 @@ object Flags {
*/
val (_, StableRealizable @ _, _) = newFlags(24, "<stable>")

/** A case parameter accessor */
val (_, CaseAccessor @ _, _) = newFlags(25, "<caseaccessor>")
/** A case parameter accessor / an unpickled Scala 2 TASTy (only for Scala 2 stdlib) */
val (_, CaseAccessor @ _, Scala2Tasty @ _) = newFlags(25, "<caseaccessor>", "<scala-2-tasty>")

/** A Scala 2x super accessor / an unpickled Scala 2.x class */
val (SuperParamAliasOrScala2x @ _, SuperParamAlias @ _, Scala2x @ _) = newFlags(26, "<super-param-alias>", "<scala-2.x>")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@ package core.tasty

import scala.language.unsafeNulls

import dotty.tools.tasty.{TastyReader, TastyBuffer}
import dotty.tools.tasty.{TastyFormat, TastyReader, TastyBuffer}

import java.nio.charset.StandardCharsets

Expand All @@ -23,4 +23,6 @@ class AttributeUnpickler(reader: TastyReader):
attributesBuilder.result()
}

def scala2Stdlib: Boolean = attributes.contains(TastyFormat.Scala2StandardLibraryAttribute)

end AttributeUnpickler
6 changes: 5 additions & 1 deletion compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,9 @@ class TreeUnpickler(reader: TastyReader,
/** Was unpickled class compiled with capture checks? */
private var withCaptureChecks: Boolean = false

private val unpicklingScala2Lib =
attributeUnpicklerOpt.exists(_.scala2Stdlib)

private def registerSym(addr: Addr, sym: Symbol) =
symAtAddr(addr) = sym

Expand Down Expand Up @@ -610,7 +613,8 @@ class TreeUnpickler(reader: TastyReader,
val rhsStart = currentAddr
val rhsIsEmpty = nothingButMods(end)
if (!rhsIsEmpty) skipTree()
val (givenFlags, annotFns, privateWithin) = readModifiers(end)
val (givenFlags0, annotFns, privateWithin) = readModifiers(end)
val givenFlags = if isClass && unpicklingScala2Lib then givenFlags0 | Scala2x | Scala2Tasty else givenFlags0
pickling.println(i"creating symbol $name at $start with flags ${givenFlags.flagsString}, isAbsType = $isAbsType, $ttag")
val flags = normalizeFlags(tag, givenFlags, name, isAbsType, rhsIsEmpty)
def adjustIfModule(completer: LazyType) =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ class ExtensionMethods extends MiniPhase with DenotTransformer with FullParamete

// Create extension methods, except if the class comes from Scala 2
// because it adds extension methods before pickling.
if (!(valueClass.is(Scala2x)))
if !valueClass.is(Scala2x, butNot = Scala2Tasty) then
for (decl <- valueClass.classInfo.decls)
if isMethodWithExtension(decl) then
enterInModuleClass(createExtensionMethod(decl, moduleClassSym.symbol))
Expand Down
5 changes: 4 additions & 1 deletion compiler/src/dotty/tools/dotc/transform/Pickler.scala
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import reporting.{ThrowingReporter, Profile, Message}
import collection.mutable
import util.concurrent.{Executor, Future}
import compiletime.uninitialized
import dotty.tools.tasty.TastyFormat.Scala2StandardLibraryAttribute

object Pickler {
val name: String = "pickler"
Expand Down Expand Up @@ -108,7 +109,9 @@ class Pickler extends Phase {
pickler, treePkl.buf.addrOfTree, treePkl.docString, tree,
scratch.commentBuffer)

val attributes = Nil // TODO add attributes here
val attributes =
if ctx.settings.Yscala2Stdlib.value then List(Scala2StandardLibraryAttribute)
else Nil
AttributePickler.pickleAttributes(attributes, pickler, scratch.attributeBuffer)

val pickled = pickler.assembleParts()
Expand Down
7 changes: 7 additions & 0 deletions scala2-library-tasty-tests/src/Main.scala
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ object HelloWorld:
testScala2ObjectParents()
testScala2CaseClassUnderscoreMembers()
testScalaNumberUnderlying()
testArrayOps()
scala.collection.mutable.UnrolledBufferTest.test()
}

Expand Down Expand Up @@ -68,3 +69,9 @@ object HelloWorld:
val _: Object = MyNumber2(BigInt(1)).underlying
val _: Object = (MyNumber2(BigInt(1)): ScalaNumber).underlying
}

def testArrayOps() = {
new collection.ArrayOps[String](Array[String]("foo")).exists(x => true)
}

end HelloWorld
2 changes: 2 additions & 0 deletions tasty/src/dotty/tools/tasty/TastyFormat.scala
Original file line number Diff line number Diff line change
Expand Up @@ -366,6 +366,8 @@ object TastyFormat {
final val CommentsSection = "Comments"
final val AttributesSection = "Attributes"

final val Scala2StandardLibraryAttribute = "Scala2StandardLibrary"

/** Tags used to serialize names, should update [[TastyFormat$.nameTagToString]] if a new constant is added */
class NameTags {
final val UTF8 = 1 // A simple name in UTF8 encoding.
Expand Down

0 comments on commit 4e12301

Please sign in to comment.