aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/TypeOps.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2016-02-04 14:37:44 +0100
committerMartin Odersky <odersky@gmail.com>2016-02-04 14:37:56 +0100
commit8efdbdc9843f66fbb8fc39aa2716da0fe7187fd9 (patch)
tree243f8f8ece4db7840291c6ce80414caed284762e /src/dotty/tools/dotc/core/TypeOps.scala
parent7d1d93e95113802bee77b9d2b89475a56be46bf7 (diff)
downloaddotty-8efdbdc9843f66fbb8fc39aa2716da0fe7187fd9.tar.gz
dotty-8efdbdc9843f66fbb8fc39aa2716da0fe7187fd9.tar.bz2
dotty-8efdbdc9843f66fbb8fc39aa2716da0fe7187fd9.zip
Try to make refinements match in approximateUnions
See comment in Typer#approximateUnion for an explanation. Fixes #1045.
Diffstat (limited to 'src/dotty/tools/dotc/core/TypeOps.scala')
-rw-r--r--src/dotty/tools/dotc/core/TypeOps.scala24
1 files changed, 22 insertions, 2 deletions
diff --git a/src/dotty/tools/dotc/core/TypeOps.scala b/src/dotty/tools/dotc/core/TypeOps.scala
index 7121d94df..28730fec9 100644
--- a/src/dotty/tools/dotc/core/TypeOps.scala
+++ b/src/dotty/tools/dotc/core/TypeOps.scala
@@ -276,6 +276,26 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
case TypeBounds(_, hi) => hi
case nx => nx
}
+ /** If `tp1` and `tp2` are typebounds, try to make one fit into the other
+ * or to make them equal, by instantiating uninstantiated type variables.
+ */
+ def homogenizedUnion(tp1: Type, tp2: Type): Type = {
+ def fitInto(tp1: Type, tp2: Type): Unit = tp1 match {
+ case tp1: TypeBounds =>
+ tp2 match {
+ case tp2: TypeBounds =>
+ val nestedCtx = ctx.fresh.setNewTyperState
+ if (tp2.boundsInterval.contains(tp1.boundsInterval)(nestedCtx))
+ nestedCtx.typerState.commit()
+ case _ =>
+ }
+ case _ =>
+ }
+ fitInto(tp1, tp2)
+ fitInto(tp2, tp1)
+ tp1 | tp2
+ }
+
tp1 match {
case tp1: RefinedType =>
tp2 match {
@@ -283,8 +303,8 @@ trait TypeOps { this: Context => // TODO: Make standalone object.
return tp1.derivedRefinedType(
approximateUnion(OrType(tp1.parent, tp2.parent)),
tp1.refinedName,
- (tp1.refinedInfo | tp2.refinedInfo).substRefinedThis(tp2, RefinedThis(tp1)))
- .ensuring { x => println(i"approx or $tp1 | $tp2 = $x"); true } // DEBUG
+ homogenizedUnion(tp1.refinedInfo, tp2.refinedInfo).substRefinedThis(tp2, RefinedThis(tp1)))
+ //.ensuring { x => println(i"approx or $tp1 | $tp2 = $x\n constr = ${ctx.typerState.constraint}"); true } // DEBUG
case _ =>
}
case _ =>