@@ -117,13 +117,15 @@ trait Deriving { this: Typer =>
117117 /** Enter type class instance with given name and info in current scope, provided
118118 * an instance woth the same name does not exist already.
119119 */
120- private def addDerivedInstance (clsName : Name , info : Type , reportErrors : Boolean ) = {
120+ private def addDerivedInstance (clsName : Name , info : Type , reportErrors : Boolean , implicitFlag : FlagSet = Implicit ) = {
121121 val instanceName = s " derived $$ $clsName" .toTermName
122122 if (ctx.denotNamed(instanceName).exists) {
123123 if (reportErrors) ctx.error(i " duplicate typeclass derivation for $clsName" )
124124 }
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+ }
127129 }
128130
129131 /* Check derived type tree `derived` for the following well-formedness conditions:
@@ -176,16 +178,31 @@ trait Deriving { this: Typer =>
176178 def implementedClass (instance : Symbol ) =
177179 instance.info.stripPoly.finalResultType.classSymbol
178180
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+ }
185202
186203 def syntheticDef (sym : Symbol ): tpd.Tree =
187204 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) )
189206
190207 def finalize (stat : tpd.TypeDef ): tpd.Tree = {
191208 val templ @ Template (_, _, _, _) = stat.rhs
0 commit comments