Skip to content

Commit d16e216

Browse files
authored
Make protocol usage obvious using any and some keywords (apple#307)
Motivation: Calling through protocols is more expensive than many other types of call. Modifications: Annotate each protocol usage with any or some keywords. Result: Protocol usage now obvious
1 parent 0f170b4 commit d16e216

File tree

5 files changed

+38
-32
lines changed

5 files changed

+38
-32
lines changed

Package.swift

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,10 @@
1515

1616
import PackageDescription
1717

18+
let swiftSettings: [SwiftSetting] = [
19+
.enableUpcomingFeature("ExistentialAny"),
20+
]
21+
1822
let package = Package(
1923
name: "swift-log",
2024
products: [
@@ -26,11 +30,13 @@ let package = Package(
2630
targets: [
2731
.target(
2832
name: "Logging",
29-
dependencies: []
33+
dependencies: [],
34+
swiftSettings: swiftSettings
3035
),
3136
.testTarget(
3237
name: "LoggingTests",
33-
dependencies: ["Logging"]
38+
dependencies: ["Logging"],
39+
swiftSettings: swiftSettings
3440
),
3541
]
3642
)

Sources/Logging/Logging.swift

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -46,10 +46,10 @@ public struct Logger {
4646
var label: String
4747

4848
@usableFromInline
49-
var handler: LogHandler
49+
var handler: any LogHandler
5050

5151
@inlinable
52-
init(label: String, handler: LogHandler) {
52+
init(label: String, handler: any LogHandler) {
5353
self.label = label
5454
self.handler = handler
5555
}
@@ -68,7 +68,7 @@ public struct Logger {
6868

6969
/// A computed property to access the `LogHandler`.
7070
@inlinable
71-
public var handler: LogHandler {
71+
public var handler: any LogHandler {
7272
get {
7373
return self._storage.handler
7474
}
@@ -87,7 +87,7 @@ public struct Logger {
8787
}
8888

8989
@usableFromInline
90-
internal init(label: String, _ handler: LogHandler) {
90+
internal init(label: String, _ handler: any LogHandler) {
9191
self._storage = Storage(label: label, handler: handler)
9292
}
9393
}
@@ -515,7 +515,7 @@ public enum LoggingSystem {
515515
///
516516
/// - parameters:
517517
/// - factory: A closure that given a `Logger` identifier, produces an instance of the `LogHandler`.
518-
public static func bootstrap(_ factory: @escaping (String) -> LogHandler) {
518+
public static func bootstrap(_ factory: @escaping (String) -> any LogHandler) {
519519
self._factory.replaceFactory({ label, _ in
520520
factory(label)
521521
}, validate: true)
@@ -531,28 +531,28 @@ public enum LoggingSystem {
531531
/// - parameters:
532532
/// - metadataProvider: The `MetadataProvider` used to inject runtime-generated metadata from the execution context.
533533
/// - factory: A closure that given a `Logger` identifier, produces an instance of the `LogHandler`.
534-
public static func bootstrap(_ factory: @escaping (String, Logger.MetadataProvider?) -> LogHandler,
534+
public static func bootstrap(_ factory: @escaping (String, Logger.MetadataProvider?) -> any LogHandler,
535535
metadataProvider: Logger.MetadataProvider?) {
536536
self._metadataProviderFactory.replaceMetadataProvider(metadataProvider, validate: true)
537537
self._factory.replaceFactory(factory, validate: true)
538538
}
539539

540540
// for our testing we want to allow multiple bootstrapping
541-
internal static func bootstrapInternal(_ factory: @escaping (String) -> LogHandler) {
541+
internal static func bootstrapInternal(_ factory: @escaping (String) -> any LogHandler) {
542542
self._metadataProviderFactory.replaceMetadataProvider(nil, validate: false)
543543
self._factory.replaceFactory({ label, _ in
544544
factory(label)
545545
}, validate: false)
546546
}
547547

548548
// for our testing we want to allow multiple bootstrapping
549-
internal static func bootstrapInternal(_ factory: @escaping (String, Logger.MetadataProvider?) -> LogHandler,
549+
internal static func bootstrapInternal(_ factory: @escaping (String, Logger.MetadataProvider?) -> any LogHandler,
550550
metadataProvider: Logger.MetadataProvider?) {
551551
self._metadataProviderFactory.replaceMetadataProvider(metadataProvider, validate: false)
552552
self._factory.replaceFactory(factory, validate: false)
553553
}
554554

555-
fileprivate static var factory: (String, Logger.MetadataProvider?) -> LogHandler {
555+
fileprivate static var factory: (String, Logger.MetadataProvider?) -> any LogHandler {
556556
return { label, metadataProvider in
557557
self._factory.underlying(label, metadataProvider)
558558
}
@@ -582,22 +582,22 @@ public enum LoggingSystem {
582582

583583
private final class FactoryBox {
584584
private let lock = ReadWriteLock()
585-
fileprivate var _underlying: (_ label: String, _ provider: Logger.MetadataProvider?) -> LogHandler
585+
fileprivate var _underlying: (_ label: String, _ provider: Logger.MetadataProvider?) -> any LogHandler
586586
private var initialized = false
587587

588-
init(_ underlying: @escaping (String, Logger.MetadataProvider?) -> LogHandler) {
588+
init(_ underlying: @escaping (String, Logger.MetadataProvider?) -> any LogHandler) {
589589
self._underlying = underlying
590590
}
591591

592-
func replaceFactory(_ factory: @escaping (String, Logger.MetadataProvider?) -> LogHandler, validate: Bool) {
592+
func replaceFactory(_ factory: @escaping (String, Logger.MetadataProvider?) -> any LogHandler, validate: Bool) {
593593
self.lock.withWriterLock {
594594
precondition(!validate || !self.initialized, "logging system can only be initialized once per process.")
595595
self._underlying = factory
596596
self.initialized = true
597597
}
598598
}
599599

600-
var underlying: (String, Logger.MetadataProvider?) -> LogHandler {
600+
var underlying: (String, Logger.MetadataProvider?) -> any LogHandler {
601601
return self.lock.withReaderLock {
602602
return self._underlying
603603
}
@@ -655,7 +655,7 @@ extension Logger {
655655
case string(String)
656656

657657
/// A metadata value which is some `CustomStringConvertible`.
658-
case stringConvertible(CustomStringConvertible & Sendable)
658+
case stringConvertible(any CustomStringConvertible & Sendable)
659659

660660
/// A metadata value which is a dictionary from `String` to `Logger.MetadataValue`.
661661
///
@@ -728,7 +728,7 @@ extension Logger {
728728
/// - parameters:
729729
/// - label: An identifier for the creator of a `Logger`.
730730
/// - factory: A closure creating non-standard `LogHandler`s.
731-
public init(label: String, factory: (String) -> LogHandler) {
731+
public init(label: String, factory: (String) -> any LogHandler) {
732732
self = Logger(label: label, factory(label))
733733
}
734734

@@ -743,7 +743,7 @@ extension Logger {
743743
/// - parameters:
744744
/// - label: An identifier for the creator of a `Logger`.
745745
/// - factory: A closure creating non-standard `LogHandler`s.
746-
public init(label: String, factory: (String, Logger.MetadataProvider?) -> LogHandler) {
746+
public init(label: String, factory: (String, Logger.MetadataProvider?) -> any LogHandler) {
747747
self = Logger(label: label, factory(label, LoggingSystem.metadataProvider))
748748
}
749749

@@ -889,7 +889,7 @@ extension Logger {
889889
/// "more important" than the second handler. The same rule applies when querying for the `metadata` property of the
890890
/// multiplex log handler - it constructs `Metadata` uniquing values.
891891
public struct MultiplexLogHandler: LogHandler {
892-
private var handlers: [LogHandler]
892+
private var handlers: [any LogHandler]
893893
private var effectiveLogLevel: Logger.Level
894894
/// This metadata provider runs after all metadata providers of the multiplexed handlers.
895895
private var _metadataProvider: Logger.MetadataProvider?
@@ -899,13 +899,13 @@ public struct MultiplexLogHandler: LogHandler {
899899
/// - parameters:
900900
/// - handlers: An array of `LogHandler`s, each of which will receive the log messages sent to this `Logger`.
901901
/// The array must not be empty.
902-
public init(_ handlers: [LogHandler]) {
902+
public init(_ handlers: [any LogHandler]) {
903903
assert(!handlers.isEmpty, "MultiplexLogHandler.handlers MUST NOT be empty")
904904
self.handlers = handlers
905905
self.effectiveLogLevel = handlers.map { $0.logLevel }.min() ?? .trace
906906
}
907907

908-
public init(_ handlers: [LogHandler], metadataProvider: Logger.MetadataProvider?) {
908+
public init(_ handlers: [any LogHandler], metadataProvider: Logger.MetadataProvider?) {
909909
assert(!handlers.isEmpty, "MultiplexLogHandler.handlers MUST NOT be empty")
910910
self.handlers = handlers
911911
self.effectiveLogLevel = handlers.map { $0.logLevel }.min() ?? .trace
@@ -1009,7 +1009,7 @@ public struct MultiplexLogHandler: LogHandler {
10091009
}
10101010
}
10111011

1012-
private mutating func mutatingForEachHandler(_ mutator: (inout LogHandler) -> Void) {
1012+
private mutating func mutatingForEachHandler(_ mutator: (inout any LogHandler) -> Void) {
10131013
for index in self.handlers.indices {
10141014
mutator(&self.handlers[index])
10151015
}
@@ -1126,7 +1126,7 @@ public struct StreamLogHandler: LogHandler {
11261126
return StreamLogHandler(label: label, stream: StdioOutputStream.stderr, metadataProvider: metadataProvider)
11271127
}
11281128

1129-
private let stream: _SendableTextOutputStream
1129+
private let stream: any _SendableTextOutputStream
11301130
private let label: String
11311131

11321132
public var logLevel: Logger.Level = .info
@@ -1150,12 +1150,12 @@ public struct StreamLogHandler: LogHandler {
11501150
}
11511151

11521152
// internal for testing only
1153-
internal init(label: String, stream: _SendableTextOutputStream) {
1153+
internal init(label: String, stream: any _SendableTextOutputStream) {
11541154
self.init(label: label, stream: stream, metadataProvider: LoggingSystem.metadataProvider)
11551155
}
11561156

11571157
// internal for testing only
1158-
internal init(label: String, stream: _SendableTextOutputStream, metadataProvider: Logger.MetadataProvider?) {
1158+
internal init(label: String, stream: any _SendableTextOutputStream, metadataProvider: Logger.MetadataProvider?) {
11591159
self.label = label
11601160
self.stream = stream
11611161
self.metadataProvider = metadataProvider

Tests/LoggingTests/CompatibilityTest.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -45,7 +45,7 @@ private struct OldSchoolTestLogging {
4545
private let _config = Config() // shared among loggers
4646
private let recorder = Recorder() // shared among loggers
4747

48-
func make(label: String) -> LogHandler {
48+
func make(label: String) -> any LogHandler {
4949
return OldSchoolLogHandler(label: label,
5050
config: self.config,
5151
recorder: self.recorder,
@@ -54,15 +54,15 @@ private struct OldSchoolTestLogging {
5454
}
5555

5656
var config: Config { return self._config }
57-
var history: History { return self.recorder }
57+
var history: some History { return self.recorder }
5858
}
5959

6060
private struct OldSchoolLogHandler: LogHandler {
6161
var label: String
6262
let config: Config
6363
let recorder: Recorder
6464

65-
func make(label: String) -> LogHandler {
65+
func make(label: String) -> some LogHandler {
6666
return TestLogHandler(label: label, config: self.config, recorder: self.recorder)
6767
}
6868

Tests/LoggingTests/LoggingTest.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1056,7 +1056,7 @@ class LoggingTest: XCTestCase {
10561056
}
10571057

10581058
extension Logger {
1059-
public func error(error: Error,
1059+
public func error(error: any Error,
10601060
metadata: @autoclosure () -> Logger.Metadata? = nil,
10611061
file: String = #fileID, function: String = #function, line: UInt = #line) {
10621062
self.error("\(error.localizedDescription)", metadata: metadata(), file: file, function: function, line: line)

Tests/LoggingTests/TestLogger.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ internal struct TestLogging {
2222
private let _config = Config() // shared among loggers
2323
private let recorder = Recorder() // shared among loggers
2424

25-
func make(label: String) -> LogHandler {
25+
func make(label: String) -> some LogHandler {
2626
return TestLogHandler(
2727
label: label,
2828
config: self.config,
@@ -31,7 +31,7 @@ internal struct TestLogging {
3131
)
3232
}
3333

34-
func makeWithMetadataProvider(label: String, metadataProvider: Logger.MetadataProvider?) -> LogHandler {
34+
func makeWithMetadataProvider(label: String, metadataProvider: Logger.MetadataProvider?) -> (some LogHandler) {
3535
return TestLogHandler(
3636
label: label,
3737
config: self.config,
@@ -41,7 +41,7 @@ internal struct TestLogging {
4141
}
4242

4343
var config: Config { return self._config }
44-
var history: History { return self.recorder }
44+
var history: some History { return self.recorder }
4545
}
4646

4747
internal struct TestLogHandler: LogHandler {

0 commit comments

Comments
 (0)