@@ -418,98 +418,99 @@ trait ConstraintHandling[AbstractContext] {
418
418
* not be AndTypes and lower bounds may not be OrTypes. This is assured by the
419
419
* way isSubType is organized.
420
420
*/
421
- protected def addConstraint (param : TypeParamRef , bound : Type , fromBelow : Boolean )(implicit actx : AbstractContext ): Boolean = {
422
- def description = i " constr $param ${if (fromBelow) " >:" else " <:" } $bound: \n $constraint"
423
- // checkPropagated(s"adding $description")(true) // DEBUG in case following fails
424
- checkPropagated(s " added $description" ) {
425
-
426
- /** When comparing lambdas we might get constraints such as
427
- * `A <: X0` or `A = List[X0]` where `A` is a constrained parameter
428
- * and `X0` is a lambda parameter. The constraint for `A` is not allowed
429
- * to refer to such a lambda parameter because the lambda parameter is
430
- * not visible where `A` is defined. Consequently, we need to
431
- * approximate the bound so that the lambda parameter does not appear in it.
432
- * If `tp` is an upper bound, we need to approximate with something smaller,
433
- * otherwise something larger.
434
- * Test case in pos/i94-nada.scala. This test crashes with an illegal instance
435
- * error in Test2 when the rest of the SI-2712 fix is applied but `pruneLambdaParams` is
436
- * missing.
437
- */
438
- def pruneLambdaParams (tp : Type ) =
439
- if (comparedTypeLambdas.nonEmpty) {
440
- val approx = new ApproximatingTypeMap {
441
- if (! fromBelow) variance = - 1
442
- def apply (t : Type ): Type = t match {
443
- case t @ TypeParamRef (tl : TypeLambda , n) if comparedTypeLambdas contains tl =>
444
- val bounds = tl.paramInfos(n)
445
- range(bounds.lo, bounds.hi)
446
- case _ =>
447
- mapOver(t)
448
- }
421
+ protected def addConstraint (param : TypeParamRef , bound : Type , fromBelow : Boolean )(implicit actx : AbstractContext ): Boolean =
422
+
423
+ /** When comparing lambdas we might get constraints such as
424
+ * `A <: X0` or `A = List[X0]` where `A` is a constrained parameter
425
+ * and `X0` is a lambda parameter. The constraint for `A` is not allowed
426
+ * to refer to such a lambda parameter because the lambda parameter is
427
+ * not visible where `A` is defined. Consequently, we need to
428
+ * approximate the bound so that the lambda parameter does not appear in it.
429
+ * If `tp` is an upper bound, we need to approximate with something smaller,
430
+ * otherwise something larger.
431
+ * Test case in pos/i94-nada.scala. This test crashes with an illegal instance
432
+ * error in Test2 when the rest of the SI-2712 fix is applied but `pruneLambdaParams` is
433
+ * missing.
434
+ */
435
+ def pruneLambdaParams (tp : Type ) =
436
+ if (comparedTypeLambdas.nonEmpty) {
437
+ val approx = new ApproximatingTypeMap {
438
+ if (! fromBelow) variance = - 1
439
+ def apply (t : Type ): Type = t match {
440
+ case t @ TypeParamRef (tl : TypeLambda , n) if comparedTypeLambdas contains tl =>
441
+ val bounds = tl.paramInfos(n)
442
+ range(bounds.lo, bounds.hi)
443
+ case _ =>
444
+ mapOver(t)
449
445
}
450
- approx(tp)
451
446
}
452
- else tp
447
+ approx(tp)
448
+ }
449
+ else tp
450
+
451
+ def addParamBound (bound : TypeParamRef ) =
452
+ constraint.entry(param) match {
453
+ case _ : TypeBounds =>
454
+ if (fromBelow) addLess(bound, param) else addLess(param, bound)
455
+ case tp =>
456
+ if (fromBelow) isSubType(bound, tp) else isSubType(tp, bound)
457
+ }
453
458
454
- def addParamBound (bound : TypeParamRef ) =
455
- constraint.entry(param) match {
456
- case _ : TypeBounds =>
457
- if (fromBelow) addLess(bound, param) else addLess(param, bound)
458
- case tp =>
459
- if (fromBelow) isSubType(bound, tp) else isSubType(tp, bound)
460
- }
459
+ /** Normalize the bound `bnd` in the following ways:
460
+ *
461
+ * 1. Any toplevel occurrences of the compared parameter `param` are
462
+ * replaced by `Nothing` if bound is from below or `Any` otherwise.
463
+ * 2. Toplevel occurrences of TypeVars over TypeRefs in the current
464
+ * constraint are dereferenced.
465
+ * 3. Toplevel occurrences of TypeRefs that are instantiated in the current
466
+ * constraint are also referenced.
467
+ * 4. Toplevel occurrences of ExprTypes lead to a `NoType` return, which
468
+ * causes the addConstraint operation to fail.
469
+ *
470
+ * An occurrence is toplevel if it is the bound itself,
471
+ * or the bound is a union or intersection, and the ocurrence is
472
+ * toplevel in one of the operands of the `&` or `|`.
473
+ */
474
+ def prune (bnd : Type ): Type = bnd match
475
+ case bnd : AndOrType =>
476
+ val p1 = prune(bnd.tp1)
477
+ val p2 = prune(bnd.tp2)
478
+ if (p1.exists && p2.exists) bnd.derivedAndOrType(p1, p2)
479
+ else NoType
480
+ case bnd : TypeVar if constraint contains bnd.origin => // (2)
481
+ prune(bnd.underlying)
482
+ case bnd : TypeParamRef =>
483
+ if bnd eq param then // (1)
484
+ if fromBelow then defn.NothingType else defn.AnyType
485
+ else constraint.entry(bnd) match
486
+ case _ : TypeBounds => bnd
487
+ case inst => prune(inst) // (3)
488
+ case bnd : ExprType => // (4)
489
+ // ExprTypes are not value types, so type parameters should not
490
+ // be instantiated to ExprTypes. A scenario where such an attempted
491
+ // instantiation can happen is if we unify (=> T) => () with A => ()
492
+ // where A is a TypeParamRef. See the comment on EtaExpansion.etaExpand
493
+ // why types such as (=> T) => () can be constructed and i7969.scala
494
+ // as a test where this happens.
495
+ // Note that scalac by contrast allows such instantiations. But letting
496
+ // type variables be ExprTypes has its own problems (e.g. you can't write
497
+ // the resulting types down) and is largely unknown terrain.
498
+ NoType
499
+ case _ =>
500
+ bnd
461
501
462
- /** Normalize the bound `bnd` in the following ways:
463
- *
464
- * 1. Any toplevel occurrences of the compared parameter `param` are
465
- * replaced by `Nothing` if bound is from below or `Any` otherwise.
466
- * 2. Toplevel occurrences of TypeVars over TypeRefs in the current
467
- * constraint are dereferenced.
468
- * 3. Toplevel occurrences of TypeRefs that are instantiated in the current
469
- * constraint are also referenced.
470
- * 4. Toplevel occurrences of ExprTypes lead to a `NoType` return, which
471
- * causes the addConstraint operation to fail.
472
- *
473
- * An occurrence is toplevel if it is the bound itself,
474
- * or the bound is a union or intersection, and the ocurrence is
475
- * toplevel in one of the operands of the `&` or `|`.
476
- */
477
- def prune (bnd : Type ): Type = bnd match
478
- case bnd : AndOrType =>
479
- val p1 = prune(bnd.tp1)
480
- val p2 = prune(bnd.tp2)
481
- if (p1.exists && p2.exists) bnd.derivedAndOrType(p1, p2)
482
- else NoType
483
- case bnd : TypeVar if constraint contains bnd.origin => // (2)
484
- prune(bnd.underlying)
485
- case bnd : TypeParamRef =>
486
- if bnd eq param then // (1)
487
- if fromBelow then defn.NothingType else defn.AnyType
488
- else constraint.entry(bnd) match
489
- case _ : TypeBounds => bnd
490
- case inst => prune(inst) // (3)
491
- case bnd : ExprType => // (4)
492
- // ExprTypes are not value types, so type parameters should not
493
- // be instantiated to ExprTypes. A scenario where such an attempted
494
- // instantiation can happen is if we unify (=> T) => () with A => ()
495
- // where A is a TypeParamRef. See the comment on EtaExpansion.etaExpand
496
- // why types such as (=> T) => () can be constructed and i7969.scala
497
- // as a test where this happens.
498
- // Note that scalac by contrast allows such instantiations. But letting
499
- // type variables be ExprTypes has its own problems (e.g. you can't write
500
- // the resulting types down) and is largely unknown terrain.
501
- NoType
502
- case _ =>
503
- bnd
502
+ def kindCompatible (tp1 : Type , tp2 : Type ): Boolean =
503
+ val tparams1 = tp1.typeParams
504
+ val tparams2 = tp2.typeParams
505
+ tparams1.corresponds(tparams2)((p1, p2) => kindCompatible(p1.paramInfo, p2.paramInfo))
506
+ && (tparams1.isEmpty || kindCompatible(tp1.hkResult, tp2.hkResult))
507
+ || tp1.hasAnyKind
508
+ || tp2.hasAnyKind
504
509
505
- def kindCompatible (tp1 : Type , tp2 : Type ): Boolean =
506
- val tparams1 = tp1.typeParams
507
- val tparams2 = tp2.typeParams
508
- tparams1.corresponds(tparams2)((p1, p2) => kindCompatible(p1.paramInfo, p2.paramInfo))
509
- && (tparams1.isEmpty || kindCompatible(tp1.hkResult, tp2.hkResult))
510
- || tp1.hasAnyKind
511
- || tp2.hasAnyKind
510
+ def description = i " constr $param ${if (fromBelow) " >:" else " <:" } $bound: \n $constraint"
512
511
512
+ // checkPropagated(s"adding $description")(true) // DEBUG in case following fails
513
+ checkPropagated(s " added $description" ) {
513
514
addConstraintInvocations += 1
514
515
try bound match
515
516
case bound : TypeParamRef if constraint contains bound =>
@@ -521,7 +522,7 @@ trait ConstraintHandling[AbstractContext] {
521
522
&& (if fromBelow then addLowerBound(param, pbound) else addUpperBound(param, pbound))
522
523
finally addConstraintInvocations -= 1
523
524
}
524
- }
525
+ end addConstraint
525
526
526
527
/** Check that constraint is fully propagated. See comment in Config.checkConstraintsPropagated */
527
528
def checkPropagated (msg : => String )(result : Boolean )(implicit actx : AbstractContext ): Boolean = {
0 commit comments