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