Skip to content

Commit b455dad

Browse files
author
Aleksander Boruch-Gruszecki
committed
Revert "Refactor Constraint to constrain TypeRefs"
This reverts commit 777a8f8.
1 parent b27e78d commit b455dad

File tree

10 files changed

+199
-243
lines changed

10 files changed

+199
-243
lines changed

compiler/src/dotty/tools/dotc/core/Constants.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,7 @@ object Constants {
161161
case TypeBounds(lo, hi) =>
162162
if (hi.classSymbol.isPrimitiveValueClass) hi //constrain further with high bound
163163
else classBound(lo)
164-
case NoType => classBound(param.binder.paramInfos(param.refNum).lo)
164+
case NoType => classBound(param.binder.paramInfos(param.paramNum).lo)
165165
case inst => classBound(inst)
166166
}
167167
case pt => pt

compiler/src/dotty/tools/dotc/core/Constraint.scala

Lines changed: 23 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,6 @@ package core
55
import Types._, Contexts._
66
import printing.Showable
77

8-
object Constraint {
9-
type VarRef = TypeVarRef
10-
type Binder = TypeVarRefBinder
11-
}
12-
138
/** Constraint over undetermined type parameters. Constraints are built
149
* over values of the following types:
1510
*
@@ -19,59 +14,58 @@ object Constraint {
1914
* that has the TypeParamRef as origin.
2015
*/
2116
abstract class Constraint extends Showable {
22-
import Constraint._
2317

2418
type This <: Constraint
2519

2620
/** Does the constraint's domain contain the type parameters of `pt`? */
27-
def contains(pt: Binder): Boolean
21+
def contains(pt: TypeLambda): Boolean
2822

2923
/** Does the constraint's domain contain the type parameter `param`? */
30-
def contains(param: VarRef): Boolean
24+
def contains(param: TypeParamRef): Boolean
3125

3226
/** Does this constraint contain the type variable `tvar` and is it uninstantiated? */
3327
def contains(tvar: TypeVar): Boolean
3428

3529
/** The constraint entry for given type parameter `param`, or NoType if `param` is not part of
3630
* the constraint domain. Note: Low level, implementation dependent.
3731
*/
38-
def entry(param: VarRef): Type
32+
def entry(param: TypeParamRef): Type
3933

4034
/** The type variable corresponding to parameter `param`, or
4135
* NoType, if `param` is not in constrained or is not paired with a type variable.
4236
*/
43-
def typeVarOfParam(param: VarRef): Type
37+
def typeVarOfParam(param: TypeParamRef): Type
4438

4539
/** Is it known that `param1 <:< param2`? */
46-
def isLess(param1: VarRef, param2: VarRef): Boolean
40+
def isLess(param1: TypeParamRef, param2: TypeParamRef): Boolean
4741

4842
/** The parameters that are known to be smaller wrt <: than `param` */
49-
def lower(param: VarRef): List[VarRef]
43+
def lower(param: TypeParamRef): List[TypeParamRef]
5044

5145
/** The parameters that are known to be greater wrt <: than `param` */
52-
def upper(param: VarRef): List[VarRef]
46+
def upper(param: TypeParamRef): List[TypeParamRef]
5347

5448
/** lower(param) \ lower(butNot) */
55-
def exclusiveLower(param: VarRef, butNot: VarRef): List[VarRef]
49+
def exclusiveLower(param: TypeParamRef, butNot: TypeParamRef): List[TypeParamRef]
5650

5751
/** upper(param) \ upper(butNot) */
58-
def exclusiveUpper(param: VarRef, butNot: VarRef): List[VarRef]
52+
def exclusiveUpper(param: TypeParamRef, butNot: TypeParamRef): List[TypeParamRef]
5953

6054
/** The constraint bounds for given type parameter `param`.
6155
* Poly params that are known to be smaller or greater than `param`
6256
* are not contained in the return bounds.
6357
* @pre `param` is not part of the constraint domain.
6458
*/
65-
def nonParamBounds(param: VarRef)(implicit ctx: Context): TypeBounds
59+
def nonParamBounds(param: TypeParamRef)(implicit ctx: Context): TypeBounds
6660

6761
/** The lower bound of `param` including all known-to-be-smaller parameters */
68-
def fullLowerBound(param: VarRef)(implicit ctx: Context): Type
62+
def fullLowerBound(param: TypeParamRef)(implicit ctx: Context): Type
6963

7064
/** The upper bound of `param` including all known-to-be-greater parameters */
71-
def fullUpperBound(param: VarRef)(implicit ctx: Context): Type
65+
def fullUpperBound(param: TypeParamRef)(implicit ctx: Context): Type
7266

7367
/** The bounds of `param` including all known-to-be-smaller and -greater parameters */
74-
def fullBounds(param: VarRef)(implicit ctx: Context): TypeBounds
68+
def fullBounds(param: TypeParamRef)(implicit ctx: Context): TypeBounds
7569

7670
/** A new constraint which is derived from this constraint by adding
7771
* entries for all type parameters of `poly`.
@@ -80,7 +74,7 @@ abstract class Constraint extends Showable {
8074
* satisfiability but will solved to give instances of
8175
* type variables.
8276
*/
83-
def add(poly: Binder, tvars: List[TypeVar])(implicit ctx: Context): This
77+
def add(poly: TypeLambda, tvars: List[TypeVar])(implicit ctx: Context): This
8478

8579
/** A new constraint which is derived from this constraint by updating
8680
* the entry for parameter `param` to `tp`.
@@ -91,44 +85,44 @@ abstract class Constraint extends Showable {
9185
*
9286
* @pre `this contains param`.
9387
*/
94-
def updateEntry(param: VarRef, tp: Type)(implicit ctx: Context): This
88+
def updateEntry(param: TypeParamRef, tp: Type)(implicit ctx: Context): This
9589

9690
/** A constraint that includes the relationship `p1 <: p2`.
9791
* `<:` relationships between parameters ("edges") are propagated, but
9892
* non-parameter bounds are left alone.
9993
*/
100-
def addLess(p1: VarRef, p2: VarRef)(implicit ctx: Context): This
94+
def addLess(p1: TypeParamRef, p2: TypeParamRef)(implicit ctx: Context): This
10195

10296
/** A constraint resulting from adding p2 = p1 to this constraint, and at the same
10397
* time transferring all bounds of p2 to p1
10498
*/
105-
def unify(p1: VarRef, p2: VarRef)(implicit ctx: Context): This
99+
def unify(p1: TypeParamRef, p2: TypeParamRef)(implicit ctx: Context): This
106100

107101
/** A new constraint which is derived from this constraint by removing
108102
* the type parameter `param` from the domain and replacing all top-level occurrences
109103
* of the parameter elsewhere in the constraint by type `tp`, or a conservative
110104
* approximation of it if that is needed to avoid cycles.
111105
* Occurrences nested inside a refinement or prefix are not affected.
112106
*/
113-
def replace(param: VarRef, tp: Type)(implicit ctx: Context): This
107+
def replace(param: TypeParamRef, tp: Type)(implicit ctx: Context): This
114108

115109
/** Is entry associated with `pt` removable? This is the case if
116110
* all type parameters of the entry are associated with type variables
117111
* which have their `inst` fields set.
118112
*/
119-
def isRemovable(pt: Binder): Boolean
113+
def isRemovable(pt: TypeLambda): Boolean
120114

121115
/** A new constraint with all entries coming from `pt` removed. */
122-
def remove(pt: Binder)(implicit ctx: Context): This
116+
def remove(pt: TypeLambda)(implicit ctx: Context): This
123117

124118
/** The type lambdas constrained by this constraint */
125-
def domainLambdas: List[Binder]
119+
def domainLambdas: List[TypeLambda]
126120

127121
/** The type lambda parameters constrained by this constraint */
128-
def domainParams: List[VarRef]
122+
def domainParams: List[TypeParamRef]
129123

130124
/** Check whether predicate holds for all parameters in constraint */
131-
def forallParams(p: VarRef => Boolean): Boolean
125+
def forallParams(p: TypeParamRef => Boolean): Boolean
132126

133127
/** Perform operation `op` on all typevars that do not have their `inst` field set. */
134128
def foreachTypeVar(op: TypeVar => Unit): Unit

compiler/src/dotty/tools/dotc/core/ConstraintHandling.scala

Lines changed: 20 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,6 @@ import config.Printers.{constr, typr}
1919
* Constraint handlers update the current constraint as a side effect.
2020
*/
2121
trait ConstraintHandling {
22-
import Constraint._
2322

2423
def constr_println(msg: => String): Unit = constr.println(msg)
2524
def typr_println(msg: => String): Unit = typr.println(msg)
@@ -61,13 +60,13 @@ trait ConstraintHandling {
6160
*/
6261
def instType(tvar: TypeVar): Type = constraint.entry(tvar.origin) match {
6362
case _: TypeBounds => NoType
64-
case tp: VarRef =>
63+
case tp: TypeParamRef =>
6564
var tvar1 = constraint.typeVarOfParam(tp)
6665
if (tvar1.exists) tvar1 else tp
6766
case tp => tp
6867
}
6968

70-
protected def addOneBound(param: VarRef, bound: Type, isUpper: Boolean): Boolean =
69+
protected def addOneBound(param: TypeParamRef, bound: Type, isUpper: Boolean): Boolean =
7170
!constraint.contains(param) || {
7271
def occursIn(bound: Type): Boolean = {
7372
val b = bound.dealias
@@ -85,7 +84,7 @@ trait ConstraintHandling {
8584
assert(!occursIn(bound), s"$param occurs in $bound")
8685

8786
val oldBounds @ TypeBounds(lo, hi) = constraint.nonParamBounds(param)
88-
val equalBounds = isUpper && (bound eq lo) || !isUpper && (bound eq hi)
87+
val equalBounds = isUpper && (lo eq bound) || !isUpper && (bound eq hi)
8988
if (equalBounds && !bound.existsPart(_.isInstanceOf[WildcardType])) {
9089
// The narrowed bounds are equal and do not contain wildcards,
9190
// so we can remove `param` from the constraint.
@@ -117,7 +116,7 @@ trait ConstraintHandling {
117116

118117
private def location(implicit ctx: Context) = "" // i"in ${ctx.typerState.stateChainStr}" // use for debugging
119118

120-
protected def addUpperBound(param: VarRef, bound: Type): Boolean = {
119+
protected def addUpperBound(param: TypeParamRef, bound: Type): Boolean = {
121120
def description = i"constraint $param <: $bound to\n$constraint"
122121
if (bound.isRef(defn.NothingClass) && ctx.typerState.isGlobalCommittable) {
123122
def msg = s"!!! instantiated to Nothing: $param, constraint = ${constraint.show}"
@@ -133,7 +132,7 @@ trait ConstraintHandling {
133132
res
134133
}
135134

136-
protected def addLowerBound(param: VarRef, bound: Type): Boolean = {
135+
protected def addLowerBound(param: TypeParamRef, bound: Type): Boolean = {
137136
def description = i"constraint $param >: $bound to\n$constraint"
138137
constr_println(i"adding $description")
139138
val upper = constraint.upper(param)
@@ -144,7 +143,7 @@ trait ConstraintHandling {
144143
res
145144
}
146145

147-
protected def addLess(p1: VarRef, p2: VarRef): Boolean = {
146+
protected def addLess(p1: TypeParamRef, p2: TypeParamRef): Boolean = {
148147
def description = i"ordering $p1 <: $p2 to\n$constraint"
149148
val res =
150149
if (constraint.isLess(p2, p1)) unify(p2, p1)
@@ -166,7 +165,7 @@ trait ConstraintHandling {
166165
/** Make p2 = p1, transfer all bounds of p2 to p1
167166
* @pre less(p1)(p2)
168167
*/
169-
private def unify(p1: VarRef, p2: VarRef): Boolean = {
168+
private def unify(p1: TypeParamRef, p2: TypeParamRef): Boolean = {
170169
constr_println(s"unifying $p1 $p2")
171170
assert(constraint.isLess(p1, p2))
172171
val down = constraint.exclusiveLower(p2, p1)
@@ -225,7 +224,7 @@ trait ConstraintHandling {
225224
* @return the instantiating type
226225
* @pre `param` is in the constraint's domain.
227226
*/
228-
final def approximation(param: VarRef, fromBelow: Boolean): Type = {
227+
final def approximation(param: TypeParamRef, fromBelow: Boolean): Type = {
229228
val avoidParam = new TypeMap {
230229
override def stopAtStatic = true
231230
def avoidInArg(arg: Type): Type =
@@ -284,9 +283,9 @@ trait ConstraintHandling {
284283
case tp: SingletonType => true
285284
case AndType(tp1, tp2) => isMultiSingleton(tp1) | isMultiSingleton(tp2)
286285
case OrType(tp1, tp2) => isMultiSingleton(tp1) & isMultiSingleton(tp2)
287-
case tp: TypeRef if !constraint.contains(tp : VarRef) => isMultiSingleton(tp.info.hiBound)
286+
case tp: TypeRef => isMultiSingleton(tp.info.hiBound)
288287
case tp: TypeVar => isMultiSingleton(tp.underlying)
289-
case tp: VarRef => isMultiSingleton(bounds(tp).hi)
288+
case tp: TypeParamRef => isMultiSingleton(bounds(tp).hi)
290289
case _ => false
291290
}
292291
def isOrType(tp: Type): Boolean = tp.dealias match {
@@ -312,7 +311,7 @@ trait ConstraintHandling {
312311
* a lower bound instantiation can be a singleton type only if the upper bound
313312
* is also a singleton type.
314313
*/
315-
def instanceType(param: VarRef, fromBelow: Boolean): Type = {
314+
def instanceType(param: TypeParamRef, fromBelow: Boolean): Type = {
316315
val inst = approximation(param, fromBelow).simplified
317316
if (fromBelow) widenInferred(inst, constraint.fullUpperBound(param)) else inst
318317
}
@@ -341,12 +340,12 @@ trait ConstraintHandling {
341340
}
342341

343342
/** The current bounds of type parameter `param` */
344-
def bounds(param: VarRef): TypeBounds = {
343+
def bounds(param: TypeParamRef): TypeBounds = {
345344
val e = constraint.entry(param)
346345
if (e.exists) e.bounds
347346
else {
348-
val pinfos = param.binder.refInfos
349-
if (pinfos != null) pinfos(param.refNum) // pinfos == null happens in pos/i536.scala
347+
val pinfos = param.binder.paramInfos
348+
if (pinfos != null) pinfos(param.paramNum) // pinfos == null happens in pos/i536.scala
350349
else TypeBounds.empty
351350
}
352351
}
@@ -355,10 +354,10 @@ trait ConstraintHandling {
355354
* and propagate all bounds.
356355
* @param tvars See Constraint#add
357356
*/
358-
def addToConstraint(tl: Binder, tvars: List[TypeVar]): Boolean =
357+
def addToConstraint(tl: TypeLambda, tvars: List[TypeVar]): Boolean =
359358
checkPropagated(i"initialized $tl") {
360359
constraint = constraint.add(tl, tvars)
361-
tl.boundRefs.forall { param =>
360+
tl.paramRefs.forall { param =>
362361
constraint.entry(param) match {
363362
case bounds: TypeBounds =>
364363
val lower = constraint.lower(param)
@@ -376,14 +375,14 @@ trait ConstraintHandling {
376375
}
377376

378377
/** Can `param` be constrained with new bounds? */
379-
final def canConstrain(param: VarRef): Boolean =
378+
final def canConstrain(param: TypeParamRef): Boolean =
380379
(!frozenConstraint || (caseLambda `eq` param.binder)) && constraint.contains(param)
381380

382381
/** Is `param` assumed to be a sub- and super-type of any other type?
383382
* This holds if `TypeVarsMissContext` is set unless `param` is a part
384383
* of a MatchType that is currently normalized.
385384
*/
386-
final def assumedTrue(param: VarRef): Boolean =
385+
final def assumedTrue(param: TypeParamRef): Boolean =
387386
ctx.mode.is(Mode.TypevarsMissContext) && (caseLambda `ne` param.binder)
388387

389388
/** Add constraint `param <: bound` if `fromBelow` is false, `param >: bound` otherwise.
@@ -393,7 +392,7 @@ trait ConstraintHandling {
393392
* not be AndTypes and lower bounds may not be OrTypes. This is assured by the
394393
* way isSubType is organized.
395394
*/
396-
protected def addConstraint(param: VarRef, bound: Type, fromBelow: Boolean): Boolean = {
395+
protected def addConstraint(param: TypeParamRef, bound: Type, fromBelow: Boolean): Boolean = {
397396
def description = i"constr $param ${if (fromBelow) ">:" else "<:"} $bound:\n$constraint"
398397
//checkPropagated(s"adding $description")(true) // DEBUG in case following fails
399398
checkPropagated(s"added $description") {
@@ -523,7 +522,7 @@ trait ConstraintHandling {
523522
if (Config.checkConstraintsPropagated && result && addConstraintInvocations == 0) {
524523
inFrozenConstraint {
525524
for (p <- constraint.domainParams) {
526-
def check(cond: => Boolean, q: VarRef, ordering: String, explanation: String): Unit =
525+
def check(cond: => Boolean, q: TypeParamRef, ordering: String, explanation: String): Unit =
527526
assert(cond, i"propagation failure for $p $ordering $q: $explanation\n$msg")
528527
for (u <- constraint.upper(p))
529528
check(bounds(p).hi <:< bounds(u).hi, u, "<:", "upper bound not propagated")

0 commit comments

Comments
 (0)