@@ -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)
@@ -165,7 +165,7 @@ trait ConstraintHandling {
165
165
/** Make p2 = p1, transfer all bounds of p2 to p1
166
166
* @pre less(p1)(p2)
167
167
*/
168
- private def unify (p1 : TypeParamRef , p2 : TypeParamRef ): Boolean = {
168
+ private def unify (p1 : TypeParamRef , p2 : TypeParamRef )( implicit actx : AbstractContext ) : Boolean = {
169
169
constr_println(s " unifying $p1 $p2" )
170
170
assert(constraint.isLess(p1, p2))
171
171
val down = constraint.exclusiveLower(p2, p1)
@@ -180,7 +180,7 @@ trait ConstraintHandling {
180
180
}
181
181
182
182
183
- protected def isSubType (tp1 : Type , tp2 : Type , whenFrozen : Boolean ): Boolean = {
183
+ protected def isSubType (tp1 : Type , tp2 : Type , whenFrozen : Boolean )( implicit actx : AbstractContext ) : Boolean = {
184
184
if (whenFrozen)
185
185
isSubTypeWhenFrozen(tp1, tp2)
186
186
else
@@ -199,13 +199,13 @@ trait ConstraintHandling {
199
199
}
200
200
}
201
201
202
- final def isSubTypeWhenFrozen (tp1 : Type , tp2 : Type ): Boolean = inFrozenConstraint(isSubType(tp1, tp2))
203
- final def isSameTypeWhenFrozen (tp1 : Type , tp2 : Type ): Boolean = inFrozenConstraint(isSameType(tp1, tp2))
202
+ final def isSubTypeWhenFrozen (tp1 : Type , tp2 : Type )( implicit actx : AbstractContext ) : Boolean = inFrozenConstraint(isSubType(tp1, tp2))
203
+ final def isSameTypeWhenFrozen (tp1 : Type , tp2 : Type )( implicit actx : AbstractContext ) : Boolean = inFrozenConstraint(isSameType(tp1, tp2))
204
204
205
205
/** Test whether the lower bounds of all parameters in this
206
206
* constraint are a solution to the constraint.
207
207
*/
208
- protected final def isSatisfiable : Boolean =
208
+ protected final def isSatisfiable ( implicit actx : AbstractContext ) : Boolean =
209
209
constraint.forallParams { param =>
210
210
val TypeBounds (lo, hi) = constraint.entry(param)
211
211
isSubType(lo, hi) || {
@@ -224,7 +224,7 @@ trait ConstraintHandling {
224
224
* @return the instantiating type
225
225
* @pre `param` is in the constraint's domain.
226
226
*/
227
- final def approximation (param : TypeParamRef , fromBelow : Boolean ): Type = {
227
+ final def approximation (param : TypeParamRef , fromBelow : Boolean )( implicit actx : AbstractContext ) : Type = {
228
228
val avoidParam = new TypeMap {
229
229
override def stopAtStatic = true
230
230
def avoidInArg (arg : Type ): Type =
@@ -278,7 +278,7 @@ trait ConstraintHandling {
278
278
* 2. If `tp` is a union type, yet upper bound is not a union type,
279
279
* approximate the union type from above by an intersection of all common base types.
280
280
*/
281
- def widenInferred (tp : Type , bound : Type ): Type = {
281
+ def widenInferred (tp : Type , bound : Type )( implicit actx : AbstractContext ) : Type = {
282
282
def isMultiSingleton (tp : Type ): Boolean = tp.stripAnnots match {
283
283
case tp : SingletonType => true
284
284
case AndType (tp1, tp2) => isMultiSingleton(tp1) | isMultiSingleton(tp2)
@@ -311,7 +311,7 @@ trait ConstraintHandling {
311
311
* a lower bound instantiation can be a singleton type only if the upper bound
312
312
* is also a singleton type.
313
313
*/
314
- def instanceType (param : TypeParamRef , fromBelow : Boolean ): Type = {
314
+ def instanceType (param : TypeParamRef , fromBelow : Boolean )( implicit actx : AbstractContext ) : Type = {
315
315
val inst = approximation(param, fromBelow).simplified
316
316
if (fromBelow) widenInferred(inst, constraint.fullUpperBound(param)) else inst
317
317
}
@@ -326,7 +326,7 @@ trait ConstraintHandling {
326
326
* Both `c1` and `c2` are required to derive from constraint `pre`, possibly
327
327
* narrowing it with further bounds.
328
328
*/
329
- protected final def subsumes (c1 : Constraint , c2 : Constraint , pre : Constraint ): Boolean =
329
+ protected final def subsumes (c1 : Constraint , c2 : Constraint , pre : Constraint )( implicit actx : AbstractContext ) : Boolean =
330
330
if (c2 eq pre) true
331
331
else if (c1 eq pre) false
332
332
else {
@@ -340,7 +340,7 @@ trait ConstraintHandling {
340
340
}
341
341
342
342
/** The current bounds of type parameter `param` */
343
- def bounds (param : TypeParamRef ): TypeBounds = {
343
+ def bounds (param : TypeParamRef )( implicit actx : AbstractContext ) : TypeBounds = {
344
344
val e = constraint.entry(param)
345
345
if (e.exists) e.bounds
346
346
else {
@@ -354,7 +354,7 @@ trait ConstraintHandling {
354
354
* and propagate all bounds.
355
355
* @param tvars See Constraint#add
356
356
*/
357
- def addToConstraint (tl : TypeLambda , tvars : List [TypeVar ]): Boolean =
357
+ def addToConstraint (tl : TypeLambda , tvars : List [TypeVar ])( implicit actx : AbstractContext ) : Boolean =
358
358
checkPropagated(i " initialized $tl" ) {
359
359
constraint = constraint.add(tl, tvars)
360
360
tl.paramRefs.forall { param =>
@@ -382,7 +382,7 @@ trait ConstraintHandling {
382
382
* This holds if `TypeVarsMissContext` is set unless `param` is a part
383
383
* of a MatchType that is currently normalized.
384
384
*/
385
- final def assumedTrue (param : TypeParamRef ): Boolean =
385
+ final def assumedTrue (param : TypeParamRef )( implicit actx : AbstractContext ) : Boolean =
386
386
ctx.mode.is(Mode .TypevarsMissContext ) && (caseLambda `ne` param.binder)
387
387
388
388
/** Add constraint `param <: bound` if `fromBelow` is false, `param >: bound` otherwise.
@@ -392,7 +392,7 @@ trait ConstraintHandling {
392
392
* not be AndTypes and lower bounds may not be OrTypes. This is assured by the
393
393
* way isSubType is organized.
394
394
*/
395
- protected def addConstraint (param : TypeParamRef , bound : Type , fromBelow : Boolean ): Boolean = {
395
+ protected def addConstraint (param : TypeParamRef , bound : Type , fromBelow : Boolean )( implicit actx : AbstractContext ) : Boolean = {
396
396
def description = i " constr $param ${if (fromBelow) " >:" else " <:" } $bound: \n $constraint"
397
397
// checkPropagated(s"adding $description")(true) // DEBUG in case following fails
398
398
checkPropagated(s " added $description" ) {
@@ -508,7 +508,7 @@ trait ConstraintHandling {
508
508
}
509
509
510
510
/** Instantiate `param` to `tp` if the constraint stays satisfiable */
511
- protected def tryInstantiate (param : TypeParamRef , tp : Type ): Boolean = {
511
+ protected def tryInstantiate (param : TypeParamRef , tp : Type )( implicit actx : AbstractContext ) : Boolean = {
512
512
val saved = constraint
513
513
constraint =
514
514
if (addConstraint(param, tp, fromBelow = true ) &&
@@ -518,7 +518,7 @@ trait ConstraintHandling {
518
518
}
519
519
520
520
/** Check that constraint is fully propagated. See comment in Config.checkConstraintsPropagated */
521
- def checkPropagated (msg : => String )(result : Boolean ): Boolean = {
521
+ def checkPropagated (msg : => String )(result : Boolean )( implicit actx : AbstractContext ) : Boolean = {
522
522
if (Config .checkConstraintsPropagated && result && addConstraintInvocations == 0 ) {
523
523
inFrozenConstraint {
524
524
for (p <- constraint.domainParams) {
0 commit comments