mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
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
20 lines
443 B
Swift
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
|
|
}
|