diff options
author | Martin Odersky <odersky@gmail.com> | 2014-05-01 11:21:43 +0200 |
---|---|---|
committer | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2014-05-08 21:51:47 +0200 |
commit | 620b2f4435249cc651d31dbabcb3c902da3b160c (patch) | |
tree | ea27a376fa81376cc51fed574892df5884018083 /src/dotty | |
parent | 615ad1f9eddc3dff9f8f4019ee9608a0b43db45f (diff) | |
download | dotty-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/dotty')
-rw-r--r-- | src/dotty/tools/dotc/core/TypeComparer.scala | 20 |
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) + } } } |