diff options
author | Georgi Krastev <joro.kr.21@gmail.com> | 2017-11-29 19:53:01 +0100 |
---|---|---|
committer | Georgi Krastev <joro.kr.21@gmail.com> | 2017-11-29 20:05:50 +0100 |
commit | d8fb2f5ca2edc1a34ed7831f06d5eca08ba4989c (patch) | |
tree | 879238ab17d24e05457d158e6af76879a53aea5a /core/shared/src/main/scala | |
parent | 93ff9742cf8cd9f2c60986ff4f7af8d24e268b1f (diff) | |
download | magnolia-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/shared/src/main/scala')
-rw-r--r-- | core/shared/src/main/scala/magnolia.scala | 16 |
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) { |