From b41b1136387a45c3ebbb129e49f2d129596ace57 Mon Sep 17 00:00:00 2001 From: Jeremy Schonfeld Date: Mon, 22 Jul 2024 16:45:44 -0700 Subject: [PATCH 1/3] Use dynamic replacement instead of _typeByName for internationalization upcalls --- .../Calendar/Calendar_Cache.swift | 44 ++++++++----------- .../FileManager/FileManager+Files.swift | 10 +++-- .../Locale/Locale_Cache.swift | 33 ++++++-------- .../TimeZone/TimeZone_Cache.swift | 41 +++++++---------- .../FoundationEssentials/URL/URLParser.swift | 23 +++++----- .../Calendar/Calendar_ICU.swift | 7 +++ .../Locale/Locale_ICU.swift | 7 +++ .../TimeZone/TimeZone_GMTICU.swift | 7 +++ .../TimeZone/TimeZone_ICU.swift | 7 +++ .../URLParser+ICU.swift | 9 +++- 10 files changed, 101 insertions(+), 87 deletions(-) diff --git a/Sources/FoundationEssentials/Calendar/Calendar_Cache.swift b/Sources/FoundationEssentials/Calendar/Calendar_Cache.swift index 81b342d6a..c32e8daa9 100644 --- a/Sources/FoundationEssentials/Calendar/Calendar_Cache.swift +++ b/Sources/FoundationEssentials/Calendar/Calendar_Cache.swift @@ -15,30 +15,24 @@ internal import _ForSwiftFoundation import CoreFoundation #endif -/// Singleton which listens for notifications about preference changes for Calendar and holds cached singletons for the current locale, calendar, and time zone. -struct CalendarCache : Sendable { - - // MARK: - Concrete Classes - - // _CalendarICU, if present - static func calendarICUClass(identifier: Calendar.Identifier, useGregorian: Bool) -> _CalendarProtocol.Type? { -#if FOUNDATION_FRAMEWORK && canImport(_FoundationICU) - if useGregorian && identifier == .gregorian { - return _CalendarGregorian.self - } else { - return _CalendarICU.self - } -#else - if useGregorian && identifier == .gregorian { - return _CalendarGregorian.self - } else if let name = _typeByName("FoundationInternationalization._CalendarICU"), let t = name as? _CalendarProtocol.Type { - return t - } else { - return nil - } -#endif +dynamic package func _calendarICUClass() -> _CalendarProtocol.Type? { + #if FOUNDATION_FRAMEWORK && canImport(_FoundationICU) + _CalendarICU.self + #else + nil + #endif +} + +func _calendarClass(identifier: Calendar.Identifier, useGregorian: Bool) -> _CalendarProtocol.Type? { + if useGregorian && identifier == .gregorian { + return _CalendarGregorian.self + } else { + return _calendarICUClass() } +} +/// Singleton which listens for notifications about preference changes for Calendar and holds cached singletons for the current locale, calendar, and time zone. +struct CalendarCache : Sendable { // MARK: - State struct State : Sendable { @@ -78,7 +72,7 @@ struct CalendarCache : Sendable { } else { let id = Locale.current._calendarIdentifier // If we cannot create the right kind of class, we fail immediately here - let calendarClass = CalendarCache.calendarICUClass(identifier: id, useGregorian: true)! + let calendarClass = _calendarClass(identifier: id, useGregorian: true)! let calendar = calendarClass.init(identifier: id, timeZone: nil, locale: Locale.current, firstWeekday: nil, minimumDaysInFirstWeek: nil, gregorianStartDate: nil) currentCalendar = calendar return calendar @@ -101,7 +95,7 @@ struct CalendarCache : Sendable { return cached } else { // If we cannot create the right kind of class, we fail immediately here - let calendarClass = CalendarCache.calendarICUClass(identifier: id, useGregorian: true)! + let calendarClass = _calendarClass(identifier: id, useGregorian: true)! let new = calendarClass.init(identifier: id, timeZone: nil, locale: nil, firstWeekday: nil, minimumDaysInFirstWeek: nil, gregorianStartDate: nil) fixedCalendars[id] = new return new @@ -140,7 +134,7 @@ struct CalendarCache : Sendable { func fixed(identifier: Calendar.Identifier, locale: Locale?, timeZone: TimeZone?, firstWeekday: Int?, minimumDaysInFirstWeek: Int?, gregorianStartDate: Date?) -> any _CalendarProtocol { // Note: Only the ObjC NSCalendar initWithCoder supports gregorian start date values. For Swift it is always nil. // If we cannot create the right kind of class, we fail immediately here - let calendarClass = CalendarCache.calendarICUClass(identifier: identifier, useGregorian: true)! + let calendarClass = _calendarClass(identifier: identifier, useGregorian: true)! return calendarClass.init(identifier: identifier, timeZone: timeZone, locale: locale, firstWeekday: firstWeekday, minimumDaysInFirstWeek: minimumDaysInFirstWeek, gregorianStartDate: gregorianStartDate) } diff --git a/Sources/FoundationEssentials/FileManager/FileManager+Files.swift b/Sources/FoundationEssentials/FileManager/FileManager+Files.swift index 9bb8f0bbb..a6fbbecf3 100644 --- a/Sources/FoundationEssentials/FileManager/FileManager+Files.swift +++ b/Sources/FoundationEssentials/FileManager/FileManager+Files.swift @@ -118,9 +118,11 @@ public protocol _NSNumberInitializer { static func initialize(value: some BinaryInteger) -> Any } -private let _nsNumberInitializer: (any _NSNumberInitializer.Type)? = { +@_spi(SwiftCorelibsFoundation) +dynamic public func _nsNumberInitializer() -> (any _NSNumberInitializer.Type)? { + // TODO: return nil here after swift-corelibs-foundation begins dynamically replacing this function _typeByName("Foundation._FoundationNSNumberInitializer") as? any _NSNumberInitializer.Type -}() +} #endif func _writeFileAttributePrimitive(_ value: T, as type: U.Type) -> Any { @@ -131,7 +133,7 @@ func _writeFileAttributePrimitive(_ value: T NSNumber(value: UInt64(value)) } #else - if let ns = _nsNumberInitializer?.initialize(value: value) { + if let ns = _nsNumberInitializer()?.initialize(value: value) { return ns } else { return U(value) @@ -143,7 +145,7 @@ func _writeFileAttributePrimitive(_ value: Bool) -> Any { #if FOUNDATION_FRAMEWORK NSNumber(value: value) #else - if let ns = _nsNumberInitializer?.initialize(value: value) { + if let ns = _nsNumberInitializer()?.initialize(value: value) { return ns } else { return value diff --git a/Sources/FoundationEssentials/Locale/Locale_Cache.swift b/Sources/FoundationEssentials/Locale/Locale_Cache.swift index f890838cd..de0e6ef35 100644 --- a/Sources/FoundationEssentials/Locale/Locale_Cache.swift +++ b/Sources/FoundationEssentials/Locale/Locale_Cache.swift @@ -19,23 +19,18 @@ internal import os internal import _FoundationCShims -/// Singleton which listens for notifications about preference changes for Locale and holds cached singletons. -struct LocaleCache : Sendable { - // MARK: - Concrete Classes - - // _LocaleICU, if present. Otherwise we use _LocaleUnlocalized. The `Locale` initializers are not failable, so we just fall back to the unlocalized type when needed without failure. - static let localeICUClass: _LocaleProtocol.Type = { +dynamic package func _localeICUClass() -> _LocaleProtocol.Type { #if FOUNDATION_FRAMEWORK && canImport(_FoundationICU) - return _LocaleICU.self + // Here, we always have access to _LocaleICU + return _LocaleICU.self #else - if let name = _typeByName("FoundationInternationalization._LocaleICU"), let t = name as? _LocaleProtocol.Type { - return t - } else { - return _LocaleUnlocalized.self - } + // Return _LocaleUnlocalized if FoundationInternationalization isn't loaded. The `Locale` initializers are not failable, so we just fall back to the unlocalized type when needed without failure. + return _LocaleUnlocalized.self #endif - }() +} +/// Singleton which listens for notifications about preference changes for Locale and holds cached singletons. +struct LocaleCache : Sendable { // MARK: - State struct State { @@ -99,7 +94,7 @@ struct LocaleCache : Sendable { return nil } - let locale = LocaleCache.localeICUClass.init(name: nil, prefs: preferences, disableBundleMatching: disableBundleMatching) + let locale = _localeICUClass().init(name: nil, prefs: preferences, disableBundleMatching: disableBundleMatching) if cache { // It's possible this was an 'incomplete locale', in which case we will want to calculate it again later. self.cachedCurrentLocale = locale @@ -122,7 +117,7 @@ struct LocaleCache : Sendable { if let locale = cachedFixedLocales[id] { return locale } else { - let locale = LocaleCache.localeICUClass.init(identifier: id, prefs: nil) + let locale = _localeICUClass().init(identifier: id, prefs: nil) cachedFixedLocales[id] = locale return locale } @@ -217,7 +212,7 @@ struct LocaleCache : Sendable { if let l = cachedFixedComponentsLocales[comps] { return l } else { - let new = LocaleCache.localeICUClass.init(components: comps) + let new = _localeICUClass().init(components: comps) cachedFixedComponentsLocales[comps] = new return new @@ -229,7 +224,7 @@ struct LocaleCache : Sendable { return locale } - let locale = LocaleCache.localeICUClass.init(identifier: "", prefs: nil) + let locale = _localeICUClass().init(identifier: "", prefs: nil) cachedSystemLocale = locale return locale } @@ -415,13 +410,13 @@ struct LocaleCache : Sendable { var (prefs, _) = preferences() if let overrides { prefs.apply(overrides) } - let inner = LocaleCache.localeICUClass.init(name: name, prefs: prefs, disableBundleMatching: disableBundleMatching) + let inner = _localeICUClass().init(name: name, prefs: prefs, disableBundleMatching: disableBundleMatching) return Locale(inner: inner) } func localeWithPreferences(identifier: String, prefs: LocalePreferences?) -> Locale { if let prefs { - let inner = LocaleCache.localeICUClass.init(identifier: identifier, prefs: prefs) + let inner = _localeICUClass().init(identifier: identifier, prefs: prefs) return Locale(inner: inner) } else { return Locale(inner: LocaleCache.cache.fixed(identifier)) diff --git a/Sources/FoundationEssentials/TimeZone/TimeZone_Cache.swift b/Sources/FoundationEssentials/TimeZone/TimeZone_Cache.swift index 8ac200a4e..6a27d7322 100644 --- a/Sources/FoundationEssentials/TimeZone/TimeZone_Cache.swift +++ b/Sources/FoundationEssentials/TimeZone/TimeZone_Cache.swift @@ -31,37 +31,26 @@ internal import _ForSwiftFoundation internal import CoreFoundation_Private.CFNotificationCenter #endif -/// Singleton which listens for notifications about preference changes for TimeZone and holds cached values for current, fixed time zones, etc. -struct TimeZoneCache : Sendable { - - // MARK: - Concrete Classes - - // _TimeZoneICU, if present - static let timeZoneICUClass: _TimeZoneProtocol.Type? = { +// _TimeZoneICU, if present +dynamic package func _timeZoneICUClass() -> _TimeZoneProtocol.Type? { #if FOUNDATION_FRAMEWORK && canImport(_FoundationICU) - _TimeZoneICU.self + _TimeZoneICU.self #else - if let name = _typeByName("FoundationInternationalization._TimeZoneICU"), let t = name as? _TimeZoneProtocol.Type { - return t - } else { - return nil - } + nil #endif - }() - - // _TimeZoneGMTICU or _TimeZoneGMT - static let timeZoneGMTClass: _TimeZoneProtocol.Type = { +} + +// _TimeZoneGMTICU or _TimeZoneGMT +dynamic package func _timeZoneGMTClass() -> _TimeZoneProtocol.Type { #if FOUNDATION_FRAMEWORK && canImport(_FoundationICU) - _TimeZoneGMTICU.self + _TimeZoneGMTICU.self #else - if let name = _typeByName("FoundationInternationalization._TimeZoneGMTICU"), let t = name as? _TimeZoneProtocol.Type { - return t - } else { - return _TimeZoneGMT.self - } + _TimeZoneGMT.self #endif - }() +} +/// Singleton which listens for notifications about preference changes for TimeZone and holds cached values for current, fixed time zones, etc. +struct TimeZoneCache : Sendable { // MARK: - State struct State { @@ -239,7 +228,7 @@ struct TimeZoneCache : Sendable { } else if let cached = fixedTimeZones[identifier] { return cached } else { - if let innerTz = TimeZoneCache.timeZoneICUClass?.init(identifier: identifier) { + if let innerTz = _timeZoneICUClass()?.init(identifier: identifier) { fixedTimeZones[identifier] = innerTz return innerTz } else { @@ -254,7 +243,7 @@ struct TimeZoneCache : Sendable { } else { // In order to avoid bloating a cache with weird time zones, only cache values that are 30min offsets (including 1hr offsets). let doCache = abs(offset) % 1800 == 0 - if let innerTz = TimeZoneCache.timeZoneGMTClass.init(secondsFromGMT: offset) { + if let innerTz = _timeZoneGMTClass().init(secondsFromGMT: offset) { if doCache { offsetTimeZones[offset] = innerTz } diff --git a/Sources/FoundationEssentials/URL/URLParser.swift b/Sources/FoundationEssentials/URL/URLParser.swift index 8a2276498..b2d32ece0 100644 --- a/Sources/FoundationEssentials/URL/URLParser.swift +++ b/Sources/FoundationEssentials/URL/URLParser.swift @@ -158,17 +158,16 @@ package protocol UIDNAHook { static func decode(_ host: some StringProtocol) -> String? } +dynamic package func _uidnaHook() -> UIDNAHook.Type? { + #if FOUNDATION_FRAMEWORK && canImport(_FoundationICU) + UIDNAHookICU.self + #else + nil + #endif +} + internal struct RFC3986Parser: URLParserProtocol { static let kind: URLParserKind = .RFC3986 - static let uidnaHook: UIDNAHook.Type? = { - #if FOUNDATION_FRAMEWORK && !canImport(_FoundationICU) - nil - #elseif FOUNDATION_FRAMEWORK - UIDNAHookICU.self - #else - _typeByName("FoundationInternationalization.UIDNAHookICU") as? UIDNAHook.Type - #endif - }() // MARK: - Encoding @@ -233,7 +232,7 @@ internal struct RFC3986Parser: URLParserProtocol { } static func shouldPercentEncodeHost(_ host: some StringProtocol, forScheme scheme: (some StringProtocol)?) -> Bool { - guard uidnaHook != nil else { + guard _uidnaHook() != nil else { // Always percent-encode the host if we can't access UIDNA encoding functions return true } @@ -279,13 +278,13 @@ internal struct RFC3986Parser: URLParserProtocol { static func IDNAEncodeHost(_ host: (some StringProtocol)?) -> String? { guard let host else { return nil } guard !host.isEmpty else { return "" } - return uidnaHook?.encode(host) + return _uidnaHook()?.encode(host) } static func IDNADecodeHost(_ host: (some StringProtocol)?) -> String? { guard let host else { return nil } guard !host.isEmpty else { return "" } - guard let uidnaHook else { return String(host) } + guard let uidnaHook = _uidnaHook() else { return String(host) } return uidnaHook.decode(host) } diff --git a/Sources/FoundationInternationalization/Calendar/Calendar_ICU.swift b/Sources/FoundationInternationalization/Calendar/Calendar_ICU.swift index 026945d62..0f0b97386 100644 --- a/Sources/FoundationInternationalization/Calendar/Calendar_ICU.swift +++ b/Sources/FoundationInternationalization/Calendar/Calendar_ICU.swift @@ -26,6 +26,13 @@ import Darwin internal import _FoundationICU +#if !FOUNDATION_FRAMEWORK +@_dynamicReplacement(for: _calendarICUClass()) +private func _calendarICUClass_localized() -> _CalendarProtocol.Type? { + return _CalendarICU.self +} +#endif + internal final class _CalendarICU: _CalendarProtocol, @unchecked Sendable { let lock: LockedState let identifier: Calendar.Identifier diff --git a/Sources/FoundationInternationalization/Locale/Locale_ICU.swift b/Sources/FoundationInternationalization/Locale/Locale_ICU.swift index 0c3512548..d26fb71aa 100644 --- a/Sources/FoundationInternationalization/Locale/Locale_ICU.swift +++ b/Sources/FoundationInternationalization/Locale/Locale_ICU.swift @@ -27,6 +27,13 @@ internal import _FoundationICU import Glibc #endif +#if !FOUNDATION_FRAMEWORK +@_dynamicReplacement(for: _localeICUClass()) +private func _localeICUClass_localized() -> any _LocaleProtocol.Type { + return _LocaleICU.self +} +#endif + let MAX_ICU_NAME_SIZE: Int32 = 1024 internal final class _LocaleICU: _LocaleProtocol, Sendable { diff --git a/Sources/FoundationInternationalization/TimeZone/TimeZone_GMTICU.swift b/Sources/FoundationInternationalization/TimeZone/TimeZone_GMTICU.swift index c97505dd8..980e37b55 100644 --- a/Sources/FoundationInternationalization/TimeZone/TimeZone_GMTICU.swift +++ b/Sources/FoundationInternationalization/TimeZone/TimeZone_GMTICU.swift @@ -16,6 +16,13 @@ import FoundationEssentials internal import _FoundationICU +#if !FOUNDATION_FRAMEWORK +@_dynamicReplacement(for: _timeZoneGMTClass()) +private func _timeZoneGMTClass_localized() -> _TimeZoneProtocol.Type { + return _TimeZoneGMTICU.self +} +#endif + internal final class _TimeZoneGMTICU : _TimeZoneProtocol, @unchecked Sendable { let offset: Int let name: String diff --git a/Sources/FoundationInternationalization/TimeZone/TimeZone_ICU.swift b/Sources/FoundationInternationalization/TimeZone/TimeZone_ICU.swift index bc8edc8d1..8b63f0931 100644 --- a/Sources/FoundationInternationalization/TimeZone/TimeZone_ICU.swift +++ b/Sources/FoundationInternationalization/TimeZone/TimeZone_ICU.swift @@ -25,6 +25,13 @@ import ucrt #if canImport(_FoundationICU) internal import _FoundationICU +#if !FOUNDATION_FRAMEWORK +@_dynamicReplacement(for: _timeZoneICUClass()) +private func _timeZoneICUClass_localized() -> _TimeZoneProtocol.Type? { + return _TimeZoneICU.self +} +#endif + internal final class _TimeZoneICU: _TimeZoneProtocol, Sendable { init?(secondsFromGMT: Int) { fatalError("Unexpected init") diff --git a/Sources/FoundationInternationalization/URLParser+ICU.swift b/Sources/FoundationInternationalization/URLParser+ICU.swift index e41cc84de..d3c13e8c7 100644 --- a/Sources/FoundationInternationalization/URLParser+ICU.swift +++ b/Sources/FoundationInternationalization/URLParser+ICU.swift @@ -15,7 +15,14 @@ import FoundationEssentials internal import _FoundationICU -internal final class UIDNAHookICU: UIDNAHook { +#if !FOUNDATION_FRAMEWORK +@_dynamicReplacement(for: _uidnaHook()) +private func _uidnaHook_localized() -> UIDNAHook.Type? { + return UIDNAHookICU.self +} +#endif + +private struct UIDNAHookICU: UIDNAHook { // `Sendable` notes: `UIDNA` from ICU is thread safe. struct UIDNAPointer : @unchecked Sendable { init(_ ptr: OpaquePointer?) { self.idnaTranscoder = ptr } From 4f542347fbff60f1a48b0a8110fadea53e019a0d Mon Sep 17 00:00:00 2001 From: Jeremy Schonfeld Date: Mon, 22 Jul 2024 18:02:25 -0700 Subject: [PATCH 2/3] Make FOUNDATION_FRAMEWORK function non-dynamic --- .../Calendar/Calendar_Cache.swift | 10 ++++++---- .../Locale/Locale_Cache.swift | 12 +++++++----- .../TimeZone/TimeZone_Cache.swift | 17 ++++++++--------- .../FoundationEssentials/URL/URLParser.swift | 10 ++++++---- 4 files changed, 27 insertions(+), 22 deletions(-) diff --git a/Sources/FoundationEssentials/Calendar/Calendar_Cache.swift b/Sources/FoundationEssentials/Calendar/Calendar_Cache.swift index c32e8daa9..97de542c6 100644 --- a/Sources/FoundationEssentials/Calendar/Calendar_Cache.swift +++ b/Sources/FoundationEssentials/Calendar/Calendar_Cache.swift @@ -15,13 +15,15 @@ internal import _ForSwiftFoundation import CoreFoundation #endif -dynamic package func _calendarICUClass() -> _CalendarProtocol.Type? { - #if FOUNDATION_FRAMEWORK && canImport(_FoundationICU) +#if FOUNDATION_FRAMEWORK && canImport(_FoundationICU) +internal func _calendarICUClass() -> _CalendarProtocol.Type? { _CalendarICU.self - #else +} +#else +dynamic package func _calendarICUClass() -> _CalendarProtocol.Type? { nil - #endif } +#endif func _calendarClass(identifier: Calendar.Identifier, useGregorian: Bool) -> _CalendarProtocol.Type? { if useGregorian && identifier == .gregorian { diff --git a/Sources/FoundationEssentials/Locale/Locale_Cache.swift b/Sources/FoundationEssentials/Locale/Locale_Cache.swift index de0e6ef35..892795d76 100644 --- a/Sources/FoundationEssentials/Locale/Locale_Cache.swift +++ b/Sources/FoundationEssentials/Locale/Locale_Cache.swift @@ -19,15 +19,17 @@ internal import os internal import _FoundationCShims -dynamic package func _localeICUClass() -> _LocaleProtocol.Type { #if FOUNDATION_FRAMEWORK && canImport(_FoundationICU) - // Here, we always have access to _LocaleICU - return _LocaleICU.self +// Here, we always have access to _LocaleICU +internal func _localeICUClass() -> _LocaleProtocol.Type { + _LocaleICU.self +} #else +dynamic package func _localeICUClass() -> _LocaleProtocol.Type { // Return _LocaleUnlocalized if FoundationInternationalization isn't loaded. The `Locale` initializers are not failable, so we just fall back to the unlocalized type when needed without failure. - return _LocaleUnlocalized.self -#endif + _LocaleUnlocalized.self } +#endif /// Singleton which listens for notifications about preference changes for Locale and holds cached singletons. struct LocaleCache : Sendable { diff --git a/Sources/FoundationEssentials/TimeZone/TimeZone_Cache.swift b/Sources/FoundationEssentials/TimeZone/TimeZone_Cache.swift index 6a27d7322..11aa55949 100644 --- a/Sources/FoundationEssentials/TimeZone/TimeZone_Cache.swift +++ b/Sources/FoundationEssentials/TimeZone/TimeZone_Cache.swift @@ -31,23 +31,22 @@ internal import _ForSwiftFoundation internal import CoreFoundation_Private.CFNotificationCenter #endif -// _TimeZoneICU, if present -dynamic package func _timeZoneICUClass() -> _TimeZoneProtocol.Type? { + #if FOUNDATION_FRAMEWORK && canImport(_FoundationICU) +internal func _timeZoneICUClass() -> _TimeZoneProtocol.Type? { _TimeZoneICU.self +} +internal func _timeZoneGMTClass() -> _TimeZoneProtocol.Type? { + _TimeZoneGMTICU.self +} #else +dynamic package func _timeZoneICUClass() -> _TimeZoneProtocol.Type? { nil -#endif } - -// _TimeZoneGMTICU or _TimeZoneGMT dynamic package func _timeZoneGMTClass() -> _TimeZoneProtocol.Type { -#if FOUNDATION_FRAMEWORK && canImport(_FoundationICU) - _TimeZoneGMTICU.self -#else _TimeZoneGMT.self -#endif } +#endif /// Singleton which listens for notifications about preference changes for TimeZone and holds cached values for current, fixed time zones, etc. struct TimeZoneCache : Sendable { diff --git a/Sources/FoundationEssentials/URL/URLParser.swift b/Sources/FoundationEssentials/URL/URLParser.swift index b2d32ece0..efea6b538 100644 --- a/Sources/FoundationEssentials/URL/URLParser.swift +++ b/Sources/FoundationEssentials/URL/URLParser.swift @@ -158,13 +158,15 @@ package protocol UIDNAHook { static func decode(_ host: some StringProtocol) -> String? } -dynamic package func _uidnaHook() -> UIDNAHook.Type? { - #if FOUNDATION_FRAMEWORK && canImport(_FoundationICU) +#if FOUNDATION_FRAMEWORK && canImport(_FoundationICU) +internal func _uidnaHook() -> UIDNAHook.Type? { UIDNAHookICU.self - #else +} +#else +dynamic package func _uidnaHook() -> UIDNAHook.Type? { nil - #endif } +#endif internal struct RFC3986Parser: URLParserProtocol { static let kind: URLParserKind = .RFC3986 From e43a74654a144e47e759782480a3d27ad70df901 Mon Sep 17 00:00:00 2001 From: Jeremy Schonfeld Date: Tue, 23 Jul 2024 09:06:11 -0700 Subject: [PATCH 3/3] Fix build failures --- Sources/FoundationEssentials/TimeZone/TimeZone_Cache.swift | 2 +- Sources/FoundationInternationalization/URLParser+ICU.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Sources/FoundationEssentials/TimeZone/TimeZone_Cache.swift b/Sources/FoundationEssentials/TimeZone/TimeZone_Cache.swift index 11aa55949..1243def34 100644 --- a/Sources/FoundationEssentials/TimeZone/TimeZone_Cache.swift +++ b/Sources/FoundationEssentials/TimeZone/TimeZone_Cache.swift @@ -36,7 +36,7 @@ internal import CoreFoundation_Private.CFNotificationCenter internal func _timeZoneICUClass() -> _TimeZoneProtocol.Type? { _TimeZoneICU.self } -internal func _timeZoneGMTClass() -> _TimeZoneProtocol.Type? { +internal func _timeZoneGMTClass() -> _TimeZoneProtocol.Type { _TimeZoneGMTICU.self } #else diff --git a/Sources/FoundationInternationalization/URLParser+ICU.swift b/Sources/FoundationInternationalization/URLParser+ICU.swift index d3c13e8c7..49f73f306 100644 --- a/Sources/FoundationInternationalization/URLParser+ICU.swift +++ b/Sources/FoundationInternationalization/URLParser+ICU.swift @@ -22,7 +22,7 @@ private func _uidnaHook_localized() -> UIDNAHook.Type? { } #endif -private struct UIDNAHookICU: UIDNAHook { +struct UIDNAHookICU: UIDNAHook { // `Sendable` notes: `UIDNA` from ICU is thread safe. struct UIDNAPointer : @unchecked Sendable { init(_ ptr: OpaquePointer?) { self.idnaTranscoder = ptr }