Skip to content

Commit 9f41699

Browse files
committed
Adapt homogenizeArgs to new scheme
Todo: We should find out whether it's worth it.
1 parent 2e6de77 commit 9f41699

File tree

2 files changed

+20
-20
lines changed

2 files changed

+20
-20
lines changed

compiler/src/dotty/tools/dotc/config/Config.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,12 +84,12 @@ object Config {
8484
/** If this flag is set, take the fast path when comparing same-named type-aliases and types */
8585
final val fastPathForRefinedSubtype = true
8686

87-
/** If this flag is set, and we compute `T1 { X = S1 }` & `T2 { X = S2 }` as a new
88-
* upper bound of a constrained parameter, try to align the refinements by computing
87+
/** If this flag is set, and we compute `T1[X1]` & `T2[X2]` as a new
88+
* upper bound of a constrained parameter, try to align the arguments by computing
8989
* `S1 =:= S2` (which might instantiate type parameters).
9090
* This rule is contentious because it cuts the constraint set.
9191
*
92-
* For more info, see the comment in `TypeComparer#distributeAnd`.
92+
* For more info, see the comment in `TypeComparer#glbArgs`.
9393
*/
9494
final val alignArgsInAnd = true
9595

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

Lines changed: 17 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1260,6 +1260,20 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
12601260
Nil
12611261
}
12621262

1263+
/** Try to produce joint arguments for a glb `A[T_1, ..., T_n] & A[T_1', ..., T_n']` using
1264+
* the following strategies:
1265+
*
1266+
* - if corresponding parameter variance is co/contra-variant, the glb/lub.
1267+
* - if arguments are the same, that argument.
1268+
* - if at least one of the arguments if a TypeBounds, the union of
1269+
* the bounds.
1270+
* - if homogenizeArgs is set, and arguments can be unified by instantiating
1271+
* type parameters, the unified argument.
1272+
* - otherwise NoType
1273+
*
1274+
* The unification rule is contentious because it cuts the constraint set.
1275+
* Therefore it is subject to Config option `alignArgsInAnd`.
1276+
*/
12631277
def glbArgs(args1: List[Type], args2: List[Type], tparams: List[TypeParamInfo]): List[Type] =
12641278
tparams match {
12651279
case tparam :: tparamsRest =>
@@ -1273,6 +1287,7 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
12731287
else if (arg1.isInstanceOf[TypeBounds] || arg2.isInstanceOf[TypeBounds])
12741288
TypeBounds(lub(arg1.loBound, arg2.loBound),
12751289
glb(arg1.hiBound, arg2.hiBound))
1290+
else if (homogenizeArgs && !frozenConstraint && isSameType(arg1, arg2)) arg1
12761291
else NoType
12771292
glbArg :: glbArgs(args1Rest, args2Rest, tparamsRest)
12781293
case nil =>
@@ -1430,26 +1445,11 @@ class TypeComparer(initctx: Context) extends DotClass with ConstraintHandling {
14301445
// opportunistically merge same-named refinements
14311446
// this does not change anything semantically (i.e. merging or not merging
14321447
// gives =:= types), but it keeps the type smaller.
1433-
// @!!! still needed?
14341448
case tp1: RefinedType =>
14351449
tp2 match {
14361450
case tp2: RefinedType if tp1.refinedName == tp2.refinedName =>
1437-
// Given two refinements `T1 { X = S1 }` and `T2 { X = S2 }` rewrite to
1438-
// `T1 & T2 { X B }` where `B` is the conjunction of the bounds of `X` in `T1` and `T2`.
1439-
//
1440-
// However, if `homogenizeArgs` is set, and both aliases `X = Si` are
1441-
// nonvariant, and `S1 =:= S2` (possibly by instantiating type parameters),
1442-
// rewrite instead to `T1 & T2 { X = S1 }`. This rule is contentious because
1443-
// it cuts the constraint set. On the other hand, without it we would replace
1444-
// the two aliases by `T { X >: S1 | S2 <: S1 & S2 }`, which looks weird
1445-
// and is probably not what's intended.
1446-
val rinfo1 = tp1.refinedInfo
1447-
val rinfo2 = tp2.refinedInfo
1448-
val parent = tp1.parent & tp2.parent
1449-
if (homogenizeArgs && rinfo1.isAlias && rinfo2.isAlias) // @!!! probably drop this case?
1450-
isSameType(rinfo1, rinfo2) // establish new constraint
1451-
1452-
tp1.derivedRefinedType(parent, tp1.refinedName, rinfo1 & rinfo2)
1451+
tp1.derivedRefinedType(tp1.parent & tp2.parent, tp1.refinedName,
1452+
tp1.refinedInfo & tp2.refinedInfo)
14531453
case _ =>
14541454
NoType
14551455
}

0 commit comments

Comments
 (0)