apple/swift-testing

Weirdness in the #expect(throws:) API with the Never type

Closed this issue · 3 comments

Description

Not sure if this is a bug or a feature request, but the current API feels like it does very weird things with the Never type.

Given 3 tests, one of them will behave differently than the other 2:

enum CustomNever: Error {}

#expect(throws: Error.self) { () } // fails
#expect(throws: CustomNever.self) { () } // fails
#expect(throws: Never.self) { () } // succeeds

This is behaving as documented, but feels like a poor API.

The first 2 read as "verify that there exists an error of type T that this closure throws".

The last one reads as "verify that there does not exist an error (of any type)".

These are near-opposite assertions, and to me they should not be named the same thing.

(As an aside, this is a violation of paramatricity, a hard-to-explain, but wonderful property for generic functions to have)

Expected behavior

No response

Actual behavior

No response

Steps to reproduce

No response

swift-testing version/commit hash

0.10.0

Swift & OS version (output of swift --version && uname -a)

No response

This is very badly explained, but I couldn't figure out how to make it better. Sorry.

Because Never conforms to Error, the only real alternative is to make #expect(throws: Never) always fail (since it is impossible to actually throw an instance of Never). That would be unfortunate.

I would expect it to always fail, just like it does for CustomNever. That would be treating the type argument uniformly.