Skip to content

Commit 6e6dc4b

Browse files
authored
Merge pull request swiftlang#81054 from DataCorrupted/FixTypedThrow
[Sema] @objc functions shall not have typed throw
2 parents 7b78a1d + 5af6e5e commit 6e6dc4b

File tree

4 files changed

+43
-0
lines changed

4 files changed

+43
-0
lines changed

include/swift/AST/DiagnosticsSema.def

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5553,6 +5553,10 @@ WARNING(no_throw_in_do_with_catch,none,
55535553
ERROR(thrown_type_not_error,none,
55545554
"thrown type %0 does not conform to the 'Error' protocol", (Type))
55555555

5556+
ERROR(typed_throw_in_objc_forbidden,none,
5557+
"typed 'throws' %kindonly0 cannot be represented in Objective-C",
5558+
(const AbstractFunctionDecl *))
5559+
55565560
//------------------------------------------------------------------------------
55575561
// MARK: Concurrency
55585562
//------------------------------------------------------------------------------

lib/Sema/TypeCheckDeclObjC.cpp

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -845,6 +845,23 @@ bool swift::isRepresentableInLanguage(
845845
}
846846
}
847847

848+
// Check that @objc functions can't have typed throw.
849+
if (AFD->hasThrows()) {
850+
Type thrownType = AFD->getThrownInterfaceType();
851+
// TODO: only `throws(Error)` is allowed.
852+
// Throwing `any MyError` that confronts `Error` is not implemented yet.
853+
// Shall we allow `any MyError` in the future, we should check against
854+
// `isExistentialType` instead, and other type checks will make sure it
855+
// confrons to `Error`.
856+
if (thrownType && !thrownType->isErrorExistentialType()) {
857+
softenIfAccessNote(AFD, Reason.getAttr(),
858+
AFD->diagnose(diag::typed_throw_in_objc_forbidden, AFD)
859+
.limitBehavior(behavior));
860+
Reason.describe(AFD);
861+
return false;
862+
}
863+
}
864+
848865
if (AFD->hasAsync()) {
849866
// Asynchronous functions move all of the result value and thrown error
850867
// information into a completion handler.

test/attr/attr_objc.swift

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2268,6 +2268,11 @@ extension Protocol_ObjC1 {
22682268
//===---
22692269
//===--- Error handling
22702270
//===---
2271+
enum ObjCError: Int, Error {
2272+
case Others
2273+
}
2274+
protocol MyError: Error { }
2275+
22712276
// CHECK-LABEL: class ClassThrows1
22722277
class ClassThrows1 {
22732278
// CHECK: @objc func methodReturnsVoid() throws
@@ -2329,6 +2334,15 @@ class ClassThrows1 {
23292334

23302335
// CHECK: {{^}} func fooWithErrorProtocolComposition2(x: any Error & Protocol_ObjC1)
23312336
func fooWithErrorProtocolComposition2(x: Error & Protocol_ObjC1) { }
2337+
2338+
@objc func throwsError() throws(Error) {}
2339+
@objc func throwsMyError() throws(MyError) {}
2340+
// expected-error@-1{{typed 'throws' instance method cannot be represented in Objective-C}}
2341+
// expected-error@-2{{thrown type 'any MyError' does not conform to the 'Error' protocol}}
2342+
@objc func throwsObjCError() throws(ObjCError) {}
2343+
// expected-error@-1{{typed 'throws' instance method cannot be represented in Objective-C}}
2344+
@objc static func throwsObjCErrorClass() throws(ObjCError) {}
2345+
// expected-error@-1{{typed 'throws' static method cannot be represented in Objective-C}}
23322346
}
23332347

23342348

test/attr/attr_objc_async.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,10 @@ class MyClass {
2727

2828
// actor exporting Objective-C entry points.
2929

30+
enum ObjCError: Int, Error {
31+
case Others
32+
}
33+
3034
// CHECK: actor MyActor
3135
actor MyActor {
3236
// CHECK: @objc func doBigJobActor() async -> Int
@@ -49,6 +53,10 @@ actor MyActor {
4953

5054
// CHECK: @objc nonisolated func synchronousGood()
5155
@objc nonisolated func synchronousGood() { }
56+
57+
@objc func objcAsyncThrowsError() async throws(Error) -> Void {}
58+
@objc func objcAsyncThrowsObjCError() async throws(ObjCError) -> Void {}
59+
// expected-error@-1 {{typed 'throws' instance method cannot be represented in Objective-C}}
5260
}
5361

5462
actor class MyActor2 { }

0 commit comments

Comments
 (0)