@@ -35,6 +35,11 @@ trait ConstraintHandling {
3535 /** If the constraint is frozen we cannot add new bounds to the constraint. */
3636 protected var frozenConstraint = false
3737
38+ /** Potentially a type lambda that is still instantiatable, even though the constraint
39+ * is generally frozen.
40+ */
41+ protected var caseLambda : Type = NoType
42+
3843 /** If set, align arguments `S1`, `S2`when taking the glb
3944 * `T1 { X = S1 } & T2 { X = S2 }` of a constraint upper bound for some type parameter.
4045 * Aligning means computing `S1 =:= S2` which may change the current constraint.
@@ -47,7 +52,7 @@ trait ConstraintHandling {
4752 */
4853 protected var comparedTypeLambdas : Set [TypeLambda ] = Set .empty
4954
50- private def addOneBound (param : TypeParamRef , bound : Type , isUpper : Boolean ): Boolean =
55+ protected def addOneBound (param : TypeParamRef , bound : Type , isUpper : Boolean ): Boolean =
5156 ! constraint.contains(param) || {
5257 def occursIn (bound : Type ): Boolean = {
5358 val b = bound.dealias
@@ -167,19 +172,20 @@ trait ConstraintHandling {
167172 isSubType(tp1, tp2)
168173 }
169174
170- final def isSubTypeWhenFrozen (tp1 : Type , tp2 : Type ): Boolean = {
171- val saved = frozenConstraint
175+ @ forceInline final def inFrozenConstraint [T ](op : => T ): T = {
176+ val savedFrozen = frozenConstraint
177+ val savedLambda = caseLambda
172178 frozenConstraint = true
173- try isSubType(tp1, tp2)
174- finally frozenConstraint = saved
179+ caseLambda = NoType
180+ try op
181+ finally {
182+ frozenConstraint = savedFrozen
183+ caseLambda = savedLambda
184+ }
175185 }
176186
177- final def isSameTypeWhenFrozen (tp1 : Type , tp2 : Type ): Boolean = {
178- val saved = frozenConstraint
179- frozenConstraint = true
180- try isSameType(tp1, tp2)
181- finally frozenConstraint = saved
182- }
187+ final def isSubTypeWhenFrozen (tp1 : Type , tp2 : Type ): Boolean = inFrozenConstraint(isSubType(tp1, tp2))
188+ final def isSameTypeWhenFrozen (tp1 : Type , tp2 : Type ): Boolean = inFrozenConstraint(isSameType(tp1, tp2))
183189
184190 /** Test whether the lower bounds of all parameters in this
185191 * constraint are a solution to the constraint.
@@ -319,7 +325,7 @@ trait ConstraintHandling {
319325 }
320326
321327 /** The current bounds of type parameter `param` */
322- final def bounds (param : TypeParamRef ): TypeBounds = {
328+ def bounds (param : TypeParamRef ): TypeBounds = {
323329 val e = constraint.entry(param)
324330 if (e.exists) e.bounds
325331 else {
@@ -355,7 +361,7 @@ trait ConstraintHandling {
355361
356362 /** Can `param` be constrained with new bounds? */
357363 final def canConstrain (param : TypeParamRef ): Boolean =
358- ! frozenConstraint && ( constraint contains param)
364+ ( ! frozenConstraint || (caseLambda `eq` param.binder)) && constraint. contains( param)
359365
360366 /** Add constraint `param <: bound` if `fromBelow` is false, `param >: bound` otherwise.
361367 * `bound` is assumed to be in normalized form, as specified in `firstTry` and
@@ -492,19 +498,18 @@ trait ConstraintHandling {
492498 /** Check that constraint is fully propagated. See comment in Config.checkConstraintsPropagated */
493499 def checkPropagated (msg : => String )(result : Boolean ): Boolean = {
494500 if (Config .checkConstraintsPropagated && result && addConstraintInvocations == 0 ) {
495- val saved = frozenConstraint
496- frozenConstraint = true
497- for (p <- constraint.domainParams) {
498- def check (cond : => Boolean , q : TypeParamRef , ordering : String , explanation : String ) : Unit =
499- assert(cond, i " propagation failure for $p $ordering $q : $explanation \n $msg " )
500- for (u <- constraint.upper(p) )
501- check(bounds(p).hi <:< bounds(u).hi, u, " <: " , " upper bound not propagated " )
502- for (l <- constraint.lower (p)) {
503- check(bounds(l).lo <:< bounds(p).hi , l, " >:" , " lower bound not propagated " )
504- check(constraint.isLess(l, p), l, " >: " , " reverse ordering (<:) missing " )
501+ inFrozenConstraint {
502+ for (p <- constraint.domainParams) {
503+ def check ( cond : => Boolean , q : TypeParamRef , ordering : String , explanation : String ) : Unit =
504+ assert (cond, i " propagation failure for $p $ ordering $q : $explanation \n $msg " )
505+ for (u <- constraint.upper(p) )
506+ check(bounds(p).hi <:< bounds(u).hi, u, " <: " , " upper bound not propagated " )
507+ for (l <- constraint.lower(p)) {
508+ check(bounds(l).lo <:< bounds (p).hi, l, " >: " , " lower bound not propagated " )
509+ check(constraint.isLess(l, p) , l, " >:" , " reverse ordering (<:) missing " )
510+ }
505511 }
506512 }
507- frozenConstraint = saved
508513 }
509514 result
510515 }
0 commit comments