swift-testing
swift-testing copied to clipboard
Add support for non-copyable types as expectation arguments
Add support for non-copyable types as expectation arguments, e.g.:
struct S: ~Copyable, ... {}
let a: S = ...
let b: S = ...
#expect(a != b)
#expect(a.foo())
#expect(a.isBar)
// etc.
Known issues:
String(describing:)does not take move-only values, so it cannot be used to describe a value that's part of a failed expectation expressiontype(of:)does not take move-only values, so we can't get the runtime type of a valueString(reflecting:)does not take move-only metatypes, so we cannot capture the FQN of a move-only type- Variadic generics don't support move-only types (or at least, I can't get the compiler to accept them) which precludes the expansion of function calls that take any move-only arguments
- We cannot syntactically distinguish
consumingfromborrowingarguments at call sites, so we may not be able to correctly expand expressions with move-only parts (and we don't have enough information during macro expansion to know to suppress these expansions, unlike withtryandawait.) @autoclosure () -> Uis treated as escaping, which means syntactically we can't borrow the right-hand argument of a binary operator.Resultneeds to support non-copyableSuccessvalues (although we could build our own monad type if needed)- Attempting to implement my own
Resultanalogue with the signature:
Seems to confuse the compiler, which still complains:enum __Result<Success, Failure>: ~Copyable where Success: ~Copyable, Failure: Error🛑 Noncopyable type 'S' cannot be substituted for copyable generic parameter 'Success' in '__Result'
- Attempting to implement my own
- For our current implementation of binary operator expansion, we need non-copyable tuples.
- Conditional casts to/from move-only types and existentials are needed for us to be able to implement
String(describingForTest:). Even if we don't support the full gamut of possible stringification techniques, we need to be able to write something likeif let value = value as? Copyable { ... }so we can opt into the full set for types that allow it.
Result needs to support non-copyable Success values (although we could build our own monad type if needed)
FWIW Result will support non-copyable Success values in Swift 6.0
Good to know—that knocks one point off the list, at least!
@autoclosure () -> Uis treated as escaping, which means syntactically we can't borrow the right-hand argument of a binary operator.
To avoid this problem, could we change our macro expansion code, and the associated __check.... functions it calls, to use an explicit closure and then stop using @autoclosure?
That causes other compilation issues (I'd have to dig into the pre-OSS commit history to determine what, exactly, the problems were—maybe they're no longer relevant?)
Thinking about it, I think it was that it forced evaluation of the RHS argument at capture time, defeating the purpose of a short-circuiting operator like &&.
String(reflecting:) does not take move-only metatypes, so we cannot capture the FQN of a move-only type
This appears to be resolved in the latest toolchains.
Tracked internally as rdar://131866222.