@@ -88,7 +88,7 @@ class Definitions {
8888 newClassSymbol(ScalaPackageClass , name, EmptyFlags , completer).entered
8989 }
9090
91- /** The trait FunctionN or ImplicitFunctionN , for some N
91+ /** The trait FunctionN, ImplicitFunctionN, UnusedFunctionN or UnusedImplicitFunction , for some N
9292 * @param name The name of the trait to be created
9393 *
9494 * FunctionN traits follow this template:
@@ -106,6 +106,20 @@ class Definitions {
106106 * trait ImplicitFunctionN[T0,...,T{N-1}, R] extends Object with FunctionN[T0,...,T{N-1}, R] {
107107 * def apply(implicit $x0: T0, ..., $x{N_1}: T{N-1}): R
108108 * }
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.
109123 */
110124 def newFunctionNTrait (name : TypeName ): ClassSymbol = {
111125 val completer = new LazyType {
@@ -117,18 +131,12 @@ class Definitions {
117131 val argParamRefs = List .tabulate(arity) { i =>
118132 enterTypeParam(cls, paramNamePrefix ++ " T" ++ (i + 1 ).toString, Contravariant , decls).typeRef
119133 }
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 ))
132140 denot.info =
133141 ClassInfo (ScalaPackageClass .thisType, cls, ObjectType :: parentTraits, decls)
134142 }
@@ -748,14 +756,14 @@ class Definitions {
748756 sym.owner.linkedClass.typeRef
749757
750758 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 )
753761 def unapply (ft : Type )(implicit ctx : Context ) = {
754762 val tsym = ft.typeSymbol
755763 if (isFunctionClass(tsym)) {
756764 val targs = ft.dealias.argInfos
757765 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 )
759767 }
760768 else None
761769 }
@@ -819,20 +827,29 @@ class Definitions {
819827
820828 lazy val TupleType = mkArityArray(" scala.Tuple" , MaxTupleArity , 2 )
821829
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) {
824836 require(n > 0 )
825837 ctx.requiredClass(" scala.ImplicitFunction" + n.toString)
826838 }
839+ else if (isUnused) {
840+ require(n > 0 )
841+ ctx.requiredClass(" scala.UnusedFunction" + n.toString)
842+ }
827843 else if (n <= MaxImplementedFunctionArity ) FunctionClassPerRun ()(ctx)(n)
828844 else ctx.requiredClass(" scala.Function" + n.toString)
845+ }
829846
830847 lazy val Function0_applyR = ImplementedFunctionType (0 ).symbol.requiredMethodRef(nme.apply)
831848 def Function0_apply (implicit ctx : Context ) = Function0_applyR .symbol
832849
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
836853
837854 private lazy val TupleTypes : Set [TypeRef ] = TupleType .toSet
838855
@@ -857,14 +874,23 @@ class Definitions {
857874 /** Is a function class.
858875 * - FunctionN for N >= 0
859876 * - ImplicitFunctionN for N > 0
877+ * - UnusedFunctionN for N > 0
878+ * - UnusedImplicitFunctionN for N > 0
860879 */
861880 def isFunctionClass (cls : Symbol ) = scalaClassName(cls).isFunction
862881
863882 /** Is an implicit function class.
864883 * - ImplicitFunctionN for N > 0
884+ * - UnusedImplicitFunctionN for N > 0
865885 */
866886 def isImplicitFunctionClass (cls : Symbol ) = scalaClassName(cls).isImplicitFunction
867887
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+
868894 /** Is a class that will be erased to FunctionXXL
869895 * - FunctionN for N >= 22
870896 * - ImplicitFunctionN for N >= 22
@@ -889,11 +915,14 @@ class Definitions {
889915 * - FunctionN for 22 > N >= 0 remains as FunctionN
890916 * - ImplicitFunctionN for N > 22 becomes FunctionXXL
891917 * - ImplicitFunctionN for 22 > N >= 0 becomes FunctionN
918+ * - UnusedFunctionN becomes Function0
919+ * - ImplicitUnusedFunctionN becomes Function0
892920 * - anything else becomes a NoSymbol
893921 */
894922 def erasedFunctionClass (cls : Symbol ): Symbol = {
895923 val arity = scalaClassName(cls).functionArity
896- if (arity > 22 ) FunctionXXLClass
924+ if (cls.name.isUnusedFunction) FunctionClass (0 )
925+ else if (arity > 22 ) FunctionXXLClass
897926 else if (arity >= 0 ) FunctionClass (arity)
898927 else NoSymbol
899928 }
@@ -903,12 +932,15 @@ class Definitions {
903932 * - FunctionN for 22 > N >= 0 remains as FunctionN
904933 * - ImplicitFunctionN for N > 22 becomes FunctionXXL
905934 * - ImplicitFunctionN for 22 > N >= 0 becomes FunctionN
935+ * - UnusedFunctionN becomes Function0
936+ * - ImplicitUnusedFunctionN becomes Function0
906937 * - anything else becomes a NoType
907938 */
908939 def erasedFunctionType (cls : Symbol ): Type = {
909940 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)
912944 else NoType
913945 }
914946
@@ -976,7 +1008,7 @@ class Definitions {
9761008 def isNonDepFunctionType (tp : Type )(implicit ctx : Context ) = {
9771009 val arity = functionArity(tp)
9781010 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)
9801012 }
9811013
9821014 /** Is `tp` a representation of a (possibly depenent) function type or an alias of such? */
@@ -1042,6 +1074,9 @@ class Definitions {
10421074 def isImplicitFunctionType (tp : Type )(implicit ctx : Context ): Boolean =
10431075 asImplicitFunctionType(tp).exists
10441076
1077+ def isUnusedFunctionType (tp : Type )(implicit ctx : Context ) =
1078+ isFunctionType(tp) && tp.dealias.typeSymbol.name.isUnusedFunction
1079+
10451080 // ----- primitive value class machinery ------------------------------------------
10461081
10471082 /** This class would also be obviated by the implicit function type design */
0 commit comments