aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-07-14 11:37:24 +0200
committerMartin Odersky <odersky@gmail.com>2015-09-18 18:05:14 +0200
commit92fe081bcdf7f02cd65350463db2d3d4fa72f1eb (patch)
treeb9ecffa0dcc6d9874a21026d3489f2db11f67301
parente2e71dcbb2343d28be0f5311c1cb0094db8cdb05 (diff)
downloaddotty-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.scala26
-rw-r--r--tests/pos/partialApplications.scala4
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]()