Files
swift-mirror/test/Sema/exhaustive_switch_huge.swift.gyb
Robert Widmann 2c417ecab9 Add a Subtraction Optimization
When subtraction encounters a large type space and a disjunction - as it
is bound to do when the exhaustiveness checker first submits the
initial pattern space to it - chaos ensues. The subtraction breaks down
like this:

T - (C1 | C2 | C3 | ...)
  = (T1 | T2 | T3 | ...) - C1
  | (T1 | T2 | T3 | ...) - C2
  | (T1 | T2 | T3 | ...) - C3
  | ...

For large types, this quickly trips the evaluation limit in the space
engine. The repeated decompositions are only necessary if Cn is
a constructor space with a payload. If it's a simple constructor space, we know
that the subtraction is for that constructor space is always going to
succeed anyways. So, avoid creating this explosion of disjuncts by
"subtracting en-masse". We gather all of the Cn that do not have
payloads, then when decompositing T we intentionally void out any
matching Cn. Thus the subtraction becomes

T - (C1 | C2 | C3 | ...)
  = ()

In the case when C1, C2, ..., Cn have no payload. Otherwise it becomes

T - (C1 | C2 | C3 | ...)
  = (T1 | T2 | T3 | ...) - Ck(c1, c2, ...)
  | ...

Which is, barring any further clever optimizations, the best we can do
for now.

This allows enormous enums on the order of 10^5 cases to typecheck in
a "reasonable" amount of time.

Resolves rdar://59129547
2021-06-08 16:05:45 -07:00

20 lines
443 B
Swift

// RUN: %empty-directory(%t)
// RUN: %gyb %s -o %t/exhaustive_switch_huge.swift
// RUN: %target-swift-frontend -typecheck -verify %t/exhaustive_switch_huge.swift
% case_limit = 10000
// Make sure the exhaustiveness checker can check an unreasonable amount of
// enum cases in a reasonable amount of time.
enum E {
% for i in range(case_limit):
case x${i}
% end
}
switch E.x1 {
% for i in range(case_limit):
case .x${i} : break
% end
}