- Proposal: SE-NNNN
- Authors: Harlan Haskins, Julio Carrettoni, Robert Widmann
- Review Manager: TBD
- Status: Awaiting review
During the review process, add the following fields as needed:
- Decision Notes: Rationale, Additional Commentary
- Bugs: SR-NNNN, SR-MMMM
- Previous Revision: 1
- Previous Proposal: SE-XXXX
Swift developers frequently use string interpolation as a convenient,
concise syntax for interweaving variable values with strings. The
interpolation machinery, however, has surprising behavior in one
specific case: Optional<T>
. If a user puts an optional value into a
string interpolation segment, it will insert either
"Optional("value")"
or "nil"
in the resulting string. Neither of
these is particularly desirable, so we propose a warning and fix-it to
surface solutions to these potential mistakes.
Swift-evolution thread: Discussion thread topic for that proposal
The Swift Programming Language defines string interpolation segments
as "a way to construct a new String value from a mix of constants,
variables, literals, and expressions". There is one type that runs
counter to this definition: Optional
. The .none
case in particular
is used to indicate the absence of a value. Moreover, its inclusion in
interpolation segments leads to the dreaded "nil"
in output that is
often fed to UI elements. Even barring that, interpolating a non-nil
optional value yields "Optional("value")"
, a result that is not useful
even in logged output.
Given that the Optional
type is never fit for display to the end user,
and can often be a surprising find in the console, we propose that
requesting an Optional
's debug description be an explicit act. This
proposal now requires a warning when using an expression of Optional
type within a string interpolation segment.
The user will be warned after attempting to use an expression with type
Optional<T>
in a string interpolation segment. They will then be
offered a fixit suggesting they explicitly request the
debugDescription
of the Optional
value instead.
Semantic analysis currently does not do much but guarantee the
well-formedness of expressions in interpolation segments. These are then
fed directly to String.init(stringInterpolationSegment:)
and are run
through the runtime reflection system to generate a description.
Semantic analysis will be tweaked to inspect the result of solving an
interpolation segment for an Optional
and will offer a fixit in that
case.
As this is a warning, code written before this proposal will continue to compile and run with the same semantics as before. Authors of code that makes use of this unsafe pattern will be offered a migration path to the safer, more explicit form.
-
A fixit that suggests a default value be inserted would be entirely appropriate (following the style of the fixit introduced in SE-0140).
-
Forbidding this pattern by hard error would make this proposal a breaking change that is out of scope for this stage of Swift's development.
-
A fixit that introduces a force-unwrapping would technically work as well, however it would be fixing a dangerous operation with yet another dangerous operation.
👍