Skip to content

Conversation

bnickel
Copy link
Contributor

@bnickel bnickel commented Sep 2, 2025

I want to use requireFail in some test cases where require doesn't feel right. The problem is that while it's guaranteed to throw, the code doesn't know that, so it can't be used in a guard statement.

For example, the following code has a compiler error "'guard' body must not fall through, consider using a 'return' or 'throw' to exit the scope"

guard interaction.responds(to: #selector(PrivateMethods._presentMenuAtLocation)) else {
    try requireFail("Cannot trigger UIContextMenuInteraction")
}

I've been getting around this locally with a simple wrapper:

func failHard(_ message: String, fileID: String = #fileID, file: FileString = #filePath, line: UInt = #line, column: UInt = #column) throws -> Never {
    try requireFail(message, fileID: fileID, filePath: file, line: line, column: column)
    preconditionFailure("This line should never be called, since requireFail should always throw")
}

We can improve requireFail by simply adding the Never return type. When compiling Nimble, Swift validates that requireFail does indeed always throw and when compiling tests, it knows no code will ever execute after requireFail.

This is an API change but should be source compatible. Any code below a requireFail call will receive a "Will never be executed" warning but still compile.

Checklist - While not every PR needs it, new features should consider this list:

  • Does this have tests?
  • Does this have documentation?
  • Does this break the public API (Requires major version bump)?
  • Is this a new feature (Requires minor version bump)?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

1 participant