aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/Types.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2014-03-01 18:16:58 +0100
committerMartin Odersky <odersky@gmail.com>2014-03-01 18:16:58 +0100
commit340ca0615bc40ca0232143b1d7e206c56e721c5c (patch)
tree0a648f4ff290bbd1919ca705c3f6e6288f4bbd64 /src/dotty/tools/dotc/core/Types.scala
parentd8356b6dc9221bfc38b1f167e5cfafcc9261f3d7 (diff)
downloaddotty-340ca0615bc40ca0232143b1d7e206c56e721c5c.tar.gz
dotty-340ca0615bc40ca0232143b1d7e206c56e721c5c.tar.bz2
dotty-340ca0615bc40ca0232143b1d7e206c56e721c5c.zip
Fixing glb/lub of TypeBounds
Need to take variances into account when forming & or | of bounds. Achieved by moving code from distributeAnd/Or to TypeBounds &/|.
Diffstat (limited to 'src/dotty/tools/dotc/core/Types.scala')
-rw-r--r--src/dotty/tools/dotc/core/Types.scala18
1 files changed, 14 insertions, 4 deletions
diff --git a/src/dotty/tools/dotc/core/Types.scala b/src/dotty/tools/dotc/core/Types.scala
index 6973af726..1aaa85481 100644
--- a/src/dotty/tools/dotc/core/Types.scala
+++ b/src/dotty/tools/dotc/core/Types.scala
@@ -1883,11 +1883,21 @@ object Types {
def contains(tp: Type)(implicit ctx: Context) = lo <:< tp && tp <:< hi
- def & (that: TypeBounds)(implicit ctx: Context): TypeBounds =
- derivedTypeBounds(this.lo | that.lo, this.hi & that.hi, this commonVariance that)
+ def & (that: TypeBounds)(implicit ctx: Context): TypeBounds = {
+ val v = this commonVariance that
+ if (v != 0 && (this.lo eq this.hi) && (that.lo eq that.hi))
+ if (v > 0) derivedTypeAlias(this.hi & that.hi, v)
+ else derivedTypeAlias(this.lo | that.lo, v)
+ else derivedTypeBounds(this.lo | that.lo, this.hi & that.hi, v)
+ }
- def | (that: TypeBounds)(implicit ctx: Context): TypeBounds =
- derivedTypeBounds(this.lo & that.lo, this.hi | that.hi, this commonVariance that)
+ def | (that: TypeBounds)(implicit ctx: Context): TypeBounds = {
+ val v = this commonVariance that
+ if (v == 0 && (this.lo eq this.hi) && (that.lo eq that.hi))
+ if (v > 0) derivedTypeAlias(this.hi | that.hi, v)
+ else derivedTypeAlias(this.lo & that.lo, v)
+ else derivedTypeBounds(this.lo & that.lo, this.hi | that.hi, v)
+ }
override def & (that: Type)(implicit ctx: Context) = that match {
case that: TypeBounds => this & that