aboutsummaryrefslogtreecommitdiff
path: root/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala
diff options
context:
space:
mode:
authorodersky <odersky@gmail.com>2017-03-09 10:20:25 +0100
committerGitHub <noreply@github.com>2017-03-09 10:20:25 +0100
commit8e5c9c4a1a4555883307b7e81fea064134f350f2 (patch)
treee2feee0b87ed785e32ed8ba8fa2953128498f917 /compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala
parent6abaa109e1add82f4add605a5cb3243e34b1ee33 (diff)
parentc7f1f35c36593ac9454c8572a59c649610829b6a (diff)
downloaddotty-8e5c9c4a1a4555883307b7e81fea064134f350f2.tar.gz
dotty-8e5c9c4a1a4555883307b7e81fea064134f350f2.tar.bz2
dotty-8e5c9c4a1a4555883307b7e81fea064134f350f2.zip
Merge pull request #2045 from dotty-staging/fix-hlist-hmap
Fix type inference for HLists and HMaps
Diffstat (limited to 'compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala')
-rw-r--r--compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala24
1 files changed, 23 insertions, 1 deletions
diff --git a/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala b/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala
index b3c50fb71..2a1f4ee6e 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) {