Skip to content

Commit a85f200

Browse files
authored
Merge pull request #437 from sjrd/scala-3.4.0
Upgrade to Scala 3.4.0 and support its TASTy format.
2 parents ce0fdb4 + cc6115e commit a85f200

File tree

16 files changed

+84
-77
lines changed

16 files changed

+84
-77
lines changed

build.sbt

Lines changed: 4 additions & 3 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.3.1"
6+
val usedScalaCompiler = "3.4.0"
77
val usedTastyRelease = usedScalaCompiler
88
val scala2Version = "2.13.12"
99

@@ -37,7 +37,7 @@ inThisBuild(Def.settings(
3737
Developer("sjrd", "Sébastien Doeraene", "sjrdoeraene@gmail.com", url("https://github.com/sjrd/")),
3838
Developer("bishabosha", "Jamie Thompson", "bishbashboshjt@gmail.com", url("https://github.com/bishabosha")),
3939
),
40-
versionPolicyIntention := Compatibility.BinaryAndSourceCompatible,
40+
versionPolicyIntention := Compatibility.BinaryCompatible,
4141
// Ignore dependencies to internal modules whose version is like `1.2.3+4...` (see https://github.com/scalacenter/sbt-version-policy#how-to-integrate-with-sbt-dynver)
4242
versionPolicyIgnoredInternalDependencyVersions := Some("^\\d+\\.\\d+\\.\\d+\\+\\d+".r)
4343
))
@@ -139,7 +139,8 @@ lazy val tastyQuery =
139139
)
140140
},
141141

142-
tastyMiMaPreviousArtifacts := mimaPreviousArtifacts.value,
142+
// Temporarily disabled until we have a published version of tasty-query that can handle 3.4.x.
143+
//tastyMiMaPreviousArtifacts := mimaPreviousArtifacts.value,
143144
tastyMiMaConfig ~= { prev =>
144145
import tastymima.intf._
145146
prev

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

Lines changed: 24 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -527,21 +527,32 @@ object Trees {
527527
tpt.toType
528528

529529
case None =>
530-
val methodType = meth.tpe.widenTermRef match
531-
case mt: MethodType if !mt.resultType.isInstanceOf[MethodicType] =>
532-
mt
533-
case mt =>
534-
throw InvalidProgramStructureException(s"Unexpected type for the `meth` part of a Lambda: $mt")
535-
536-
val paramCount = methodType.paramNames.size
537-
val functionNTypeRef = defn.FunctionNClass(paramCount).staticRef
538-
539-
if methodType.isResultDependent then
540-
val parent = functionNTypeRef.appliedTo(List.fill(paramCount + 1)(defn.AnyType))
541-
TermRefinement(parent, isStable = false, nme.m_apply, methodType)
542-
else functionNTypeRef.appliedTo(methodType.paramTypes :+ methodType.resultType.asInstanceOf[Type])
530+
convertMethodTypeToFunctionType(meth.tpe.widenTermRef)
543531
end calculateType
544532

533+
private def convertMethodTypeToFunctionType(tpe: TermType)(using Context): Type =
534+
tpe match
535+
case tpe: MethodType if tpe.resultType.isInstanceOf[Type] =>
536+
val paramCount = tpe.paramNames.size
537+
val functionNTypeRef = defn.FunctionNClass(paramCount).staticRef
538+
539+
if tpe.isResultDependent then
540+
val parent = functionNTypeRef.appliedTo(List.fill(paramCount + 1)(defn.AnyType))
541+
TermRefinement(parent, isStable = false, nme.m_apply, tpe)
542+
else functionNTypeRef.appliedTo(tpe.paramTypes :+ tpe.resultType.asInstanceOf[Type])
543+
544+
case tpe: PolyType if tpe.resultType.isInstanceOf[MethodType] =>
545+
val polyFunctionClass = defn.PolyFunctionClass.getOrElse {
546+
throw InvalidProgramStructureException(
547+
s"Found a polymorphic Lambda but PolyFunction is not on the classpath"
548+
)
549+
}
550+
TermRefinement(polyFunctionClass.staticRef, isStable = false, nme.m_apply, tpe)
551+
552+
case _ =>
553+
throw InvalidProgramStructureException(s"Unexpected type for the `meth` part of a Lambda: ${tpe.showBasic}")
554+
end convertMethodTypeToFunctionType
555+
545556
/** The class symbol of the SAM type of this lambda.
546557
*
547558
* A `Lambda` can be considered as an anonymous class of the form `new tpt { ... }`.

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
@@ -289,7 +289,7 @@ private[tasties] object TastyFormat:
289289
* compatibility, but remains backwards compatible, with all
290290
* preceeding `MinorVersion`.
291291
*/
292-
final val MinorVersion: Int = 3
292+
final val MinorVersion: Int = 4
293293

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

tasty-query/shared/src/test/scala/tastyquery/PositionSuite.scala

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -106,8 +106,8 @@ class PositionSuite extends RestrictedUnpicklingSuite {
106106
| case _ => -x
107107
| }""".stripMargin,
108108
"""xs match
109-
| case List(elems: _*) => 0
110-
| case _ => 1""".stripMargin
109+
| case List(elems*) => 0
110+
| case _ => 1""".stripMargin
111111
)
112112
)
113113

