aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-05-01 11:21:43 +0200
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2014-05-08 21:51:47 +0200
commit620b2f4435249cc651d31dbabcb3c902da3b160c (patch)
treeea27a376fa81376cc51fed574892df5884018083 /src
parent615ad1f9eddc3dff9f8f4019ee9608a0b43db45f (diff)
downloaddotty-620b2f4435249cc651d31dbabcb3c902da3b160c.tar.gz
dotty-620b2f4435249cc651d31dbabcb3c902da3b160c.tar.bz2
dotty-620b2f4435249cc651d31dbabcb3c902da3b160c.zip
Handling of higher-kinded types in intersections and unions.
If we intersect a higher-kinded type C with an instance C[T], we should expect C[T]. Conversely, taking the union of a higher-kinded type C and an instance C[T] should give C. Previously, the higher-kinded place-holder $hkN was merged with &/| with the type T which led to type errors.
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/dotc/core/TypeComparer.scala20
1 files changed, 17 insertions, 3 deletions
diff --git a/src/dotty/tools/dotc/core/TypeComparer.scala b/src/dotty/tools/dotc/core/TypeComparer.scala
index f5f7ac367..9003de3c1 100644
--- a/src/dotty/tools/dotc/core/TypeComparer.scala
+++ b/src/dotty/tools/dotc/core/TypeComparer.scala
@@ -337,7 +337,7 @@ class TypeComparer(initctx: Context) extends DotClass {
tp2 match {
case tp2: NamedType =>
def compareNamed = {
- implicit val ctx = this.ctx
+ implicit val ctx: Context = this.ctx // Dotty deviation: implicits need explicit type
tp1 match {
case tp1: NamedType =>
val sym1 = tp1.symbol
@@ -673,6 +673,12 @@ class TypeComparer(initctx: Context) extends DotClass {
i < tparams.length && tparams(i).name == name2
}
+ /** Is type `tp` a TypeRef referring to a higher-kinded parameter? */
+ private def isHKRef(tp: Type) = tp match {
+ case TypeRef(_, name) => name.isHkParamName
+ case _ => false
+ }
+
/** Can type `tp` be constrained from above by adding a constraint to
* a typevar that it refers to? In that case we have to be careful not
* to approximate with the lower bound of a type in `thirdTry`. Instead,
@@ -956,7 +962,11 @@ class TypeComparer(initctx: Context) extends DotClass {
else {
val t2 = distributeAnd(tp2, tp1)
if (t2.exists) t2
- else AndType(tp1, tp2)
+ else {
+ if (isHKRef(tp1)) tp2
+ else if (isHKRef(tp2)) tp1
+ else AndType(tp1, tp2)
+ }
}
}
@@ -976,7 +986,11 @@ class TypeComparer(initctx: Context) extends DotClass {
else {
val t2 = distributeOr(tp2, tp1)
if (t2.exists) t2
- else OrType(tp1, tp2)
+ else {
+ if (isHKRef(tp1)) tp1
+ else if (isHKRef(tp2)) tp2
+ else OrType(tp1, tp2)
+ }
}
}