Skip to content

Commit f02472d

Browse files
authored
Emphasize type erasure in buildLimitedAvailability (#320)
A common misconception that people have about `buildLimitedAvailability` is that it enables the following syntax in result builders: ```swift @DrawingBuilder var x: Drawable { if #available(macOS 99, *) { FutureText("Inside.future") } else { Text("Inside.present") } } ``` and would implement `buildLimitedAvailability` as follows: ```swift static func buildLimitedAvailability(component: some Drawable) -> some Drawable { component } ``` However, the above code will still result in a crash in an earlier OS where `FutureText` is not available. This change calls out the importance and need to perform type erasure in `buildLimitedAvailability`.
2 parents 7b67a55 + 78d2092 commit f02472d

File tree

1 file changed

+12
-8
lines changed

1 file changed

+12
-8
lines changed

TSPL.docc/ReferenceManual/Attributes.md

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1694,11 +1694,10 @@ The additional result-building methods are as follows:
16941694
or to perform other postprocessing on a result before returning it.
16951695

16961696
- term `static func buildLimitedAvailability(_ component: Component) -> Component`:
1697-
Builds a partial result that propagates or erases type information
1698-
outside a compiler-control statement
1697+
Builds a partial result that erases type information.
1698+
You can implement this method to prevent type information
1699+
from propagating outside a compiler-control statement
16991700
that performs an availability check.
1700-
You can use this to erase type information
1701-
that varies between the conditional branches.
17021701

17031702
For example, the code below defines a simple result builder
17041703
that builds an array of integers.
@@ -1797,9 +1796,14 @@ into code that calls the static methods of the result builder type:
17971796
You can define an overload of `buildExpression(_:)`
17981797
that takes an argument of type `()` to handle assignments specifically.
17991798
- A branch statement that checks an availability condition
1800-
becomes a call to the `buildLimitedAvailability(_:)` method.
1799+
becomes a call to the `buildLimitedAvailability(_:)` method,
1800+
if that method is implemented.
1801+
If you don't implement `buildLimitedAvailability(_:)`,
1802+
then branch statements that check availability
1803+
use the same transformations as other branch statements.
18011804
This transformation happens before the transformation into a call to
18021805
`buildEither(first:)`, `buildEither(second:)`, or `buildOptional(_:)`.
1806+
18031807
You use the `buildLimitedAvailability(_:)` method to erase type information
18041808
that changes depending on which branch is taken.
18051809
For example,
@@ -1874,7 +1878,7 @@ into code that calls the static methods of the result builder type:
18741878

18751879
To solve this problem,
18761880
implement a `buildLimitedAvailability(_:)` method
1877-
to erase type information.
1881+
to erase type information by returning a type that's always available.
18781882
For example, the code below builds an `AnyDrawable` value
18791883
from its availability check.
18801884

@@ -1884,7 +1888,7 @@ into code that calls the static methods of the result builder type:
18841888
func draw() -> String { return content.draw() }
18851889
}
18861890
extension DrawingBuilder {
1887-
static func buildLimitedAvailability(_ content: Drawable) -> AnyDrawable {
1891+
static func buildLimitedAvailability(_ content: some Drawable) -> AnyDrawable {
18881892
return AnyDrawable(content: content)
18891893
}
18901894
}
@@ -2276,7 +2280,7 @@ into code that calls the static methods of the result builder type:
22762280
func draw() -> String { return content.draw() }
22772281
}
22782282
-> extension DrawingBuilder {
2279-
static func buildLimitedAvailability(_ content: Drawable) -> AnyDrawable {
2283+
static func buildLimitedAvailability(_ content: some Drawable) -> AnyDrawable {
22802284
return AnyDrawable(content: content)
22812285
}
22822286
}

0 commit comments

Comments
 (0)