@@ -18,15 +18,15 @@ import config.Printers.{constr, typr}
18
18
* By comparison: Constraint handlers are parts of type comparers and can use their functionality.
19
19
* Constraint handlers update the current constraint as a side effect.
20
20
*/
21
- trait ConstraintHandling {
21
+ trait ConstraintHandling [ AbstractContext ] {
22
22
23
23
def constr_println (msg : => String ): Unit = constr.println(msg)
24
24
def typr_println (msg : => String ): Unit = typr.println(msg)
25
25
26
- implicit def ctx : Context
26
+ implicit def ctx ( implicit ac : AbstractContext ) : Context
27
27
28
- protected def isSubType (tp1 : Type , tp2 : Type ): Boolean
29
- protected def isSameType (tp1 : Type , tp2 : Type ): Boolean
28
+ protected def isSubType (tp1 : Type , tp2 : Type )( implicit actx : AbstractContext ) : Boolean
29
+ protected def isSameType (tp1 : Type , tp2 : Type )( implicit actx : AbstractContext ) : Boolean
30
30
31
31
protected def constraint : Constraint
32
32
protected def constraint_= (c : Constraint ): Unit
@@ -66,7 +66,7 @@ trait ConstraintHandling {
66
66
case tp => tp
67
67
}
68
68
69
- protected def addOneBound (param : TypeParamRef , bound : Type , isUpper : Boolean ): Boolean =
69
+ protected def addOneBound (param : TypeParamRef , bound : Type , isUpper : Boolean )( implicit actx : AbstractContext ) : Boolean =
70
70
! constraint.contains(param) || {
71
71
def occursIn (bound : Type ): Boolean = {
72
72
val b = bound.dealias
@@ -116,7 +116,7 @@ trait ConstraintHandling {
116
116
117
117
private def location (implicit ctx : Context ) = " " // i"in ${ctx.typerState.stateChainStr}" // use for debugging
118
118
119
- protected def addUpperBound (param : TypeParamRef , bound : Type ): Boolean = {
119
+ protected def addUpperBound (param : TypeParamRef , bound : Type )( implicit actx : AbstractContext ) : Boolean = {
120
120
def description = i " constraint $param <: $bound to \n $constraint"
121
121
if (bound.isRef(defn.NothingClass ) && ctx.typerState.isGlobalCommittable) {
122
122
def msg = s " !!! instantiated to Nothing: $param, constraint = ${constraint.show}"
@@ -132,7 +132,7 @@ trait ConstraintHandling {
132
132
res
133
133
}
134
134
135
- protected def addLowerBound (param : TypeParamRef , bound : Type ): Boolean = {
135
+ protected def addLowerBound (param : TypeParamRef , bound : Type )( implicit actx : AbstractContext ) : Boolean = {
136
136
def description = i " constraint $param >: $bound to \n $constraint"
137
137
constr_println(i " adding $description" )
138
138
val upper = constraint.upper(param)
@@ -143,7 +143,7 @@ trait ConstraintHandling {
143
143
res
144
144
}
145
145
146
- protected def addLess (p1 : TypeParamRef , p2 : TypeParamRef ): Boolean = {
146
+ protected def addLess (p1 : TypeParamRef , p2 : TypeParamRef )( implicit actx : AbstractContext ) : Boolean = {
147
147
def description = i " ordering $p1 <: $p2 to \n $constraint"
148
148
val res =
149
149
if (constraint.isLess(p2, p1)) unify(p2, p1)
@@ -164,7 +164,7 @@ trait ConstraintHandling {
164
164
/** Make p2 = p1, transfer all bounds of p2 to p1
165
165
* @pre less(p1)(p2)
166
166
*/
167
- private def unify (p1 : TypeParamRef , p2 : TypeParamRef ): Boolean = {
167
+ private def unify (p1 : TypeParamRef , p2 : TypeParamRef )( implicit actx : AbstractContext ) : Boolean = {
168
168
constr_println(s " unifying $p1 $p2" )
169
169
assert(constraint.isLess(p1, p2))
170
170
val down = constraint.exclusiveLower(p2, p1)
@@ -179,7 +179,7 @@ trait ConstraintHandling {
179
179
}
180
180
181
181
182
- protected def isSubType (tp1 : Type , tp2 : Type , whenFrozen : Boolean ): Boolean = {
182
+ protected def isSubType (tp1 : Type , tp2 : Type , whenFrozen : Boolean )( implicit actx : AbstractContext ) : Boolean = {
183
183
if (whenFrozen)
184
184
isSubTypeWhenFrozen(tp1, tp2)
185
185
else
@@ -198,13 +198,13 @@ trait ConstraintHandling {
198
198
}
199
199
}
200
200
201
- final def isSubTypeWhenFrozen (tp1 : Type , tp2 : Type ): Boolean = inFrozenConstraint(isSubType(tp1, tp2))
202
- final def isSameTypeWhenFrozen (tp1 : Type , tp2 : Type ): Boolean = inFrozenConstraint(isSameType(tp1, tp2))
201
+ final def isSubTypeWhenFrozen (tp1 : Type , tp2 : Type )( implicit actx : AbstractContext ) : Boolean = inFrozenConstraint(isSubType(tp1, tp2))
202
+ final def isSameTypeWhenFrozen (tp1 : Type , tp2 : Type )( implicit actx : AbstractContext ) : Boolean = inFrozenConstraint(isSameType(tp1, tp2))
203
203
204
204
/** Test whether the lower bounds of all parameters in this
205
205
* constraint are a solution to the constraint.
206
206
*/
207
- protected final def isSatisfiable : Boolean =
207
+ protected final def isSatisfiable ( implicit actx : AbstractContext ) : Boolean =
208
208
constraint.forallParams { param =>
209
209
val TypeBounds (lo, hi) = constraint.entry(param)
210
210
isSubType(lo, hi) || {
@@ -223,7 +223,7 @@ trait ConstraintHandling {
223
223
* @return the instantiating type
224
224
* @pre `param` is in the constraint's domain.
225
225
*/
226
- final def approximation (param : TypeParamRef , fromBelow : Boolean ): Type = {
226
+ final def approximation (param : TypeParamRef , fromBelow : Boolean )( implicit actx : AbstractContext ) : Type = {
227
227
val avoidParam = new TypeMap {
228
228
override def stopAtStatic = true
229
229
def avoidInArg (arg : Type ): Type =
@@ -277,7 +277,7 @@ trait ConstraintHandling {
277
277
* 2. If `tp` is a union type, yet upper bound is not a union type,
278
278
* approximate the union type from above by an intersection of all common base types.
279
279
*/
280
- def widenInferred (tp : Type , bound : Type ): Type = {
280
+ def widenInferred (tp : Type , bound : Type )( implicit actx : AbstractContext ) : Type = {
281
281
def isMultiSingleton (tp : Type ): Boolean = tp.stripAnnots match {
282
282
case tp : SingletonType => true
283
283
case AndType (tp1, tp2) => isMultiSingleton(tp1) | isMultiSingleton(tp2)
@@ -310,7 +310,7 @@ trait ConstraintHandling {
310
310
* a lower bound instantiation can be a singleton type only if the upper bound
311
311
* is also a singleton type.
312
312
*/
313
- def instanceType (param : TypeParamRef , fromBelow : Boolean ): Type = {
313
+ def instanceType (param : TypeParamRef , fromBelow : Boolean )( implicit actx : AbstractContext ) : Type = {
314
314
val inst = approximation(param, fromBelow).simplified
315
315
if (fromBelow) widenInferred(inst, constraint.fullUpperBound(param)) else inst
316
316
}
@@ -325,7 +325,7 @@ trait ConstraintHandling {
325
325
* Both `c1` and `c2` are required to derive from constraint `pre`, possibly
326
326
* narrowing it with further bounds.
327
327
*/
328
- protected final def subsumes (c1 : Constraint , c2 : Constraint , pre : Constraint ): Boolean =
328
+ protected final def subsumes (c1 : Constraint , c2 : Constraint , pre : Constraint )( implicit actx : AbstractContext ) : Boolean =
329
329
if (c2 eq pre) true
330
330
else if (c1 eq pre) false
331
331
else {
@@ -339,7 +339,7 @@ trait ConstraintHandling {
339
339
}
340
340
341
341
/** The current bounds of type parameter `param` */
342
- def bounds (param : TypeParamRef ): TypeBounds = {
342
+ def bounds (param : TypeParamRef )( implicit actx : AbstractContext ) : TypeBounds = {
343
343
val e = constraint.entry(param)
344
344
if (e.exists) e.bounds
345
345
else {
@@ -353,7 +353,7 @@ trait ConstraintHandling {
353
353
* and propagate all bounds.
354
354
* @param tvars See Constraint#add
355
355
*/
356
- def addToConstraint (tl : TypeLambda , tvars : List [TypeVar ]): Boolean =
356
+ def addToConstraint (tl : TypeLambda , tvars : List [TypeVar ])( implicit actx : AbstractContext ) : Boolean =
357
357
checkPropagated(i " initialized $tl" ) {
358
358
constraint = constraint.add(tl, tvars)
359
359
tl.paramRefs.forall { param =>
@@ -381,7 +381,7 @@ trait ConstraintHandling {
381
381
* This holds if `TypeVarsMissContext` is set unless `param` is a part
382
382
* of a MatchType that is currently normalized.
383
383
*/
384
- final def assumedTrue (param : TypeParamRef ): Boolean =
384
+ final def assumedTrue (param : TypeParamRef )( implicit actx : AbstractContext ) : Boolean =
385
385
ctx.mode.is(Mode .TypevarsMissContext ) && (caseLambda `ne` param.binder)
386
386
387
387
/** Add constraint `param <: bound` if `fromBelow` is false, `param >: bound` otherwise.
@@ -391,7 +391,7 @@ trait ConstraintHandling {
391
391
* not be AndTypes and lower bounds may not be OrTypes. This is assured by the
392
392
* way isSubType is organized.
393
393
*/
394
- protected def addConstraint (param : TypeParamRef , bound : Type , fromBelow : Boolean ): Boolean = {
394
+ protected def addConstraint (param : TypeParamRef , bound : Type , fromBelow : Boolean )( implicit actx : AbstractContext ) : Boolean = {
395
395
def description = i " constr $param ${if (fromBelow) " >:" else " <:" } $bound: \n $constraint"
396
396
// checkPropagated(s"adding $description")(true) // DEBUG in case following fails
397
397
checkPropagated(s " added $description" ) {
@@ -507,7 +507,7 @@ trait ConstraintHandling {
507
507
}
508
508
509
509
/** Instantiate `param` to `tp` if the constraint stays satisfiable */
510
- protected def tryInstantiate (param : TypeParamRef , tp : Type ): Boolean = {
510
+ protected def tryInstantiate (param : TypeParamRef , tp : Type )( implicit actx : AbstractContext ) : Boolean = {
511
511
val saved = constraint
512
512
constraint =
513
513
if (addConstraint(param, tp, fromBelow = true ) &&
@@ -517,7 +517,7 @@ trait ConstraintHandling {
517
517
}
518
518
519
519
/** Check that constraint is fully propagated. See comment in Config.checkConstraintsPropagated */
520
- def checkPropagated (msg : => String )(result : Boolean ): Boolean = {
520
+ def checkPropagated (msg : => String )(result : Boolean )( implicit actx : AbstractContext ) : Boolean = {
521
521
if (Config .checkConstraintsPropagated && result && addConstraintInvocations == 0 ) {
522
522
inFrozenConstraint {
523
523
for (p <- constraint.domainParams) {
0 commit comments