diff options
author | Martin Odersky <odersky@gmail.com> | 2015-07-14 11:37:24 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2015-09-18 18:05:14 +0200 |
commit | 92fe081bcdf7f02cd65350463db2d3d4fa72f1eb (patch) | |
tree | b9ecffa0dcc6d9874a21026d3489f2db11f67301 | |
parent | e2e71dcbb2343d28be0f5311c1cb0094db8cdb05 (diff) | |
download | dotty-92fe081bcdf7f02cd65350463db2d3d4fa72f1eb.tar.gz dotty-92fe081bcdf7f02cd65350463db2d3d4fa72f1eb.tar.bz2 dotty-92fe081bcdf7f02cd65350463db2d3d4fa72f1eb.zip |
Eta expand type arguments corresponding to lambdas
In Namer, eta expand any type argument that corresponds to a higher-kinded type parameter.
Also, check that all type parameter lists are fully applied.
-rw-r--r-- | src/dotty/tools/dotc/typer/Namer.scala | 26 | ||||
-rw-r--r-- | tests/pos/partialApplications.scala | 4 |
2 files changed, 27 insertions, 3 deletions
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala index 7349b3198..9df928f12 100644 --- a/src/dotty/tools/dotc/typer/Namer.scala +++ b/src/dotty/tools/dotc/typer/Namer.scala @@ -803,6 +803,30 @@ class Namer { typer: Typer => case alias => TypeAlias(alias, if (sym is Local) sym.variance else 0) } sym.info = NoCompleter - checkNonCyclic(sym, unsafeInfo, reportErrors = true) + sym.info = checkNonCyclic(sym, unsafeInfo, reportErrors = true) + etaExpandArgs.apply(sym.info) + } + + /** Eta expand all class types C appearing as arguments to a higher-kinded + * type parameter to type lambdas, e.g. [HK0] => C[HK0] + */ + def etaExpandArgs(implicit ctx: Context) = new TypeMap { + def etaExpandArg(tp: Type, tparam: Symbol): Type = + if (tparam.info.isLambda && tp.typeSymbol.isClass && tp.isLambda) tp.EtaExpand + else tp + def apply(tp: Type) = tp match { + case tp: RefinedType => + val args = tp.argInfos(interpolate = false).mapconserve(this) + if (args.nonEmpty) { + val tycon = tp.withoutArgs(args) + val tparams = tycon.typeParams + assert(args.length == tparams.length, + i"lengths differ in $tp: args = $args%, %, type params of $tycon = $tparams%, %") + this(tycon).appliedTo(args.zipWithConserve(tparams)(etaExpandArg)) + } + else mapOver(tp) + case _ => + mapOver(tp) + } } } diff --git a/tests/pos/partialApplications.scala b/tests/pos/partialApplications.scala index b68c4b945..c1df1dee2 100644 --- a/tests/pos/partialApplications.scala +++ b/tests/pos/partialApplications.scala @@ -1,8 +1,8 @@ object Test { - type Histogram = Map[_, Int] + type Histogram[X] = Map[X, Int] - type StringlyHistogram = Histogram[_ >: String] + type StringlyHistogram[X >: String] = Histogram[X] val xs: Histogram[String] = Map[String, Int]() |