@@ -66,6 +66,9 @@ object Typer {
66
66
if (! tree.isEmpty && ! tree.isInstanceOf [untpd.TypedSplice ] && ctx.typerState.isGlobalCommittable)
67
67
assert(tree.span.exists, i " position not set for $tree # ${tree.uniqueId} of ${tree.getClass} in ${tree.source}" )
68
68
69
+ /** An attachment for GADT constraints that were inferred for a pattern. */
70
+ val InferredGadtConstraints = new Property .StickyKey [core.GadtConstraint ]
71
+
69
72
/** A context property that indicates the owner of any expressions to be typed in the context
70
73
* if that owner is different from the context's owner. Typically, a context with a class
71
74
* as owner would have a local dummy as ExprOwner value.
@@ -1598,6 +1601,13 @@ class Typer extends Namer
1598
1601
val pat1 = indexPattern(tree).transform(pat)
1599
1602
val guard1 = typedExpr(tree.guard, defn.BooleanType )
1600
1603
var body1 = ensureNoLocalRefs(typedExpr(tree.body, pt1), pt1, ctx.scope.toList)
1604
+ if ctx.gadt.nonEmpty then
1605
+ // Store GADT constraint to later retrieve it (in PostTyper, for now).
1606
+ // GADT constraints are necessary to correctly check bounds of type app,
1607
+ // see tests/pos/i12226 and issue #12226. It might be possible that this
1608
+ // will end up taking too much memory. If it does, we should just limit
1609
+ // how much GADT constraints we infer - it's always sound to infer less.
1610
+ pat1.putAttachment(InferredGadtConstraints , ctx.gadt)
1601
1611
if (pt1.isValueType) // insert a cast if body does not conform to expected type if we disregard gadt bounds
1602
1612
body1 = body1.ensureConforms(pt1)(using originalCtx)
1603
1613
assignType(cpy.CaseDef (tree)(pat1, guard1, body1), pat1, body1)
0 commit comments