@@ -393,6 +393,16 @@ object desugar {
393
393
vparam.withMods(mods & (GivenOrImplicit | Erased | hasDefault) | Param )
394
394
}
395
395
396
+ def mkApply (fn : Tree , paramss : List [ParamClause ])(using Context ): Tree =
397
+ paramss.foldLeft(fn) { (fn, params) => params match
398
+ case TypeDefs (params) =>
399
+ TypeApply (fn, params.map(refOfDef))
400
+ case (vparam : ValDef ) :: _ if vparam.mods.is(Given ) =>
401
+ Apply (fn, params.map(refOfDef)).setApplyKind(ApplyKind .Using )
402
+ case _ =>
403
+ Apply (fn, params.map(refOfDef))
404
+ }
405
+
396
406
/** The expansion of a class definition. See inline comments for what is involved */
397
407
def classDef (cdef : TypeDef )(using Context ): Tree = {
398
408
val impl @ Template (constr0, _, self, _) = cdef.rhs
@@ -588,22 +598,13 @@ object desugar {
588
598
}
589
599
590
600
// new C[Ts](paramss)
591
- lazy val creatorExpr = {
592
- val vparamss = constrVparamss match {
601
+ lazy val creatorExpr =
602
+ val vparamss = constrVparamss match
593
603
case (vparam :: _) :: _ if vparam.mods.isOneOf(GivenOrImplicit ) => // add a leading () to match class parameters
594
604
Nil :: constrVparamss
595
605
case _ =>
596
606
constrVparamss
597
- }
598
- val nu = vparamss.foldLeft(makeNew(classTypeRef)) { (nu, vparams) =>
599
- val app = Apply (nu, vparams.map(refOfDef))
600
- vparams match {
601
- case vparam :: _ if vparam.mods.is(Given ) => app.setApplyKind(ApplyKind .Using )
602
- case _ => app
603
- }
604
- }
605
- ensureApplied(nu)
606
- }
607
+ ensureApplied(mkApply(makeNew(classTypeRef), vparamss))
607
608
608
609
val copiedAccessFlags = if migrateTo3 then EmptyFlags else AccessFlags
609
610
@@ -888,48 +889,50 @@ object desugar {
888
889
}
889
890
}
890
891
892
+ def extMethod (mdef : DefDef , extParamss : List [ParamClause ])(using Context ): DefDef =
893
+ cpy.DefDef (mdef)(
894
+ name = normalizeName(mdef, mdef.tpt).asTermName,
895
+ paramss =
896
+ if mdef.name.isRightAssocOperatorName then
897
+ val (typaramss, paramss) = mdef.paramss.span(isTypeParamClause) // first extract type parameters
898
+
899
+ paramss match
900
+ case params :: paramss1 => // `params` must have a single parameter and without `given` flag
901
+
902
+ def badRightAssoc (problem : String ) =
903
+ report.error(i " right-associative extension method $problem" , mdef.srcPos)
904
+ extParamss ++ mdef.paramss
905
+
906
+ params match
907
+ case ValDefs (vparam :: Nil ) =>
908
+ if ! vparam.mods.is(Given ) then
909
+ // we merge the extension parameters with the method parameters,
910
+ // swapping the operator arguments:
911
+ // e.g.
912
+ // extension [A](using B)(c: C)(using D)
913
+ // def %:[E](f: F)(g: G)(using H): Res = ???
914
+ // will be encoded as
915
+ // def %:[A](using B)[E](f: F)(c: C)(using D)(g: G)(using H): Res = ???
916
+ val (leadingUsing, otherExtParamss) = extParamss.span(isUsingOrTypeParamClause)
917
+ leadingUsing ::: typaramss ::: params :: otherExtParamss ::: paramss1
918
+ else
919
+ badRightAssoc(" cannot start with using clause" )
920
+ case _ =>
921
+ badRightAssoc(" must start with a single parameter" )
922
+ case _ =>
923
+ // no value parameters, so not an infix operator.
924
+ extParamss ++ mdef.paramss
925
+ else
926
+ extParamss ++ mdef.paramss
927
+ ).withMods(mdef.mods | ExtensionMethod )
928
+
891
929
/** Transform extension construct to list of extension methods */
892
930
def extMethods (ext : ExtMethods )(using Context ): Tree = flatTree {
893
- for mdef <- ext.methods yield
894
- defDef(
895
- cpy.DefDef (mdef)(
896
- name = normalizeName(mdef, ext).asTermName,
897
- paramss =
898
- if mdef.name.isRightAssocOperatorName then
899
- val (typaramss, paramss) = mdef.paramss.span(isTypeParamClause) // first extract type parameters
900
-
901
- paramss match
902
- case params :: paramss1 => // `params` must have a single parameter and without `given` flag
903
-
904
- def badRightAssoc (problem : String ) =
905
- report.error(i " right-associative extension method $problem" , mdef.srcPos)
906
- ext.paramss ++ mdef.paramss
907
-
908
- params match
909
- case ValDefs (vparam :: Nil ) =>
910
- if ! vparam.mods.is(Given ) then
911
- // we merge the extension parameters with the method parameters,
912
- // swapping the operator arguments:
913
- // e.g.
914
- // extension [A](using B)(c: C)(using D)
915
- // def %:[E](f: F)(g: G)(using H): Res = ???
916
- // will be encoded as
917
- // def %:[A](using B)[E](f: F)(c: C)(using D)(g: G)(using H): Res = ???
918
- val (leadingUsing, otherExtParamss) = ext.paramss.span(isUsingOrTypeParamClause)
919
- leadingUsing ::: typaramss ::: params :: otherExtParamss ::: paramss1
920
- else
921
- badRightAssoc(" cannot start with using clause" )
922
- case _ =>
923
- badRightAssoc(" must start with a single parameter" )
924
- case _ =>
925
- // no value parameters, so not an infix operator.
926
- ext.paramss ++ mdef.paramss
927
- else
928
- ext.paramss ++ mdef.paramss
929
- ).withMods(mdef.mods | ExtensionMethod )
930
- )
931
+ ext.methods map {
932
+ case exp : Export => exp
933
+ case mdef : DefDef => defDef(extMethod(mdef, ext.paramss))
934
+ }
931
935
}
932
-
933
936
/** Transforms
934
937
*
935
938
* <mods> type t >: Low <: Hi
0 commit comments