mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
The constraint graph models type variables (as the nodes) and constraints (as the multi-edges connecting nodes). The connected components within this (multi-)graph are independent subproblems that are solved separately; the results from each subproblem are then combined. The approach helps curtail exponential behavior, because (e.g.) the disjunctions/type variables in one component won't ever be explored while solving for another component This approach assumes that all of the constraints that cannot be immediately solved are associated with one or more type variables. This is almost entirely true---constraints that don't involve type variables are immediately simplified. Except for disjunctions. A disjunction involving no type variables would not appear *at all* in the constraint graph. Worse, it's independence from other constraints could not be established, so the constraint solver would go exponential for every one of these constraints. This has always been an issue, but it got worse with the separation of type checking of "as" into the "coercion" case and the "bridging" case, which introduced more of these disjunctions. This led to counterintuitive behavior where adding "as Foo" would cause the type checking to take *more* time than leaving it off, if both sides of the "as" were known to be concrete. rdar://problem/30545483 captures a case (now in the new test case) where we saw such exponential blow-ups. Teach the constraint graph to keep track of "orphaned" constraints that don't reference any type variables, and treat each "orphaned" constraint as a separate connected component. That way, they're solved independently. Fixes rdar://problem/30545483 and will likely curtain other exponential behavior we're seeing in the solver.
20 lines
746 B
Swift
20 lines
746 B
Swift
// RUN: %target-swift-frontend -typecheck %s
|
|
|
|
public class Foo : CustomReflectable {
|
|
public var booleanValue : Bool?
|
|
public var customMirror: Mirror {
|
|
return Mirror(self, children: [
|
|
"booleanValue": booleanValue as Bool? as Any,
|
|
"booleanValue": booleanValue as Bool? as Any,
|
|
"booleanValue": booleanValue as Bool? as Any,
|
|
"booleanValue": booleanValue as Bool? as Any,
|
|
"booleanValue": booleanValue as Bool? as Any,
|
|
"booleanValue": booleanValue as Bool? as Any,
|
|
"booleanValue": booleanValue as Bool? as Any,
|
|
"booleanValue": booleanValue as Bool? as Any,
|
|
"booleanValue": booleanValue as Bool? as Any,
|
|
"booleanValue": booleanValue as Bool? as Any
|
|
])
|
|
}
|
|
}
|