diff --git a/Sources/Testing/Parameterization/TypeInfo.swift b/Sources/Testing/Parameterization/TypeInfo.swift index 0ebda0a82..50026ec17 100644 --- a/Sources/Testing/Parameterization/TypeInfo.swift +++ b/Sources/Testing/Parameterization/TypeInfo.swift @@ -79,7 +79,7 @@ public struct TypeInfo: Sendable { /// /// - Parameters: /// - type: The type which this instance should describe. - init(describing type: any ~Copyable.Type) { + init(describing type: (some ~Copyable).Type) { _kind = .type(type) } @@ -88,8 +88,21 @@ public struct TypeInfo: Sendable { /// /// - Parameters: /// - value: The value whose type this instance should describe. - init(describingTypeOf value: Any) { - self.init(describing: Swift.type(of: value)) + init(describingTypeOf value: some Any) { +#if !hasFeature(Embedded) + let value = value as Any +#endif + let type = Swift.type(of: value) + self.init(describing: type) + } + + /// Initialize an instance of this type describing the type of the specified + /// value. + /// + /// - Parameters: + /// - value: The value whose type this instance should describe. + init(describingTypeOf value: borrowing T) where T: ~Copyable { + self.init(describing: T.self) } } diff --git a/Sources/Testing/Test+Macro.swift b/Sources/Testing/Test+Macro.swift index a8d9eaf51..023ee5d17 100644 --- a/Sources/Testing/Test+Macro.swift +++ b/Sources/Testing/Test+Macro.swift @@ -157,16 +157,16 @@ extension Test { /// /// - Warning: This function is used to implement the `@Test` macro. Do not /// call it directly. - public static func __function( + public static func __function( named testFunctionName: String, - in containingType: (any ~Copyable.Type)?, + in containingType: S.Type?, xcTestCompatibleSelector: __XCTestCompatibleSelector?, displayName: String? = nil, traits: [any TestTrait], sourceLocation: SourceLocation, parameters: [__Parameter] = [], testFunction: @escaping @Sendable () async throws -> Void - ) -> Self { + ) -> Self where S: ~Copyable { // Don't use Optional.map here due to a miscompile/crash. Expand out to an // if expression instead. SEE: rdar://134280902 let containingTypeInfo: TypeInfo? = if let containingType { @@ -241,9 +241,9 @@ extension Test { /// /// - Warning: This function is used to implement the `@Test` macro. Do not /// call it directly. - public static func __function( + public static func __function( named testFunctionName: String, - in containingType: (any ~Copyable.Type)?, + in containingType: S.Type?, xcTestCompatibleSelector: __XCTestCompatibleSelector?, displayName: String? = nil, traits: [any TestTrait], @@ -251,7 +251,7 @@ extension Test { sourceLocation: SourceLocation, parameters paramTuples: [__Parameter], testFunction: @escaping @Sendable (C.Element) async throws -> Void - ) -> Self where C: Collection & Sendable, C.Element: Sendable { + ) -> Self where S: ~Copyable, C: Collection & Sendable, C.Element: Sendable { let containingTypeInfo: TypeInfo? = if let containingType { TypeInfo(describing: containingType) } else { @@ -388,9 +388,9 @@ extension Test { /// /// - Warning: This function is used to implement the `@Test` macro. Do not /// call it directly. - public static func __function( + public static func __function( named testFunctionName: String, - in containingType: (any ~Copyable.Type)?, + in containingType: S.Type?, xcTestCompatibleSelector: __XCTestCompatibleSelector?, displayName: String? = nil, traits: [any TestTrait], @@ -398,7 +398,7 @@ extension Test { sourceLocation: SourceLocation, parameters paramTuples: [__Parameter], testFunction: @escaping @Sendable (C1.Element, C2.Element) async throws -> Void - ) -> Self where C1: Collection & Sendable, C1.Element: Sendable, C2: Collection & Sendable, C2.Element: Sendable { + ) -> Self where S: ~Copyable, C1: Collection & Sendable, C1.Element: Sendable, C2: Collection & Sendable, C2.Element: Sendable { let containingTypeInfo: TypeInfo? = if let containingType { TypeInfo(describing: containingType) } else { @@ -416,9 +416,9 @@ extension Test { /// /// - Warning: This function is used to implement the `@Test` macro. Do not /// call it directly. - public static func __function( + public static func __function( named testFunctionName: String, - in containingType: (any ~Copyable.Type)?, + in containingType: S.Type?, xcTestCompatibleSelector: __XCTestCompatibleSelector?, displayName: String? = nil, traits: [any TestTrait], @@ -426,7 +426,7 @@ extension Test { sourceLocation: SourceLocation, parameters paramTuples: [__Parameter], testFunction: @escaping @Sendable ((E1, E2)) async throws -> Void - ) -> Self where C: Collection & Sendable, C.Element == (E1, E2), E1: Sendable, E2: Sendable { + ) -> Self where S: ~Copyable, C: Collection & Sendable, C.Element == (E1, E2), E1: Sendable, E2: Sendable { let containingTypeInfo: TypeInfo? = if let containingType { TypeInfo(describing: containingType) } else { @@ -447,9 +447,9 @@ extension Test { /// /// - Warning: This function is used to implement the `@Test` macro. Do not /// call it directly. - public static func __function( + public static func __function( named testFunctionName: String, - in containingType: (any ~Copyable.Type)?, + in containingType: S.Type?, xcTestCompatibleSelector: __XCTestCompatibleSelector?, displayName: String? = nil, traits: [any TestTrait], @@ -457,7 +457,7 @@ extension Test { sourceLocation: SourceLocation, parameters paramTuples: [__Parameter], testFunction: @escaping @Sendable ((Key, Value)) async throws -> Void - ) -> Self where Key: Sendable, Value: Sendable { + ) -> Self where S: ~Copyable, Key: Sendable, Value: Sendable { let containingTypeInfo: TypeInfo? = if let containingType { TypeInfo(describing: containingType) } else { @@ -472,9 +472,9 @@ extension Test { /// /// - Warning: This function is used to implement the `@Test` macro. Do not /// call it directly. - public static func __function( + public static func __function( named testFunctionName: String, - in containingType: (any ~Copyable.Type)?, + in containingType: S.Type?, xcTestCompatibleSelector: __XCTestCompatibleSelector?, displayName: String? = nil, traits: [any TestTrait], @@ -482,7 +482,7 @@ extension Test { sourceLocation: SourceLocation, parameters paramTuples: [__Parameter], testFunction: @escaping @Sendable (C1.Element, C2.Element) async throws -> Void - ) -> Self where C1: Collection & Sendable, C1.Element: Sendable, C2: Collection & Sendable, C2.Element: Sendable { + ) -> Self where S: ~Copyable, C1: Collection & Sendable, C1.Element: Sendable, C2: Collection & Sendable, C2.Element: Sendable { let containingTypeInfo: TypeInfo? = if let containingType { TypeInfo(describing: containingType) } else { diff --git a/Sources/TestingMacros/TestDeclarationMacro.swift b/Sources/TestingMacros/TestDeclarationMacro.swift index b67bf3360..8007c3aaf 100644 --- a/Sources/TestingMacros/TestDeclarationMacro.swift +++ b/Sources/TestingMacros/TestDeclarationMacro.swift @@ -382,7 +382,7 @@ public struct TestDeclarationMacro: PeerMacro, Sendable { // Get the name of the type containing the function for passing to the test // factory function later. - let typeNameExpr: ExprSyntax = typeName.map { "\($0).self" } ?? "nil" + let typeNameExpr: ExprSyntax = typeName.map { "\($0).self" } ?? "nil as Swift.Never.Type?" if typeName != nil, let genericGuardDecl = makeGenericGuardDecl(guardingAgainst: functionDecl, in: context) { result.append(genericGuardDecl) diff --git a/Tests/TestingTests/MiscellaneousTests.swift b/Tests/TestingTests/MiscellaneousTests.swift index 84d1ce493..d47811f90 100644 --- a/Tests/TestingTests/MiscellaneousTests.swift +++ b/Tests/TestingTests/MiscellaneousTests.swift @@ -560,7 +560,7 @@ struct MiscellaneousTests { let line = 12345 let column = 67890 let sourceLocation = SourceLocation(fileID: fileID, filePath: filePath, line: line, column: column) - let testFunction = Test.__function(named: "myTestFunction()", in: nil, xcTestCompatibleSelector: nil, displayName: nil, traits: [], sourceLocation: sourceLocation) {} + let testFunction = Test.__function(named: "myTestFunction()", in: nil as Never.Type?, xcTestCompatibleSelector: nil, displayName: nil, traits: [], sourceLocation: sourceLocation) {} #expect(String(describing: testFunction.id) == "Module.myTestFunction()/Y.swift:12345:67890") } diff --git a/Tests/TestingTests/SwiftPMTests.swift b/Tests/TestingTests/SwiftPMTests.swift index e61c3b237..4543d3932 100644 --- a/Tests/TestingTests/SwiftPMTests.swift +++ b/Tests/TestingTests/SwiftPMTests.swift @@ -285,7 +285,7 @@ struct SwiftPMTests { @Test("Unsupported ABI version") func unsupportedABIVersion() async throws { let versionNumber = VersionNumber(-100, 0) - let versionTypeInfo = ABI.version(forVersionNumber: versionNumber).map(TypeInfo.init(describing:)) + let versionTypeInfo = ABI.version(forVersionNumber: versionNumber).map {TypeInfo(describing: $0) } #expect(versionTypeInfo == nil) } @@ -294,7 +294,7 @@ struct SwiftPMTests { #expect(swiftCompilerVersion >= VersionNumber(6, 0)) #expect(swiftCompilerVersion < VersionNumber(8, 0), "Swift 8.0 is here! Please update this test.") let versionNumber = VersionNumber(8, 0) - let versionTypeInfo = ABI.version(forVersionNumber: versionNumber).map(TypeInfo.init(describing:)) + let versionTypeInfo = ABI.version(forVersionNumber: versionNumber).map {TypeInfo(describing: $0) } #expect(versionTypeInfo == nil) } diff --git a/Tests/TestingTests/TypeInfoTests.swift b/Tests/TestingTests/TypeInfoTests.swift index b2a79f1ab..2063a7684 100644 --- a/Tests/TestingTests/TypeInfoTests.swift +++ b/Tests/TestingTests/TypeInfoTests.swift @@ -122,6 +122,11 @@ struct TypeInfoTests { #expect(!TypeInfo(describing: String.self).isSwiftEnumeration) #expect(TypeInfo(describing: SomeEnum.self).isSwiftEnumeration) } + + @Test func typeOfMoveOnlyValueIsInferred() { + let value = MoveOnlyType() + #expect(TypeInfo(describingTypeOf: value).unqualifiedName == "MoveOnlyType") + } } // MARK: - Fixtures @@ -131,3 +136,5 @@ extension String { } private enum SomeEnum {} + +private struct MoveOnlyType: ~Copyable {}