Skip to content

Commit 32328db

Browse files
sjrdmrdziuban
andcommitted
Upgrade to Scala 3.8.1.
Major changes: * Add support for the special erasure of `scala.caps.Pure`. * Add the magic type aliases `scala.ImpureXYZFunctionN`, because apparently references to them are in TASTy, so they are de facto standard. More benign changes: * Switch `-Xfatal-warnings` to `-Werror`, as the former is not supported anymore. * Disable `-source:future` for now, as it wants to enforce a bunch of syntax that we are not using yet. * Address warnings from changes to `-Yexplicit-nulls`. * Adjust tests to "cosmetic" changes to the inferred trees and their types. Co-authored-by: Matt Dziuban <mrdziuban@gmail.com>
1 parent 7fce4f9 commit 32328db

File tree

12 files changed

+118
-65
lines changed

12 files changed

+118
-65
lines changed

build.sbt

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ import sbt.internal.util.ManagedLogger
33

44
import org.scalajs.jsenv.nodejs.NodeJSEnv
55

6-
val usedScalaCompiler = "3.7.1"
6+
val usedScalaCompiler = "3.8.1"
77
val usedTastyRelease = usedScalaCompiler
88
val scala2Version = "2.13.18"
99

@@ -50,10 +50,10 @@ val commonSettings = Seq(
5050

5151
val strictCompileSettings = Seq(
5252
scalacOptions ++= Seq(
53-
"-Xfatal-warnings",
5453
"-Yexplicit-nulls",
54+
"-Werror",
5555
"-Wsafe-init",
56-
"-source:future",
56+
// "-source:future",
5757
),
5858
)
5959

@@ -69,7 +69,7 @@ lazy val scala2TestSources = crossProject(JSPlatform, JVMPlatform)
6969
.settings(
7070
scalaVersion := scala2Version,
7171
publish / skip := true,
72-
scalacOptions += "-Xfatal-warnings",
72+
scalacOptions += "-Werror",
7373
libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value % "provided",
7474
)
7575

@@ -79,7 +79,7 @@ lazy val testSources = crossProject(JSPlatform, JVMPlatform)
7979
.settings(commonSettings)
8080
.settings(
8181
publish / skip := true,
82-
scalacOptions += "-Xfatal-warnings",
82+
scalacOptions += "-Werror",
8383
javacOptions += "-parameters",
8484
)
8585
.dependsOn(scala2TestSources)
@@ -126,10 +126,13 @@ lazy val tastyQuery =
126126
mimaBinaryIssueFilters ++= {
127127
import com.typesafe.tools.mima.core.*
128128
Seq(
129+
// Scala 3.8.x generates fewer static initializers, but that is never an issue
130+
ProblemFilters.exclude[DirectMissingMethodProblem]("*.<clinit>"),
129131
)
130132
},
131133

132-
tastyMiMaPreviousArtifacts := mimaPreviousArtifacts.value,
134+
// Temporarily disabled until we have a published version of tasty-query that can handle 3.8.x.
135+
// tastyMiMaPreviousArtifacts := mimaPreviousArtifacts.value,
133136
tastyMiMaTastyQueryVersionOverride := Some("1.6.0"),
134137
tastyMiMaConfig ~= { prev =>
135138
import tastymima.intf._

tasty-query/js/src/test/scala/tastyquery/testutil/nodejs/NodeJSTestPlatform.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,10 @@ object NodeJSTestPlatform:
2626
classpath
2727

2828
lazy val scala3ClasspathIndex: Int =
29-
classpathEntries.indexWhere(_.contains("scala3-library_3").nn)
29+
classpathEntries.indexWhere(_.contains("scala-library-3"))
3030

3131
def readResourceCodeFile(relPath: String): String =
32-
val path = getEnvVar(ResourceCodeEnvVar).nn + "/" + relPath
32+
val path = getEnvVar(ResourceCodeEnvVar) + "/" + relPath
3333
NodeFS.readFileSync(path, "utf-8")
3434

3535
private object NodeFS:

tasty-query/jvm/src/main/scala/tastyquery/jdk/ClasspathLoaders.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ object ClasspathLoaders {
2121
case Tasty extends FileKind("tasty")
2222

2323
def appliesTo(path: Path): Boolean =
24-
path.getFileName().nn.toString().nn.endsWith("." + ext)
24+
path.getFileName().nn.toString().endsWith("." + ext)
2525
end FileKind
2626

2727
private object FileKind:

tasty-query/jvm/src/test/scala/tastyquery/testutil/jdk/JavaTestPlatform.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ object JavaTestPlatform {
2727
ClasspathLoaders.read(classpathPaths)
2828

2929
lazy val scala3ClasspathIndex: Int =
30-
classpathEntries.indexWhere(_.contains("scala3-library_3").nn)
30+
classpathEntries.indexWhere(_.contains("scala-library-3"))
3131

3232
def loadClasspath(): Future[Classpath] =
3333
Future(classpath)

tasty-query/shared/src/main/scala/tastyquery/Definitions.scala

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ final class Definitions private[tastyquery] (
3232
private val javaPackage = RootPackage.getPackageDeclOrCreate(nme.javaPackageName)
3333
val javaLangPackage = javaPackage.getPackageDeclOrCreate(nme.langPackageName)
3434
private[tastyquery] val javaLangInvokePackage = javaLangPackage.getPackageDeclOrCreate(termName("invoke"))
35+
private val capsPackage = scalaPackage.getPackageDeclOrCreate(termName("caps"))
3536

3637
private val scalaAnnotationPackage =
3738
scalaPackage.getPackageDeclOrCreate(termName("annotation"))
@@ -419,9 +420,37 @@ final class Definitions private[tastyquery] (
419420
cls
420421
end createContextFunctionNClass
421422

423+
/** Creates one of the `ImpureXYZFunctionN` classes.
424+
*
425+
* Despite capture checking being highly experimental, we find references to
426+
* these type aliases in stable TASTy, so we have to define them.
427+
*
428+
* They are of the form:
429+
*
430+
* ```scala
431+
* type ImpureXYZFunctionN[-T0,...,-T{N-1}, +R] = XYZFunctionN[T0,...,T{N-1}, R]^{any}
432+
* ```
433+
*
434+
* although of course we don't introduce the `^{any}` part of it.
435+
*/
436+
private def createImpureFunctionTypeAlias(targetClassName: TypeName, n: Int): TypeSymbol =
437+
val name = typeName("Impure" + targetClassName.toString())
438+
val targetClassRef = TypeRef(scalaPackage.packageRef, targetClassName)
439+
val alias = TypeLambda(List.tabulate(n)(i => typeName("T$i")) :+ typeName("R"))(
440+
paramInfosExp = tl => List.fill(n + 1)(NothingAnyBounds),
441+
resultTypeExp = tl => AppliedType(targetClassRef, tl.paramRefs)
442+
)
443+
createSpecialTypeAlias(name, scalaPackage, EmptyFlagSet, alias)
444+
end createImpureFunctionTypeAlias
445+
422446
locally {
423447
for (n <- 0 to 22)
424448
createContextFunctionNClass(n)
449+
450+
for (n <- 0 to 22) {
451+
createImpureFunctionTypeAlias(typeName(s"Function$n"), n)
452+
createImpureFunctionTypeAlias(typeName(s"ContextFunction$n"), n)
453+
}
425454
}
426455

427456
// Derived symbols, found on the classpath
@@ -469,6 +498,8 @@ final class Definitions private[tastyquery] (
469498

470499
lazy val ProductClass = scalaPackage.requiredClass("Product")
471500

501+
lazy val PureClass = capsPackage.requiredClass("Pure")
502+
472503
lazy val ErasedNothingClass = scalaRuntimePackage.requiredClass("Nothing$")
473504
lazy val ErasedBoxedUnitClass = scalaRuntimePackage.requiredClass("BoxedUnit")
474505

tasty-query/shared/src/main/scala/tastyquery/Erasure.scala

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -95,14 +95,23 @@ private[tastyquery] object Erasure:
9595
finishErase(preErase(tpe.first, keepUnit = false)),
9696
finishErase(preErase(tpe.second, keepUnit = false))
9797
)
98+
9899
case tpe: AndType =>
99-
summon[SourceLanguage] match
100-
case SourceLanguage.Java =>
101-
preErase(tpe.first, keepUnit = false)
102-
case SourceLanguage.Scala2 =>
103-
preErase(Scala2Erasure.eraseAndType(tpe), keepUnit = false)
104-
case SourceLanguage.Scala3 =>
105-
erasedGlb(preErase(tpe.first, keepUnit = false), preErase(tpe.second, keepUnit = false))
100+
/* When erasing something that is `A & Pure` or `Pure & A`, we should take the erasure of A.
101+
* This also work for [T <: Pure] `T & A` or `A & T`.
102+
* The root problem is described here: https://github.com/scala/scala3/issues/24113
103+
*/
104+
if tpe.first.dealias.classSymbol.contains(defn.PureClass) then preErase(tpe.second, keepUnit)
105+
else if tpe.second.dealias.classSymbol.contains(defn.PureClass) then preErase(tpe.first, keepUnit)
106+
else
107+
summon[SourceLanguage] match
108+
case SourceLanguage.Java =>
109+
preErase(tpe.first, keepUnit = false)
110+
case SourceLanguage.Scala2 =>
111+
preErase(Scala2Erasure.eraseAndType(tpe), keepUnit = false)
112+
case SourceLanguage.Scala3 =>
113+
erasedGlb(preErase(tpe.first, keepUnit = false), preErase(tpe.second, keepUnit = false))
114+
106115
case tpe: AnnotatedType =>
107116
preErase(tpe.typ, keepUnit)
108117
case tpe @ defn.PolyFunctionType(mt) =>

tasty-query/shared/src/main/scala/tastyquery/TypeOps.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ private[tastyquery] object TypeOps:
6565
toPrefix(pre.select(nme.PACKAGE), cls, thiscls)*/
6666
else
6767
pre.baseType(cls).flatMap(_.normalizedPrefix) match
68-
case Some(normalizedPrefix) => toPrefix(origTp, normalizedPrefix, cls.owner.nn, thiscls)
68+
case Some(normalizedPrefix) => toPrefix(origTp, normalizedPrefix, cls.owner, thiscls)
6969
case None => origTp
7070
case _ =>
7171
throw AssertionError(

tasty-query/shared/src/main/scala/tastyquery/Types.scala

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1711,11 +1711,11 @@ object Types {
17111711

17121712
def paramTypes: List[Type] =
17131713
if !initialized then throw CyclicReferenceException(s"method [$paramNames]=>???")
1714-
myParamTypes.nn
1714+
myParamTypes
17151715

17161716
def resultType: TypeOrMethodic =
17171717
if !initialized then throw CyclicReferenceException(s"method [$paramNames]=>???")
1718-
myRes.nn
1718+
myRes
17191719

17201720
private[tastyquery] def isResultDependent(using Context): Boolean =
17211721
// TODO This should be made more efficient; we only need to traverse the type, not transform it
@@ -1830,11 +1830,11 @@ object Types {
18301830

18311831
def paramTypeBounds: List[TypeBounds] =
18321832
if !initialized then throw CyclicReferenceException(s"polymorphic method [$paramNames]=>???")
1833-
myBounds.nn
1833+
myBounds
18341834

18351835
def resultType: TypeOrMethodic =
18361836
if !initialized then throw CyclicReferenceException(s"polymorphic method [$paramNames]=>???")
1837-
myRes.nn
1837+
myRes
18381838

18391839
def companion: LambdaTypeCompanion[TypeName, TypeBounds, TypeOrMethodic, PolyType] =
18401840
PolyType
@@ -1937,11 +1937,11 @@ object Types {
19371937

19381938
def paramTypeBounds: List[TypeBounds] =
19391939
if !initialized then throw CyclicReferenceException(s"type lambda [$paramNames]=>???")
1940-
myBounds.nn
1940+
myBounds
19411941

19421942
def resultType: Type =
19431943
if !initialized then throw CyclicReferenceException(s"type lambda [$paramNames]=>???")
1944-
myRes.nn
1944+
myRes
19451945

19461946
private[tastyquery] lazy val typeLambdaParams: List[TypeLambdaParam] =
19471947
List.tabulate(paramNames.size)(num => TypeLambdaParam(this, num))
@@ -2194,15 +2194,15 @@ object Types {
21942194

21952195
def paramTypeBounds: List[TypeBounds] =
21962196
if !initialized then throw CyclicReferenceException(s"match [$paramNames]=>???")
2197-
myParamTypeBounds.nn
2197+
myParamTypeBounds
21982198

21992199
def pattern: Type =
22002200
if !initialized then throw CyclicReferenceException(s"match [$paramNames]=>???")
2201-
myPattern.nn
2201+
myPattern
22022202

22032203
def result: Type =
22042204
if !initialized then throw CyclicReferenceException(s"match [$paramNames]=>???")
2205-
myResult.nn
2205+
myResult
22062206

22072207
/** The type `[params := this.paramRefs] tp`. */
22082208
private def integrate(params: List[Symbol], tp: Type): Type =

tasty-query/shared/src/main/scala/tastyquery/reader/pickles/PickleReader.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ private[pickles] class PickleReader {
243243
case Scala2Constructor | Scala2TraitConstructor =>
244244
nme.Constructor
245245
case SimpleName(MangledDefaultGetterNameRegex(underlyingStr, indexStr)) =>
246-
DefaultGetterName(termName(underlyingStr), indexStr.toInt - 1)
246+
DefaultGetterName(termName(underlyingStr.nn), indexStr.nn.toInt - 1)
247247
case _ =>
248248
name2
249249
else name2

tasty-query/shared/src/main/scala/tastyquery/reader/tasties/TastyFormat.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -296,7 +296,7 @@ private[tasties] object TastyFormat:
296296
* compatibility, but remains backwards compatible, with all
297297
* preceeding `MinorVersion`.
298298
*/
299-
final val MinorVersion: Int = 7
299+
final val MinorVersion: Int = 8
300300

301301
/** Natural Number. The `ExperimentalVersion` allows for
302302
* experimentation with changes to TASTy without committing

0 commit comments

Comments
 (0)