Skip to content

Commit 85334cd

Browse files
committed
[Distributed] ban typed throws in distributed funcs
They don't yield a correct error type as we didn't implement it, so rather allow it and risk crashes, ban it until we get the time to implement it. The real solution is to adjust typed throws error inference to do an union of the thrown error of the func and the type thrown by the distributed actor system remote call -- which today always would be (E | Error) -> Error... We could add a new associated type to DAS and then we could make it more proper... resolves rdar://136467528 Update DiagnosticsSema.def Co-authored-by: Holly Borla <[email protected]> Update test/Distributed/distributed_actor_unsupported_typed_throws.swift
1 parent eedae18 commit 85334cd

File tree

3 files changed

+46
-0
lines changed

3 files changed

+46
-0
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5629,6 +5629,9 @@ ERROR(distributed_actor_func_unsupported_specifier, none,
56295629
ERROR(distributed_actor_func_variadic, none,
56305630
"cannot declare variadic argument %0 in %kind1",
56315631
(DeclName, const ValueDecl *))
5632+
ERROR(distributed_actor_func_typed_throws, none,
5633+
"cannot declare distributed function with typed throws",
5634+
())
56325635
NOTE(actor_mutable_state,none,
56335636
"mutation of this %0 is only permitted within the actor",
56345637
(DescriptiveDeclKind))

lib/Sema/TypeCheckDistributed.cpp

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -618,6 +618,19 @@ bool CheckDistributedFunctionRequest::evaluate(
618618
return true;
619619
}
620620

621+
// TODO: rdar://136467591 Currently typed throws were not implemented for distributed methods
622+
if (func->hasThrows()) {
623+
if (auto thrownError = func->getEffectiveThrownErrorType()) {
624+
// Basically we only support throwing `any Error` out of a distributed
625+
// function because then the effective error thrown by thunk calls naturally
626+
// is correct and the same `any Error`
627+
if (thrownError.has_value() &&
628+
!(*thrownError)->isEqual(C.getErrorExistentialType())) {
629+
func->diagnose(diag::distributed_actor_func_typed_throws);
630+
}
631+
}
632+
}
633+
621634
return false;
622635
}
623636

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// RUN: %target-swift-frontend -typecheck -verify -target %target-swift-5.7-abi-triple -I %t 2>&1 %s
2+
3+
// UNSUPPORTED: back_deploy_concurrency
4+
// REQUIRES: concurrency
5+
// REQUIRES: distributed
6+
7+
import Distributed
8+
9+
typealias DefaultDistributedActorSystem = LocalTestingDistributedActorSystem
10+
11+
distributed actor Foo {
12+
distributed func alwaysThrows() throws(FooError) { // expected-error{{cannot declare distributed function with typed throws}}
13+
throw FooError()
14+
}
15+
}
16+
17+
struct FooError: Codable, Error { }
18+
struct RemoteInvocationError: Codable, Error { }
19+
20+
func test(foo: Foo) async throws {
21+
do {
22+
try await foo.alwaysThrows() // actually, this is throws(Error) because network errors etc
23+
fatalError("Should not reach here")
24+
// FIXME: the following warning is showing why we had to ban typed throws;
25+
// the error type must instead be (FooError | Error (from the distributed thunk))
26+
// rdar://136467591
27+
} catch let error as RemoteInvocationError { // expected-warning{{cast from 'FooError' to unrelated type 'RemoteInvocationError' always fails}}
28+
print("error = \(error)")
29+
}
30+
}

0 commit comments

Comments
 (0)