aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorodersky <odersky@gmail.com>2016-12-03 11:01:43 +0100
committerGitHub <noreply@github.com>2016-12-03 11:01:43 +0100
commit8288a3462353de80d8295bbd1f69afe141b2ed4c (patch)
treeba4031a89c9ec87af02cc62096dd931db75f88ad
parentb0a64ec191b1b0c4ab0b066c4dcb11e0c073d6b5 (diff)
parent055f12f957ec176323e4e0bf01af51666b9ff433 (diff)
downloaddotty-8288a3462353de80d8295bbd1f69afe141b2ed4c.tar.gz
dotty-8288a3462353de80d8295bbd1f69afe141b2ed4c.tar.bz2
dotty-8288a3462353de80d8295bbd1f69afe141b2ed4c.zip
Merge pull request #1758 from dotty-staging/change-functions
Drop function 22 limit
-rw-r--r--compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/core/Definitions.scala214
-rw-r--r--compiler/src/dotty/tools/dotc/core/NameOps.scala6
-rw-r--r--compiler/src/dotty/tools/dotc/core/Scopes.scala2
-rw-r--r--compiler/src/dotty/tools/dotc/core/StdNames.scala1
-rw-r--r--compiler/src/dotty/tools/dotc/core/TypeErasure.scala17
-rw-r--r--compiler/src/dotty/tools/dotc/transform/Erasure.scala80
-rw-r--r--library/src/scala/Function23.scala21
-rw-r--r--library/src/scala/Function24.scala21
-rw-r--r--library/src/scala/Function25.scala21
-rw-r--r--library/src/scala/Function26.scala20
-rw-r--r--library/src/scala/Function27.scala20
-rw-r--r--library/src/scala/Function28.scala20
-rw-r--r--library/src/scala/Function29.scala20
-rw-r--r--library/src/scala/Function30.scala20
-rw-r--r--library/src/scala/FunctionXXL.scala9
-rw-r--r--tests/pos/functionXXL.scala72
-rw-r--r--tests/pos/lazyValsSepComp.scala2
18 files changed, 307 insertions, 261 deletions
diff --git a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala
index a7c449947..397382c2f 100644
--- a/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala
+++ b/compiler/src/dotty/tools/backend/jvm/DottyBackendInterface.scala
@@ -140,7 +140,7 @@ class DottyBackendInterface(outputDirectory: AbstractFile, val superCallsMap: Ma
val externalEqualsNumChar: Symbol = NoSymbol // ctx.requiredMethod(BoxesRunTimeTypeRef, nme.equalsNumChar) // this method is private
val externalEqualsNumObject: Symbol = defn.BoxesRunTimeModule.requiredMethod(nme.equalsNumObject)
val externalEquals: Symbol = defn.BoxesRunTimeClass.info.decl(nme.equals_).suchThat(toDenot(_).info.firstParamTypes.size == 2).symbol
- val MaxFunctionArity: Int = Definitions.MaxFunctionArity
+ val MaxFunctionArity: Int = Definitions.MaxImplementedFunctionArity
val FunctionClass: Array[Symbol] = defn.FunctionClassPerRun()
val AbstractFunctionClass: Array[Symbol] = defn.AbstractFunctionClassPerRun()
val PartialFunctionClass: Symbol = defn.PartialFunctionClass
diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala
index c5ccab261..e4e5761b2 100644
--- a/compiler/src/dotty/tools/dotc/core/Definitions.scala
+++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala
@@ -12,13 +12,20 @@ import collection.mutable
import scala.reflect.api.{ Universe => ApiUniverse }
object Definitions {
- val MaxTupleArity, MaxAbstractFunctionArity = 22
- val MaxFunctionArity = 30
- // Awaiting a definite solution that drops the limit altogether, 30 gives a safety
- // margin over the previous 22, so that treecopiers in miniphases are allowed to
- // temporarily create larger closures. This is needed in lambda lift where large closures
- // are first formed by treecopiers before they are split apart into parameters and
- // environment in the lambdalift transform itself.
+
+ /** The maximum number of elements in a tuple or product.
+ * This should be removed once we go to hlists.
+ */
+ val MaxTupleArity = 22
+
+ /** The maximum arity N of a function type that's implemented
+ * as a trait `scala.FunctionN`. Functions of higher arity are possible,
+ * but are mapped in erasure to functions taking a single parameter of type
+ * Object[].
+ * The limit 22 is chosen for Scala2x interop. It could be something
+ * else without affecting the set of programs that can be compiled.
+ */
+ val MaxImplementedFunctionArity = 22
}
/** A class defining symbols and types of standard definitions
@@ -45,32 +52,29 @@ class Definitions {
ctx.newSymbol(owner, name, flags | Permanent, info)
private def newClassSymbol(owner: Symbol, name: TypeName, flags: FlagSet, infoFn: ClassSymbol => Type) =
- ctx.newClassSymbol(owner, name, flags | Permanent, infoFn).entered
+ ctx.newClassSymbol(owner, name, flags | Permanent, infoFn)
- private def newCompleteClassSymbol(owner: Symbol, name: TypeName, flags: FlagSet, parents: List[TypeRef], decls: Scope = newScope) =
+ private def enterCompleteClassSymbol(owner: Symbol, name: TypeName, flags: FlagSet, parents: List[TypeRef], decls: Scope = newScope) =
ctx.newCompleteClassSymbol(owner, name, flags | Permanent, parents, decls).entered
- private def newTopClassSymbol(name: TypeName, flags: FlagSet, parents: List[TypeRef]) =
- completeClass(newCompleteClassSymbol(ScalaPackageClass, name, flags, parents))
-
- private def newTypeField(cls: ClassSymbol, name: TypeName, flags: FlagSet, scope: MutableScope) =
+ private def enterTypeField(cls: ClassSymbol, name: TypeName, flags: FlagSet, scope: MutableScope) =
scope.enter(newSymbol(cls, name, flags, TypeBounds.empty))
- private def newTypeParam(cls: ClassSymbol, name: TypeName, flags: FlagSet, scope: MutableScope) =
- newTypeField(cls, name, flags | ClassTypeParamCreationFlags, scope)
+ private def enterTypeParam(cls: ClassSymbol, name: TypeName, flags: FlagSet, scope: MutableScope) =
+ enterTypeField(cls, name, flags | ClassTypeParamCreationFlags, scope)
- private def newSyntheticTypeParam(cls: ClassSymbol, scope: MutableScope, paramFlags: FlagSet, suffix: String = "T0") =
- newTypeParam(cls, suffix.toTypeName.expandedName(cls), ExpandedName | paramFlags, scope)
+ private def enterSyntheticTypeParam(cls: ClassSymbol, paramFlags: FlagSet, scope: MutableScope, suffix: String = "T0") =
+ enterTypeParam(cls, suffix.toTypeName.expandedName(cls), ExpandedName | paramFlags, scope)
// NOTE: Ideally we would write `parentConstrs: => Type*` but SIP-24 is only
// implemented in Dotty and not in Scala 2.
// See <http://docs.scala-lang.org/sips/pending/repeated-byname.html>.
- private def specialPolyClass(name: TypeName, paramFlags: FlagSet, parentConstrs: => Seq[Type]): ClassSymbol = {
+ private def enterSpecialPolyClass(name: TypeName, paramFlags: FlagSet, parentConstrs: => Seq[Type]): ClassSymbol = {
val completer = new LazyType {
def complete(denot: SymDenotation)(implicit ctx: Context): Unit = {
val cls = denot.asClass.classSymbol
val paramDecls = newScope
- val typeParam = newSyntheticTypeParam(cls, paramDecls, paramFlags)
+ val typeParam = enterSyntheticTypeParam(cls, paramFlags, paramDecls)
def instantiate(tpe: Type) =
if (tpe.typeParams.nonEmpty) tpe.appliedTo(typeParam.typeRef)
else tpe
@@ -79,31 +83,54 @@ class Definitions {
denot.info = ClassInfo(ScalaPackageClass.thisType, cls, parentRefs, paramDecls)
}
}
- newClassSymbol(ScalaPackageClass, name, EmptyFlags, completer)
+ newClassSymbol(ScalaPackageClass, name, EmptyFlags, completer).entered
+ }
+
+ /** The trait FunctionN, for some N */
+ private def newFunctionNTrait(n: Int) = {
+ val completer = new LazyType {
+ def complete(denot: SymDenotation)(implicit ctx: Context): Unit = {
+ val cls = denot.asClass.classSymbol
+ val decls = newScope
+ val argParams =
+ for (i <- List.range(0, n)) yield
+ enterTypeParam(cls, s"T$i".toTypeName, Contravariant, decls)
+ val resParam = enterTypeParam(cls, s"R".toTypeName, Covariant, decls)
+ val applyMeth =
+ decls.enter(
+ newMethod(cls, nme.apply,
+ MethodType(argParams.map(_.typeRef), resParam.typeRef), Deferred))
+ denot.info = ClassInfo(ScalaPackageClass.thisType, cls, ObjectType :: Nil, decls)
+ }
+ }
+ newClassSymbol(ScalaPackageClass, s"Function$n".toTypeName, Trait, completer)
}
private def newMethod(cls: ClassSymbol, name: TermName, info: Type, flags: FlagSet = EmptyFlags): TermSymbol =
- newSymbol(cls, name.encode, flags | Method, info).entered.asTerm
+ newSymbol(cls, name.encode, flags | Method, info).asTerm
- private def newAliasType(name: TypeName, tpe: Type, flags: FlagSet = EmptyFlags): TypeSymbol = {
+ private def enterMethod(cls: ClassSymbol, name: TermName, info: Type, flags: FlagSet = EmptyFlags): TermSymbol =
+ newMethod(cls, name, info, flags).entered
+
+ private def enterAliasType(name: TypeName, tpe: Type, flags: FlagSet = EmptyFlags): TypeSymbol = {
val sym = newSymbol(ScalaPackageClass, name, flags, TypeAlias(tpe))
ScalaPackageClass.currentPackageDecls.enter(sym)
sym
}
- private def newPolyMethod(cls: ClassSymbol, name: TermName, typeParamCount: Int,
+ private def enterPolyMethod(cls: ClassSymbol, name: TermName, typeParamCount: Int,
resultTypeFn: PolyType => Type, flags: FlagSet = EmptyFlags) = {
val tparamNames = tpnme.syntheticTypeParamNames(typeParamCount)
val tparamBounds = tparamNames map (_ => TypeBounds.empty)
val ptype = PolyType(tparamNames)(_ => tparamBounds, resultTypeFn)
- newMethod(cls, name, ptype, flags)
+ enterMethod(cls, name, ptype, flags)
}
- private def newT1ParameterlessMethod(cls: ClassSymbol, name: TermName, resultTypeFn: PolyType => Type, flags: FlagSet) =
- newPolyMethod(cls, name, 1, resultTypeFn, flags)
+ private def enterT1ParameterlessMethod(cls: ClassSymbol, name: TermName, resultTypeFn: PolyType => Type, flags: FlagSet) =
+ enterPolyMethod(cls, name, 1, resultTypeFn, flags)
- private def newT1EmptyParamsMethod(cls: ClassSymbol, name: TermName, resultTypeFn: PolyType => Type, flags: FlagSet) =
- newPolyMethod(cls, name, 1, pt => MethodType(Nil, resultTypeFn(pt)), flags)
+ private def enterT1EmptyParamsMethod(cls: ClassSymbol, name: TermName, resultTypeFn: PolyType => Type, flags: FlagSet) =
+ enterPolyMethod(cls, name, 1, pt => MethodType(Nil, resultTypeFn(pt)), flags)
private def mkArityArray(name: String, arity: Int, countFrom: Int): Array[TypeRef] = {
val arr = new Array[TypeRef](arity + 1)
@@ -172,20 +199,20 @@ class Definitions {
* def getClass: java.lang.Class[T] = ???
* }
*/
- lazy val AnyClass: ClassSymbol = completeClass(newCompleteClassSymbol(ScalaPackageClass, tpnme.Any, Abstract, Nil))
+ lazy val AnyClass: ClassSymbol = completeClass(enterCompleteClassSymbol(ScalaPackageClass, tpnme.Any, Abstract, Nil))
def AnyType = AnyClass.typeRef
- lazy val AnyValClass: ClassSymbol = completeClass(newCompleteClassSymbol(ScalaPackageClass, tpnme.AnyVal, Abstract, List(AnyClass.typeRef)))
+ lazy val AnyValClass: ClassSymbol = completeClass(enterCompleteClassSymbol(ScalaPackageClass, tpnme.AnyVal, Abstract, List(AnyClass.typeRef)))
def AnyValType = AnyValClass.typeRef
- lazy val Any_== = newMethod(AnyClass, nme.EQ, methOfAny(BooleanType), Final)
- lazy val Any_!= = newMethod(AnyClass, nme.NE, methOfAny(BooleanType), Final)
- lazy val Any_equals = newMethod(AnyClass, nme.equals_, methOfAny(BooleanType))
- lazy val Any_hashCode = newMethod(AnyClass, nme.hashCode_, MethodType(Nil, IntType))
- lazy val Any_toString = newMethod(AnyClass, nme.toString_, MethodType(Nil, StringType))
- lazy val Any_## = newMethod(AnyClass, nme.HASHHASH, ExprType(IntType), Final)
- lazy val Any_getClass = newMethod(AnyClass, nme.getClass_, MethodType(Nil, ClassClass.typeRef.appliedTo(TypeBounds.empty)), Final)
- lazy val Any_isInstanceOf = newT1ParameterlessMethod(AnyClass, nme.isInstanceOf_, _ => BooleanType, Final)
- lazy val Any_asInstanceOf = newT1ParameterlessMethod(AnyClass, nme.asInstanceOf_, PolyParam(_, 0), Final)
+ lazy val Any_== = enterMethod(AnyClass, nme.EQ, methOfAny(BooleanType), Final)
+ lazy val Any_!= = enterMethod(AnyClass, nme.NE, methOfAny(BooleanType), Final)
+ lazy val Any_equals = enterMethod(AnyClass, nme.equals_, methOfAny(BooleanType))
+ lazy val Any_hashCode = enterMethod(AnyClass, nme.hashCode_, MethodType(Nil, IntType))
+ lazy val Any_toString = enterMethod(AnyClass, nme.toString_, MethodType(Nil, StringType))
+ lazy val Any_## = enterMethod(AnyClass, nme.HASHHASH, ExprType(IntType), Final)
+ lazy val Any_getClass = enterMethod(AnyClass, nme.getClass_, MethodType(Nil, ClassClass.typeRef.appliedTo(TypeBounds.empty)), Final)
+ lazy val Any_isInstanceOf = enterT1ParameterlessMethod(AnyClass, nme.isInstanceOf_, _ => BooleanType, Final)
+ lazy val Any_asInstanceOf = enterT1ParameterlessMethod(AnyClass, nme.asInstanceOf_, PolyParam(_, 0), Final)
def AnyMethods = List(Any_==, Any_!=, Any_equals, Any_hashCode,
Any_toString, Any_##, Any_getClass, Any_isInstanceOf, Any_asInstanceOf)
@@ -205,37 +232,37 @@ class Definitions {
}
def ObjectType = ObjectClass.typeRef
- lazy val AnyRefAlias: TypeSymbol = newAliasType(tpnme.AnyRef, ObjectType)
+ lazy val AnyRefAlias: TypeSymbol = enterAliasType(tpnme.AnyRef, ObjectType)
def AnyRefType = AnyRefAlias.typeRef
- lazy val Object_eq = newMethod(ObjectClass, nme.eq, methOfAnyRef(BooleanType), Final)
- lazy val Object_ne = newMethod(ObjectClass, nme.ne, methOfAnyRef(BooleanType), Final)
- lazy val Object_synchronized = newPolyMethod(ObjectClass, nme.synchronized_, 1,
+ lazy val Object_eq = enterMethod(ObjectClass, nme.eq, methOfAnyRef(BooleanType), Final)
+ lazy val Object_ne = enterMethod(ObjectClass, nme.ne, methOfAnyRef(BooleanType), Final)
+ lazy val Object_synchronized = enterPolyMethod(ObjectClass, nme.synchronized_, 1,
pt => MethodType(List(PolyParam(pt, 0)), PolyParam(pt, 0)), Final)
- lazy val Object_clone = newMethod(ObjectClass, nme.clone_, MethodType(Nil, ObjectType), Protected)
- lazy val Object_finalize = newMethod(ObjectClass, nme.finalize_, MethodType(Nil, UnitType), Protected)
- lazy val Object_notify = newMethod(ObjectClass, nme.notify_, MethodType(Nil, UnitType))
- lazy val Object_notifyAll = newMethod(ObjectClass, nme.notifyAll_, MethodType(Nil, UnitType))
- lazy val Object_wait = newMethod(ObjectClass, nme.wait_, MethodType(Nil, UnitType))
- lazy val Object_waitL = newMethod(ObjectClass, nme.wait_, MethodType(LongType :: Nil, UnitType))
- lazy val Object_waitLI = newMethod(ObjectClass, nme.wait_, MethodType(LongType :: IntType :: Nil, UnitType))
+ lazy val Object_clone = enterMethod(ObjectClass, nme.clone_, MethodType(Nil, ObjectType), Protected)
+ lazy val Object_finalize = enterMethod(ObjectClass, nme.finalize_, MethodType(Nil, UnitType), Protected)
+ lazy val Object_notify = enterMethod(ObjectClass, nme.notify_, MethodType(Nil, UnitType))
+ lazy val Object_notifyAll = enterMethod(ObjectClass, nme.notifyAll_, MethodType(Nil, UnitType))
+ lazy val Object_wait = enterMethod(ObjectClass, nme.wait_, MethodType(Nil, UnitType))
+ lazy val Object_waitL = enterMethod(ObjectClass, nme.wait_, MethodType(LongType :: Nil, UnitType))
+ lazy val Object_waitLI = enterMethod(ObjectClass, nme.wait_, MethodType(LongType :: IntType :: Nil, UnitType))
def ObjectMethods = List(Object_eq, Object_ne, Object_synchronized, Object_clone,
Object_finalize, Object_notify, Object_notifyAll, Object_wait, Object_waitL, Object_waitLI)
/** Dummy method needed by elimByName */
- lazy val dummyApply = newPolyMethod(
+ lazy val dummyApply = enterPolyMethod(
OpsPackageClass, nme.dummyApply, 1,
pt => MethodType(List(FunctionOf(Nil, PolyParam(pt, 0))), PolyParam(pt, 0)))
/** Method representing a throw */
- lazy val throwMethod = newMethod(OpsPackageClass, nme.THROWkw,
+ lazy val throwMethod = enterMethod(OpsPackageClass, nme.THROWkw,
MethodType(List(ThrowableType), NothingType))
- lazy val NothingClass: ClassSymbol = newCompleteClassSymbol(
+ lazy val NothingClass: ClassSymbol = enterCompleteClassSymbol(
ScalaPackageClass, tpnme.Nothing, AbstractFinal, List(AnyClass.typeRef))
def NothingType = NothingClass.typeRef
- lazy val NullClass: ClassSymbol = newCompleteClassSymbol(
+ lazy val NullClass: ClassSymbol = enterCompleteClassSymbol(
ScalaPackageClass, tpnme.Null, AbstractFinal, List(ObjectClass.typeRef))
def NullType = NullClass.typeRef
@@ -281,7 +308,7 @@ class Definitions {
lazy val SingletonClass: ClassSymbol =
// needed as a synthetic class because Scala 2.x refers to it in classfiles
// but does not define it as an explicit class.
- newCompleteClassSymbol(
+ enterCompleteClassSymbol(
ScalaPackageClass, tpnme.Singleton, PureInterfaceCreationFlags | Final,
List(AnyClass.typeRef), EmptyScope)
@@ -387,17 +414,17 @@ class Definitions {
lazy val BoxedDoubleModule = ctx.requiredModule("java.lang.Double")
lazy val BoxedUnitModule = ctx.requiredModule("java.lang.Void")
- lazy val ByNameParamClass2x = specialPolyClass(tpnme.BYNAME_PARAM_CLASS, Covariant, Seq(AnyType))
- lazy val EqualsPatternClass = specialPolyClass(tpnme.EQUALS_PATTERN, EmptyFlags, Seq(AnyType))
+ lazy val ByNameParamClass2x = enterSpecialPolyClass(tpnme.BYNAME_PARAM_CLASS, Covariant, Seq(AnyType))
+ lazy val EqualsPatternClass = enterSpecialPolyClass(tpnme.EQUALS_PATTERN, EmptyFlags, Seq(AnyType))
- lazy val RepeatedParamClass = specialPolyClass(tpnme.REPEATED_PARAM_CLASS, Covariant, Seq(ObjectType, SeqType))
+ lazy val RepeatedParamClass = enterSpecialPolyClass(tpnme.REPEATED_PARAM_CLASS, Covariant, Seq(ObjectType, SeqType))
// fundamental classes
lazy val StringClass = ctx.requiredClass("java.lang.String")
def StringType: Type = StringClass.typeRef
lazy val StringModule = StringClass.linkedClass
- lazy val String_+ = newMethod(StringClass, nme.raw.PLUS, methOfAny(StringType), Final)
+ lazy val String_+ = enterMethod(StringClass, nme.raw.PLUS, methOfAny(StringType), Final)
lazy val String_valueOf_Object = StringModule.info.member(nme.valueOf).suchThat(_.info.firstParamTypes match {
case List(pt) => (pt isRef AnyClass) || (pt isRef ObjectClass)
case _ => false
@@ -431,6 +458,9 @@ class Definitions {
def PartialFunctionClass(implicit ctx: Context) = PartialFunctionType.symbol.asClass
lazy val AbstractPartialFunctionType: TypeRef = ctx.requiredClassRef("scala.runtime.AbstractPartialFunction")
def AbstractPartialFunctionClass(implicit ctx: Context) = AbstractPartialFunctionType.symbol.asClass
+ lazy val FunctionXXLType: TypeRef = ctx.requiredClassRef("scala.FunctionXXL")
+ def FunctionXXLClass(implicit ctx: Context) = FunctionXXLType.symbol.asClass
+
lazy val SymbolType: TypeRef = ctx.requiredClassRef("scala.Symbol")
def SymbolClass(implicit ctx: Context) = SymbolType.symbol.asClass
lazy val DynamicType: TypeRef = ctx.requiredClassRef("scala.Dynamic")
@@ -562,14 +592,15 @@ class Definitions {
object FunctionOf {
def apply(args: List[Type], resultType: Type)(implicit ctx: Context) =
FunctionType(args.length).appliedTo(args ::: resultType :: Nil)
- def unapply(ft: Type)(implicit ctx: Context)/*: Option[(List[Type], Type)]*/ = {
- // -language:keepUnions difference: unapply needs result type because inferred type
- // is Some[(List[Type], Type)] | None, which is not a legal unapply type.
+ def unapply(ft: Type)(implicit ctx: Context) = {
val tsym = ft.typeSymbol
- lazy val targs = ft.argInfos
- val numArgs = targs.length - 1
- if (numArgs >= 0 && numArgs <= MaxFunctionArity &&
- (FunctionType(numArgs).symbol == tsym)) Some(targs.init, targs.last)
+ if (isFunctionClass(tsym)) {
+ lazy val targs = ft.argInfos
+ val numArgs = targs.length - 1
+ if (numArgs >= 0 && FunctionType(numArgs).symbol == tsym)
+ Some(targs.init, targs.last)
+ else None
+ }
else None
}
}
@@ -612,19 +643,26 @@ class Definitions {
// ----- Symbol sets ---------------------------------------------------
- lazy val AbstractFunctionType = mkArityArray("scala.runtime.AbstractFunction", MaxAbstractFunctionArity, 0)
+ lazy val AbstractFunctionType = mkArityArray("scala.runtime.AbstractFunction", MaxImplementedFunctionArity, 0)
val AbstractFunctionClassPerRun = new PerRun[Array[Symbol]](implicit ctx => AbstractFunctionType.map(_.symbol.asClass))
def AbstractFunctionClass(n: Int)(implicit ctx: Context) = AbstractFunctionClassPerRun()(ctx)(n)
- lazy val FunctionType = mkArityArray("scala.Function", MaxFunctionArity, 0)
- def FunctionClassPerRun = new PerRun[Array[Symbol]](implicit ctx => FunctionType.map(_.symbol.asClass))
- def FunctionClass(n: Int)(implicit ctx: Context) = FunctionClassPerRun()(ctx)(n)
- lazy val Function0_applyR = FunctionType(0).symbol.requiredMethodRef(nme.apply)
- def Function0_apply(implicit ctx: Context) = Function0_applyR.symbol
+ private lazy val ImplementedFunctionType = mkArityArray("scala.Function", MaxImplementedFunctionArity, 0)
+ def FunctionClassPerRun = new PerRun[Array[Symbol]](implicit ctx => ImplementedFunctionType.map(_.symbol.asClass))
lazy val TupleType = mkArityArray("scala.Tuple", MaxTupleArity, 2)
lazy val ProductNType = mkArityArray("scala.Product", MaxTupleArity, 0)
- private lazy val FunctionTypes: Set[TypeRef] = FunctionType.toSet
+ def FunctionClass(n: Int)(implicit ctx: Context) =
+ if (n < MaxImplementedFunctionArity) FunctionClassPerRun()(ctx)(n)
+ else ctx.requiredClass("scala.Function" + n.toString)
+
+ lazy val Function0_applyR = ImplementedFunctionType(0).symbol.requiredMethodRef(nme.apply)
+ def Function0_apply(implicit ctx: Context) = Function0_applyR.symbol
+
+ def FunctionType(n: Int)(implicit ctx: Context): TypeRef =
+ if (n < MaxImplementedFunctionArity) ImplementedFunctionType(n)
+ else FunctionClass(n).typeRef
+
private lazy val TupleTypes: Set[TypeRef] = TupleType.toSet
private lazy val ProductTypes: Set[TypeRef] = ProductNType.toSet
@@ -646,6 +684,8 @@ class Definitions {
tp.derivesFrom(NothingClass) || tp.derivesFrom(NullClass)
def isFunctionClass(cls: Symbol) = isVarArityClass(cls, tpnme.Function)
+ def isUnimplementedFunctionClass(cls: Symbol) =
+ isFunctionClass(cls) && cls.name.functionArity > MaxImplementedFunctionArity
def isAbstractFunctionClass(cls: Symbol) = isVarArityClass(cls, tpnme.AbstractFunction)
def isTupleClass(cls: Symbol) = isVarArityClass(cls, tpnme.Tuple)
def isProductClass(cls: Symbol) = isVarArityClass(cls, tpnme.Product)
@@ -695,10 +735,11 @@ class Definitions {
def isProductSubType(tp: Type)(implicit ctx: Context) =
(tp derivesFrom ProductType.symbol) && tp.baseClasses.exists(isProductClass)
- def isFunctionType(tp: Type)(implicit ctx: Context) = {
- val arity = functionArity(tp)
- 0 <= arity && arity <= MaxFunctionArity && (tp isRef FunctionType(arity).symbol)
- }
+ def isFunctionType(tp: Type)(implicit ctx: Context) =
+ isFunctionClass(tp.dealias.typeSymbol) && {
+ val arity = functionArity(tp)
+ arity >= 0 && tp.isRef(FunctionType(functionArity(tp)).typeSymbol)
+ }
def functionArity(tp: Type)(implicit ctx: Context) = tp.dealias.argInfos.length - 1
@@ -774,6 +815,23 @@ class Definitions {
// ----- Initialization ---------------------------------------------------
+ /** Give the scala package a scope where a FunctionN trait is automatically
+ * added when someone looks for it.
+ */
+ private def makeScalaSpecial()(implicit ctx: Context) = {
+ val oldInfo = ScalaPackageClass.classInfo
+ val oldDecls = oldInfo.decls
+ val newDecls = new MutableScope(oldDecls) {
+ override def lookupEntry(name: Name)(implicit ctx: Context): ScopeEntry = {
+ val res = super.lookupEntry(name)
+ if (res == null && name.functionArity > 0)
+ newScopeEntry(newFunctionNTrait(name.functionArity))
+ else res
+ }
+ }
+ ScalaPackageClass.info = oldInfo.derivedClassInfo(decls = newDecls)
+ }
+
/** Lists core classes that don't have underlying bytecode, but are synthesized on-the-fly in every reflection universe */
lazy val syntheticScalaClasses = List(
AnyClass,
@@ -801,6 +859,8 @@ class Definitions {
def init()(implicit ctx: Context) = {
this.ctx = ctx
if (!_isInitialized) {
+ makeScalaSpecial()
+
// force initialization of every symbol that is synthesized or hijacked by the compiler
val forced = syntheticCoreClasses ++ syntheticCoreMethods ++ ScalaValueClasses()
diff --git a/compiler/src/dotty/tools/dotc/core/NameOps.scala b/compiler/src/dotty/tools/dotc/core/NameOps.scala
index 4c7f5b0a9..7a4fc0512 100644
--- a/compiler/src/dotty/tools/dotc/core/NameOps.scala
+++ b/compiler/src/dotty/tools/dotc/core/NameOps.scala
@@ -229,6 +229,12 @@ object NameOps {
}
}
+ def functionArity: Int =
+ if (name.startsWith(tpnme.Function))
+ try name.drop(tpnme.Function.length).toString.toInt
+ catch { case ex: NumberFormatException => -1 }
+ else -1
+
/** The name of the generic runtime operation corresponding to an array operation */
def genericArrayOp: TermName = name match {
case nme.apply => nme.array_apply
diff --git a/compiler/src/dotty/tools/dotc/core/Scopes.scala b/compiler/src/dotty/tools/dotc/core/Scopes.scala
index 3daa8117e..6090079e5 100644
--- a/compiler/src/dotty/tools/dotc/core/Scopes.scala
+++ b/compiler/src/dotty/tools/dotc/core/Scopes.scala
@@ -309,7 +309,7 @@ object Scopes {
/** Lookup a symbol entry matching given name.
*/
- override final def lookupEntry(name: Name)(implicit ctx: Context): ScopeEntry = {
+ override def lookupEntry(name: Name)(implicit ctx: Context): ScopeEntry = {
var e: ScopeEntry = null
if (hashTable ne null) {
e = hashTable(name.hashCode & (hashTable.length - 1))
diff --git a/compiler/src/dotty/tools/dotc/core/StdNames.scala b/compiler/src/dotty/tools/dotc/core/StdNames.scala
index c2a14b36f..741ff8b1f 100644
--- a/compiler/src/dotty/tools/dotc/core/StdNames.scala
+++ b/compiler/src/dotty/tools/dotc/core/StdNames.scala
@@ -265,6 +265,7 @@ object StdNames {
val THIS: N = "_$this"
val TRAIT_CONSTRUCTOR: N = "$init$"
val U2EVT: N = "u2evt$"
+ val ALLARGS: N = "$allArgs"
final val Nil: N = "Nil"
final val Predef: N = "Predef"
diff --git a/compiler/src/dotty/tools/dotc/core/TypeErasure.scala b/compiler/src/dotty/tools/dotc/core/TypeErasure.scala
index abbacee49..57397a8bc 100644
--- a/compiler/src/dotty/tools/dotc/core/TypeErasure.scala
+++ b/compiler/src/dotty/tools/dotc/core/TypeErasure.scala
@@ -7,6 +7,7 @@ import Uniques.unique
import dotc.transform.ExplicitOuter._
import dotc.transform.ValueClasses._
import util.DotClass
+import Definitions.MaxImplementedFunctionArity
/** Erased types are:
*
@@ -38,7 +39,10 @@ object TypeErasure {
case _: ErasedValueType =>
true
case tp: TypeRef =>
- tp.symbol.isClass && tp.symbol != defn.AnyClass && tp.symbol != defn.ArrayClass
+ val sym = tp.symbol
+ sym.isClass &&
+ sym != defn.AnyClass && sym != defn.ArrayClass &&
+ !defn.isUnimplementedFunctionClass(sym)
case _: TermRef =>
true
case JavaArrayType(elem) =>
@@ -176,8 +180,13 @@ object TypeErasure {
else if (sym.isAbstractType) TypeAlias(WildcardType)
else if (sym.isConstructor) outer.addParam(sym.owner.asClass, erase(tp)(erasureCtx))
else erase.eraseInfo(tp, sym)(erasureCtx) match {
- case einfo: MethodType if sym.isGetter && einfo.resultType.isRef(defn.UnitClass) =>
- MethodType(Nil, defn.BoxedUnitType)
+ case einfo: MethodType =>
+ if (sym.isGetter && einfo.resultType.isRef(defn.UnitClass))
+ MethodType(Nil, defn.BoxedUnitType)
+ else if (sym.isAnonymousFunction && einfo.paramTypes.length > MaxImplementedFunctionArity)
+ MethodType(nme.ALLARGS :: Nil, JavaArrayType(defn.ObjectType) :: Nil, einfo.resultType)
+ else
+ einfo
case einfo =>
einfo
}
@@ -317,6 +326,7 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
* - For a term ref p.x, the type <noprefix> # x.
* - For a typeref scala.Any, scala.AnyVal or scala.Singleton: |java.lang.Object|
* - For a typeref scala.Unit, |scala.runtime.BoxedUnit|.
+ * - For a typeref scala.FunctionN, where N > MaxImplementedFunctionArity, scala.FunctionXXL
* - For a typeref P.C where C refers to a class, <noprefix> # C.
* - For a typeref P.C where C refers to an alias type, the erasure of C's alias.
* - For a typeref P.C where C refers to an abstract type, the erasure of C's upper bound.
@@ -345,6 +355,7 @@ class TypeErasure(isJava: Boolean, semiEraseVCs: Boolean, isConstructor: Boolean
if (!sym.isClass) this(tp.info)
else if (semiEraseVCs && isDerivedValueClass(sym)) eraseDerivedValueClassRef(tp)
else if (sym == defn.ArrayClass) apply(tp.appliedTo(TypeBounds.empty)) // i966 shows that we can hit a raw Array type.
+ else if (defn.isUnimplementedFunctionClass(sym)) defn.FunctionXXLType
else eraseNormalClassRef(tp)
case tp: RefinedType =>
val parent = tp.parent
diff --git a/compiler/src/dotty/tools/dotc/transform/Erasure.scala b/compiler/src/dotty/tools/dotc/transform/Erasure.scala
index 069176111..d1f5bd532 100644
--- a/compiler/src/dotty/tools/dotc/transform/Erasure.scala
+++ b/compiler/src/dotty/tools/dotc/transform/Erasure.scala
@@ -13,6 +13,7 @@ import core.StdNames._
import core.NameOps._
import core.Decorators._
import core.Constants._
+import core.Definitions._
import typer.NoChecking
import typer.ProtoTypes._
import typer.ErrorReporting._
@@ -36,9 +37,17 @@ class Erasure extends Phase with DenotTransformer { thisTransformer =>
def transform(ref: SingleDenotation)(implicit ctx: Context): SingleDenotation = ref match {
case ref: SymDenotation =>
+ def isCompacted(sym: Symbol) =
+ sym.isAnonymousFunction && {
+ sym.info(ctx.withPhase(ctx.phase.next)) match {
+ case MethodType(nme.ALLARGS :: Nil, _) => true
+ case _ => false
+ }
+ }
+
assert(ctx.phase == this, s"transforming $ref at ${ctx.phase}")
if (ref.symbol eq defn.ObjectClass) {
- // Aftre erasure, all former Any members are now Object members
+ // After erasure, all former Any members are now Object members
val ClassInfo(pre, _, ps, decls, selfInfo) = ref.info
val extendedScope = decls.cloneScope
for (decl <- defn.AnyClass.classInfo.decls)
@@ -59,7 +68,10 @@ class Erasure extends Phase with DenotTransformer { thisTransformer =>
val oldInfo = ref.info
val newInfo = transformInfo(ref.symbol, oldInfo)
val oldFlags = ref.flags
- val newFlags = ref.flags &~ Flags.HasDefaultParams // HasDefaultParams needs to be dropped because overriding might become overloading
+ val newFlags =
+ if (oldSymbol.is(Flags.TermParam) && isCompacted(oldSymbol.owner)) oldFlags &~ Flags.Param
+ else oldFlags &~ Flags.HasDefaultParams // HasDefaultParams needs to be dropped because overriding might become overloading
+
// TODO: define derivedSymDenotation?
if ((oldSymbol eq newSymbol) && (oldOwner eq newOwner) && (oldInfo eq newInfo) && (oldFlags == newFlags)) ref
else {
@@ -331,8 +343,23 @@ object Erasure extends TypeTestsCasts{
* e.m -> e.[]m if `m` is an array operation other than `clone`.
*/
override def typedSelect(tree: untpd.Select, pt: Type)(implicit ctx: Context): Tree = {
- val sym = tree.symbol
- assert(sym.exists, tree.show)
+
+ def mapOwner(sym: Symbol): Symbol = {
+ val owner = sym.owner
+ if ((owner eq defn.AnyClass) || (owner eq defn.AnyValClass)) {
+ assert(sym.isConstructor, s"${sym.showLocated}")
+ defn.ObjectClass
+ }
+ else if (defn.isUnimplementedFunctionClass(owner))
+ defn.FunctionXXLClass
+ else
+ owner
+ }
+
+ var sym = tree.symbol
+ val owner = mapOwner(sym)
+ if (owner ne sym.owner) sym = owner.info.decl(sym.name).symbol
+ assert(sym.exists, owner)
def select(qual: Tree, sym: Symbol): Tree = {
val name = tree.typeOpt match {
@@ -366,11 +393,7 @@ object Erasure extends TypeTestsCasts{
def recur(qual: Tree): Tree = {
val qualIsPrimitive = qual.tpe.widen.isPrimitiveValueType
val symIsPrimitive = sym.owner.isPrimitiveValueClass
- if ((sym.owner eq defn.AnyClass) || (sym.owner eq defn.AnyValClass)) {
- assert(sym.isConstructor, s"${sym.showLocated}")
- select(qual, defn.ObjectClass.info.decl(sym.name).symbol)
- }
- else if (qualIsPrimitive && !symIsPrimitive || qual.tpe.widenDealias.isErasedValueType)
+ if (qualIsPrimitive && !symIsPrimitive || qual.tpe.widenDealias.isErasedValueType)
recur(box(qual))
else if (!qualIsPrimitive && symIsPrimitive)
recur(unbox(qual, sym.owner.typeRef))
@@ -423,6 +446,9 @@ object Erasure extends TypeTestsCasts{
}
}
+ /** Besides normal typing, this method collects all arguments
+ * to a compacted function into a single argument of array type.
+ */
override def typedApply(tree: untpd.Apply, pt: Type)(implicit ctx: Context): Tree = {
val Apply(fun, args) = tree
if (fun.symbol == defn.dummyApply)
@@ -434,7 +460,13 @@ object Erasure extends TypeTestsCasts{
fun1.tpe.widen match {
case mt: MethodType =>
val outers = outer.args(fun.asInstanceOf[tpd.Tree]) // can't use fun1 here because its type is already erased
- val args1 = (outers ::: args ++ protoArgs(pt)).zipWithConserve(mt.paramTypes)(typedExpr)
+ var args0 = outers ::: args ++ protoArgs(pt)
+ if (args0.length > MaxImplementedFunctionArity && mt.paramTypes.length == 1) {
+ val bunchedArgs = untpd.JavaSeqLiteral(args0, TypeTree(defn.ObjectType))
+ .withType(defn.ArrayOf(defn.ObjectType))
+ args0 = bunchedArgs :: Nil
+ }
+ val args1 = args0.zipWithConserve(mt.paramTypes)(typedExpr)
untpd.cpy.Apply(tree)(fun1, args1) withType mt.resultType
case _ =>
throw new MatchError(i"tree $tree has unexpected type of function ${fun1.tpe.widen}, was ${fun.typeOpt.widen}")
@@ -470,18 +502,36 @@ object Erasure extends TypeTestsCasts{
super.typedValDef(untpd.cpy.ValDef(vdef)(
tpt = untpd.TypedSplice(TypeTree(sym.info).withPos(vdef.tpt.pos))), sym)
+ /** Besides normal typing, this function also compacts anonymous functions
+ * with more than `MaxImplementedFunctionArity` parameters to ise a single
+ * parameter of type `[]Object`.
+ */
override def typedDefDef(ddef: untpd.DefDef, sym: Symbol)(implicit ctx: Context) = {
val restpe =
if (sym.isConstructor) defn.UnitType
else sym.info.resultType
+ var vparamss1 = (outer.paramDefs(sym) ::: ddef.vparamss.flatten) :: Nil
+ var rhs1 = ddef.rhs match {
+ case id @ Ident(nme.WILDCARD) => untpd.TypedSplice(id.withType(restpe))
+ case _ => ddef.rhs
+ }
+ if (sym.isAnonymousFunction && vparamss1.head.length > MaxImplementedFunctionArity) {
+ val bunchedParam = ctx.newSymbol(sym, nme.ALLARGS, Flags.TermParam, JavaArrayType(defn.ObjectType))
+ def selector(n: Int) = ref(bunchedParam)
+ .select(defn.Array_apply)
+ .appliedTo(Literal(Constant(n)))
+ val paramDefs = vparamss1.head.zipWithIndex.map {
+ case (paramDef, idx) =>
+ assignType(untpd.cpy.ValDef(paramDef)(rhs = selector(idx)), paramDef.symbol)
+ }
+ vparamss1 = (tpd.ValDef(bunchedParam) :: Nil) :: Nil
+ rhs1 = untpd.Block(paramDefs, rhs1)
+ }
val ddef1 = untpd.cpy.DefDef(ddef)(
tparams = Nil,
- vparamss = (outer.paramDefs(sym) ::: ddef.vparamss.flatten) :: Nil,
+ vparamss = vparamss1,
tpt = untpd.TypedSplice(TypeTree(restpe).withPos(ddef.tpt.pos)),
- rhs = ddef.rhs match {
- case id @ Ident(nme.WILDCARD) => untpd.TypedSplice(id.withType(restpe))
- case _ => ddef.rhs
- })
+ rhs = rhs1)
super.typedDefDef(ddef1, sym)
}
diff --git a/library/src/scala/Function23.scala b/library/src/scala/Function23.scala
deleted file mode 100644
index 254772d53..000000000
--- a/library/src/scala/Function23.scala
+++ /dev/null
@@ -1,21 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-package scala
-
-
-/** A function of 23 parameters. Used as a temporary fix until arity limit is dropped.
- *
- */
-trait Function23[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, -T22, -T23, +R] extends AnyRef { self =>
- /** Apply the body of this function to the arguments.
- * @return the result of function application.
- */
- def apply(v1: T1, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6, v7: T7, v8: T8, v9: T9, v10: T10, v11: T11, v12: T12, v13: T13, v14: T14, v15: T15, v16: T16, v17: T17, v18: T18, v19: T19, v20: T20, v21: T21, v22: T22, v23: T23): R
-
- override def toString() = "<function23>"
-}
diff --git a/library/src/scala/Function24.scala b/library/src/scala/Function24.scala
deleted file mode 100644
index 8af8ed995..000000000
--- a/library/src/scala/Function24.scala
+++ /dev/null
@@ -1,21 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-package scala
-
-
-/** A function of 24 parameters. Used as a temporary fix until arity limit is dropped.
- *
- */
-trait Function24[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, -T22, -T23, -T24, +R] extends AnyRef { self =>
- /** Apply the body of this function to the arguments.
- * @return the result of function application.
- */
- def apply(v1: T1, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6, v7: T7, v8: T8, v9: T9, v10: T10, v11: T11, v12: T12, v13: T13, v14: T14, v15: T15, v16: T16, v17: T17, v18: T18, v19: T19, v20: T20, v21: T21, v22: T22, v23: T23, v24: T24): R
-
- override def toString() = "<function24>"
-}
diff --git a/library/src/scala/Function25.scala b/library/src/scala/Function25.scala
deleted file mode 100644
index 6df740b5b..000000000
--- a/library/src/scala/Function25.scala
+++ /dev/null
@@ -1,21 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-package scala
-
-
-/** A function of 25 parameters. Used as a temporary fix until arity limit is dropped.
- *
- */
-trait Function25[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, -T22, -T23, -T24, -T25, +R] extends AnyRef { self =>
- /** Apply the body of this function to the arguments.
- * @return the result of function application.
- */
- def apply(v1: T1, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6, v7: T7, v8: T8, v9: T9, v10: T10, v11: T11, v12: T12, v13: T13, v14: T14, v15: T15, v16: T16, v17: T17, v18: T18, v19: T19, v20: T20, v21: T21, v22: T22, v23: T23, v24: T24, v25: T25): R
-
- override def toString() = "<function25>"
-}
diff --git a/library/src/scala/Function26.scala b/library/src/scala/Function26.scala
deleted file mode 100644
index 5daccb6f0..000000000
--- a/library/src/scala/Function26.scala
+++ /dev/null
@@ -1,20 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-package scala
-
-/** A function of 26 parameters. Used as a temporary fix until arity limit is dropped.
- *
- */
-trait Function26[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, -T22, -T23, -T24, -T25, -T26, +R] extends AnyRef { self =>
- /** Apply the body of this function to the arguments.
- * @return the result of function application.
- */
- def apply(v1: T1, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6, v7: T7, v8: T8, v9: T9, v10: T10, v11: T11, v12: T12, v13: T13, v14: T14, v15: T15, v16: T16, v17: T17, v18: T18, v19: T19, v20: T20, v21: T21, v22: T22, v23: T23, v24: T24, v25: T25, v26: T26): R
-
- override def toString() = "<function26>"
-}
diff --git a/library/src/scala/Function27.scala b/library/src/scala/Function27.scala
deleted file mode 100644
index daebd3ed4..000000000
--- a/library/src/scala/Function27.scala
+++ /dev/null
@@ -1,20 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-package scala
-
-/** A function of 27 parameters. Used as a temporary fix until arity limit is dropped.
- *
- */
-trait Function27[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, -T22, -T23, -T24, -T25, -T26, -T27, +R] extends AnyRef { self =>
- /** Apply the body of this function to the arguments.
- * @return the result of function application.
- */
- def apply(v1: T1, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6, v7: T7, v8: T8, v9: T9, v10: T10, v11: T11, v12: T12, v13: T13, v14: T14, v15: T15, v16: T16, v17: T17, v18: T18, v19: T19, v20: T20, v21: T21, v22: T22, v23: T23, v24: T24, v25: T25, v26: T26, v27: T27): R
-
- override def toString() = "<function27>"
-}
diff --git a/library/src/scala/Function28.scala b/library/src/scala/Function28.scala
deleted file mode 100644
index 82912caea..000000000
--- a/library/src/scala/Function28.scala
+++ /dev/null
@@ -1,20 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-package scala
-
-/** A function of 28 parameters. Used as a temporary fix until arity limit is dropped.
- *
- */
-trait Function28[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, -T22, -T23, -T24, -T25, -T26, -T27, -T28, +R] extends AnyRef { self =>
- /** Apply the body of this function to the arguments.
- * @return the result of function application.
- */
- def apply(v1: T1, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6, v7: T7, v8: T8, v9: T9, v10: T10, v11: T11, v12: T12, v13: T13, v14: T14, v15: T15, v16: T16, v17: T17, v18: T18, v19: T19, v20: T20, v21: T21, v22: T22, v23: T23, v24: T24, v25: T25, v26: T26, v27: T27, v28: T28): R
-
- override def toString() = "<function28>"
-}
diff --git a/library/src/scala/Function29.scala b/library/src/scala/Function29.scala
deleted file mode 100644
index 6dabf2051..000000000
--- a/library/src/scala/Function29.scala
+++ /dev/null
@@ -1,20 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-package scala
-
-/** A function of 29 parameters. Used as a temporary fix until arity limit is dropped.
- *
- */
-trait Function29[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, -T22, -T23, -T24, -T25, -T26, -T27, -T28, -T29, +R] extends AnyRef { self =>
- /** Apply the body of this function to the arguments.
- * @return the result of function application.
- */
- def apply(v1: T1, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6, v7: T7, v8: T8, v9: T9, v10: T10, v11: T11, v12: T12, v13: T13, v14: T14, v15: T15, v16: T16, v17: T17, v18: T18, v19: T19, v20: T20, v21: T21, v22: T22, v23: T23, v24: T24, v25: T25, v26: T26, v27: T27, v28: T28, v29: T29): R
-
- override def toString() = "<function29>"
-}
diff --git a/library/src/scala/Function30.scala b/library/src/scala/Function30.scala
deleted file mode 100644
index 20fd970dd..000000000
--- a/library/src/scala/Function30.scala
+++ /dev/null
@@ -1,20 +0,0 @@
-/* __ *\
-** ________ ___ / / ___ Scala API **
-** / __/ __// _ | / / / _ | (c) 2002-2013, LAMP/EPFL **
-** __\ \/ /__/ __ |/ /__/ __ | http://scala-lang.org/ **
-** /____/\___/_/ |_/____/_/ | | **
-** |/ **
-\* */
-package scala
-
-/** A function of 30 parameters. Used as a temporary fix until arity limit is dropped.
- *
- */
-trait Function30[-T1, -T2, -T3, -T4, -T5, -T6, -T7, -T8, -T9, -T10, -T11, -T12, -T13, -T14, -T15, -T16, -T17, -T18, -T19, -T20, -T21, -T22, -T23, -T24, -T25, -T26, -T27, -T28, -T29, -T30, +R] extends AnyRef { self =>
- /** Apply the body of this function to the arguments.
- * @return the result of function application.
- */
- def apply(v1: T1, v2: T2, v3: T3, v4: T4, v5: T5, v6: T6, v7: T7, v8: T8, v9: T9, v10: T10, v11: T11, v12: T12, v13: T13, v14: T14, v15: T15, v16: T16, v17: T17, v18: T18, v19: T19, v20: T20, v21: T21, v22: T22, v23: T23, v24: T24, v25: T25, v26: T26, v27: T27, v28: T28, v29: T29, v30: T30): R
-
- override def toString() = "<function30>"
-}
diff --git a/library/src/scala/FunctionXXL.scala b/library/src/scala/FunctionXXL.scala
new file mode 100644
index 000000000..25e7af609
--- /dev/null
+++ b/library/src/scala/FunctionXXL.scala
@@ -0,0 +1,9 @@
+package scala
+
+/** A function with all parameters grouped in an array. */
+trait FunctionXXL {
+
+ def apply(xs: Array[Object]): Object
+
+ override def toString() = "<functionXXL>"
+}
diff --git a/tests/pos/functionXXL.scala b/tests/pos/functionXXL.scala
new file mode 100644
index 000000000..1063e4170
--- /dev/null
+++ b/tests/pos/functionXXL.scala
@@ -0,0 +1,72 @@
+object Test {
+
+ val f = (x1: Int,
+ x2: Int,
+ x3: Int,
+ x4: Int,
+ x5: Int,
+ x6: Int,
+ x7: Int,
+ x8: Int,
+ x9: Int,
+ x10: Int,
+ x11: Int,
+ x12: Int,
+ x13: Int,
+ x14: Int,
+ x15: Int,
+ x16: Int,
+ x17: Int,
+ x18: Int,
+ x19: Int,
+ x20: Int,
+ x21: Int,
+ x22: Int,
+ x23: Int,
+ x24: Int,
+ x25: Int,
+ x26: Int) => 42
+
+ def main(args: Array[String]) = {
+ val g = (x1: Int,
+ x2: Int,
+ x3: Int,
+ x4: Int,
+ x5: Int,
+ x6: Int,
+ x7: Int,
+ x8: Int,
+ x9: Int,
+ x10: Int,
+ x11: Int,
+ x12: Int,
+ x13: Int,
+ x14: Int,
+ x15: Int,
+ x16: Int,
+ x17: Int,
+ x18: Int,
+ x19: Int,
+ x20: Int,
+ x21: Int,
+ x22: Int,
+ x23: Int,
+ x24: Int,
+ x25: Int,
+ x26: Int) => f(x1, x2, x3, x4, x5, x6, x7, x8, x9, x10,
+ x11, x12, x13, x14, x15, x16, x17, x18, x19, x20,
+ x21, x22, x23, x24, x25, x26)
+
+
+
+ println(f(1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26))
+
+
+ println(g(1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
+ 11, 12, 13, 14, 15, 16, 17, 18, 19, 20,
+ 21, 22, 23, 24, 25, 26))
+ }
+
+}
diff --git a/tests/pos/lazyValsSepComp.scala b/tests/pos/lazyValsSepComp.scala
index 1a7e37020..048231eb0 100644
--- a/tests/pos/lazyValsSepComp.scala
+++ b/tests/pos/lazyValsSepComp.scala
@@ -12,5 +12,5 @@ import dotty.tools.dotc.core.Contexts._
object Foo {
val definitions: Definitions = null
def defn = definitions
- def go = defn.FunctionType(0)
+ def go = defn.FunctionClassPerRun
}