When preparing my Swift 5.8 code to Swift 6 using -enable-upcoming-feature ForwardTrailingClosures
I noticed a source breaking change in some framework.
extension View {
public func sheet<Content>(isPresented: Binding<Bool>, onDismiss: (() -> Void)? = nil, @ViewBuilder content: @escaping () -> Content) -> some View where Content : View
}
Before I enable this feature, the following code compiles (with onDismiss default to nil, the closure I provide is for content):
xx.sheet(isPresented: $editingItem) {
Text("")
}
However after I enable this feature, the following code will give me an error saying Content could not be inferred. And I have to change it to the following
All the upcoming features are not enabled in Swift 5 because they’re source-breaking, IIRC. So source breakages are expected (or else we can enable them right away!).
For the specific case, I felt that whether trailing closures are matched due to its effect on call site. The case you encountered is matched with SE-0286, but it indeed looks unnatural. I think the following pattern will look a little bit better:
But it’s still annoying. It seemed the backward scanning rule was designed because we once had trailing closure, so API designers naturally put whichever parameter they want user to use the syntax at the back. Now that multiple trailing closures are introduced, along with the forward scanning rule, it feels that in Swift 6 we’ll eventually change the previous practice, arranging closure inputs according to priority in descending order. In this case, it should be:
extension View {
@_disfavoredOverload // deprecation is up to your need
public func sheet<Content>(isPresented: Binding<Bool>, onDismiss: (() -> Void)? = nil, @ViewBuilder content: @escaping () -> Content) -> some View where Content : View
public func sheet<Content>(isPresented: Binding<Bool>, @ViewBuilder content: @escaping () -> Content, onDismiss: (() -> Void)? = nil) -> some View where Content : View
}