Skip to content

Commit 8d9e092

Browse files
committed
Refactor extension desugaring
1 parent 849017b commit 8d9e092

File tree

1 file changed

+32
-34
lines changed

1 file changed

+32
-34
lines changed

compiler/src/dotty/tools/dotc/ast/Desugar.scala

Lines changed: 32 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -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

Comments
 (0)