Skip to content

Commit ec097a9

Browse files
committed
Fix 1 cause of infinite recursion in the new provablyDisjoint.
And add an additional test for another cause of infinite recursion that was fixed earlier.
1 parent 2dd9f45 commit ec097a9

File tree

3 files changed

+30
-2
lines changed

3 files changed

+30
-2
lines changed

Diff for: compiler/src/dotty/tools/dotc/core/TypeComparer.scala

+16-2
Original file line numberDiff line numberDiff line change
@@ -2808,8 +2808,22 @@ class TypeComparer(@constructorOnly initctx: Context) extends ConstraintHandling
28082808
val optGadtBounds = gadtBounds(sym)
28092809
if optGadtBounds != null then disjointnessBoundary(optGadtBounds.hi)
28102810
else disjointnessBoundary(tp.superTypeNormalized)
2811-
case tp @ AppliedType(tycon: TypeRef, _) if tycon.symbol.isClass =>
2812-
tp
2811+
case tp @ AppliedType(tycon: TypeRef, targs) if tycon.symbol.isClass =>
2812+
/* The theory says we should just return `tp` here. However, due to how
2813+
* baseType works (called from `isBaseTypeWithDisjointArguments`),
2814+
* it can create infinitely growing towers of `AnnotatedType`s. This
2815+
* defeats the infinite recursion detection with the `pending` set.
2816+
* Therefore, we eagerly remove all non-refining annotations. We are
2817+
* allowed to do that because they don't affect subtyping (so cannot
2818+
* create an ill-kinded `AppliedType`) and would anyway be stripped
2819+
* later on by the recursive calls to `provablyDisjoint`, though
2820+
* `disjointnessBoundary`).
2821+
* See tests/pos/provably-disjoint-infinite-recursion-1.scala for an example.
2822+
*/
2823+
tp.derivedAppliedType(
2824+
tycon,
2825+
targs.mapConserve(_.stripAnnots(keep = _.symbol.derivesFrom(defn.RefiningAnnotationClass)))
2826+
)
28132827
case tp: TermRef =>
28142828
val isEnumValue = tp.termSymbol.isAllOf(EnumCase, butNot = JavaDefined)
28152829
if isEnumValue then tp
+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
class Test {
2+
def isTraversableAgain(from: Iterator[Int]): Boolean =
3+
from.isInstanceOf[Iterable[?]]
4+
}
+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
type Tupled[A] <: Tuple = A match
2+
case Tuple => A & Tuple
3+
case _ => A *: EmptyTuple
4+
5+
enum Day:
6+
case Saturday, Sunday
7+
8+
type Foo = Tupled[Day]
9+
10+
def foo(): Foo = Day.Saturday *: EmptyTuple

0 commit comments

Comments
 (0)