diff options
author | odersky <odersky@gmail.com> | 2017-01-11 10:15:14 +0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-01-11 10:15:14 +0700 |
commit | 486b0293dd07a3d969d75aaa1aeb438ce14ae726 (patch) | |
tree | 75f55e4a9b8b372eb24c3cda3f7e808ebf8bded4 /compiler | |
parent | d62a2c911ce481d8d7e2ebd84173b77fc628cc00 (diff) | |
parent | 918a3fba3ceeebf0bc3e0087f9ead63f4ae30381 (diff) | |
download | dotty-486b0293dd07a3d969d75aaa1aeb438ce14ae726.tar.gz dotty-486b0293dd07a3d969d75aaa1aeb438ce14ae726.tar.bz2 dotty-486b0293dd07a3d969d75aaa1aeb438ce14ae726.zip |
Merge pull request #1893 from dotty-staging/fix-#1891
Fix #1891: Don't add redundant constraint
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala | 1 | ||||
-rw-r--r-- | compiler/src/dotty/tools/dotc/core/TypeComparer.scala | 15 |
2 files changed, 14 insertions, 2 deletions
diff --git a/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala b/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala index 0e155b9e1..42df53fed 100644 --- a/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala +++ b/compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala @@ -57,6 +57,7 @@ trait ConstraintHandling { b match { case b: AndOrType => occursIn(b.tp1) || occursIn(b.tp2) case b: TypeVar => occursIn(b.origin) + case b: TermRef => occursIn(b.underlying) case _ => false } } diff --git a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala index 8930983f3..6063cbf38 100644 --- a/compiler/src/dotty/tools/dotc/core/TypeComparer.scala +++ b/compiler/src/dotty/tools/dotc/core/TypeComparer.scala @@ -375,11 +375,22 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling { thirdTryNamed(tp1, tp2) case tp2: PolyParam => def comparePolyParam = - (ctx.mode is Mode.TypevarsMissContext) || - isSubTypeWhenFrozen(tp1, bounds(tp2).lo) || { + (ctx.mode is Mode.TypevarsMissContext) || { + val alwaysTrue = + // The following condition is carefully formulated to catch all cases + // where the subtype relation is true without needing to add a constraint + // It's tricky because we might need to either appriximate tp2 by its + // lower bound or else widen tp1 and check that the result is a subtype of tp2. + // So if the constraint is not yet frozen, we do the same comparison again + // with a frozen constraint, which means that we get a chance to do the + // widening in `fourthTry` before adding to the constraint. + if (frozenConstraint || alwaysFluid) isSubType(tp1, bounds(tp2).lo) + else isSubTypeWhenFrozen(tp1, tp2) + alwaysTrue || { if (canConstrain(tp2)) addConstraint(tp2, tp1.widenExpr, fromBelow = true) else fourthTry(tp1, tp2) } + } comparePolyParam case tp2: RefinedType => def compareRefinedSlow: Boolean = { |