diff options
Diffstat (limited to 'src/dotty/tools/dotc/core/TrackingConstraint.scala')
-rw-r--r-- | src/dotty/tools/dotc/core/TrackingConstraint.scala | 122 |
1 files changed, 61 insertions, 61 deletions
diff --git a/src/dotty/tools/dotc/core/TrackingConstraint.scala b/src/dotty/tools/dotc/core/TrackingConstraint.scala index 3f15f2b37..fc8a083f4 100644 --- a/src/dotty/tools/dotc/core/TrackingConstraint.scala +++ b/src/dotty/tools/dotc/core/TrackingConstraint.scala @@ -30,14 +30,14 @@ import TrackingConstraint._ * An instantiated type parameter is represented by having its instance type in * the corresponding array entry. */ -class TrackingConstraint(private val myMap: ParamInfo, - private val less: Array[BitSet], +class TrackingConstraint(private val myMap: ParamInfo, + private val less: Array[BitSet], private val params: Array[PolyParam]) extends Constraint { - + type This = TrackingConstraint - + assert(less.length == params.length) - + /** A new constraint which is derived from this constraint by adding or replacing * the entries corresponding to `pt` with `entries`. */ @@ -47,19 +47,19 @@ class TrackingConstraint(private val myMap: ParamInfo, ctx.runInfo.recordConstraintSize(result, result.myMap.size) result } - + // ----------- Basic indices -------------------------------------------------- /** The immutable array of constrained polytypes */ private val polyTypes = new Array[PolyType](myMap.size) - + /** The start positions of parameters of constrained polytypes in `params` and `less` */ private val polyStart = new Array[Int](myMap.size) - + { var idx = 0 var count = 0 - myMap.foreachBinding { (pt, _) => + myMap.foreachBinding { (pt, _) => polyTypes(idx) = pt polyStart(idx) = count count += pt.paramNames.length @@ -67,8 +67,8 @@ class TrackingConstraint(private val myMap: ParamInfo, } assert(count == params.length) } - - /** The index of given polytype `pt` in this constraint, + + /** The index of given polytype `pt` in this constraint, * or `polyTypes.length` if constraint does not contain `pt`. */ private def polyIndex(pt: PolyType): Int = { @@ -76,16 +76,16 @@ class TrackingConstraint(private val myMap: ParamInfo, while (i < polyTypes.length && (polyTypes(i) ne pt)) i += 1 i } - + /** The index of the first parameter of given polytype `pt` in this constraint */ private def polyStart(pt: PolyType): Int = this.polyStart.apply(polyIndex(pt)) - + /** The index of `param` in `params` and `less` */ private def paramIndex(param: PolyParam): Int = { assert(contains(param.binder)) polyStart(param.binder) + param.paramNum } - + /** The number of type parameters in the given entry array */ private def paramCount(entries: Array[Type]) = entries.length >> 1 @@ -98,7 +98,7 @@ class TrackingConstraint(private val myMap: ParamInfo, if (entries == null) NoType else entries(param.paramNum) } - + // ----------- Contains tests -------------------------------------------------- def contains(pt: PolyType): Boolean = polyIndex(pt) < polyTypes.length @@ -116,59 +116,59 @@ class TrackingConstraint(private val myMap: ParamInfo, } private def isBounds(tp: Type) = tp.isInstanceOf[TypeBounds] - + // ---------- Dependency handling ---------------------------------------------- - + private def upperBits(less: Array[BitSet], i: Int): BitSet = less(i) - - private def lowerBits(less: Array[BitSet], i: Int): BitSet = + + private def lowerBits(less: Array[BitSet], i: Int): BitSet = (BitSet() /: less.indices) ((bits, j) => if (less(j)(i)) bits + j else bits) - + private def minUpperBits(less: Array[BitSet], i: Int): BitSet = { val all = upperBits(less, i) all.filterNot(j => all.exists(k => less(k)(j))) } - + private def minLowerBits(less: Array[BitSet], i: Int): BitSet = { val all = lowerBits(less, i) all.filterNot(j => all.exists(k => less(j)(k))) } - + private def overParams(op: (Array[BitSet], Int) => BitSet): PolyParam => List[PolyParam] = param => op(less, paramIndex(param)).toList.map(params).filter(contains) - + val allUpper = overParams(upperBits) val allLower = overParams(lowerBits) val minUpper = overParams(minUpperBits) val minLower = overParams(minLowerBits) - + def upper(param: PolyParam): List[PolyParam] = allUpper(param) def lower(param: PolyParam): List[PolyParam] = allLower(param) - + def exclusiveLower(param: PolyParam, butNot: PolyParam): List[PolyParam] = { val excluded = lowerBits(less, paramIndex(butNot)) overParams(lowerBits(_, _) &~ excluded)(param) } - + def exclusiveUpper(param: PolyParam, butNot: PolyParam): List[PolyParam] = { val excluded = upperBits(less, paramIndex(butNot)) overParams(upperBits(_, _) &~ excluded)(param) } - + // ---------- Info related to PolyParams ------------------------------------------- - def isLess(param1: PolyParam, param2: PolyParam)(implicit ctx: Context): Boolean = + def isLess(param1: PolyParam, param2: PolyParam): Boolean = less(paramIndex(param1))(paramIndex(param2)) - def nonParamBounds(param: PolyParam): TypeBounds = + def nonParamBounds(param: PolyParam): TypeBounds = entry(param).asInstanceOf[TypeBounds] - + def fullLowerBound(param: PolyParam)(implicit ctx: Context): Type = (nonParamBounds(param).lo /: minLower(param))(_ | _) - def fullUpperBound(param: PolyParam)(implicit ctx: Context): Type = + def fullUpperBound(param: PolyParam)(implicit ctx: Context): Type = (nonParamBounds(param).hi /: minUpper(param))(_ & _) - + def fullBounds(param: PolyParam)(implicit ctx: Context): TypeBounds = nonParamBounds(param).derivedTypeBounds(fullLowerBound(param), fullUpperBound(param)) @@ -180,16 +180,16 @@ class TrackingConstraint(private val myMap: ParamInfo, if (tvar != null) tvar else NoType } } - + // ---------- Adding PolyTypes -------------------------------------------------- - + /** The bound type `tp` without dependent parameters * NoType if type consists only of dependent parameters. * @param seenFromBelow If true, `bound` is an upper bound, else a lower bound. */ - private def stripParams(tp: Type, handleParam: (PolyParam, Boolean) => Type, + private def stripParams(tp: Type, handleParam: (PolyParam, Boolean) => Type, seenFromBelow: Boolean)(implicit ctx: Context): Type = tp match { - case tp: PolyParam => + case tp: PolyParam => handleParam(tp, seenFromBelow) case tp: AndOrType if seenFromBelow == tp.isAnd => val tp1 = stripParams(tp.tp1, handleParam, seenFromBelow) @@ -200,17 +200,17 @@ class TrackingConstraint(private val myMap: ParamInfo, else tp2 case _ => tp - } - + } + /** The bound type `tp` without dependent parameters. * A top or bottom type if type consists only of dependent parameters. * @param seenFromBelow If true, `bound` is an upper bound, else a lower bound. */ - private def nonParamType(tp: Type, handleParam: (PolyParam, Boolean) => Type, - seenFromBelow: Boolean)(implicit ctx: Context): Type = + private def nonParamType(tp: Type, handleParam: (PolyParam, Boolean) => Type, + seenFromBelow: Boolean)(implicit ctx: Context): Type = stripParams(tp, handleParam, seenFromBelow) .orElse(if (seenFromBelow) defn.AnyType else defn.NothingType) - + /** The bounds of `tp1` without dependent parameters. * @pre `tp` is a TypeBounds type. */ @@ -234,7 +234,7 @@ class TrackingConstraint(private val myMap: ParamInfo, for (i <- is) { def handleParam(param: PolyParam, seenFromBelow: Boolean): Type = { def record(paramIdx: Int): Type = { - less1 = + less1 = if (seenFromBelow) updatedLess(less1, nparams + i, paramIdx) else updatedLess(less1, paramIdx, nparams + i) NoType @@ -247,9 +247,9 @@ class TrackingConstraint(private val myMap: ParamInfo, } newConstraint(myMap.updated(poly, entries1), less1, params1) } - + // ---------- Updates ------------------------------------------------------------ - + /** An updated partial order matrix that incorporates `less` and also reflects that `param` relates * to `p2` wrt <:< if `inOrder` is true, `>:>` otherwise. */ @@ -267,31 +267,31 @@ class TrackingConstraint(private val myMap: ParamInfo, result } } - + def addLess(p1: PolyParam, p2: PolyParam)(implicit ctx: Context): This = { val less1 = updatedLess(less, paramIndex(p1), paramIndex(p2)) if (less1 eq less) this else newConstraint(myMap, less1, params) } - + def updateEntry(param: PolyParam, tp: Type)(implicit ctx: Context): This = { val entries = myMap(param.binder) val entry = entries(param.paramNum) - if (entry eq tp) this + if (entry eq tp) this else { val entries1 = entries.clone entries1(param.paramNum) = tp newConstraint(myMap.updated(param.binder, entries1), less, params) - } + } } def unify(p1: PolyParam, p2: PolyParam)(implicit ctx: Context): This = { val p1Bounds = (nonParamBounds(p1) & nonParamBounds(p2)).substParam(p2, p1) 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 = + val oldBounds @ TypeBounds(lo, hi) = nonParamBounds(param) + val newBounds = if (isUpper) oldBounds.derivedTypeBounds(lo, hi & bound) else oldBounds.derivedTypeBounds(lo | bound, hi) if (newBounds eq oldBounds) this @@ -342,8 +342,8 @@ class TrackingConstraint(private val myMap: ParamInfo, } result } - - if (param == replacement) this + + if (param == replacement) this else { assert(replacement.isValueType) val pt = param.binder @@ -355,7 +355,7 @@ class TrackingConstraint(private val myMap: ParamInfo, def remove(pt: PolyType)(implicit ctx: Context): This = { val start = polyStart(pt) val skipped = pt.paramNames.length - + def shrinkSet(bits: BitSet): BitSet = (BitSet() /: bits) ((res, i) => if (i < start) res + i @@ -364,12 +364,12 @@ class TrackingConstraint(private val myMap: ParamInfo, def shrinkArray[T: ClassTag](src: Array[T]) = { val dst = new Array[T](src.length - skipped) Array.copy(src, 0, dst, 0, start) - Array.copy(src, start + skipped, dst, start, dst.length - start) + Array.copy(src, start + skipped, dst, start, dst.length - start) dst } newConstraint( - myMap = myMap remove pt, - less = shrinkArray(less).map(shrinkSet(_)), + myMap = myMap remove pt, + less = shrinkArray(less).map(shrinkSet(_)), params = shrinkArray(params)) } @@ -438,14 +438,14 @@ class TrackingConstraint(private val myMap: ParamInfo, def checkNonCyclic()(implicit ctx: Context): Unit = for (i <- params.indices) checkNonCyclic(i) - + // ---------- toText ----------------------------------------------------- override def toText(printer: Printer): Text = { def entryText(tp: Type) = tp match { - case tp: TypeBounds => + case tp: TypeBounds => tp.toText(printer) - case _ => + case _ => " := " ~ tp.toText(printer) } val indent = 3 @@ -469,7 +469,7 @@ class TrackingConstraint(private val myMap: ParamInfo, ups = minUpper(param) if ups.nonEmpty } - yield + yield (" " * indent) ~ param.toText(printer) ~ " <: " ~ Text(ups.map(_.toText(printer)), ", ") Text(deps, "\n") |