From b94e6ea5a54d38470e5793c0084785e2d2f9a819 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 30 Nov 2016 14:34:17 +0100 Subject: Drop function 22 limit. Functions with more than 22 parameters are now automatically converted to functions taking a single object array parameter. This has been achieved by tweaking erasure. Other things I have tried that did ot work out well: - Use a single function type in typer. The problem with this one which could not be circumvented was that existing higher-kinded code with e.g. Funcor assumes that Functon1 is a binary type constructor. - Have a late phase that converts to FunctonXXL instead of doing it in erasure. The problem with that one was that potentially every type could be affected, which was ill-suited to the architecture of a miniphase. --- compiler/src/dotty/tools/dotc/core/Definitions.scala | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) (limited to 'compiler/src/dotty/tools/dotc/core/Definitions.scala') diff --git a/compiler/src/dotty/tools/dotc/core/Definitions.scala b/compiler/src/dotty/tools/dotc/core/Definitions.scala index e1a87d1f7..29b7bb60a 100644 --- a/compiler/src/dotty/tools/dotc/core/Definitions.scala +++ b/compiler/src/dotty/tools/dotc/core/Definitions.scala @@ -457,6 +457,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") @@ -645,6 +648,9 @@ class Definitions { 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) + def FunctionClass(n: Int)(implicit ctx: Context) = if (n < MaxImplementedFunctionArity) FunctionClassPerRun()(ctx)(n) else ctx.requiredClass("scala.Function" + n.toString) @@ -652,10 +658,7 @@ class Definitions { lazy val Function0_applyR = ImplementedFunctionType(0).symbol.requiredMethodRef(nme.apply) def Function0_apply(implicit ctx: Context) = Function0_applyR.symbol - lazy val TupleType = mkArityArray("scala.Tuple", MaxTupleArity, 2) - lazy val ProductNType = mkArityArray("scala.Product", MaxTupleArity, 0) - - def FunctionType(n: Int): TypeRef = + def FunctionType(n: Int)(implicit ctx: Context): TypeRef = if (n < MaxImplementedFunctionArity) ImplementedFunctionType(n) else FunctionClass(n).typeRef @@ -680,6 +683,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) -- cgit v1.2.3