[Pitch N+1] Typed Throws

Some of the links in the table of contents don't work — if the section has code in its title, then the link's URL has the wrong fragment. For example, the link to the section "Typed rethrows" tries to take me to #typed--rethrows-, but the correct fragment is #typed-rethrows.

@Douglas_Gregor can you fix this?


It seems that this proposal could help with testing functions that call fatalError, precondition, and similar functions, which is actively being discussed on these forums. Consider this function:

func requiresAPositiveNumber(_ number: Int) {
    precondition(number > 0)
    // the rest of the function goes here
}

Currently, there's no good way to test that this function disallows numbers that aren't positive, since calling it with a nonpositive number would crash the test suite. Even if you were to isolate the test to a separate thread, the crashed thread could still leak resources and leave locks in a bad state. However, with this proposal, we could do this:

protocol ValidationStrategy {
    associatedtype Failure: Error
    static func validationFailure() throws(Failure) -> Never
}

enum PreconditionValidationStrategy: ValidationStrategy {
    static func validationFailure() -> Never {
        preconditionFailure()
    }
}

enum ThrowingValidationStrategy: ValidationStrategy {
    static func validationFailure() throws(ValidationError) -> Never {
        throw ValidationError()
    }
}
struct ValidationError: Error {}

func requiresAPositiveNumber<V: ValidationStrategy>(
    _ number: Int,
    validationStrategy: V.Type = PreconditionValidationStrategy.self
) throws(V.Failure) {
    guard number > 0 else {
        V.validationFailure()
    }
    // the rest of the function goes here
}

Production code would call requiresAPositiveNumber with PreconditionValidationStrategy and the function would act the same as the original function (including its non-throwing signature), but test code could call it with ThrowingValidationStrategy and verify that the function correctly rejects non-positive numbers.

2 Likes