@@ -40,7 +40,11 @@ object desugar {
40
40
def derivedType (sym : Symbol )(implicit ctx : Context ) = sym.typeRef
41
41
}
42
42
43
- class DerivedFromParamTree extends DerivedTypeTree {
43
+ /** A type tree that computes its type from an existing parameter.
44
+ * @param suffix String difference between existing parameter (call it `P`) and parameter owning the
45
+ * DerivedTypeTree (call it `O`). We have: `O.name == P.name + suffix`.
46
+ */
47
+ class DerivedFromParamTree (suffix : String ) extends DerivedTypeTree {
44
48
45
49
/** Make sure that for all enclosing module classes their companion lasses
46
50
* are completed. Reason: We need the constructor of such companion classes to
@@ -58,24 +62,28 @@ object desugar {
58
62
59
63
/** Return info of original symbol, where all references to siblings of the
60
64
* original symbol (i.e. sibling and original symbol have the same owner)
61
- * are rewired to same -named parameters or accessors in the scope enclosing
65
+ * are rewired to like -named* parameters or accessors in the scope enclosing
62
66
* the current scope. The current scope is the scope owned by the defined symbol
63
67
* itself, that's why we have to look one scope further out. If the resulting
64
68
* type is an alias type, dealias it. This is necessary because the
65
69
* accessor of a type parameter is a private type alias that cannot be accessed
66
70
* from subclasses.
71
+ *
72
+ * (*) like-named means:
73
+ *
74
+ * parameter name == reference name ++ suffix
67
75
*/
68
76
def derivedType (sym : Symbol )(implicit ctx : Context ) = {
69
77
val relocate = new TypeMap {
70
78
val originalOwner = sym.owner
71
79
def apply (tp : Type ) = tp match {
72
80
case tp : NamedType if tp.symbol.exists && (tp.symbol.owner eq originalOwner) =>
73
81
val defctx = ctx.outersIterator.dropWhile(_.scope eq ctx.scope).next()
74
- var local = defctx.denotNamed(tp.name).suchThat(_.isParamOrAccessor).symbol
82
+ var local = defctx.denotNamed(tp.name ++ suffix ).suchThat(_.isParamOrAccessor).symbol
75
83
if (local.exists) (defctx.owner.thisType select local).dealias
76
84
else {
77
85
def msg =
78
- s " no matching symbol for ${tp.symbol.showLocated} in ${defctx.owner} / ${defctx.effectiveScope}"
86
+ s " no matching symbol for ${tp.symbol.showLocated} in ${defctx.owner} / ${defctx.effectiveScope.toList }"
79
87
if (ctx.reporter.errorsReported) ErrorType (msg)
80
88
else throw new java.lang.Error (msg)
81
89
}
@@ -88,18 +96,20 @@ object desugar {
88
96
}
89
97
90
98
/** A type definition copied from `tdef` with a rhs typetree derived from it */
91
- def derivedTypeParam (tdef : TypeDef ) =
99
+ def derivedTypeParam (tdef : TypeDef , suffix : String = " " ) : TypeDef =
92
100
cpy.TypeDef (tdef)(
93
- rhs = new DerivedFromParamTree () withPos tdef.rhs.pos watching tdef)
101
+ name = tdef.name ++ suffix,
102
+ rhs = new DerivedFromParamTree (suffix).withPos(tdef.rhs.pos).watching(tdef)
103
+ )
94
104
95
105
/** A derived type definition watching `sym` */
96
106
def derivedTypeParam (sym : TypeSymbol )(implicit ctx : Context ): TypeDef =
97
- TypeDef (sym.name, new DerivedFromParamTree ().watching(sym)).withFlags(TypeParam )
107
+ TypeDef (sym.name, new DerivedFromParamTree (" " ).watching(sym)).withFlags(TypeParam )
98
108
99
109
/** A value definition copied from `vdef` with a tpt typetree derived from it */
100
110
def derivedTermParam (vdef : ValDef ) =
101
111
cpy.ValDef (vdef)(
102
- tpt = new DerivedFromParamTree () withPos vdef.tpt.pos watching vdef)
112
+ tpt = new DerivedFromParamTree (" " ) withPos vdef.tpt.pos watching vdef)
103
113
104
114
// ----- Desugar methods -------------------------------------------------
105
115
@@ -321,8 +331,8 @@ object desugar {
321
331
}
322
332
def anyRef = ref(defn.AnyRefAlias .typeRef)
323
333
324
- val derivedTparams = constrTparams map derivedTypeParam
325
- val derivedVparamss = constrVparamss nestedMap derivedTermParam
334
+ val derivedTparams = constrTparams. map( derivedTypeParam(_))
335
+ val derivedVparamss = constrVparamss. nestedMap( derivedTermParam(_))
326
336
val arity = constrVparamss.head.length
327
337
328
338
val classTycon : Tree = new TypeRefTree // watching is set at end of method
@@ -423,9 +433,8 @@ object desugar {
423
433
// ev1: Eq[T1$1, T1$2], ..., evn: Eq[Tn$1, Tn$2]])
424
434
// : Eq[C[T1$1, ..., Tn$1], C[T1$2, ..., Tn$2]] = Eq
425
435
def eqInstance = {
426
- def append (tdef : TypeDef , str : String ) = cpy.TypeDef (tdef)(name = tdef.name ++ str)
427
- val leftParams = derivedTparams.map(append(_, " $1" ))
428
- val rightParams = derivedTparams.map(append(_, " $2" ))
436
+ val leftParams = constrTparams.map(derivedTypeParam(_, " $1" ))
437
+ val rightParams = constrTparams.map(derivedTypeParam(_, " $2" ))
429
438
val subInstances = (leftParams, rightParams).zipped.map((param1, param2) =>
430
439
appliedRef(ref(defn.EqType ), List (param1, param2)))
431
440
DefDef (
0 commit comments