From a81a3d37b01131df2716e0c55fb02bc93426c3a2 Mon Sep 17 00:00:00 2001 From: Slava Pestov Date: Tue, 4 Nov 2025 18:30:44 -0500 Subject: [PATCH] docs: Remove obsolete example from TypeChecker.md Swift has not had user-defined conversions since before Swift 1.0. Remove the running example from the discussion of locators. This probably makes the explanation too opaque, but the old explanation was useless because it was out of date. I'll add a proper example later. --- docs/TypeChecker.md | 131 ++++++++++---------------------------------- 1 file changed, 28 insertions(+), 103 deletions(-) diff --git a/docs/TypeChecker.md b/docs/TypeChecker.md index f5a848d8495ee..ac620bff5cff2 100644 --- a/docs/TypeChecker.md +++ b/docs/TypeChecker.md @@ -838,10 +838,7 @@ node based on the kind of expression: the body of the closure is type-checked with that complete function type. -The solution application step cannot fail for any type checking rule -modeled by the constraint system. However, there are some failures -that are intentionally left to the solution application phase, such as -a postfix '!' applied to a non-optional type. +The solution application step cannot fail. #### Locators @@ -849,62 +846,26 @@ During constraint generation and solving, numerous constraints are created, broken apart, and solved. During constraint application as well as during diagnostics emission, it is important to track the relationship between the constraints and the actual AST nodes from -which they originally came. For example, consider the following type -checking problem:: -```swift - struct X { - // user-defined conversions - func [conversion] __conversion () -> String { /* ... */ } - func [conversion] __conversion () -> Int { /* ... */ } - } - - func f(_ i : Int, s : String) { } - - var x : X - f(10.5, x) -``` -This constraint system generates the constraints "`T(f)` ==Fn `T0 -> T1`" -(for fresh variables `T0` and `T1`), "`(T2, X) T1`" -constraint has a locator that is anchored at the function application -and a path with the "apply function" derivation step, meaning that -this is the function being applied. Similarly, the "`(T2, X) apply argument -> tuple element #1 -> conversion member -``` -When the solver selects a particular overload from the overload set, +associated with a particular locator. + +When the solver selects a particular overload an the overload set, it records the selected overload based on the locator of the overload set. When it comes time to perform constraint application, the locator is recreated based on context (as the bottom-up traversal walks the @@ -942,46 +896,17 @@ the path of the solver, and can be used to query and recover the important decisions made by the solver. However, the locators determined by the solver may not directly refer to the most specific AST node for the purposes of identifying the corresponding source -location. For example, the failed constraint "`Int` conforms to -`ExpressibleByFloatLiteral`" can most specifically by centered on the -floating-point literal `10.5`, but its locator is:: -``` - function application -> apply argument -> tuple element #0 -``` +location. + The process of locator simplification maps a locator to its most specific AST node. Essentially, it starts at the anchor of the -locator (in this case, the application `f(10.5, x)`) and then walks -the path, matching derivation steps to subexpressions. The "function -application" derivation step extracts the argument (`(10.5, x)`). -Then, the "tuple element #0" derivation extracts the tuple -element 0 subexpression, `10.5`, at which point we have traversed -the entire path and now have the most specific expression for -source-location purposes. - -Simplification does not always exhaust the complete path. For example, -consider a slight modification to our example, so that the argument to -`f` is provided by another call, we get a different result -entirely:: -```swift - func f(_ i : Int, s : String) { } - func g() -> (f : Float, x : X) { } +locator and then walks the path, matching derivation steps to +subexpressions. + +For example, the "function application" derivation step extracts +the argument list, and the "tuple element #0" derivation extracts +the sub-expression for the first argument. - f(g()) -``` -Here, the failing constraint is `Float apply argument -> tuple element #0 -``` -When we simplify this locator, we start with `f(g())`. The "apply -argument" derivation step takes us to the argument expression -`g()`. Here, however, there is no subexpression for the first tuple -element of `g()`, because it's simply part of the tuple returned -from `g`. At this point, simplification ceases, and creates the -simplified locator:: -``` - function application of g -> tuple element #0 -``` ### Performance The performance of the type checker is dependent on a number of