@@ -834,17 +834,45 @@ object desugar {
834834 }
835835 }.withPos(tree.pos)
836836
837- /** Create a class definition with the same info as this refined type.
837+ /** Create a class definition with the same info as the refined type given by `parent`
838+ * and `refinements`.
839+ *
838840 * parent { refinements }
839841 * ==>
840- * trait <refinement> extends parent { refinements }
842+ * trait <refinement> extends core { this: self => refinements }
843+ *
844+ * Here, `core` is the (possibly parameterized) class part of `parent`.
845+ * If `parent` is the same as `core`, self is empty. Otherwise `self` is `parent`.
846+ *
847+ * Example: Given
848+ *
849+ * class C
850+ * type T1 extends C { type T <: A }
851+ *
852+ * the refined type
841853 *
842- * If the parent is missing, Object is assumed.
843- * The result is used for validity checking, is thrown away afterwards.
854+ * T1 { type T <: B }
855+ *
856+ * is expanded to
857+ *
858+ * trait <refinement> extends C { this: T1 => type T <: A }
859+ *
860+ * The result of this method is used for validity checking, is thrown away afterwards.
861+ * @param parentType The type of `parent`
844862 */
845- def refinedTypeToClass (tree : RefinedTypeTree )(implicit ctx : Context ): TypeDef = {
846- val parent = if (tree.tpt.isEmpty) TypeTree (defn.ObjectType ) else tree.tpt
847- val impl = Template (emptyConstructor, parent :: Nil , EmptyValDef , tree.refinements)
863+ def refinedTypeToClass (parent : tpd.Tree , refinements : List [Tree ])(implicit ctx : Context ): TypeDef = {
864+ def stripToCore (tp : Type ): Type = tp match {
865+ case tp : RefinedType if tp.argInfos.nonEmpty => tp // parameterized class type
866+ case tp : TypeRef if tp.symbol.isClass => tp // monomorphic class type
867+ case tp : TypeProxy => stripToCore(tp.underlying)
868+ case _ => defn.AnyType
869+ }
870+ val parentCore = stripToCore(parent.tpe)
871+ val untpdParent = TypedSplice (parent)
872+ val (classParent, self) =
873+ if (parent.tpe eq parentCore) (untpdParent, EmptyValDef )
874+ else (TypeTree (parentCore), ValDef (nme.WILDCARD , untpdParent, EmptyTree ))
875+ val impl = Template (emptyConstructor, classParent :: Nil , self, refinements)
848876 TypeDef (tpnme.REFINE_CLASS , impl).withFlags(Trait )
849877 }
850878
0 commit comments