Skip to content

Commit efe7a9b

Browse files
committed
Fix non-termination
The following test explodes: tests/init/pos/local-warm5.scala. Ideally we should use an actual set in RefSet, which we don't do for both performance and determinism. The performance concern might be a premature optimization.
1 parent d5fb3e9 commit efe7a9b

File tree

1 file changed

+12
-4
lines changed

1 file changed

+12
-4
lines changed

compiler/src/dotty/tools/dotc/transform/init/Semantic.scala

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -414,12 +414,20 @@ object Semantic {
414414
case (Cold, _) => Cold
415415
case (_, Cold) => Cold
416416

417-
case (a: (Fun | Warm | ThisRef), b: (Fun | Warm | ThisRef)) => RefSet(a :: b :: Nil)
417+
case (a: (Fun | Warm | ThisRef), b: (Fun | Warm | ThisRef)) =>
418+
if a == b then a else RefSet(a :: b :: Nil)
418419

419-
case (a: (Fun | Warm | ThisRef), RefSet(refs)) => RefSet(a :: refs)
420-
case (RefSet(refs), b: (Fun | Warm | ThisRef)) => RefSet(b :: refs)
420+
case (a: (Fun | Warm | ThisRef), RefSet(refs)) =>
421+
if refs.exists(_ == a) then b
422+
else RefSet(a :: refs)
421423

422-
case (RefSet(refs1), RefSet(refs2)) => RefSet(refs1 ++ refs2)
424+
case (RefSet(refs), b: (Fun | Warm | ThisRef)) =>
425+
if refs.exists(_ == b) then a
426+
else RefSet(b :: refs)
427+
428+
case (RefSet(refs1), RefSet(refs2)) =>
429+
val diff = refs2.filter(ref => refs1.forall(_ != ref))
430+
RefSet(refs1 ++ diff)
423431

424432
/** Conservatively approximate the value with `Cold` or `Hot` */
425433
def widenArg: Value =

0 commit comments

Comments
 (0)