@@ -341,8 +341,21 @@ object desugar {
341
341
(if (args.isEmpty) tycon else AppliedTypeTree (tycon, args))
342
342
.withPos(cdef.pos.startPos)
343
343
344
- def appliedRef (tycon : Tree , tparams : List [TypeDef ] = constrTparams) =
345
- appliedTypeTree(tycon, tparams map refOfDef)
344
+ def appliedRef (tycon : Tree , tparams : List [TypeDef ] = constrTparams, widenHK : Boolean = false ) = {
345
+ val targs = for (tparam <- tparams) yield {
346
+ val targ = refOfDef(tparam)
347
+ def fullyApplied (tparam : Tree ): Tree = tparam match {
348
+ case TypeDef (_, LambdaTypeTree (tparams, body)) =>
349
+ AppliedTypeTree (targ, tparams.map(_ => TypeBoundsTree (EmptyTree , EmptyTree )))
350
+ case TypeDef (_, rhs : DerivedTypeTree ) =>
351
+ fullyApplied(rhs.watched)
352
+ case _ =>
353
+ targ
354
+ }
355
+ if (widenHK) fullyApplied(tparam) else targ
356
+ }
357
+ appliedTypeTree(tycon, targs)
358
+ }
346
359
347
360
// a reference to the class type bound by `cdef`, with type parameters coming from the constructor
348
361
val classTypeRef = appliedRef(classTycon)
@@ -431,12 +444,16 @@ object desugar {
431
444
//
432
445
// implicit def eqInstance[T1$1, ..., Tn$1, T1$2, ..., Tn$2](implicit
433
446
// ev1: Eq[T1$1, T1$2], ..., evn: Eq[Tn$1, Tn$2]])
434
- // : Eq[C[T1$1, ..., Tn$1], C[T1$2, ..., Tn$2]] = Eq
447
+ // : Eq[C[T1$, ..., Tn$1], C[T1$2, ..., Tn$2]] = Eq
448
+ //
449
+ // If any of the T_i are higher-kinded, say `Ti[X1 >: L1 <: U1, ..., Xm >: Lm <: Um]`,
450
+ // the corresponding type parameters for $ev_i are `Ti$1[_, ..., _], Ti$2[_, ..., _]`
451
+ // (with m underscores `_`).
435
452
def eqInstance = {
436
453
val leftParams = constrTparams.map(derivedTypeParam(_, " $1" ))
437
454
val rightParams = constrTparams.map(derivedTypeParam(_, " $2" ))
438
455
val subInstances = (leftParams, rightParams).zipped.map((param1, param2) =>
439
- appliedRef(ref(defn.EqType ), List (param1, param2)))
456
+ appliedRef(ref(defn.EqType ), List (param1, param2), widenHK = true ))
440
457
DefDef (
441
458
name = nme.eqInstance,
442
459
tparams = leftParams ++ rightParams,
@@ -725,6 +742,31 @@ object desugar {
725
742
tree
726
743
}
727
744
745
+ /** Translate infix operation expression
746
+ *
747
+ * l op r ==> l.op(r) if op is left-associative
748
+ * ==> r.op(l) if op is right-associative
749
+ */
750
+ def binop (left : Tree , op : Ident , right : Tree )(implicit ctx : Context ): Apply = {
751
+ def assignToNamedArg (arg : Tree ) = arg match {
752
+ case Assign (Ident (name), rhs) => cpy.NamedArg (arg)(name, rhs)
753
+ case _ => arg
754
+ }
755
+ def makeOp (fn : Tree , arg : Tree , selectPos : Position ) = {
756
+ val args : List [Tree ] = arg match {
757
+ case Parens (arg) => assignToNamedArg(arg) :: Nil
758
+ case Tuple (args) => args.mapConserve(assignToNamedArg)
759
+ case _ => arg :: Nil
760
+ }
761
+ Apply (Select (fn, op.name).withPos(selectPos), args)
762
+ }
763
+
764
+ if (isLeftAssoc(op.name))
765
+ makeOp(left, right, Position (left.pos.start, op.pos.end, op.pos.start))
766
+ else
767
+ makeOp(right, left, Position (op.pos.start, right.pos.end))
768
+ }
769
+
728
770
/** Make closure corresponding to function.
729
771
* params => body
730
772
* ==>
@@ -832,30 +874,6 @@ object desugar {
832
874
Block (ldef, call)
833
875
}
834
876
835
- /** Translate infix operation expression left op right
836
- */
837
- def makeBinop (left : Tree , op : Ident , right : Tree ): Tree = {
838
- def assignToNamedArg (arg : Tree ) = arg match {
839
- case Assign (Ident (name), rhs) => cpy.NamedArg (arg)(name, rhs)
840
- case _ => arg
841
- }
842
- if (isLeftAssoc(op.name)) {
843
- val args : List [Tree ] = right match {
844
- case Parens (arg) => assignToNamedArg(arg) :: Nil
845
- case Tuple (args) => args mapConserve assignToNamedArg
846
- case _ => right :: Nil
847
- }
848
- val selectPos = Position (left.pos.start, op.pos.end, op.pos.start)
849
- Apply (Select (left, op.name).withPos(selectPos), args)
850
- } else {
851
- val x = UniqueName .fresh()
852
- val selectPos = Position (op.pos.start, right.pos.end, op.pos.start)
853
- new InfixOpBlock (
854
- ValDef (x, TypeTree (), left).withMods(synthetic),
855
- Apply (Select (right, op.name).withPos(selectPos), Ident (x).withPos(left.pos)))
856
- }
857
- }
858
-
859
877
/** Create tree for for-comprehension `<for (enums) do body>` or
860
878
* `<for (enums) yield body>` where mapName and flatMapName are chosen
861
879
* corresponding to whether this is a for-do or a for-yield.
@@ -1066,10 +1084,10 @@ object desugar {
1066
1084
if (! op.isBackquoted && op.name == tpnme.raw.AMP ) AndTypeTree (l, r) // l & r
1067
1085
else if (! op.isBackquoted && op.name == tpnme.raw.BAR ) OrTypeTree (l, r) // l | r
1068
1086
else AppliedTypeTree (op, l :: r :: Nil ) // op[l, r]
1069
- else if (ctx.mode is Mode .Pattern )
1087
+ else {
1088
+ assert(ctx.mode is Mode .Pattern ) // expressions are handled separately by `binop`
1070
1089
Apply (op, l :: r :: Nil ) // op(l, r)
1071
- else // l.op(r), or val x = r; l.op(x), plus handle named args specially
1072
- makeBinop(l, op, r)
1090
+ }
1073
1091
case PostfixOp (t, op) =>
1074
1092
if ((ctx.mode is Mode .Type ) && ! op.isBackquoted && op.name == tpnme.raw.STAR ) {
1075
1093
val seqType = if (ctx.compilationUnit.isJava) defn.ArrayType else defn.SeqType
0 commit comments