@@ -88,7 +88,7 @@ class Definitions {
88
88
newClassSymbol(ScalaPackageClass , name, EmptyFlags , completer).entered
89
89
}
90
90
91
- /** The trait FunctionN or ImplicitFunctionN , for some N
91
+ /** The trait FunctionN, ImplicitFunctionN, UnusedFunctionN or UnusedImplicitFunction , for some N
92
92
* @param name The name of the trait to be created
93
93
*
94
94
* FunctionN traits follow this template:
@@ -106,6 +106,20 @@ class Definitions {
106
106
* trait ImplicitFunctionN[T0,...,T{N-1}, R] extends Object with FunctionN[T0,...,T{N-1}, R] {
107
107
* def apply(implicit $x0: T0, ..., $x{N_1}: T{N-1}): R
108
108
* }
109
+ *
110
+ * UnusedFunctionN traits follow this template:
111
+ *
112
+ * trait UnusedFunctionN[T0,...,T{N-1}, R] extends Object {
113
+ * def apply(unused $x0: T0, ..., $x{N_1}: T{N-1}): R
114
+ * }
115
+ *
116
+ * UnusedImplicitFunctionN traits follow this template:
117
+ *
118
+ * trait UnusedImplicitFunctionN[T0,...,T{N-1}, R] extends Object with UnusedFunctionN[T0,...,T{N-1}, R] {
119
+ * def apply(unused implicit $x0: T0, ..., $x{N_1}: T{N-1}): R
120
+ * }
121
+ *
122
+ * UnusedFunctionN and UnusedImplicitFunctionN erase to Function0.
109
123
*/
110
124
def newFunctionNTrait (name : TypeName ): ClassSymbol = {
111
125
val completer = new LazyType {
@@ -117,18 +131,12 @@ class Definitions {
117
131
val argParamRefs = List .tabulate(arity) { i =>
118
132
enterTypeParam(cls, paramNamePrefix ++ " T" ++ (i + 1 ).toString, Contravariant , decls).typeRef
119
133
}
120
- val resParam = enterTypeParam(cls, paramNamePrefix ++ " R" , Covariant , decls)
121
- val (methodType, parentTraits) =
122
- if (name.firstPart.startsWith(str.ImplicitFunction )) {
123
- val superTrait =
124
- FunctionType (arity).appliedTo(argParamRefs ::: resParam.typeRef :: Nil )
125
- (ImplicitMethodType , superTrait :: Nil )
126
- }
127
- else (MethodType , Nil )
128
- val applyMeth =
129
- decls.enter(
130
- newMethod(cls, nme.apply,
131
- methodType(argParamRefs, resParam.typeRef), Deferred ))
134
+ val resParamRef = enterTypeParam(cls, paramNamePrefix ++ " R" , Covariant , decls).typeRef
135
+ val methodType = MethodType .maker(isJava = false , name.isImplicitFunction, name.isUnusedFunction)
136
+ val parentTraits =
137
+ if (! name.isImplicitFunction) Nil
138
+ else FunctionType (arity, isUnused = name.isUnusedFunction).appliedTo(argParamRefs ::: resParamRef :: Nil ) :: Nil
139
+ decls.enter(newMethod(cls, nme.apply, methodType(argParamRefs, resParamRef), Deferred ))
132
140
denot.info =
133
141
ClassInfo (ScalaPackageClass .thisType, cls, ObjectType :: parentTraits, decls)
134
142
}
@@ -748,14 +756,14 @@ class Definitions {
748
756
sym.owner.linkedClass.typeRef
749
757
750
758
object FunctionOf {
751
- def apply (args : List [Type ], resultType : Type , isImplicit : Boolean = false )(implicit ctx : Context ) =
752
- FunctionType (args.length, isImplicit).appliedTo(args ::: resultType :: Nil )
759
+ def apply (args : List [Type ], resultType : Type , isImplicit : Boolean = false , isUnused : Boolean = false )(implicit ctx : Context ) =
760
+ FunctionType (args.length, isImplicit, isUnused ).appliedTo(args ::: resultType :: Nil )
753
761
def unapply (ft : Type )(implicit ctx : Context ) = {
754
762
val tsym = ft.typeSymbol
755
763
if (isFunctionClass(tsym)) {
756
764
val targs = ft.dealias.argInfos
757
765
if (targs.isEmpty) None
758
- else Some (targs.init, targs.last, tsym.name.isImplicitFunction)
766
+ else Some (targs.init, targs.last, tsym.name.isImplicitFunction, tsym.name.isUnusedFunction )
759
767
}
760
768
else None
761
769
}
@@ -819,20 +827,29 @@ class Definitions {
819
827
820
828
lazy val TupleType = mkArityArray(" scala.Tuple" , MaxTupleArity , 2 )
821
829
822
- def FunctionClass (n : Int , isImplicit : Boolean = false )(implicit ctx : Context ) =
823
- if (isImplicit) {
830
+ def FunctionClass (n : Int , isImplicit : Boolean = false , isUnused : Boolean = false )(implicit ctx : Context ) = {
831
+ if (isImplicit && isUnused) {
832
+ require(n > 0 )
833
+ ctx.requiredClass(" scala.UnusedImplicitFunction" + n.toString)
834
+ }
835
+ else if (isImplicit) {
824
836
require(n > 0 )
825
837
ctx.requiredClass(" scala.ImplicitFunction" + n.toString)
826
838
}
839
+ else if (isUnused) {
840
+ require(n > 0 )
841
+ ctx.requiredClass(" scala.UnusedFunction" + n.toString)
842
+ }
827
843
else if (n <= MaxImplementedFunctionArity ) FunctionClassPerRun ()(ctx)(n)
828
844
else ctx.requiredClass(" scala.Function" + n.toString)
845
+ }
829
846
830
847
lazy val Function0_applyR = ImplementedFunctionType (0 ).symbol.requiredMethodRef(nme.apply)
831
848
def Function0_apply (implicit ctx : Context ) = Function0_applyR .symbol
832
849
833
- def FunctionType (n : Int , isImplicit : Boolean = false )(implicit ctx : Context ): TypeRef =
834
- if (n <= MaxImplementedFunctionArity && (! isImplicit || ctx.erasedTypes)) ImplementedFunctionType (n)
835
- else FunctionClass (n, isImplicit).typeRef
850
+ def FunctionType (n : Int , isImplicit : Boolean = false , isUnused : Boolean = false )(implicit ctx : Context ): TypeRef =
851
+ if (n <= MaxImplementedFunctionArity && (! isImplicit || ctx.erasedTypes) && ! isUnused ) ImplementedFunctionType (n)
852
+ else FunctionClass (n, isImplicit, isUnused ).typeRef
836
853
837
854
private lazy val TupleTypes : Set [TypeRef ] = TupleType .toSet
838
855
@@ -857,14 +874,23 @@ class Definitions {
857
874
/** Is a function class.
858
875
* - FunctionN for N >= 0
859
876
* - ImplicitFunctionN for N > 0
877
+ * - UnusedFunctionN for N > 0
878
+ * - UnusedImplicitFunctionN for N > 0
860
879
*/
861
880
def isFunctionClass (cls : Symbol ) = scalaClassName(cls).isFunction
862
881
863
882
/** Is an implicit function class.
864
883
* - ImplicitFunctionN for N > 0
884
+ * - UnusedImplicitFunctionN for N > 0
865
885
*/
866
886
def isImplicitFunctionClass (cls : Symbol ) = scalaClassName(cls).isImplicitFunction
867
887
888
+ /** Is an unused function class.
889
+ * - UnusedFunctionN for N > 0
890
+ * - UnusedImplicitFunctionN for N > 0
891
+ */
892
+ def isUnusedFunctionClass (cls : Symbol ) = scalaClassName(cls).isUnusedFunction
893
+
868
894
/** Is a class that will be erased to FunctionXXL
869
895
* - FunctionN for N >= 22
870
896
* - ImplicitFunctionN for N >= 22
@@ -889,11 +915,14 @@ class Definitions {
889
915
* - FunctionN for 22 > N >= 0 remains as FunctionN
890
916
* - ImplicitFunctionN for N > 22 becomes FunctionXXL
891
917
* - ImplicitFunctionN for 22 > N >= 0 becomes FunctionN
918
+ * - UnusedFunctionN becomes Function0
919
+ * - ImplicitUnusedFunctionN becomes Function0
892
920
* - anything else becomes a NoSymbol
893
921
*/
894
922
def erasedFunctionClass (cls : Symbol ): Symbol = {
895
923
val arity = scalaClassName(cls).functionArity
896
- if (arity > 22 ) FunctionXXLClass
924
+ if (cls.name.isUnusedFunction) FunctionClass (0 )
925
+ else if (arity > 22 ) FunctionXXLClass
897
926
else if (arity >= 0 ) FunctionClass (arity)
898
927
else NoSymbol
899
928
}
@@ -903,12 +932,15 @@ class Definitions {
903
932
* - FunctionN for 22 > N >= 0 remains as FunctionN
904
933
* - ImplicitFunctionN for N > 22 becomes FunctionXXL
905
934
* - ImplicitFunctionN for 22 > N >= 0 becomes FunctionN
935
+ * - UnusedFunctionN becomes Function0
936
+ * - ImplicitUnusedFunctionN becomes Function0
906
937
* - anything else becomes a NoType
907
938
*/
908
939
def erasedFunctionType (cls : Symbol ): Type = {
909
940
val arity = scalaClassName(cls).functionArity
910
- if (arity > 22 ) defn.FunctionXXLType
911
- else if (arity >= 0 ) defn.FunctionType (arity)
941
+ if (cls.name.isUnusedFunction) FunctionType (0 )
942
+ else if (arity > 22 ) FunctionXXLType
943
+ else if (arity >= 0 ) FunctionType (arity)
912
944
else NoType
913
945
}
914
946
@@ -976,7 +1008,7 @@ class Definitions {
976
1008
def isNonDepFunctionType (tp : Type )(implicit ctx : Context ) = {
977
1009
val arity = functionArity(tp)
978
1010
val sym = tp.dealias.typeSymbol
979
- arity >= 0 && isFunctionClass(sym) && tp.isRef(FunctionType (arity, sym.name.isImplicitFunction).typeSymbol)
1011
+ arity >= 0 && isFunctionClass(sym) && tp.isRef(FunctionType (arity, sym.name.isImplicitFunction, sym.name.isUnusedFunction ).typeSymbol)
980
1012
}
981
1013
982
1014
/** Is `tp` a representation of a (possibly depenent) function type or an alias of such? */
@@ -1042,6 +1074,9 @@ class Definitions {
1042
1074
def isImplicitFunctionType (tp : Type )(implicit ctx : Context ): Boolean =
1043
1075
asImplicitFunctionType(tp).exists
1044
1076
1077
+ def isUnusedFunctionType (tp : Type )(implicit ctx : Context ) =
1078
+ isFunctionType(tp) && tp.dealias.typeSymbol.name.isUnusedFunction
1079
+
1045
1080
// ----- primitive value class machinery ------------------------------------------
1046
1081
1047
1082
/** This class would also be obviated by the implicit function type design */
0 commit comments