From 8e84fb013abeb613af4a3414b836f02140e2e866 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Wed, 29 Jun 2016 19:43:44 +0200 Subject: Eta-expand unapplied types that have type parameters We would like to change from a scheme where eta-expansion was prototype driven to one where unapplied parameterized types are always eta expanded. The reason is that we might miss some eta expansions due to cyclic references. run/colltest4 is an exmaple. Here, we missed an eta expansion in the type of Iterator. The class definition is: trait Iterable[+A] extends IterableOnce[A] with FromIterable[Iterable] { We'd expect that the second parent would expand to FromIterable[[X0] -> Iterable[X0]] But we miss the expansion because at the time we complete Iterable we have not completed FromIterable yet. In fact this happens in both the old and the new hk scheme. But in the old scheme we did not notice the error whereas in the new scheme we get an error in PostTyper that the type Iterable does not conform to its bound `[X0] -> Iterable[X0]`. With this commit, we change the scheme, so that eta-expansion depends on the type parameters of a type itself, instead of the expected type. We should investigate whether we can do a similar change for Scala2 classloading. Check kinds of type parameters Also, do not allow a hk type if the bound is a * type. --- src/dotty/tools/dotc/core/TypeApplications.scala | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) (limited to 'src/dotty/tools/dotc/core/TypeApplications.scala') diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala index be0eb9230..1700a9c9c 100644 --- a/src/dotty/tools/dotc/core/TypeApplications.scala +++ b/src/dotty/tools/dotc/core/TypeApplications.scala @@ -378,15 +378,18 @@ class TypeApplications(val self: Type) extends AnyVal { } } + /** If `self` is a higher-kinded type, its type parameters $hk_i, otherwise Nil */ final def hkTypeParams(implicit ctx: Context): List[MemberBinding] = if (Config.newHK) if (isHK) typeParams else Nil else LambdaTraitOBS.typeParams - final def typeParamSymbols(implicit ctx: Context): List[TypeSymbol] = { - val tparams = typeParams - assert(tparams.isEmpty || tparams.head.isInstanceOf[Symbol], self) - tparams.asInstanceOf[List[TypeSymbol]] + /** If `self` is a generic class, its type parameter symbols, otherwise Nil */ + final def typeParamSymbols(implicit ctx: Context): List[TypeSymbol] = typeParams match { + case (_: Symbol) :: _ => + assert(typeParams.forall(_.isInstanceOf[Symbol])) + typeParams.asInstanceOf[List[TypeSymbol]] + case _ => Nil } /** The named type parameters declared or inherited by this type. -- cgit v1.2.3