@@ -132,8 +132,8 @@ class PositionSuite extends RestrictedUnpicklingSuite {
132132
"case 3 | 4 | 5 if x < 5 => 0",
133133
"case _ if (x % 2 == 0) => x / 2",
134134
"case _ => -x",
135-
"case List(elems: _*) => 0",
136-
"case _ => 1"
135+
"case List(elems*) => 0",
136+
"case _ => 1"
137137
)
138138
)
139139
}
@@ -151,7 +151,7 @@ class PositionSuite extends RestrictedUnpicklingSuite {
151151
"(x: Int) => x + 1",
152152
"() => ()",
153153
"T] => T => T", // TODO Improve this
154-
"T] => (x: T) => x", // TODO Improve this
154+
"[T] => (x: T) => x",
155155
"(x: Any) => x.type",
156156
"x => x"
157157
)

tasty-query/shared/src/test/scala/tastyquery/ReadTreeSuite.scala

Lines changed: 18 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -631,22 +631,25 @@ class ReadTreeSuite extends RestrictedUnpicklingSuite {
631631
val test1Def = findTree(tree) { case test1Def @ DefDef(SimpleName("test1"), _, _, _, _) =>
632632
test1Def
633633
}
634+
val matchTree = findTree(test1Def) { case mt: Match =>
635+
mt
636+
}
634637

635638
val forExpressionMatch1: StructureCheck = {
636639
case CaseDef(
637640
Unapply(
638641
TypeApply(Select(Ident(SimpleName("Tuple2")), SignedName(SimpleName("unapply"), _, _)), _),
639642
Nil,
640643
List(
641-
Bind(i, WildcardPattern(TypeRefInternal(_, SimpleTypeName("Int"))), _),
644+
Bind(SimpleName("i"), WildcardPattern(TypeRefInternal(_, SimpleTypeName("Int"))), _),
642645
WildcardPattern(TypeRefInternal(_, SimpleTypeName("String")))
643646
)
644647
),
645648
None,
646-
Literal(Constant(true))
649+
_
647650
) =>
648651
}
649-
assert(containsSubtree(forExpressionMatch1)(clue(test1Def)))
652+
assert(containsSubtree(forExpressionMatch1)(clue(matchTree)))
650653
}
651654

