From 965e7e368bcf7346b28ef19f694be502e76a1ca3 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Sun, 19 Jul 2015 13:04:39 +0200 Subject: Project all high-kinded types with #Apply Used to be just instantiated lambdas. With the new scheme every type with a kind higher than * needs to be projected with #Apply. --- src/dotty/tools/dotc/core/TypeApplications.scala | 15 ++++++++++++--- src/dotty/tools/dotc/core/TypeOps.scala | 2 +- 2 files changed, 13 insertions(+), 4 deletions(-) diff --git a/src/dotty/tools/dotc/core/TypeApplications.scala b/src/dotty/tools/dotc/core/TypeApplications.scala index dca56e812..12b540cf4 100644 --- a/src/dotty/tools/dotc/core/TypeApplications.scala +++ b/src/dotty/tools/dotc/core/TypeApplications.scala @@ -206,11 +206,20 @@ class TypeApplications(val self: Type) extends AnyVal { tp } + def isHK(tp: Type): Boolean = tp match { + case tp: TypeRef => + val sym = tp.symbol + if (sym.isClass) sym.isLambdaTrait + else !sym.isAliasType || isHK(tp.info) + case tp: TypeProxy => isHK(tp.underlying) + case _ => false + } + if (args.isEmpty || ctx.erasedTypes) self else { val res = instantiate(self, self) - if (res.isInstantiatedLambda) - // Note: isInstantiatedLambda needs to be conservative, using isSafeLambda + if (isHK(res)) + // Note: isHK needs to be conservative, using isSafeLambda // in order to avoid cyclic reference errors. But this means that some fully // instantiated types will remain unprojected, which essentially means // that they stay as higher-kinded types. checkNonCyclic checks the type again @@ -218,7 +227,7 @@ class TypeApplications(val self: Type) extends AnyVal { // that fall through the hole. Not adding an #Apply typically manifests itself // with a <:< failure of two types that "look the same". An example is #779, // where compiling scala.immutable.Map gives a bounds violation. - res.select(tpnme.Apply) + TypeRef(res, tpnme.Apply) else res } } diff --git a/src/dotty/tools/dotc/core/TypeOps.scala b/src/dotty/tools/dotc/core/TypeOps.scala index 2a9dbd09c..77c6805f0 100644 --- a/src/dotty/tools/dotc/core/TypeOps.scala +++ b/src/dotty/tools/dotc/core/TypeOps.scala @@ -21,7 +21,7 @@ trait TypeOps { this: Context => // TODO: Make standalone object. * class C { type T; def f(x: T): T } * * and an expression `e` of type `C`. Then computing the type of `e.f` leads - * to the query asSeenFrom(`C`, `(x: T)T`). What should it's result be? The + * to the query asSeenFrom(`C`, `(x: T)T`). What should its result be? The * naive answer `(x: C.T)C.T` is incorrect given that we treat `C.T` as the existential * `exists(c: C)c.T`. What we need to do instead is to skolemize the existential. So * the answer would be `(x: c.T)c.T` for some (unknown) value `c` of type `C`. -- cgit v1.2.3