aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/Types.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-10-20 09:47:21 +0200
committerMartin Odersky <odersky@gmail.com>2015-10-24 10:34:51 +0200
commita415ca1ab713f92788262057d9810d937dc7499a (patch)
tree309b87812b05d0be733b09abdd78b2ecfb7b6c3b /src/dotty/tools/dotc/core/Types.scala
parent87098e63c2796387c598513a2af2d8f2d1aae91b (diff)
downloaddotty-a415ca1ab713f92788262057d9810d937dc7499a.tar.gz
dotty-a415ca1ab713f92788262057d9810d937dc7499a.tar.bz2
dotty-a415ca1ab713f92788262057d9810d937dc7499a.zip
Allow existential types in hk types
Diffstat (limited to 'src/dotty/tools/dotc/core/Types.scala')
-rw-r--r--src/dotty/tools/dotc/core/Types.scala44
1 files changed, 32 insertions, 12 deletions
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 58a6d226d..3fe5afb33 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -846,14 +846,16 @@ object Types {
* (*) normalizes means: follow instantiated typevars and aliases.
*/
def lookupRefined(name: Name)(implicit ctx: Context): Type = {
- def loop(pre: Type, resolved: List[Name]): Type = pre.stripTypeVar match {
+ def loop(pre: Type): Type = pre.stripTypeVar match {
case pre: RefinedType =>
object instantiate extends TypeMap {
var isSafe = true
def apply(tp: Type): Type = tp match {
case TypeRef(RefinedThis(`pre`), name) if name.isLambdaArgName =>
- val TypeAlias(alias) = member(name).info
- alias
+ member(name).info match {
+ case TypeAlias(alias) => alias
+ case _ => isSafe = false; tp
+ }
case tp: TypeVar if !tp.inst.exists =>
isSafe = false
tp
@@ -861,23 +863,37 @@ object Types {
mapOver(tp)
}
}
- def betaReduce(tp: Type) = {
- val lam = pre.parent.LambdaClass(forcing = false)
- if (lam.exists && lam.typeParams.forall(tparam => resolved.contains(tparam.name))) {
- val reduced = instantiate(tp)
+ def instArg(tp: Type): Type = tp match {
+ case tp @ TypeAlias(TypeRef(RefinedThis(`pre`), name)) if name.isLambdaArgName =>
+ member(name).info match {
+ case TypeAlias(alias) => tp.derivedTypeAlias(alias) // needed to keep variance
+ case bounds => bounds
+ }
+ case _ =>
+ instantiate(tp)
+ }
+ def instTop(tp: Type): Type = tp.stripTypeVar match {
+ case tp: RefinedType =>
+ tp.derivedRefinedType(instTop(tp.parent), tp.refinedName, instArg(tp.refinedInfo))
+ case _ =>
+ instantiate(tp)
+ }
+ /** Reduce rhs of $hkApply to make it stand alone */
+ def betaReduce(tp: Type) =
+ if (pre.parent.isSafeLambda) {
+ val reduced = instTop(tp)
if (instantiate.isSafe) reduced else NoType
}
else NoType
- }
pre.refinedInfo match {
case TypeAlias(alias) =>
- if (pre.refinedName ne name) loop(pre.parent, pre.refinedName :: resolved)
+ if (pre.refinedName ne name) loop(pre.parent)
else if (!pre.refinementRefersToThis) alias
else alias match {
case TypeRef(RefinedThis(`pre`), aliasName) => lookupRefined(aliasName) // (1)
case _ => if (name == tpnme.hkApply) betaReduce(alias) else NoType // (2)
}
- case _ => loop(pre.parent, resolved)
+ case _ => loop(pre.parent)
}
case RefinedThis(binder) =>
binder.lookupRefined(name)
@@ -887,14 +903,14 @@ object Types {
WildcardType
case pre: TypeRef =>
pre.info match {
- case TypeAlias(alias) => loop(alias, resolved)
+ case TypeAlias(alias) => loop(alias)
case _ => NoType
}
case _ =>
NoType
}
- loop(this, Nil)
+ loop(this)
}
/** The type <this . name> , reduced if possible */
@@ -1886,6 +1902,10 @@ object Types {
s"variance mismatch for $this, $cls, ${cls.typeParams}, ${cls.typeParams.apply(refinedName.LambdaArgIndex).variance}, ${refinedInfo.variance}")
case _ =>
}
+ if (Config.checkProjections &&
+ (refinedName == tpnme.hkApply || refinedName.isLambdaArgName) &&
+ parent.noHK)
+ assert(false, s"illegal refinement of first-order type: $this")
this
}