diff options
author | Martin Odersky <odersky@gmail.com> | 2015-09-21 12:46:35 +0200 |
---|---|---|
committer | Martin Odersky <odersky@gmail.com> | 2015-09-21 12:50:05 +0200 |
commit | 71e3133ef65b06a5bce605cd4f0ebf879cc05118 (patch) | |
tree | 1faffde9a7ef4e882ef8ba5c8dcd59719a4aa6a0 /src/dotty/tools/dotc/core/Types.scala | |
parent | 154f3511d52c6b748c03d97dd035f0ad79f9a355 (diff) | |
download | dotty-71e3133ef65b06a5bce605cd4f0ebf879cc05118.tar.gz dotty-71e3133ef65b06a5bce605cd4f0ebf879cc05118.tar.bz2 dotty-71e3133ef65b06a5bce605cd4f0ebf879cc05118.zip |
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.
Diffstat (limited to 'src/dotty/tools/dotc/core/Types.scala')
-rw-r--r-- | src/dotty/tools/dotc/core/Types.scala | 20 |
1 files changed, 16 insertions, 4 deletions
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala index 312d6b290..e545066af 100644 --- a/src/dotty/tools/dotc/core/Types.scala +++ b/src/dotty/tools/dotc/core/Types.scala @@ -1487,7 +1487,9 @@ object Types { if (prefix eq this.prefix) this else { val res = prefix.lookupRefined(name) - if (res.exists) res else newLikeThis(prefix) + if (res.exists) res + else if (name == tpnme.hkApply && prefix.noHK) derivedSelect(prefix.EtaExpandCore) + else newLikeThis(prefix) } /** Create a NamedType of the same kind as this type, but with a new prefix. @@ -1725,9 +1727,15 @@ object Types { } object TypeRef { + def checkProjection(prefix: Type, name: TypeName)(implicit ctx: Context) = + if (name == tpnme.hkApply && prefix.noHK) + assert(false, s"bad type : $prefix.$name should not be $$applied") + /** Create type ref with given prefix and name */ - def apply(prefix: Type, name: TypeName)(implicit ctx: Context): TypeRef = + def apply(prefix: Type, name: TypeName)(implicit ctx: Context): TypeRef = { + if (Config.checkProjections) checkProjection(prefix, name) ctx.uniqueNamedTypes.enterIfNew(prefix, name).asInstanceOf[TypeRef] + } /** Create type ref to given symbol */ def apply(prefix: Type, sym: TypeSymbol)(implicit ctx: Context): TypeRef = @@ -1736,8 +1744,10 @@ object Types { /** Create a non-member type ref (which cannot be reloaded using `member`), * with given prefix, name, and symbol. */ - def withFixedSym(prefix: Type, name: TypeName, sym: TypeSymbol)(implicit ctx: Context): TypeRef = + def withFixedSym(prefix: Type, name: TypeName, sym: TypeSymbol)(implicit ctx: Context): TypeRef = { + if (Config.checkProjections) checkProjection(prefix, name) unique(new TypeRefWithFixedSym(prefix, name, sym)) + } /** Create a type ref referring to given symbol with given name. * This is very similar to TypeRef(Type, Symbol), @@ -3198,7 +3208,9 @@ object Types { class MissingType(pre: Type, name: Name)(implicit ctx: Context) extends TypeError( i"""cannot resolve reference to type $pre.$name - |the classfile defining the type might be missing from the classpath${otherReason(pre)}""".stripMargin) + |the classfile defining the type might be missing from the classpath${otherReason(pre)}""".stripMargin) { + printStackTrace() + } private def otherReason(pre: Type)(implicit ctx: Context): String = pre match { case pre: ThisType if pre.givenSelfType.exists => |