Files
swift-mirror/stdlib/public/core/Print.swift
Doug Gregor 42bb2528dd [Overload resolution] Prefer functions with fewer defaulted/variadic arguments.
When comparing two functions for overload resolution, break apart the
parameter lists to compare individual parameters rather than comparing
the tuples. This allows us to prefer functions with fewer arguments to
ones with more, defaulted or variadic arguments. That preference was
already encoded in the constraint optimizer, which led to some strange
behavior where the preference was expressed for function calls but not
for calls to initializers. Fixes rdar://problem/24128153.

The standard library change tweaks the anachronistic, unavailable
"print" variants somewhat. The only behavior change here is a slight
regression for cases like:

  print(a: 1, b: 2)

where we used to produce a diagnostic:

  Please wrap your tuple argument in parentheses: 'print((...))'

but we now get:

  argument labels '(a:, b:)' do not match any available overloads

However, this regression will happen at some point *anyway*, if
SE-0029 (or anything else that removes the implicit tuple splat
operation) goes through.
2016-02-05 11:41:01 -08:00

177 lines
6.3 KiB
Swift

//===--- Print.swift ------------------------------------------------------===//
//
// This source file is part of the Swift.org open source project
//
// Copyright (c) 2014 - 2016 Apple Inc. and the Swift project authors
// Licensed under Apache License v2.0 with Runtime Library Exception
//
// See http://swift.org/LICENSE.txt for license information
// See http://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
//
//===----------------------------------------------------------------------===//
/// Writes the textual representations of `items`, separated by
/// `separator` and terminated by `terminator`, into the standard
/// output.
///
/// The textual representations are obtained for each `item` via
/// the expression `String(item)`.
///
/// - Note: To print without a trailing newline, pass `terminator: ""`
///
/// - SeeAlso: `debugPrint`, `Streamable`, `CustomStringConvertible`,
/// `CustomDebugStringConvertible`
@inline(never)
@_semantics("stdlib_binary_only")
public func print(
items: Any...,
separator: String = " ",
terminator: String = "\n"
) {
if let hook = _playgroundPrintHook {
var output = _TeeStream(left: "", right: _Stdout())
_print(
items, separator: separator, terminator: terminator, toStream: &output)
hook(output.left)
}
else {
var output = _Stdout()
_print(
items, separator: separator, terminator: terminator, toStream: &output)
}
}
/// Writes the textual representations of `items` most suitable for
/// debugging, separated by `separator` and terminated by
/// `terminator`, into the standard output.
///
/// The textual representations are obtained for each `item` via
/// the expression `String(reflecting: item)`.
///
/// - Note: To print without a trailing newline, pass `terminator: ""`
///
/// - SeeAlso: `print`, `Streamable`, `CustomStringConvertible`,
/// `CustomDebugStringConvertible`
@inline(never)
@_semantics("stdlib_binary_only")
public func debugPrint(
items: Any...,
separator: String = " ",
terminator: String = "\n") {
if let hook = _playgroundPrintHook {
var output = _TeeStream(left: "", right: _Stdout())
_debugPrint(
items, separator: separator, terminator: terminator, toStream: &output)
hook(output.left)
}
else {
var output = _Stdout()
_debugPrint(
items, separator: separator, terminator: terminator, toStream: &output)
}
}
/// Writes the textual representations of `items`, separated by
/// `separator` and terminated by `terminator`, into `output`.
///
/// The textual representations are obtained for each `item` via
/// the expression `String(item)`.
///
/// - Note: To print without a trailing newline, pass `terminator: ""`
///
/// - SeeAlso: `debugPrint`, `Streamable`, `CustomStringConvertible`,
/// `CustomDebugStringConvertible`
@inline(__always)
public func print<Target: OutputStreamType>(
items: Any...,
separator: String = " ",
terminator: String = "\n",
inout toStream output: Target
) {
_print(items, separator: separator, terminator: terminator, toStream: &output)
}
/// Writes the textual representations of `items` most suitable for
/// debugging, separated by `separator` and terminated by
/// `terminator`, into `output`.
///
/// The textual representations are obtained for each `item` via
/// the expression `String(reflecting: item)`.
///
/// - Note: To print without a trailing newline, pass `terminator: ""`
///
/// - SeeAlso: `print`, `Streamable`, `CustomStringConvertible`,
/// `CustomDebugStringConvertible`
@inline(__always)
public func debugPrint<Target: OutputStreamType>(
items: Any...,
separator: String = " ",
terminator: String = "\n",
inout toStream output: Target
) {
_debugPrint(
items, separator: separator, terminator: terminator, toStream: &output)
}
@inline(never)
@_semantics("stdlib_binary_only")
internal func _print<Target: OutputStreamType>(
items: [Any],
separator: String = " ",
terminator: String = "\n",
inout toStream output: Target
) {
var prefix = ""
output._lock()
defer { output._unlock() }
for item in items {
output.write(prefix)
_print_unlocked(item, &output)
prefix = separator
}
output.write(terminator)
}
@inline(never)
@_semantics("stdlib_binary_only")
internal func _debugPrint<Target: OutputStreamType>(
items: [Any],
separator: String = " ",
terminator: String = "\n",
inout toStream output: Target
) {
var prefix = ""
output._lock()
defer { output._unlock() }
for item in items {
output.write(prefix)
_debugPrint_unlocked(item, &output)
prefix = separator
}
output.write(terminator)
}
//===----------------------------------------------------------------------===//
//===--- Migration Aids ---------------------------------------------------===//
@available(*, unavailable, message="Please use 'terminator: \"\"' instead of 'appendNewline: false': 'print((...), terminator: \"\")'")
public func print<T>(_: T, appendNewline: Bool = true) {}
@available(*, unavailable, message="Please use 'terminator: \"\"' instead of 'appendNewline: false': 'debugPrint((...), terminator: \"\")'")
public func debugPrint<T>(_: T, appendNewline: Bool = true) {}
//===--- FIXME: Not working due to <rdar://22101775> ----------------------===//
@available(*, unavailable, message="Please use the 'toStream' label for the target stream: 'print((...), toStream: &...)'")
public func print<T>(_: T, inout _: OutputStreamType) {}
@available(*, unavailable, message="Please use the 'toStream' label for the target stream: 'debugPrint((...), toStream: &...))'")
public func debugPrint<T>(_: T, inout _: OutputStreamType) {}
@available(*, unavailable, message="Please use 'terminator: \"\"' instead of 'appendNewline: false' and use the 'toStream' label for the target stream: 'print((...), terminator: \"\", toStream: &...)'")
public func print<T>(_: T, inout _: OutputStreamType, appendNewline: Bool = true) {}
@available(*, unavailable, message="Please use 'terminator: \"\"' instead of 'appendNewline: false' and use the 'toStream' label for the target stream: 'debugPrint((...), terminator: \"\", toStream: &...)'")
public func debugPrint<T>(
_: T, inout _: OutputStreamType, appendNewline: Bool = true
) {}
//===----------------------------------------------------------------------===//
//===----------------------------------------------------------------------===//