Skip to content

Commit ea05881

Browse files
committed
Address comments
Signed-off-by: Peter Rong <[email protected]>
1 parent 841b583 commit ea05881

File tree

5 files changed

+49
-16
lines changed

5 files changed

+49
-16
lines changed

lib/Sema/TypeCheckDecl.cpp

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2569,12 +2569,12 @@ InterfaceTypeRequest::evaluate(Evaluator &eval, ValueDecl *D) const {
25692569
ProtocolDecl *errorProto = Context.getErrorDecl();
25702570
if (thrownTy && !thrownTy->hasError() && errorProto) {
25712571
Type thrownTyInContext = AFD->mapTypeIntoContext(thrownTy);
2572-
auto thrownTypeRepr = AFD->getThrownTypeRepr();
2573-
SourceLoc loc =
2574-
(thrownTypeRepr) ? thrownTypeRepr->getLoc() : AFD->getLoc();
2575-
if (AFD->getAttrs().hasAttribute<ObjCAttr>()) {
2576-
Context.Diags.diagnose(loc, diag::typed_thrown_in_objc_forbidden);
2577-
} else if (!checkConformance(thrownTyInContext, errorProto)) {
2572+
if (!checkConformance(thrownTyInContext, errorProto)) {
2573+
SourceLoc loc;
2574+
if (auto thrownTypeRepr = AFD->getThrownTypeRepr())
2575+
loc = thrownTypeRepr->getLoc();
2576+
else
2577+
loc = AFD->getLoc();
25782578
Context.Diags.diagnose(loc, diag::thrown_type_not_error, thrownTy);
25792579
}
25802580
}

lib/Sema/TypeCheckDeclObjC.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -809,6 +809,24 @@ bool swift::isRepresentableInLanguage(
809809
return false;
810810
}
811811
}
812+
auto isTypedThrow = [&]() {
813+
// With no AST token this should be `throws`
814+
if (!AFD->getThrownTypeRepr())
815+
return false;
816+
// Or it is a `throws(<ErrorType>)`
817+
CanType thrownType = AFD->getThrownInterfaceType()->getCanonicalType();
818+
// TODO: only `throws(Error)` is allowed.
819+
// Throwing `any MyError` that confronts `Error` is not implemented yet.
820+
// Shall we allow `any MyError` in the future, we should check against
821+
// `isExistentialType` instead.
822+
if (thrownType->isErrorExistentialType())
823+
return false;
824+
softenIfAccessNote(AFD, Reason.getAttr(),
825+
AFD->diagnose(diag::typed_thrown_in_objc_forbidden)
826+
.limitBehavior(behavior));
827+
Reason.describe(AFD);
828+
return true;
829+
};
812830

813831
if (AFD->hasAsync()) {
814832
// Asynchronous functions move all of the result value and thrown error
@@ -888,6 +906,8 @@ bool swift::isRepresentableInLanguage(
888906
// a thrown error.
889907
std::optional<unsigned> completionHandlerErrorParamIndex;
890908
if (FD->hasThrows()) {
909+
if (isTypedThrow())
910+
return false;
891911
completionHandlerErrorParamIndex = completionHandlerParams.size();
892912
auto errorType = ctx.getErrorExistentialType();
893913
addCompletionHandlerParam(OptionalType::get(errorType));
@@ -912,6 +932,9 @@ bool swift::isRepresentableInLanguage(
912932
SourceLoc throwsLoc;
913933
Type resultType;
914934

935+
if (isTypedThrow())
936+
return false;
937+
915938
const ConstructorDecl *ctor = nullptr;
916939
if (auto func = dyn_cast<FuncDecl>(AFD)) {
917940
resultType = func->getResultInterfaceType();

test/attr/attr_objc.swift

Lines changed: 12 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,13 @@ 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{{@objc functions cannot have typed throw}}
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{{@objc functions cannot have typed throw}}
23322344
}
23332345

23342346

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 {{@objc functions cannot have typed throw}}
5260
}
5361

5462
actor class MyActor2 { }

test/decl/func/typed_throws.swift

Lines changed: 0 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -216,13 +216,3 @@ struct NotAnError<T> {}
216216

217217
func badThrowingFunctionType<T>(_: () throws(NotAnError<T>) -> ()) {}
218218
// expected-error@-1 {{thrown type 'NotAnError<T>' does not conform to the 'Error' protocol}}
219-
220-
enum ObjCError: Int, Error {
221-
case Others
222-
}
223-
224-
import Foundation
225-
@objc class ObjCClass: NSObject {
226-
@objc func objcTypedThrow() throws(ObjCError) -> () {}
227-
// expected-error@-1 {{@objc functions cannot have typed throw}}
228-
}

0 commit comments

Comments
 (0)