Skip to content

Commit 28481bf

Browse files
committed
Harmonize only for constants
We now widen a vararg parameter or alternative of an If or Match only to another numeric value type only if the original type is a constant type, and the type can be widened without loss of precision (here we deem it acceptable that Ints are widened to Floats, but Longs can only be widened to Doubles).
1 parent 7953479 commit 28481bf

File tree

1 file changed

+15
-3
lines changed

1 file changed

+15
-3
lines changed

compiler/src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -445,6 +445,9 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
445445
val harmonizedArgs = harmonizeArgs(typedArgs)
446446
if (harmonizedArgs ne typedArgs) {
447447
ctx.typerState.constraint = origConstraint
448+
// reset constraint, we will test constraint anyway when we
449+
// compare against the seqliteral. The reset is needed
450+
// otherwise pos/harmonize.scala would fail on line 40.
448451
typedArgs = harmonizedArgs
449452
}
450453
typedArgs.foreach(addArg(_, elemFormal))
@@ -1441,9 +1444,18 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
14411444
}
14421445
val clss = numericClasses(ts, Set())
14431446
if (clss.size > 1) {
1447+
def isCompatible(cls: Symbol, sup: TypeRef) =
1448+
defn.isValueSubType(cls.typeRef, sup) &&
1449+
!(cls == defn.LongClass && sup.isRef(defn.FloatClass))
1450+
// exclude Long <: Float from list of allowable widenings
14441451
val lub = defn.ScalaNumericValueTypeList.find(lubTpe =>
1445-
clss.forall(cls => defn.isValueSubType(cls.typeRef, lubTpe))).get
1446-
ts.mapConserve(adapt(_, lub))
1452+
clss.forall(cls => isCompatible(cls, lubTpe))).get
1453+
ts.mapConserve { t =>
1454+
tpe(t).widenTermRefExpr match {
1455+
case ct: ConstantType => adapt(t, lub)
1456+
case _ => t
1457+
}
1458+
}
14471459
}
14481460
else ts
14491461
}
@@ -1462,7 +1474,7 @@ trait Applications extends Compatibility { self: Typer with Dynamic =>
14621474
/** If all `types` are numeric value types, and they are not all the same type,
14631475
* pick a common numeric supertype and return it instead of every original type.
14641476
*/
1465-
def harmonizeTypes(tpes: List[Type])(implicit ctx: Context): List[Type] =
1477+
private def harmonizeTypes(tpes: List[Type])(implicit ctx: Context): List[Type] =
14661478
harmonizeWith(tpes)(identity, (tp, pt) => pt)
14671479
}
14681480

0 commit comments

Comments
 (0)