diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index 9df62ec7128c..a0584e97a026 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -1741,27 +1741,27 @@ class Definitions { @tu lazy val Tuple2SpecializedParamClasses: PerRun[Set[Symbol]] = new PerRun(Tuple2SpecializedParamTypes.map(_.symbol)) // Specialized type parameters defined for scala.Function{0,1,2}. - @tu lazy val Function1SpecializedParamTypes: collection.Set[TypeRef] = - Set(IntType, LongType, FloatType, DoubleType) - @tu lazy val Function2SpecializedParamTypes: collection.Set[TypeRef] = - Set(IntType, LongType, DoubleType) - @tu lazy val Function0SpecializedReturnTypes: collection.Set[TypeRef] = - ScalaNumericValueTypeList.toSet + UnitType + BooleanType - @tu lazy val Function1SpecializedReturnTypes: collection.Set[TypeRef] = - Set(UnitType, BooleanType, IntType, FloatType, LongType, DoubleType) - @tu lazy val Function2SpecializedReturnTypes: collection.Set[TypeRef] = + @tu lazy val Function1SpecializedParamTypes: List[TypeRef] = + List(IntType, LongType, FloatType, DoubleType) + @tu lazy val Function2SpecializedParamTypes: List[TypeRef] = + List(IntType, LongType, DoubleType) + @tu lazy val Function0SpecializedReturnTypes: List[TypeRef] = + ScalaNumericValueTypeList :+ UnitType :+ BooleanType + @tu lazy val Function1SpecializedReturnTypes: List[TypeRef] = + List(UnitType, BooleanType, IntType, FloatType, LongType, DoubleType) + @tu lazy val Function2SpecializedReturnTypes: List[TypeRef] = Function1SpecializedReturnTypes @tu lazy val Function1SpecializedParamClasses: PerRun[collection.Set[Symbol]] = - new PerRun(Function1SpecializedParamTypes.map(_.symbol)) + new PerRun(Function1SpecializedParamTypes.toSet.map(_.symbol)) @tu lazy val Function2SpecializedParamClasses: PerRun[collection.Set[Symbol]] = - new PerRun(Function2SpecializedParamTypes.map(_.symbol)) + new PerRun(Function2SpecializedParamTypes.toSet.map(_.symbol)) @tu lazy val Function0SpecializedReturnClasses: PerRun[collection.Set[Symbol]] = - new PerRun(Function0SpecializedReturnTypes.map(_.symbol)) + new PerRun(Function0SpecializedReturnTypes.toSet.map(_.symbol)) @tu lazy val Function1SpecializedReturnClasses: PerRun[collection.Set[Symbol]] = - new PerRun(Function1SpecializedReturnTypes.map(_.symbol)) + new PerRun(Function1SpecializedReturnTypes.toSet.map(_.symbol)) @tu lazy val Function2SpecializedReturnClasses: PerRun[collection.Set[Symbol]] = - new PerRun(Function2SpecializedReturnTypes.map(_.symbol)) + new PerRun(Function2SpecializedReturnTypes.toSet.map(_.symbol)) def isSpecializableTuple(base: Symbol, args: List[Type])(using Context): Boolean = args.length <= 2 && base.isClass && TupleSpecializedClasses.exists(base.asClass.derivesFrom) && args.match @@ -1791,18 +1791,18 @@ class Definitions { false }) - @tu lazy val Function0SpecializedApplyNames: collection.Set[TermName] = + @tu lazy val Function0SpecializedApplyNames: List[TermName] = for r <- Function0SpecializedReturnTypes yield nme.apply.specializedFunction(r, Nil).asTermName - @tu lazy val Function1SpecializedApplyNames: collection.Set[TermName] = + @tu lazy val Function1SpecializedApplyNames: List[TermName] = for r <- Function1SpecializedReturnTypes t1 <- Function1SpecializedParamTypes yield nme.apply.specializedFunction(r, List(t1)).asTermName - @tu lazy val Function2SpecializedApplyNames: collection.Set[TermName] = + @tu lazy val Function2SpecializedApplyNames: List[TermName] = for r <- Function2SpecializedReturnTypes t1 <- Function2SpecializedParamTypes @@ -1811,7 +1811,7 @@ class Definitions { nme.apply.specializedFunction(r, List(t1, t2)).asTermName @tu lazy val FunctionSpecializedApplyNames: collection.Set[Name] = - Function0SpecializedApplyNames ++ Function1SpecializedApplyNames ++ Function2SpecializedApplyNames + Set.concat(Function0SpecializedApplyNames, Function1SpecializedApplyNames, Function2SpecializedApplyNames) def functionArity(tp: Type)(using Context): Int = tp.functionArgInfos.length - 1 diff --git a/compiler/src/dotty/tools/dotc/transform/SpecializeApplyMethods.scala b/compiler/src/dotty/tools/dotc/transform/SpecializeApplyMethods.scala index 6ffa05075201..afa2318c8f07 100644 --- a/compiler/src/dotty/tools/dotc/transform/SpecializeApplyMethods.scala +++ b/compiler/src/dotty/tools/dotc/transform/SpecializeApplyMethods.scala @@ -90,7 +90,7 @@ class SpecializeApplyMethods extends MiniPhase with InfoTransformer { override def transformTemplate(tree: Template)(using Context) = { val cls = tree.symbol.owner.asClass - def synthesizeApply(names: collection.Set[TermName]): Tree = { + def synthesizeApply(names: List[TermName]): Tree = { val applyBuf = new mutable.ListBuffer[DefDef] names.foreach { name => val applySym = cls.info.decls.lookup(name) diff --git a/compiler/test/dotty/tools/dotc/transform/SpecializeFunctionsTests.scala b/compiler/test/dotty/tools/dotc/transform/SpecializeFunctionsTests.scala index bf33dad915c4..2982238490e1 100644 --- a/compiler/test/dotty/tools/dotc/transform/SpecializeFunctionsTests.scala +++ b/compiler/test/dotty/tools/dotc/transform/SpecializeFunctionsTests.scala @@ -36,6 +36,10 @@ class SpecializeFunctionsTests extends DottyBytecodeTest { ) assert(applys.contains("apply"), "Foo did not contain `apply` forwarder method") assert(applys.contains("apply$mcII$sp"), "Foo did not contain specialized apply") + + // It's not essential they are in this particular order, + // but they should be in deterministic order + assert(applys == List("apply", "apply$mcII$sp", "apply")) } } @@ -48,20 +52,84 @@ class SpecializeFunctionsTests extends DottyBytecodeTest { checkBCode(source) { dir => val apps = findClass("Func2", dir).methods.asScala.collect { + case m if m.name == "apply" => m case m if m.name == "apply$mcIII$sp" => - assert(!hasInvokeStatic(m)) // should not call super specialized method + assert(!hasInvokeStatic(m), s"${m.name} should not call super specialized method") m - case m if m.name == "apply" => m + case m if m.name.startsWith("apply") => m } .map(_.name) .toList assert( - apps.length == 3, + apps.length == 56, s"Wrong number of specialized applys, actual length: ${apps.length} - $apps" ) assert(apps.contains("apply"), "Func2 did not contain `apply` forwarder method") assert(apps.contains("apply$mcIII$sp"), "Func2 did not contain specialized apply") + + // It's not essential they are in this particular order, + // but they should be in some deterministic order: + assert( + apps == List( + "apply$mcVII$sp", + "apply$mcVIJ$sp", + "apply$mcVID$sp", + "apply$mcVJI$sp", + "apply$mcVJJ$sp", + "apply$mcVJD$sp", + "apply$mcVDI$sp", + "apply$mcVDJ$sp", + "apply$mcVDD$sp", + "apply$mcZII$sp", + "apply$mcZIJ$sp", + "apply$mcZID$sp", + "apply$mcZJI$sp", + "apply$mcZJJ$sp", + "apply$mcZJD$sp", + "apply$mcZDI$sp", + "apply$mcZDJ$sp", + "apply$mcZDD$sp", + "apply$mcIIJ$sp", + "apply$mcIID$sp", + "apply$mcIJI$sp", + "apply$mcIJJ$sp", + "apply$mcIJD$sp", + "apply$mcIDI$sp", + "apply$mcIDJ$sp", + "apply$mcIDD$sp", + "apply$mcFII$sp", + "apply$mcFIJ$sp", + "apply$mcFID$sp", + "apply$mcFJI$sp", + "apply$mcFJJ$sp", + "apply$mcFJD$sp", + "apply$mcFDI$sp", + "apply$mcFDJ$sp", + "apply$mcFDD$sp", + "apply$mcJII$sp", + "apply$mcJIJ$sp", + "apply$mcJID$sp", + "apply$mcJJI$sp", + "apply$mcJJJ$sp", + "apply$mcJJD$sp", + "apply$mcJDI$sp", + "apply$mcJDJ$sp", + "apply$mcJDD$sp", + "apply$mcDII$sp", + "apply$mcDIJ$sp", + "apply$mcDID$sp", + "apply$mcDJI$sp", + "apply$mcDJJ$sp", + "apply$mcDJD$sp", + "apply$mcDDI$sp", + "apply$mcDDJ$sp", + "apply$mcDDD$sp", + "apply", + "apply$mcIII$sp", + "apply"), + s"Apply methods were not in the expected order: $apps" + ) } }