Skip to content

[Diags] Add an edu note explaining StringInterpolationProtocol informal requirements #30827

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Apr 22, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions include/swift/AST/EducationalNotes.def
Original file line number Diff line number Diff line change
Expand Up @@ -46,4 +46,11 @@ EDUCATIONAL_NOTES(property_wrapper_failable_init,
EDUCATIONAL_NOTES(property_wrapper_type_requirement_not_accessible,
"property-wrapper-requirements.md")

EDUCATIONAL_NOTES(missing_append_interpolation,
"string-interpolation-conformance.md")
EDUCATIONAL_NOTES(append_interpolation_static,
"string-interpolation-conformance.md")
EDUCATIONAL_NOTES(append_interpolation_void_or_discardable,
"string-interpolation-conformance.md")

#undef EDUCATIONAL_NOTES
6 changes: 3 additions & 3 deletions test/Parse/invalid_string_interpolation_protocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,13 @@

// Has a lot of invalid 'appendInterpolation' methods
public struct BadStringInterpolation: StringInterpolationProtocol {
// expected-error@-1{{type conforming to 'StringInterpolationProtocol' does not implement a valid 'appendInterpolation' method}}
// expected-error@-1{{type conforming to 'StringInterpolationProtocol' does not implement a valid 'appendInterpolation' method}} {{educational-notes=string-interpolation-conformance}}

public init(literalCapacity: Int, interpolationCount: Int) {}
public mutating func appendLiteral(_: String) {}

public static func appendInterpolation(static: ()) {
// expected-warning@-1{{'appendInterpolation' method will never be used because it is static}} {{10-17=}}
// expected-warning@-1{{'appendInterpolation' method will never be used because it is static}} {{10-17=}} {{educational-notes=string-interpolation-conformance}}
}

private func appendInterpolation(private: ()) {
Expand All @@ -20,7 +20,7 @@ public struct BadStringInterpolation: StringInterpolationProtocol {
}

public func appendInterpolation(intResult: ()) -> Int {
// expected-warning@-1{{'appendInterpolation' method does not return 'Void' or have a discardable result}} {{10-10=@discardableResult }}
// expected-warning@-1{{'appendInterpolation' method does not return 'Void' or have a discardable result}} {{10-10=@discardableResult }} {{educational-notes=string-interpolation-conformance}}
}
}

Expand Down
16 changes: 16 additions & 0 deletions userdocs/diagnostics/string-interpolation-conformance.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Conforming to `StringInterpolationProtocol`
A type conforming to `ExpressibleByStringInterpolation` uses a helper type called `StringInterpolation` to perform its interpolation. Many types can use `DefaultStringInterpolation`, which implements `String`'s interpolation behavior. Types can also implement custom behavior by providing their own type conforming to `StringInterpolationProtocol`.

In addition to its formal requirements, `init(literalCapacity:interpolationCount:)` and `appendLiteral(_:)`, `StringInterpolationProtocol` has an additional, informal requirement, `appendInterpolation`. String interpolations using `\()` syntax are translated into calls to matching `appendInterpolation` methods.

`StringInterpolationProtocol` conformers must provide at least one `appendInterpolation` method which:

- Is an instance method, as opposed to a `static` or `class` method
- Does not specify a return type, explicitly returns `Void`, or is marked with the `@discardableResult` attribute
- Is at least as accessible as its containing type

There are no restrictions on an `appendInterpolation` method's argument list, generic parameters, availability, or error-throwing behavior.

If `appendInterpolation` is overloaded, the Swift compiler will choose an appropriate overload using the labels and argument types of each interpolation. When choosing an overload, any accessible `appendInterpolation` instance method may be used, even if it does not meet all of the requirements above. However, if a `StringInterpolationProtocol` conformer doesn't have any `appendInterpolation` methods which meet all of the requirments, an error will be reported at compile time.

To learn more about customizing string interpolation behavior, see the standard library documentation of the `ExpressibleByStringInterpolation` and `StringInterpolationProtocol` protocols.