From f76e81ed5cc5f57fcbdde6ea98503bd031c903a2 Mon Sep 17 00:00:00 2001 From: Martin Odersky Date: Mon, 12 Jan 2015 18:37:47 +0100 Subject: Streamline unification Instead of recording a `TypeAlias(p)` for the entry of an eliminated parameter we record directly the solution `p`. --- src/dotty/tools/dotc/core/ConstraintHandling.scala | 67 +++++++++++----------- src/dotty/tools/dotc/core/NaiveConstraint.scala | 2 +- 2 files changed, 33 insertions(+), 36 deletions(-) diff --git a/src/dotty/tools/dotc/core/ConstraintHandling.scala b/src/dotty/tools/dotc/core/ConstraintHandling.scala index d8078e26b..264cff012 100644 --- a/src/dotty/tools/dotc/core/ConstraintHandling.scala +++ b/src/dotty/tools/dotc/core/ConstraintHandling.scala @@ -107,44 +107,41 @@ trait ConstraintHandling { * make sure 'B >: A' gets added and vice versa. Furthermore, if the constraint * implies 'A <: B <: A', A and B get unified. */ - def addc(param: PolyParam, bound: Type, fromBelow: Boolean): Boolean = - constraint.bounds(param) match { - case TypeBounds(plo: PolyParam, phi) if (plo eq phi) && constraint.contains(plo) => - addc(plo, bound, fromBelow) - case pbounds0 => - bound match { - case bound: PolyParam if constraint contains bound => - val bbounds0 @ TypeBounds(lo, hi) = constraint.bounds(bound) - if (lo eq hi) - addc(param, lo, fromBelow) - else if (param == bound) - true - else if (fromBelow && param.occursIn(lo, fromBelow = true)) - unify(param, bound) - else if (!fromBelow && param.occursIn(hi, fromBelow = false)) - unify(bound, param) - else { - val pbounds = prepare(param, bound, fromBelow) - val bbounds = prepare(bound, param, !fromBelow) - pbounds.exists && bbounds.exists && { - install(param, pbounds.bounds, pbounds0) - install(bound, bbounds.bounds, bbounds0) - true - } - } - case bound: AndOrType if fromBelow != bound.isAnd => - addc(param, bound.tp1, fromBelow) && - addc(param, bound.tp2, fromBelow) - case bound: WildcardType => + def addc(param: PolyParam, bound: Type, fromBelow: Boolean): Boolean = { + val pbounds0 = constraint.bounds(param) + bound match { + case bound: PolyParam if constraint contains bound => + val bbounds0 @ TypeBounds(lo, hi) = constraint.bounds(bound) + if (lo eq hi) + addc(param, lo, fromBelow) + else if (param == bound) + true + else if (fromBelow && param.occursIn(lo, fromBelow = true)) + unify(param, bound) + else if (!fromBelow && param.occursIn(hi, fromBelow = false)) + unify(bound, param) + else { + val pbounds = prepare(param, bound, fromBelow) + val bbounds = prepare(bound, param, !fromBelow) + pbounds.exists && bbounds.exists && { + install(param, pbounds.bounds, pbounds0) + install(bound, bbounds.bounds, bbounds0) true - case bound => // !!! remove to keep the originals - val pbounds = prepare(param, bound, fromBelow) - pbounds.exists && { - install(param, pbounds.bounds, pbounds0) - true - } + } + } + case bound: AndOrType if fromBelow != bound.isAnd => + addc(param, bound.tp1, fromBelow) && + addc(param, bound.tp2, fromBelow) + case bound: WildcardType => + true + case bound => // !!! remove to keep the originals + val pbounds = prepare(param, bound, fromBelow) + pbounds.exists && { + install(param, pbounds.bounds, pbounds0) + true } } + } /** Install bounds for param */ def install(param: PolyParam, newBounds: TypeBounds, oldBounds: TypeBounds): Unit = { diff --git a/src/dotty/tools/dotc/core/NaiveConstraint.scala b/src/dotty/tools/dotc/core/NaiveConstraint.scala index 34affc35a..f79a7d05f 100644 --- a/src/dotty/tools/dotc/core/NaiveConstraint.scala +++ b/src/dotty/tools/dotc/core/NaiveConstraint.scala @@ -304,7 +304,7 @@ class NaiveConstraint(private val myMap: ParamInfo) extends Constraint { val p1Bounds = dropParamIn(bounds(p1), p2.binder, p2.paramNum) & dropParamIn(bounds(p2), p1.binder, p1.paramNum) - this.updated(p1, p1Bounds).updated(p2, TypeAlias(p1)) + this.updated(p1, p1Bounds).updated(p2, p1) } def add(poly: PolyType, tvars: List[TypeVar])(implicit ctx: Context): This = { -- cgit v1.2.3