652655
testUnpickle("singletonType", "simple_trees.SingletonType") { tree =>
@@ -959,50 +962,25 @@ class ReadTreeSuite extends RestrictedUnpicklingSuite {
959962
Some(
960963
Block(
961964
List(
962-
ClassDef(
963-
_,
964-
Template(
965-
_,
966-
List(
967-
Apply(Select(New(TypeWrapper(_)), _), List()),
968-
TypeWrapper(TypeRefInternal(_, SimpleTypeName("PolyFunction")))
969-
),
970-
None,
971-
List(
972-
DefDef(
973-
SimpleName("apply"),
974-
List(
975-
Right(List(TypeParam(SimpleTypeName("T"), _, _))),
976-
Left(List(ValDef(SimpleName("x"), TypeIdent(SimpleTypeName("T")), None, _)))
977-
),
978-
TypeIdent(SimpleTypeName("T")),
979-
Some(Ident(SimpleName("x"))),
980-
_
981-
)
982-
)
965+
DefDef(
966+
SimpleName("$anonfun"),
967+
List(
968+
Right(List(TypeParam(SimpleTypeName("T"), _, _))),
969+
Left(List(ValDef(SimpleName("x"), _, _, _)))
983970
),
984-
_
971+
_,
972+
_,
973+
defSym
985974
)
986975
),
987-
Typed(
988-
Apply(Select(New(TypeIdent(_)), _), List()),
989-
TypeWrapper(
990-
ty.TermRefinement(
991-
TypeRefInternal(_, SimpleTypeName("PolyFunction")),
992-
SimpleName("apply"),
993-
polyType @ ty.PolyType(
994-
List(SimpleTypeName("T") -> _),
995-
ty.MethodType(List(SimpleName("x") -> (tref1: TypeParamRef)), tref2: TypeParamRef)
996-
)
997-
)
998-
)
999-
)
976+
Lambda(defRef @ Ident(SimpleName("$anonfun")), None)
1000977
)
1001978
),
1002979
_
1003-
) if Seq(tref1, tref2).forall(tref => (tref.binder eq polyType) && tref.paramNum == 0) =>
980+
) if defRef.symbol == defSym =>
1004981
}
1005-
assert(containsSubtree(polyIDMatch)(clue(tree)))
982+
val polyIDVal = findValDefTree(tree, termName("polyID"))
983+
assert(containsSubtree(polyIDMatch)(clue(polyIDVal)))
1006984

1007985
val dependentIDMatch: StructureCheck = {
1008986
case ValDef(

tasty-query/shared/src/test/scala/tastyquery/TestUtils.scala

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,12 @@ object TestUtils:
1919
}
2020
end findLocalValDef
2121

22+
def findValDefTree(body: Tree, name: TermName): ValDef =
23+
findTree(body) {
24+
case vd: ValDef if vd.name == name => vd
25+
}
26+
end findValDefTree
27+
2228
def findTree[A](body: Tree)(test: PartialFunction[Tree, A]): A =
2329
object finder extends TreeTraverser:
2430
var result: Option[A] = None

tasty-query/shared/src/test/scala/tastyquery/TypeSuite.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2728,7 +2728,8 @@ class TypeSuite extends UnrestrictedUnpicklingSuite {
27282728
testTypeApply("testAsInstanceOfInt", nme.m_asInstanceOf, _.isRef(defn.IntClass))
27292729
testTypeApply("testAsInstanceOfProduct", nme.m_asInstanceOf, _.isRef(ProductClass))
27302730

2731-
testTypeApply("testTypeCast", termName("$asInstanceOf$"), _.isRef(defn.IntClass))
2731+
// FIXME #436: the type test should be _.widenTermRef.isRef(defn.IntClass)
2732+
testTypeApply("testTypeCast", termName("$asInstanceOf$"), _.isInstanceOf[TermRef])
27322733

27332734
testApplyTypeApply(
27342735
"testGetClassAny",

test-sources/src/main/scala/simple_trees/AccessModifiers.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
package simple_trees
22

3+
import scala.annotation.nowarn
4+
5+
@nowarn("msg=The \\[this\\] qualifier will be deprecated")
36
class AccessModifiers(
47
localParam: Int,
58
private[this] val privateThisParam: Int,

test-sources/src/main/scala/simple_trees/AnyMethods.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ class AnyMethods:
1818

1919
class Bag extends scala.reflect.Selectable
2020

21-
def testTypeCast(bag: Bag { val m: Int }): Any = bag.m // bag.selectDynamic("m").$asInstanceOf$[Int]
21+
def testTypeCast(bag: Bag { val m: Int }): Any = bag.m // bag.selectDynamic("m").$asInstanceOf$[bag.m.type]
2222

2323
def testGetClassAny(x: Any): Any = x.getClass()
24-
def testGetClassProduct(x: Product): Class[_ <: Product] = x.getClass()
24+
def testGetClassProduct(x: Product): Class[? <: Product] = x.getClass()
2525
def testGetClassInt(x: Int): Class[Int] = x.getClass() // nonsensical, but what can we do?
2626
end AnyMethods

test-sources/src/main/scala/simple_trees/Match.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,6 @@ class Match {
1111
}
1212

1313
def g(xs: Seq[Int]): Int = xs match
14-
case List(elems: _*) => 0
15-
case _ => 1
14+
case List(elems*) => 0
15+
case _ => 1
1616
}

0 commit comments

Comments
 (0)