@@ -117,13 +117,15 @@ trait Deriving { this: Typer =>
117
117
/** Enter type class instance with given name and info in current scope, provided
118
118
* an instance woth the same name does not exist already.
119
119
*/
120
- private def addDerivedInstance (clsName : Name , info : Type , reportErrors : Boolean ) = {
120
+ private def addDerivedInstance (clsName : Name , info : Type , reportErrors : Boolean , implicitFlag : FlagSet = Implicit ) = {
121
121
val instanceName = s " derived $$ $clsName" .toTermName
122
122
if (ctx.denotNamed(instanceName).exists) {
123
123
if (reportErrors) ctx.error(i " duplicate typeclass derivation for $clsName" )
124
124
}
125
- else
126
- add(ctx.newSymbol(ctx.owner, instanceName, Synthetic | Method , info, coord = cls.pos))
125
+ else {
126
+ val implFlag = if (reportErrors) Implicit else EmptyFlags // for now
127
+ add(ctx.newSymbol(ctx.owner, instanceName, Synthetic | Method | implFlag, info, coord = cls.pos.startPos))
128
+ }
127
129
}
128
130
129
131
/* Check derived type tree `derived` for the following well-formedness conditions:
@@ -176,16 +178,31 @@ trait Deriving { this: Typer =>
176
178
def implementedClass (instance : Symbol ) =
177
179
instance.info.stripPoly.finalResultType.classSymbol
178
180
179
- def typeclassInstance (sym : Symbol )(tparamRefs : List [Type ])(paramRefss : List [List [tpd.Tree ]]): tpd.Tree = {
180
- val tparams = tparamRefs.map(_.typeSymbol.asType)
181
- val params = if (paramRefss.isEmpty) Nil else paramRefss.head.map(_.symbol.asTerm)
182
- val typeCls = implementedClass(sym)
183
- tpd.ref(defn.Predef_undefinedR ) // TODO: flesh out
184
- }
181
+ private def typeclassInstance (sym : Symbol )(implicit ctx : Context ) =
182
+ (tparamRefs : List [Type ]) => (paramRefss : List [List [tpd.Tree ]]) => {
183
+ val tparams = tparamRefs.map(_.typeSymbol.asType)
184
+ val params = if (paramRefss.isEmpty) Nil else paramRefss.head.map(_.symbol.asTerm)
185
+ tparams.foreach(ctx.enter)
186
+ params.foreach(ctx.enter)
187
+ def instantiated (info : Type ): Type = info match {
188
+ case info : PolyType => instantiated(info.instantiate(tparamRefs))
189
+ case info : MethodType => info.instantiate(params.map(_.termRef))
190
+ case info => info
191
+ }
192
+ val resultType = instantiated(sym.info)
193
+ val typeCls = resultType.classSymbol
194
+ if (typeCls == defn.ShapedClass )
195
+ tpd.ref(defn.Predef_undefinedR ) // TODO: flesh out
196
+ else {
197
+ val module = untpd.ref(typeCls.companionModule.termRef).withPos(sym.pos)
198
+ val rhs = untpd.Select (module, nme.derived)
199
+ typed(rhs, resultType)
200
+ }
201
+ }
185
202
186
203
def syntheticDef (sym : Symbol ): tpd.Tree =
187
204
if (sym.isType) tpd.TypeDef (sym.asType)
188
- else tpd.polyDefDef(sym.asTerm, typeclassInstance(sym))
205
+ else tpd.polyDefDef(sym.asTerm, typeclassInstance(sym)(ctx.fresh.setOwner(sym).setNewScope) )
189
206
190
207
def finalize (stat : tpd.TypeDef ): tpd.Tree = {
191
208
val templ @ Template (_, _, _, _) = stat.rhs
0 commit comments