Skip to content

Commit e239b78

Browse files
Make sure synthetic apply methods are generated in deterministic order (#18210)
Fixes #17330
2 parents 046ba60 + 03a7ba5 commit e239b78

File tree

3 files changed

+90
-22
lines changed

3 files changed

+90
-22
lines changed

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

Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1751,27 +1751,27 @@ class Definitions {
17511751
@tu lazy val Tuple2SpecializedParamClasses: PerRun[Set[Symbol]] = new PerRun(Tuple2SpecializedParamTypes.map(_.symbol))
17521752

17531753
// Specialized type parameters defined for scala.Function{0,1,2}.
1754-
@tu lazy val Function1SpecializedParamTypes: collection.Set[TypeRef] =
1755-
Set(IntType, LongType, FloatType, DoubleType)
1756-
@tu lazy val Function2SpecializedParamTypes: collection.Set[TypeRef] =
1757-
Set(IntType, LongType, DoubleType)
1758-
@tu lazy val Function0SpecializedReturnTypes: collection.Set[TypeRef] =
1759-
ScalaNumericValueTypeList.toSet + UnitType + BooleanType
1760-
@tu lazy val Function1SpecializedReturnTypes: collection.Set[TypeRef] =
1761-
Set(UnitType, BooleanType, IntType, FloatType, LongType, DoubleType)
1762-
@tu lazy val Function2SpecializedReturnTypes: collection.Set[TypeRef] =
1754+
@tu lazy val Function1SpecializedParamTypes: List[TypeRef] =
1755+
List(IntType, LongType, FloatType, DoubleType)
1756+
@tu lazy val Function2SpecializedParamTypes: List[TypeRef] =
1757+
List(IntType, LongType, DoubleType)
1758+
@tu lazy val Function0SpecializedReturnTypes: List[TypeRef] =
1759+
ScalaNumericValueTypeList :+ UnitType :+ BooleanType
1760+
@tu lazy val Function1SpecializedReturnTypes: List[TypeRef] =
1761+
List(UnitType, BooleanType, IntType, FloatType, LongType, DoubleType)
1762+
@tu lazy val Function2SpecializedReturnTypes: List[TypeRef] =
17631763
Function1SpecializedReturnTypes
17641764

17651765
@tu lazy val Function1SpecializedParamClasses: PerRun[collection.Set[Symbol]] =
1766-
new PerRun(Function1SpecializedParamTypes.map(_.symbol))
1766+
new PerRun(Function1SpecializedParamTypes.toSet.map(_.symbol))
17671767
@tu lazy val Function2SpecializedParamClasses: PerRun[collection.Set[Symbol]] =
1768-
new PerRun(Function2SpecializedParamTypes.map(_.symbol))
1768+
new PerRun(Function2SpecializedParamTypes.toSet.map(_.symbol))
17691769
@tu lazy val Function0SpecializedReturnClasses: PerRun[collection.Set[Symbol]] =
1770-
new PerRun(Function0SpecializedReturnTypes.map(_.symbol))
1770+
new PerRun(Function0SpecializedReturnTypes.toSet.map(_.symbol))
17711771
@tu lazy val Function1SpecializedReturnClasses: PerRun[collection.Set[Symbol]] =
1772-
new PerRun(Function1SpecializedReturnTypes.map(_.symbol))
1772+
new PerRun(Function1SpecializedReturnTypes.toSet.map(_.symbol))
17731773
@tu lazy val Function2SpecializedReturnClasses: PerRun[collection.Set[Symbol]] =
1774-
new PerRun(Function2SpecializedReturnTypes.map(_.symbol))
1774+
new PerRun(Function2SpecializedReturnTypes.toSet.map(_.symbol))
17751775

17761776
def isSpecializableTuple(base: Symbol, args: List[Type])(using Context): Boolean =
17771777
args.length <= 2 && base.isClass && TupleSpecializedClasses.exists(base.asClass.derivesFrom) && args.match
@@ -1803,18 +1803,18 @@ class Definitions {
18031803
})
18041804
&& !ctx.settings.Yscala2Stdlib.value // We do not add the specilized FunctionN methods/classes when compiling the stdlib
18051805

1806-
@tu lazy val Function0SpecializedApplyNames: collection.Set[TermName] =
1806+
@tu lazy val Function0SpecializedApplyNames: List[TermName] =
18071807
for r <- Function0SpecializedReturnTypes
18081808
yield nme.apply.specializedFunction(r, Nil).asTermName
18091809

1810-
@tu lazy val Function1SpecializedApplyNames: collection.Set[TermName] =
1810+
@tu lazy val Function1SpecializedApplyNames: List[TermName] =
18111811
for
18121812
r <- Function1SpecializedReturnTypes
18131813
t1 <- Function1SpecializedParamTypes
18141814
yield
18151815
nme.apply.specializedFunction(r, List(t1)).asTermName
18161816

1817-
@tu lazy val Function2SpecializedApplyNames: collection.Set[TermName] =
1817+
@tu lazy val Function2SpecializedApplyNames: List[TermName] =
18181818
for
18191819
r <- Function2SpecializedReturnTypes
18201820
t1 <- Function2SpecializedParamTypes
@@ -1823,7 +1823,7 @@ class Definitions {
18231823
nme.apply.specializedFunction(r, List(t1, t2)).asTermName
18241824

18251825
@tu lazy val FunctionSpecializedApplyNames: collection.Set[Name] =
1826-
Function0SpecializedApplyNames ++ Function1SpecializedApplyNames ++ Function2SpecializedApplyNames
1826+
Set.concat(Function0SpecializedApplyNames, Function1SpecializedApplyNames, Function2SpecializedApplyNames)
18271827

18281828
def functionArity(tp: Type)(using Context): Int = tp.functionArgInfos.length - 1
18291829

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ class SpecializeApplyMethods extends MiniPhase with InfoTransformer {
9090
override def transformTemplate(tree: Template)(using Context) = {
9191
val cls = tree.symbol.owner.asClass
9292

93-
def synthesizeApply(names: collection.Set[TermName]): Tree = {
93+
def synthesizeApply(names: List[TermName]): Tree = {
9494
val applyBuf = new mutable.ListBuffer[DefDef]
9595
names.foreach { name =>
9696
val applySym = cls.info.decls.lookup(name)

compiler/test/dotty/tools/dotc/transform/SpecializeFunctionsTests.scala

Lines changed: 71 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,10 @@ class SpecializeFunctionsTests extends DottyBytecodeTest {
3636
)
3737
assert(applys.contains("apply"), "Foo did not contain `apply` forwarder method")
3838
assert(applys.contains("apply$mcII$sp"), "Foo did not contain specialized apply")
39+
40+
// It's not essential they are in this particular order,
41+
// but they should be in deterministic order
42+
assert(applys == List("apply", "apply$mcII$sp", "apply"))
3943
}
4044
}
4145

@@ -48,20 +52,84 @@ class SpecializeFunctionsTests extends DottyBytecodeTest {
4852
checkBCode(source) { dir =>
4953
val apps =
5054
findClass("Func2", dir).methods.asScala.collect {
55+
case m if m.name == "apply" => m
5156
case m if m.name == "apply$mcIII$sp" =>
52-
assert(!hasInvokeStatic(m)) // should not call super specialized method
57+
assert(!hasInvokeStatic(m), s"${m.name} should not call super specialized method")
5358
m
54-
case m if m.name == "apply" => m
59+
case m if m.name.startsWith("apply") => m
5560
}
5661
.map(_.name)
5762
.toList
5863

5964
assert(
60-
apps.length == 3,
65+
apps.length == 56,
6166
s"Wrong number of specialized applys, actual length: ${apps.length} - $apps"
6267
)
6368
assert(apps.contains("apply"), "Func2 did not contain `apply` forwarder method")
6469
assert(apps.contains("apply$mcIII$sp"), "Func2 did not contain specialized apply")
70+
71+
// It's not essential they are in this particular order,
72+
// but they should be in some deterministic order:
73+
assert(
74+
apps == List(
75+
"apply$mcVII$sp",
76+
"apply$mcVIJ$sp",
77+
"apply$mcVID$sp",
78+
"apply$mcVJI$sp",
79+
"apply$mcVJJ$sp",
80+
"apply$mcVJD$sp",
81+
"apply$mcVDI$sp",
82+
"apply$mcVDJ$sp",
83+
"apply$mcVDD$sp",
84+
"apply$mcZII$sp",
85+
"apply$mcZIJ$sp",
86+
"apply$mcZID$sp",
87+
"apply$mcZJI$sp",
88+
"apply$mcZJJ$sp",
89+
"apply$mcZJD$sp",
90+
"apply$mcZDI$sp",
91+
"apply$mcZDJ$sp",
92+
"apply$mcZDD$sp",
93+
"apply$mcIIJ$sp",
94+
"apply$mcIID$sp",
95+
"apply$mcIJI$sp",
96+
"apply$mcIJJ$sp",
97+
"apply$mcIJD$sp",
98+
"apply$mcIDI$sp",
99+
"apply$mcIDJ$sp",
100+
"apply$mcIDD$sp",
101+
"apply$mcFII$sp",
102+
"apply$mcFIJ$sp",
103+
"apply$mcFID$sp",
104+
"apply$mcFJI$sp",
105+
"apply$mcFJJ$sp",
106+
"apply$mcFJD$sp",
107+
"apply$mcFDI$sp",
108+
"apply$mcFDJ$sp",
109+
"apply$mcFDD$sp",
110+
"apply$mcJII$sp",
111+
"apply$mcJIJ$sp",
112+
"apply$mcJID$sp",
113+
"apply$mcJJI$sp",
114+
"apply$mcJJJ$sp",
115+
"apply$mcJJD$sp",
116+
"apply$mcJDI$sp",
117+
"apply$mcJDJ$sp",
118+
"apply$mcJDD$sp",
119+
"apply$mcDII$sp",
120+
"apply$mcDIJ$sp",
121+
"apply$mcDID$sp",
122+
"apply$mcDJI$sp",
123+
"apply$mcDJJ$sp",
124+
"apply$mcDJD$sp",
125+
"apply$mcDDI$sp",
126+
"apply$mcDDJ$sp",
127+
"apply$mcDDD$sp",
128+
"apply",
129+
"apply$mcIII$sp",
130+
"apply"),
131+
s"Apply methods were not in the expected order: $apps"
132+
)
65133
}
66134
}
67135

0 commit comments

Comments
 (0)