mirror of
https://github.com/apple/swift.git
synced 2026-06-20 15:42:51 +02:00
c2ce1e4cc3
Since Swift 4.x, NaN printing behavior has drifted from version to version. But we actually have documented guarantees about how it should behave. From `CustomStringConvertible`: > If the passed instance conforms to `CustomStringConvertible`, the `String(describing:)` initializer and the `print(_:)` function use the instance’s custom `description` property. From `description` on `Double` (or `Float`, etc.): > For any NaN value, the property’s value is “nan” As of recent versions of Swift, this is not so for stdlib floating-point types: `print(-Float.nan)` outputs the _debug_ description instead of the non-debug description. These two string representations are distinguishable because `debugDescription` shows the sign (and, if nonzero, the payload) of NaN. --- The underlying implementation-level issue is that stdlib floating-point types were made to conform to `TextOutputStreamable` as part of string interpolation work for performance reasons. That implementation elected to use debugging output, but (afaict) that decision does not seem to have been based on a deliberate choice specifically to change the behavior of NaN interpolation. Prior to that change, streaming and interpolation used the non-debug description for stdlib floating-point types (verified with Swift 4.x using SwiftFiddle). (It seems an unstated invariant of `TextOutputStreamable` assumed by various bits of the stdlib—including the quoted documentation above since `TextOutputStreamable` conformance "trumps" `CustomStringConvertible` conformance when it comes to printing—is that what's written to the stream matches `description`.) Therefore, this PR adds an explicit code path to `TextOutputStreamable.write` to restore `"nan"` as the printed, interpolated, and streamed output for floating-point NaN. This parallels the existing explicit code path for `description` itself. Additional testing is added to prevent this behavior from silently drifting again from documented guarantees. (It's telling that getting CI to pass on all platforms required no changes to any existing test.) Resolves #89496 <!-- If this pull request is targeting a release branch, please fill out the following form: https://github.com/swiftlang/.github/blob/main/PULL_REQUEST_TEMPLATE/release.md?plain=1 Otherwise, replace this comment with a description of your changes and rationale. Provide links to external references/discussions if appropriate. If this pull request resolves any GitHub issues, link them like so: Resolves <link to issue>, resolves <link to another issue>. For more information about linking a pull request to an issue, see: https://docs.github.com/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue --> <!-- Before merging this pull request, you must run the Swift continuous integration tests. For information about triggering CI builds via @swift-ci, see: https://github.com/apple/swift/blob/main/docs/ContinuousIntegration.md#swift-ci Thank you for your contribution to Swift! -->