This function should throw only ThrowsError type, however, when used, compiler says Thrown expression type 'any Error' cannot be converted to error type 'XXX'
However, what you've got there is not actually using a task group. Switching to Task doesn't help with the problem, though, as Task doesn't support typed errors, either.
You are not at the point. The generic function is declared (and compiled) as throwing ThrowsError, however when used, compiler ignores the exception type.
Yup, you're right—Task does not currently throw CancellationError on its own and I was misremembering. Need more coffee!
I believe @hibernat is not explicitly writing throws inside the body of the closure, in which case in Swift 6 mode the compiler does not infer an error type for the closure (beyond any Error). This is by design. See the relevant section in SE-0413.
Thanks, that is great response. However, why is this function accepted by the compiler? There is no inference needed, the exception type is declared, required is the same exception type for the perform throwing function/closure and the exception thrown by the function.
From what I see locally, this fails to compile in a way I'd expect:
func f() async throws(E) {
do throws(E) {
try await withSingleTaskInThrowingTaskGroup(cancellationError: E()) {
// ^ ^ ^ Thrown expression type 'any Error' cannot be converted to error type 'E'
try await g()
}
} catch {
}
}
This is because you didn't explicitly write () throws(E) in in the body of the closure you passed to withSingleTaskInThrowingTaskGroup(), which causes it to infer the type of the closure as throwing any Error, which is then incompatible with the expected type E (which is inferred from the explicit E() you passed as an argument to withSingleTaskInThrowingTaskGroup().)
If I add () throws(E) in, it compiles as expected:
I disagree here only because nobody knows how this stuff works yet, and it will help to be clear about it until it's not broken anymore. I.e. when we can use no code instead of the horrible throws(_).