Open Kyle-Ye opened 1 month ago
Looks like it can be workaround by explicitly mark as Any.Type
.
Hope the compiler/swift-testing macro can infer it automatically here.
@Test(
arguments: [
(type: Int.self as Any.Type, nominalName: "Int"),
(type: String.self as Any.Type, nominalName: "String"),
]
)
func name(type: Any.Type, nominalName: String)
Type inference here is at the compiler level. Swift Testing receives an array of [Any]
and doesn't have the opportunity to do its own type checking.
Swift Testing receives an array of
[Any]
and doesn't have the opportunity to do its own type checking.
Since we already have the parameter signature here - (Any.Type, String), can we add some explicit type inference hint to the Test macro's arguments variable type? (the variable c in the following example)
let a = (Int.self, "A") // Inferred as (Int.Type, String)
let b1 = [
(Int.self, "Int"),
(String.self, "String"),
] // Inferred as [Any] with an error "Heterogeneous collection literal could only be inferred to '[Any]'; add explicit type annotation if this is intentional"
let b2: [Any] = [
(Int.self, "Int"),
(String.self, "String"),
]
let c: [(Any.Type, String)] = [
(Int.self, "Int"),
(String.self, "String"),
]
Type inference occurs before the @Test
macro is expanded. There's nothing we can add that's in the language today that would tell the compiler to infer a type other than [Any]
here, and the signature of the test function itself does not (currently) participate in type inference for arguments to the macro.
Find a solution here - use as [(Any.Type, String)]
after the Array Liternal
@Test(
arguments: [
(type: Int.self, nominalName: "Int"),
(type: String.self, nominalName: "String"),
] as [(Any.Type, String)]
)
func name1(type: Any.Type, nominalName: String) {
#expect(API.name(type) == nominalName)
}
Although the original reporter of this issue identified a workaround (explicitly typing the expression using as
), I think we should pursue some kind macros enhancement to automate this, since users of Swift Testing in particular hit it fairly often. In particular, I think it would be great if there were a way for an attached macro such as @Test
to include, as part of its declaration, that the types of arguments passed to some of its parameters (arguments: ...
) should use the parameter types of the declaration the macro is attached to as a hint.
This is not something we can do in Swift Testing today because the failure happens before macro expansion (because the type inference on the array resolves to [Any]
instead of [any Sendable]
or [Any.Type]
.) I know I'd filed a bug against macros ages ago asking for some way to infer types more betterer but I do not know where it ended up. @DougGregor do you happen to recall that issue/radar?
Description
I'm using name2 pattern at first. But then I thought I should refactor to use name1 pattern. But it will give me a strange compiler error.
Is this an expected unsupported feature like swiftlang/swift-testing#202 or a bug here.
Expected behavior
Compile and test successfully.
Actual behavior
Compile error on language mode v5. (On v6 it is Any is not conform to Sendable)
Steps to reproduce
See description field.
Or use the following demokit package
DemoKit.zip
swift-testing version/commit hash
Xcode 16.0.0
Swift & OS version (output of
swift --version ; uname -a
)Swift 6 compiler with Swift 5 language mode