@@ -573,10 +573,12 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
573
573
val tree1 = untpdCpy.Block (tree)(stats, expr)
574
574
tree match {
575
575
case tree : Block if (expr.tpe eq tree.expr.tpe) && (expr.tpe eq tree.tpe) =>
576
- // the second guard is needed in case avoid somehow widened the type.
577
- // if it did it could potentially need to rewiden it
578
- // eg {val s = ...; s}
579
- // changing type of s should change type of block, though type of expr is unchanged - TermRef(s)
576
+ // The last guard is a conservative check: if `tree.tpe` is different from `expr.tpe`, then
577
+ // it was computed from widening `expr.tpe`, and tree transforms might cause `expr.tpe.widen`
578
+ // to change even if `expr.tpe` itself didn't change, e.g:
579
+ // { val s = ...; s }
580
+ // If the type of `s` changed, then the type of the block might have changed, even though `expr.tpe`
581
+ // will still be `TermRef(NoPrefix, s)`
580
582
tree1.withTypeUnchecked(tree.tpe)
581
583
case _ => ta.assignType(tree1, stats, expr)
582
584
}
@@ -587,9 +589,10 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
587
589
tree match {
588
590
case tree : If if (thenp.tpe eq tree.thenp.tpe) && (elsep.tpe eq tree.elsep.tpe) &&
589
591
((tree.tpe eq thenp.tpe) || (tree.tpe eq elsep.tpe)) =>
590
- // last guard is needed in case previous if had computed a widened ORType that needs to be recomputed
591
- // eg {val a = ...; val b = ...; if(...) a else b}
592
- // changing type of a or b should change type of if, though types of both trees remain unchanged
592
+ // The last guard is a conservative check similar to the one done in `Block` above,
593
+ // if `tree.tpe` is not identical to the type of one of its branch, it might have been
594
+ // computed from the widened type of the branches, so the same reasoning than
595
+ // in `Block` applies.
593
596
tree1.withTypeUnchecked(tree.tpe)
594
597
case _ => ta.assignType(tree1, thenp, elsep)
595
598
}
0 commit comments