Description
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.
struct DemoKitTests {
@Test(
arguments: [
(type: Int.self, nominalName: "Int"),
(type: String.self, nominalName: "String"),
]
)
func name1(type: Any.Type, nominalName: String) {
#expect(API.name(type) == nominalName)
}
@Test
func name2() {
#expect(API.name(Int.self) == "Int")
#expect(API.name(String.self) == "String")
}
}
Expected behavior
Compile and test successfully.
Actual behavior
Compile error on language mode v5. (On v6 it is Any is not conform to Sendable)
xx.swift:17:4 Static method '__function(named:in:xcTestCompatibleSelector:displayName:traits:arguments:sourceLocation:parameters:testFunction:)' requires the types 'Any' and '(any Any.Type, String)' be equivalent
Steps to reproduce
See description field.
Or use the following demokit package
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
Activity
[-]Any.Type issue with [/-][+]Any.Type issue with @Test[/+]Kyle-Ye commentedon Sep 22, 2024
Looks like it can be workaround by explicitly mark
as Any.Type
.Hope the compiler/swift-testing macro can infer it automatically here.
grynspan commentedon Sep 22, 2024
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.Kyle-Ye commentedon Sep 23, 2024
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)
grynspan commentedon Sep 23, 2024
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.Kyle-Ye commentedon Oct 7, 2024
Find a solution here - use
as [(Any.Type, String)]
after the Array Liternalstmontgomery commentedon Oct 9, 2024
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.grynspan commentedon Oct 9, 2024
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?DougGregor commentedon Nov 7, 2024
There was some discussion at one point about being able to reference the enclosing
Self
type within the macro declaration as a way to help type inference, but it didn't go anywhere and I don't think that's what you mean. This would be a generalization of that (which was effectively constraining based on the type of theself
parameter) to all of the parameter types. For example, let's imagine thatParameterType
would magically be provided with the types of all of the parameters to the function to which this@Test
macro is attached. Maybe the macro looks like this:and if you attached it to a function like this:
ParameterType
would getAny.Type
,String
, so the collectionC
would have the element type(Any.Type, String)
.This would all need language design and I don't know if it's worth doing, but I think it could work.