aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools/dotc/core
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2017-03-01 22:10:17 +0100
committerMartin Odersky <odersky@gmail.com>2017-03-01 22:11:45 +0100
commit1d237bb1f0c7aac949b52601e26e96fff0fe4ffd (patch)
treefc1f8cdcf01bc9939ee50b1d138c00616ddbc72d /compiler/src/dotty/tools/dotc/core
parent58b71ca50ded400efa92ac8d92f4378844baaf7d (diff)
downloaddotty-1d237bb1f0c7aac949b52601e26e96fff0fe4ffd.tar.gz
dotty-1d237bb1f0c7aac949b52601e26e96fff0fe4ffd.tar.bz2
dotty-1d237bb1f0c7aac949b52601e26e96fff0fe4ffd.zip
Make alignArgsInAnd safe and turn it on by default
Turned out hmaps.scala requires the arg alignment to compile. So we have our first counterexample that we cannot drop this hack. Now it is made safe in the sense that no constraints get lost anymore.
Diffstat (limited to 'compiler/src/dotty/tools/dotc/core')
-rw-r--r--compiler/src/dotty/tools/dotc/core/Constraint.scala6
-rw-r--r--compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala24
-rw-r--r--compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala8
-rw-r--r--compiler/src/dotty/tools/dotc/core/TypeComparer.scala4
4 files changed, 25 insertions, 17 deletions
diff --git a/compiler/src/dotty/tools/dotc/core/Constraint.scala b/compiler/src/dotty/tools/dotc/core/Constraint.scala
index c99b748b7..50136a26c 100644
--- a/compiler/src/dotty/tools/dotc/core/Constraint.scala
+++ b/compiler/src/dotty/tools/dotc/core/Constraint.scala
@@ -111,12 +111,6 @@ abstract class Constraint extends Showable {
*/
def replace(param: PolyParam, tp: Type)(implicit ctx: Context): This
- /** Narrow one of the bounds of type parameter `param`
- * If `isUpper` is true, ensure that `param <: `bound`, otherwise ensure
- * that `param >: bound`.
- */
- def narrowBound(param: PolyParam, bound: Type, isUpper: Boolean)(implicit ctx: Context): This
-
/** Is entry associated with `pt` removable? This is the case if
* all type parameters of the entry are associated with type variables
* which have their `inst` fields set.
diff --git a/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala b/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala
index 3aa20f15b..89861f6db 100644
--- a/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala
+++ b/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala
@@ -44,6 +44,13 @@ trait ConstraintHandling {
try op finally alwaysFluid = saved
}
+ /** If set, align arguments `S1`, `S2`when taking the glb
+ * `T1 { X = S1 } & T2 { X = S2 }` of a constraint upper bound for some type parameter.
+ * Aligning means computing `S1 =:= S2` which may change the current constraint.
+ * See note in TypeComparer#distributeAnd.
+ */
+ protected var homogenizeArgs = false
+
/** We are currently comparing polytypes. Used as a flag for
* optimization: when `false`, no need to do an expensive `pruneLambdaParams`
*/
@@ -64,7 +71,8 @@ trait ConstraintHandling {
}
if (Config.checkConstraintsSeparated)
assert(!occursIn(bound), s"$param occurs in $bound")
- val c1 = constraint.narrowBound(param, bound, isUpper)
+ val newBound = narrowedBound(param, bound, isUpper)
+ val c1 = constraint.updateEntry(param, newBound)
(c1 eq constraint) || {
constraint = c1
val TypeBounds(lo, hi) = constraint.entry(param)
@@ -72,6 +80,20 @@ trait ConstraintHandling {
}
}
+ /** Narrow one of the bounds of type parameter `param`
+ * If `isUpper` is true, ensure that `param <: `bound`, otherwise ensure
+ * that `param >: bound`.
+ */
+ def narrowedBound(param: PolyParam, bound: Type, isUpper: Boolean)(implicit ctx: Context): TypeBounds = {
+ val oldBounds @ TypeBounds(lo, hi) = constraint.nonParamBounds(param)
+ val saved = homogenizeArgs
+ homogenizeArgs = Config.alignArgsInAnd
+ try
+ if (isUpper) oldBounds.derivedTypeBounds(lo, hi & bound)
+ else oldBounds.derivedTypeBounds(lo | bound, hi)
+ finally homogenizeArgs = saved
+ }
+
protected def addUpperBound(param: PolyParam, bound: Type): Boolean = {
def description = i"constraint $param <: $bound to\n$constraint"
if (bound.isRef(defn.NothingClass) && ctx.typerState.isGlobalCommittable) {
diff --git a/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala b/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala
index 72c7a8e51..61dd5a445 100644
--- a/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala
+++ b/compiler/src/dotty/tools/dotc/core/OrderingConstraint.scala
@@ -354,14 +354,6 @@ class OrderingConstraint(private val boundsMap: ParamBounds,
updateEntry(p1, p1Bounds).replace(p2, p1)
}
- def narrowBound(param: PolyParam, bound: Type, isUpper: Boolean)(implicit ctx: Context): This = {
- val oldBounds @ TypeBounds(lo, hi) = nonParamBounds(param)
- val newBounds =
- if (isUpper) oldBounds.derivedTypeBounds(lo, hi & bound)
- else oldBounds.derivedTypeBounds(lo | bound, hi)
- updateEntry(param, newBounds)
- }
-
// ---------- Removals ------------------------------------------------------------
/** A new constraint which is derived from this constraint by removing
diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala
index 744112280..6042cc12c 100644
--- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala
+++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala
@@ -1315,7 +1315,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
// Given two refinements `T1 { X = S1 }` and `T2 { X = S2 }` rwrite to
// `T1 & T2 { X B }` where `B` is the conjunction of the bounds of `X` in `T1` and `T2`.
//
- // However, if `Config.alignArgsInAnd` is set, and both aliases `X = Si` are
+ // However, if `homogenizeArgs` is set, and both aliases `X = Si` are
// nonvariant, and `S1 =:= S2` (possibly by instantiating type parameters),
// rewrite instead to `T1 & T2 { X = S1 }`. This rule is contentious because
// it cuts the constraint set. On the other hand, without it we would replace
@@ -1329,7 +1329,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
case tp: TypeAlias => tp.variance == 0
case _ => false
}
- if (Config.alignArgsInAnd &&
+ if (homogenizeArgs &&
isNonvariantAlias(rinfo1) && isNonvariantAlias(rinfo2))
isSameType(rinfo1, rinfo2)