@@ -859,21 +859,22 @@ object desugar {
859859 * given object name extends parents { self => body' }
860860 *
861861 * where every definition in `body` is expanded to an extension method
862- * taking type parameters `tparams` and a leading parameter `(x: T)`.
863- * See: makeExtensionDef
862+ * taking type parameters `tparams` and a leading paramter `(x: T)`.
863+ * See: collectiveExtensionBody
864864 */
865865 def moduleDef (mdef : ModuleDef )(implicit ctx : Context ): Tree = {
866866 val impl = mdef.impl
867867 val mods = mdef.mods
868868 impl.constr match {
869- case DefDef (_, tparams, (vparams @ (vparam :: Nil )) :: givenParamss, _, _) =>
869+ case DefDef (_, tparams, vparamss @ (vparam :: Nil ) :: givenParamss, _, _) =>
870+ // Transform collective extension
870871 assert(mods.is(Given ))
871872 return moduleDef(
872873 cpy.ModuleDef (mdef)(
873874 mdef.name,
874875 cpy.Template (impl)(
875876 constr = emptyConstructor,
876- body = impl.body.map(makeExtensionDef(_ , tparams, vparams, givenParamss) ))))
877+ body = collectiveExtensionBody( impl.body, tparams, vparamss ))))
877878 case _ =>
878879 }
879880
@@ -916,43 +917,40 @@ object desugar {
916917 }
917918 }
918919
919- /** Given tpe parameters `Ts` (possibly empty) and a leading value parameter `(x: T)`,
920- * map a method definition
920+ /** Transform the statements of a collective extension
921+ * @param stats the original statements as they were parsed
922+ * @param tparams the collective type parameters
923+ * @param vparamss the collective value parameters, consisting
924+ * of a single leading value parameter, followed by
925+ * zero or more context parameter clauses
921926 *
922- * def foo [Us] paramss ...
927+ * Note: It is already assured by Parser.checkExtensionMethod that all
928+ * statements conform to requirements.
923929 *
924- * to
930+ * Each method in stats is transformed into an extension method. Example:
931+ *
932+ * extension on [Ts](x: T)(using C):
933+ * def f(y: T) = ???
934+ * def g(z: T) = f(z)
925935 *
926- * <extension> def foo[Ts ++ Us](x: T) parammss ...
936+ * is turned into
927937 *
928- * If the given member `mdef` is not of this form, flag it as an error.
938+ * extension:
939+ * <extension> def f[Ts](x: T)(using C)(y: T) = ???
940+ * <extension> def g[Ts](x: T)(using C)(z: T) = f(z)
929941 */
930-
931- def makeExtensionDef (mdef : Tree , tparams : List [TypeDef ], leadingParams : List [ValDef ],
932- givenParamss : List [List [ValDef ]])(using ctx : Context ): Tree = {
933- mdef match {
934- case mdef : DefDef =>
935- if (mdef.mods.is(Extension )) {
936- ctx.error(NoExtensionMethodAllowed (mdef), mdef.sourcePos)
937- mdef
938- } else {
939- if (tparams.nonEmpty && mdef.tparams.nonEmpty) then
940- ctx.error(ExtensionMethodCannotHaveTypeParams (mdef), mdef.tparams.head.sourcePos)
941- mdef
942- else cpy.DefDef (mdef)(
942+ def collectiveExtensionBody (stats : List [Tree ],
943+ tparams : List [TypeDef ], vparamss : List [List [ValDef ]])(using ctx : Context ): List [Tree ] =
944+ for stat <- stats yield
945+ stat match
946+ case mdef : DefDef =>
947+ cpy.DefDef (mdef)(
943948 tparams = tparams ++ mdef.tparams,
944- vparamss = leadingParams :: givenParamss ::: mdef.vparamss
949+ vparamss = vparamss ::: mdef.vparamss,
945950 ).withMods(mdef.mods | Extension )
946- }
947- case mdef : Import =>
948- mdef
949- case mdef if ! mdef.isEmpty => {
950- ctx.error(ExtensionCanOnlyHaveDefs (mdef), mdef.sourcePos)
951- mdef
952- }
953- case mdef => mdef
954- }
955- }
951+ case mdef =>
952+ mdef
953+ end collectiveExtensionBody
956954
957955 /** Transforms
958956 *
0 commit comments