@@ -12,13 +12,19 @@ import collection.mutable
12
12
import scala .reflect .api .{ Universe => ApiUniverse }
13
13
14
14
object Definitions {
15
- val MaxTupleArity, MaxAbstractFunctionArity = 22
16
- val MaxFunctionArity = 30
17
- // Awaiting a definite solution that drops the limit altogether, 30 gives a safety
18
- // margin over the previous 22, so that treecopiers in miniphases are allowed to
19
- // temporarily create larger closures. This is needed in lambda lift where large closures
20
- // are first formed by treecopiers before they are split apart into parameters and
21
- // environment in the lambdalift transform itself.
15
+
16
+ /** The maximum number of elements in a tuple or product.
17
+ * This should be removed once we go to hlists.
18
+ */
19
+ val MaxTupleArity = 22
20
+
21
+ /** The maximum arity N of a function type that's implemented
22
+ * as a trait `scala.FunctionN`. Functions of higher arity are possible,
23
+ * but are mapped to functions taking a vararg by erasure.
24
+ * The limit 22 is chosen for Scala2x interop. It could be something
25
+ * else without affecting the set of programs that can be compiled.
26
+ */
27
+ val MaxImplementedFunctionArity = 22
22
28
}
23
29
24
30
/** A class defining symbols and types of standard definitions
@@ -76,7 +82,27 @@ class Definitions {
76
82
denot.info = ClassInfo (ScalaPackageClass .thisType, cls, parentRefs, paramDecls)
77
83
}
78
84
}
79
- newClassSymbol(ScalaPackageClass , name, EmptyFlags , completer)
85
+ newClassSymbol(ScalaPackageClass , name, EmptyFlags , completer).entered
86
+ }
87
+
88
+ /** The trait FunctionN, for some N */
89
+ private def newFunctionNTrait (n : Int ) = {
90
+ val completer = new LazyType {
91
+ def complete (denot : SymDenotation )(implicit ctx : Context ): Unit = {
92
+ val cls = denot.asClass.classSymbol
93
+ val decls = newScope
94
+ val argParams =
95
+ for (i <- List .range(0 , n)) yield
96
+ enterTypeParam(cls, s " T $i" .toTypeName, Contravariant , decls)
97
+ val resParam = enterTypeParam(cls, s " R " .toTypeName, Covariant , decls)
98
+ val applyMeth =
99
+ decls.enter(
100
+ newMethod(cls, nme.apply,
101
+ MethodType (argParams.map(_.typeRef), resParam.typeRef), Deferred ))
102
+ denot.info = ClassInfo (ScalaPackageClass .thisType, cls, ObjectType :: Nil , decls)
103
+ }
104
+ }
105
+ newClassSymbol(ScalaPackageClass , s " Function $n" .toTypeName, Trait , completer)
80
106
}
81
107
82
108
private def newMethod (cls : ClassSymbol , name : TermName , info : Type , flags : FlagSet = EmptyFlags ): TermSymbol =
@@ -562,14 +588,15 @@ class Definitions {
562
588
object FunctionOf {
563
589
def apply (args : List [Type ], resultType : Type )(implicit ctx : Context ) =
564
590
FunctionType (args.length).appliedTo(args ::: resultType :: Nil )
565
- def unapply (ft : Type )(implicit ctx : Context )/* : Option[(List[Type], Type)]*/ = {
566
- // -language:keepUnions difference: unapply needs result type because inferred type
567
- // is Some[(List[Type], Type)] | None, which is not a legal unapply type.
591
+ def unapply (ft : Type )(implicit ctx : Context ) = {
568
592
val tsym = ft.typeSymbol
569
- lazy val targs = ft.argInfos
570
- val numArgs = targs.length - 1
571
- if (numArgs >= 0 && numArgs <= MaxFunctionArity &&
572
- (FunctionType (numArgs).symbol == tsym)) Some (targs.init, targs.last)
593
+ if (isFunctionClass(tsym)) {
594
+ lazy val targs = ft.argInfos
595
+ val numArgs = targs.length - 1
596
+ if (numArgs >= 0 && FunctionType (numArgs).symbol == tsym)
597
+ Some (targs.init, targs.last)
598
+ else None
599
+ }
573
600
else None
574
601
}
575
602
}
@@ -612,19 +639,26 @@ class Definitions {
612
639
613
640
// ----- Symbol sets ---------------------------------------------------
614
641
615
- lazy val AbstractFunctionType = mkArityArray(" scala.runtime.AbstractFunction" , MaxAbstractFunctionArity , 0 )
642
+ lazy val AbstractFunctionType = mkArityArray(" scala.runtime.AbstractFunction" , MaxImplementedFunctionArity , 0 )
616
643
val AbstractFunctionClassPerRun = new PerRun [Array [Symbol ]](implicit ctx => AbstractFunctionType .map(_.symbol.asClass))
617
644
def AbstractFunctionClass (n : Int )(implicit ctx : Context ) = AbstractFunctionClassPerRun ()(ctx)(n)
618
- lazy val FunctionType = mkArityArray(" scala.Function" , MaxFunctionArity , 0 )
619
- def FunctionClassPerRun = new PerRun [Array [Symbol ]](implicit ctx => FunctionType .map(_.symbol.asClass))
620
- def FunctionClass (n : Int )(implicit ctx : Context ) = FunctionClassPerRun ()(ctx)(n)
621
- lazy val Function0_applyR = FunctionType (0 ).symbol.requiredMethodRef(nme.apply)
645
+ private lazy val ImplementedFunctionType = mkArityArray(" scala.Function" , MaxImplementedFunctionArity , 0 )
646
+ def FunctionClassPerRun = new PerRun [Array [Symbol ]](implicit ctx => ImplementedFunctionType .map(_.symbol.asClass))
647
+
648
+ def FunctionClass (n : Int )(implicit ctx : Context ) =
649
+ if (n < MaxImplementedFunctionArity ) FunctionClassPerRun ()(ctx)(n)
650
+ else ctx.requiredClass(" scala.Function" + n.toString)
651
+
652
+ lazy val Function0_applyR = ImplementedFunctionType (0 ).symbol.requiredMethodRef(nme.apply)
622
653
def Function0_apply (implicit ctx : Context ) = Function0_applyR .symbol
623
654
624
655
lazy val TupleType = mkArityArray(" scala.Tuple" , MaxTupleArity , 2 )
625
656
lazy val ProductNType = mkArityArray(" scala.Product" , MaxTupleArity , 0 )
626
657
627
- private lazy val FunctionTypes : Set [TypeRef ] = FunctionType .toSet
658
+ def FunctionType (n : Int ): TypeRef =
659
+ if (n < MaxImplementedFunctionArity ) ImplementedFunctionType (n)
660
+ else FunctionClass (n).typeRef
661
+
628
662
private lazy val TupleTypes : Set [TypeRef ] = TupleType .toSet
629
663
private lazy val ProductTypes : Set [TypeRef ] = ProductNType .toSet
630
664
@@ -688,10 +722,11 @@ class Definitions {
688
722
def isProductSubType (tp : Type )(implicit ctx : Context ) =
689
723
(tp derivesFrom ProductType .symbol) && tp.baseClasses.exists(isProductClass)
690
724
691
- def isFunctionType (tp : Type )(implicit ctx : Context ) = {
692
- val arity = functionArity(tp)
693
- 0 <= arity && arity <= MaxFunctionArity && (tp isRef FunctionType (arity).symbol)
694
- }
725
+ def isFunctionType (tp : Type )(implicit ctx : Context ) =
726
+ isFunctionClass(tp.dealias.typeSymbol) && {
727
+ val arity = functionArity(tp)
728
+ arity >= 0 && tp.isRef(FunctionType (functionArity(tp)).typeSymbol)
729
+ }
695
730
696
731
def functionArity (tp : Type )(implicit ctx : Context ) = tp.dealias.argInfos.length - 1
697
732
0 commit comments