From f9bfd814a0411080180e2240e8bffbb41597aa20 Mon Sep 17 00:00:00 2001 From: Jonathan Grynspan Date: Wed, 21 Aug 2024 09:42:55 -0400 Subject: [PATCH 1/2] Fix a merge conflict on main-next. This PR fixes a conflict between #610 and #619. #610 added a string cache to `TypeInfo` using `ObjectIdentifier` instances as keys. #619 added support for move-only types to `TypeInfo`. Due to rdar://134276458, move-only types cannot be used with `ObjectIdentifier`. This PR uses `UInt` instead until that issue can be resolved in a future stdlib update. --- Sources/Testing/Parameterization/TypeInfo.swift | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/Sources/Testing/Parameterization/TypeInfo.swift b/Sources/Testing/Parameterization/TypeInfo.swift index d02bfaa11..0b4030f09 100644 --- a/Sources/Testing/Parameterization/TypeInfo.swift +++ b/Sources/Testing/Parameterization/TypeInfo.swift @@ -75,7 +75,11 @@ public struct TypeInfo: Sendable { extension TypeInfo { /// An in-memory cache of fully-qualified type name components. - private static let _fullyQualifiedNameComponentsCache = Locked<[ObjectIdentifier: [String]]>() + /// + /// - Bug: The key type of this cache should be `ObjectIdentifier`, but such + /// values cannot be constructed from move-only types. + /// ([134276458](rdar://134276458)) + private static let _fullyQualifiedNameComponentsCache = Locked<[UInt: [String]]>() /// The complete name of this type, with the names of all referenced types /// fully-qualified by their module names when possible. @@ -95,7 +99,8 @@ extension TypeInfo { public var fullyQualifiedNameComponents: [String] { switch _kind { case let .type(type): - if let cachedResult = Self._fullyQualifiedNameComponentsCache.rawValue[ObjectIdentifier(type)] { + let cacheKey = unsafeBitCast(type, to: UInt.self) + if let cachedResult = Self._fullyQualifiedNameComponentsCache.rawValue[cacheKey] { return cachedResult } @@ -117,7 +122,7 @@ extension TypeInfo { result = result.filter { !$0.starts(with: "(unknown context at") } Self._fullyQualifiedNameComponentsCache.withLock { fullyQualifiedNameComponentsCache in - fullyQualifiedNameComponentsCache[ObjectIdentifier(type)] = result + fullyQualifiedNameComponentsCache[cacheKey] = result } return result @@ -314,7 +319,7 @@ extension TypeInfo: Hashable { case let (.type(lhs), .type(rhs)): // == and ObjectIdentifier do not support move-only metatypes, so compare // the bits of the types directly. SEE: rdar://134276458 - return unsafeBitCast(lhs, to: UnsafeRawPointer.self) == unsafeBitCast(rhs, to: UnsafeRawPointer.self) + return unsafeBitCast(lhs, to: UInt.self) == unsafeBitCast(rhs, to: UInt.self) default: return lhs.fullyQualifiedNameComponents == rhs.fullyQualifiedNameComponents } From 34236dcb877587124ded4310b460b92361780dc1 Mon Sep 17 00:00:00 2001 From: Jonathan Grynspan Date: Wed, 21 Aug 2024 10:10:45 -0400 Subject: [PATCH 2/2] Different approach --- .../Testing/Parameterization/TypeInfo.swift | 30 ++++++++++++------- 1 file changed, 19 insertions(+), 11 deletions(-) diff --git a/Sources/Testing/Parameterization/TypeInfo.swift b/Sources/Testing/Parameterization/TypeInfo.swift index 0b4030f09..1ba3bea06 100644 --- a/Sources/Testing/Parameterization/TypeInfo.swift +++ b/Sources/Testing/Parameterization/TypeInfo.swift @@ -75,11 +75,7 @@ public struct TypeInfo: Sendable { extension TypeInfo { /// An in-memory cache of fully-qualified type name components. - /// - /// - Bug: The key type of this cache should be `ObjectIdentifier`, but such - /// values cannot be constructed from move-only types. - /// ([134276458](rdar://134276458)) - private static let _fullyQualifiedNameComponentsCache = Locked<[UInt: [String]]>() + private static let _fullyQualifiedNameComponentsCache = Locked<[ObjectIdentifier: [String]]>() /// The complete name of this type, with the names of all referenced types /// fully-qualified by their module names when possible. @@ -99,8 +95,7 @@ extension TypeInfo { public var fullyQualifiedNameComponents: [String] { switch _kind { case let .type(type): - let cacheKey = unsafeBitCast(type, to: UInt.self) - if let cachedResult = Self._fullyQualifiedNameComponentsCache.rawValue[cacheKey] { + if let cachedResult = Self._fullyQualifiedNameComponentsCache.rawValue[ObjectIdentifier(type)] { return cachedResult } @@ -122,7 +117,7 @@ extension TypeInfo { result = result.filter { !$0.starts(with: "(unknown context at") } Self._fullyQualifiedNameComponentsCache.withLock { fullyQualifiedNameComponentsCache in - fullyQualifiedNameComponentsCache[cacheKey] = result + fullyQualifiedNameComponentsCache[ObjectIdentifier(type)] = result } return result @@ -317,9 +312,7 @@ extension TypeInfo: Hashable { public static func ==(lhs: Self, rhs: Self) -> Bool { switch (lhs._kind, rhs._kind) { case let (.type(lhs), .type(rhs)): - // == and ObjectIdentifier do not support move-only metatypes, so compare - // the bits of the types directly. SEE: rdar://134276458 - return unsafeBitCast(lhs, to: UInt.self) == unsafeBitCast(rhs, to: UInt.self) + return ObjectIdentifier(lhs) == ObjectIdentifier(rhs) default: return lhs.fullyQualifiedNameComponents == rhs.fullyQualifiedNameComponents } @@ -330,6 +323,21 @@ extension TypeInfo: Hashable { } } +// MARK: - ObjectIdentifier support + +extension ObjectIdentifier { + /// Initialize an instance of this type from a type reference. + /// + /// - Parameters: + /// - type: The type to initialize this instance from. + /// + /// - Bug: The standard library should support this conversion. + /// ([134276458](rdar://134276458), [134415960](rdar://134415960)) + fileprivate init(_ type: any ~Copyable.Type) { + self.init(unsafeBitCast(type, to: Any.Type.self)) + } +} + // MARK: - Codable extension TypeInfo: Codable {