aboutsummaryrefslogtreecommitdiff
path: root/core
diff options
context:
space:
mode:
authorGeorgi Krastev <joro.kr.21@gmail.com>2017-11-29 19:53:01 +0100
committerGeorgi Krastev <joro.kr.21@gmail.com>2017-11-29 20:05:50 +0100
commitd8fb2f5ca2edc1a34ed7831f06d5eca08ba4989c (patch)
tree879238ab17d24e05457d158e6af76879a53aea5a /core
parent93ff9742cf8cd9f2c60986ff4f7af8d24e268b1f (diff)
downloadmagnolia-d8fb2f5ca2edc1a34ed7831f06d5eca08ba4989c.tar.gz
magnolia-d8fb2f5ca2edc1a34ed7831f06d5eca08ba4989c.tar.bz2
magnolia-d8fb2f5ca2edc1a34ed7831f06d5eca08ba4989c.zip
Existentially abstract unbound subtype parameters
That happens when the subtype of a sealed trait has more type parameters than its parent. When those extra type parameters are covariant they are replaced by their upper bounds, otherwise they are existentially quantified.
Diffstat (limited to 'core')
-rw-r--r--core/shared/src/main/scala/magnolia.scala16
1 files changed, 9 insertions, 7 deletions
diff --git a/core/shared/src/main/scala/magnolia.scala b/core/shared/src/main/scala/magnolia.scala
index 2113dff..62a36a5 100644
--- a/core/shared/src/main/scala/magnolia.scala
+++ b/core/shared/src/main/scala/magnolia.scala
@@ -65,6 +65,7 @@ object Magnolia {
* */
def gen[T: c.WeakTypeTag](c: whitebox.Context): c.Tree = {
import c.universe._
+ import internal._
val magnoliaPkg = q"_root_.magnolia"
val scalaPkg = q"_root_.scala"
@@ -246,9 +247,7 @@ object Magnolia {
val caseParamsReversed = caseClassParameters.foldLeft[List[CaseParam]](Nil) {
(acc, param) =>
val paramName = param.name.decodedName.toString
- val paramType = param.returnType.substituteTypes(genericType.etaExpand.typeParams,
- genericType.typeArgs)
-
+ val paramType = param.typeSignatureIn(genericType).resultType
val predefinedRef = acc.find(_.paramType == paramType)
val caseParamOpt = predefinedRef.map { backRef =>
@@ -332,10 +331,13 @@ object Magnolia {
} else if (isSealedTrait) {
val genericSubtypes = classType.get.knownDirectSubclasses.to[List]
val subtypes = genericSubtypes.map { sub =>
- val typeArgs = sub.asType.typeSignature.baseType(genericType.typeSymbol).typeArgs
- val mapping = typeArgs.zip(genericType.typeArgs).toMap
- val newTypeParams = sub.asType.toType.typeArgs.map(mapping(_))
- appliedType(sub.asType.toType.typeConstructor, newTypeParams)
+ val subType = sub.asType.toType // FIXME: Broken for path dependent types
+ val typeParams = sub.asType.typeParams
+ val typeArgs = thisType(sub).baseType(genericType.typeSymbol).typeArgs
+ val mapping = (typeArgs.map(_.typeSymbol), genericType.typeArgs).zipped.toMap
+ val newTypeArgs = typeParams.map(mapping.withDefault(_.asType.toType))
+ val applied = appliedType(subType.typeConstructor, newTypeArgs)
+ existentialAbstraction(typeParams, applied)
}
if (subtypes.isEmpty) {