Skip to content

Commit 7f2c5f0

Browse files
committed
Do not widen hard unions
1 parent 7939ddb commit 7f2c5f0

File tree

4 files changed

+28
-7
lines changed

4 files changed

+28
-7
lines changed

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -557,8 +557,8 @@ trait ConstraintHandling {
557557
// Widening can add extra constraints, in particular the widened type might
558558
// be a type variable which is now instantiated to `param`, and therefore
559559
// cannot be used as an instantiation of `param` without creating a loop.
560-
// If that happens, we run `instanceType` again to find a new instantation.
561-
// (we do not check for non-toplevel occurences: those should never occur
560+
// If that happens, we run `instanceType` again to find a new instantiation.
561+
// (we do not check for non-toplevel occurrences: those should never occur
562562
// since `addOneBound` disallows recursive lower bounds).
563563
if constraint.occursAtToplevel(param, widened) then
564564
instanceType(param, fromBelow)

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

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3266,7 +3266,7 @@ object Types {
32663266
TypeComparer.lub(tp1.widenUnionWithoutNull, tp2.widenUnionWithoutNull, canConstrain = true) match
32673267
case union: OrType => union.join
32683268
case res => res
3269-
else derivedOrType(tp1.widenUnionWithoutNull, tp2.widenUnionWithoutNull)
3269+
else this
32703270
if !isProvisional then myUnionPeriod = ctx.period
32713271
myUnion
32723272

@@ -3280,11 +3280,16 @@ object Types {
32803280
if tp1.hasClassSymbol(defn.NothingClass) then tp2.atoms
32813281
else if tp2.hasClassSymbol(defn.NothingClass) then tp1.atoms
32823282
else tp1.atoms | tp2.atoms
3283-
val tp1w = tp1.widenSingletons
3284-
val tp2w = tp2.widenSingletons
3285-
myWidened = if ((tp1 eq tp1w) && (tp2 eq tp2w)) this else tp1w | tp2w
32863283
atomsRunId = ctx.runId
32873284

3285+
myWidened =
3286+
if isSoft then
3287+
val tp1w = tp1.widenSingletons
3288+
val tp2w = tp2.widenSingletons
3289+
if ((tp1 eq tp1w) && (tp2 eq tp2w)) this else tp1w | tp2w
3290+
else
3291+
this
3292+
32883293
override def atoms(using Context): Atoms =
32893294
ensureAtomsComputed()
32903295
myAtoms

tests/pos/singleton-widen.scala

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import scala.compiletime.ops.int._
2+
3+
class Test:
4+
5+
def test() =
6+
val a: 2 | 3 = 2
7+
val b = a

tests/pos/widen-union.scala

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,21 @@ object Test2:
1313
|| xs.corresponds(ys)(consistent(_, _)) // error, found: Any, required: Int | String
1414

1515
object Test3:
16-
1716
def g[X](x: X | String): Int = ???
1817
def y: Boolean | String = ???
1918
g[Boolean](y)
2019
g(y)
2120
g[Boolean](identity(y))
2221
g(identity(y))
2322

23+
object Test4:
24+
def f(a: 2 | 3) = a
25+
26+
def test() =
27+
val x: 2 | 3 = 2
28+
val y = x
29+
f(y)
2430

31+
def g: 2 | 3 = 2
32+
val z = g
33+
f(z)

0 commit comments

Comments
 (0)