Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save harlanhaskins/63b7343e7fe4e5f4c6cfbe9413a98fdd to your computer and use it in GitHub Desktop.
Save harlanhaskins/63b7343e7fe4e5f4c6cfbe9413a98fdd to your computer and use it in GitHub Desktop.
Disallow Optionals in String Interpolation

Disallow Optionals in String Interpolation Segments

During the review process, add the following fields as needed:

Introduction

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

Motivation

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.

Proposed solution

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.

Detailed design

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.

Impact on existing code

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.

Alternatives considered

  • 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.

@kandelvijaya
Copy link

👍

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment