I just wanted to follow up on this thread. Due to the discussion and suggestions here (thank you all!) and some work over the last month or so by @Douglas_Gregor and I and related general type check fix cleanup by @xedin and @rudkx, a lot of these issues are improved. The force unwrap fixit still exists, but it is now never the only or preferred fixit offered, and hopefully the explanations of the errors are a lot more beginner-friendly now.
-
For the original motivating example:
-
And for member access with optional chaining:
-
The compiler is now smarter about optional chaining in general, and won't even offer force-unwrap as a fix where the contextually required type is optional or if the member itself returns optional (because you'd have to deal with that member's result via force-unwrap or a default value in any case).
-
If you do choose to force-unwrap with '!' in an expression that contains an optional chain, the compiler fixit now changes the chain into a force instead of wrapping the whole mess in parentheses. I.e. if you choose the '!' fix for
object?.url
it will now becomeobject!.url
instead of the former especially lovely(object?.url)!
. -
Finally, if a local variable is inferred to be optional, but then used only in an expression that needs to be non-optional, the compiler can now offer to fix this where the variable is declared instead of only where it is used. In addition, that declaration can be converted via fixit into a guard statement.
becomes:
More details in:
https://github.com/apple/swift/pull/17921
https://github.com/apple/swift/pull/18094
https://github.com/apple/swift/pull/18324