From 71e3133ef65b06a5bce605cd4f0ebf879cc05118 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 21 Sep 2015 12:46:35 +0200 Subject: Eta expand $apply projected types if needed It turns out that asSeenFrom can produce types that get projected with $apply but that are not higher-kinded. An exampple failure is in Iter3, andother in scala.collection.immutable.Map (which is now part of the test suite). We now detect that situation, and eta expand the projected type in `derivedSelect`, this will force a subssequent `lookupRefined` which will give the desired normalized type. Also added is a configurable test that checks that $apply projected tyeps are in fact higher-kinded. --- src/dotty/tools/dotc/core/TypeApplications.scala | 29 ++++++++++++++++++++++++ 1 file changed, 29 insertions(+) (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 d6cb3dc15..d7d205be6 100644 --- a/src/dotty/tools/dotc/core/TypeApplications.scala +++ b/src/dotty/tools/dotc/core/TypeApplications.scala @@ -155,6 +155,27 @@ class TypeApplications(val self: Type) extends AnyVal { case _ => false } + /** True if it can be determined without forcing that the class symbol + * of this application exists and is not a lambda trait. + * Equivalent to + * + * self.classSymbol.exists && !self.classSymbol.isLambdaTrait + * + * but without forcing anything. + */ + def noHK(implicit ctx: Context): Boolean = self.stripTypeVar match { + case self: RefinedType => + self.parent.noHK + case self: TypeRef => + (self.denot.exists) && { + val sym = self.symbol + if (sym.isClass) !sym.isLambdaTrait + else sym.isCompleted && self.info.isAlias && self.info.bounds.hi.noHK + } + case _ => + false + } + /** Encode the type resulting from applying this type to given arguments */ final def appliedTo(args: List[Type])(implicit ctx: Context): Type = /*>|>*/ track("appliedTo") /*<|<*/ { def matchParams(tp: Type, tparams: List[TypeSymbol], args: List[Type]): Type = args match { @@ -510,6 +531,14 @@ class TypeApplications(val self: Type) extends AnyVal { if (bound.isHK && !isHK && self.typeSymbol.isClass && typeParams.nonEmpty) EtaExpand else self + /** Eta expand the prefix in front of any refinements. */ + def EtaExpandCore(implicit ctx: Context): Type = self.stripTypeVar match { + case self: RefinedType => + self.derivedRefinedType(self.parent.EtaExpandCore, self.refinedName, self.refinedInfo) + case _ => + self.EtaExpand + } + /** If `self` is a (potentially partially instantiated) eta expansion of type T, return T, * otherwise NoType. More precisely if `self` is of the form * -- cgit v1.2.3