Skip to content

Commit 61fb9fd

Browse files
committed
Cherry-pick swiftlang#74135 (Fix two objcImpl resyntaxing bugs)
1 parent 2484307 commit 61fb9fd

File tree

5 files changed

+31
-3
lines changed

5 files changed

+31
-3
lines changed

lib/AST/ASTPrinter.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1326,6 +1326,14 @@ void PrintAST::printAttributes(const Decl *D) {
13261326
}
13271327
}
13281328

1329+
// If we are suppressing @implementation, also suppress @objc on extensions.
1330+
if (auto ED = dyn_cast<ExtensionDecl>(D)) {
1331+
if (ED->isObjCImplementation() &&
1332+
Options.excludeAttrKind(DeclAttrKind::ObjCImplementation)) {
1333+
Options.ExcludeAttrList.push_back(DeclAttrKind::ObjC);
1334+
}
1335+
}
1336+
13291337
// We will handle ownership specifiers separately.
13301338
if (isa<FuncDecl>(D)) {
13311339
Options.ExcludeAttrList.push_back(DeclAttrKind::Mutating);

lib/Sema/TypeCheckDeclObjC.cpp

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ using namespace swift;
3838
DiagnosticBehavior
3939
swift::behaviorLimitForObjCReason(ObjCReason reason, ASTContext &ctx) {
4040
switch(reason) {
41+
case ObjCReason::MemberOfObjCImplementationExtension:
42+
// If they're using the old syntax, soften to a warning.
43+
if (cast<ObjCImplementationAttr>(reason.getAttr())->isEarlyAdopter())
44+
return DiagnosticBehavior::Warning;
45+
46+
LLVM_FALLTHROUGH;
47+
4148
case ObjCReason::ExplicitlyCDecl:
4249
case ObjCReason::ExplicitlyDynamic:
4350
case ObjCReason::ExplicitlyObjC:
@@ -51,7 +58,6 @@ swift::behaviorLimitForObjCReason(ObjCReason reason, ASTContext &ctx) {
5158
case ObjCReason::WitnessToObjC:
5259
case ObjCReason::ImplicitlyObjC:
5360
case ObjCReason::MemberOfObjCExtension:
54-
case ObjCReason::MemberOfObjCImplementationExtension:
5561
return DiagnosticBehavior::Unspecified;
5662

5763
case ObjCReason::ExplicitlyIBInspectable:

test/ModuleInterface/objc_implementation.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,10 @@ import Foundation
1616

1717
// We should never see @_objcImplementation in the header
1818
// NEGATIVE-NOT: @_objcImplementation
19+
// NEGATIVE-NOT: @implementation
20+
21+
// @objc should be omitted on extensions
22+
// NEGATIVE-NOT: @objc{{.*}} extension
1923

2024
//
2125
// @_objcImplementation class

test/decl/ext/objc_implementation.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,11 @@ protocol EmptySwiftProto {}
229229
// rdar://122280735 - crash when the parameter of a block property needs @escaping
230230
let rdar122280735: (() -> ()) -> Void = { _ in }
231231
// expected-error@-1 {{property 'rdar122280735' of type '(() -> ()) -> Void' does not match type '(@escaping () -> Void) -> Void' declared by the header}}
232+
233+
private func privateNonObjCMethod(_: EmptySwiftProto) {
234+
// expected-error@-1 {{method cannot be in an @objc @implementation extension of a class (without final or @nonobjc) because the type of the parameter cannot be represented in Objective-C}}
235+
// expected-note@-2 {{protocol-constrained type containing protocol 'EmptySwiftProto' cannot be represented in Objective-C}}
236+
}
232237
}
233238

234239
@objc(PresentAdditions) @implementation extension ObjCClass {

test/decl/ext/objc_implementation_early_adopter.swift

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,11 @@ protocol EmptySwiftProto {}
229229
// rdar://122280735 - crash when the parameter of a block property needs @escaping
230230
let rdar122280735: (() -> ()) -> Void = { _ in }
231231
// expected-warning@-1 {{property 'rdar122280735' of type '(() -> ()) -> Void' does not match type '(@escaping () -> Void) -> Void' declared by the header}}
232+
233+
private func privateNonObjCMethod(_: EmptySwiftProto) {
234+
// expected-warning@-1 {{method cannot be in an @objc @implementation extension of a class (without final or @nonobjc) because the type of the parameter cannot be represented in Objective-C}}
235+
// expected-note@-2 {{protocol-constrained type containing protocol 'EmptySwiftProto' cannot be represented in Objective-C}}
236+
}
232237
}
233238

234239
@_objcImplementation(PresentAdditions) extension ObjCClass {
@@ -428,8 +433,8 @@ protocol EmptySwiftProto {}
428433
func nullableResult() -> Any { fatalError() } // expected-warning {{instance method 'nullableResult()' of type '() -> Any' does not match type '() -> Any?' declared by the header}}
429434
func nullableArgument(_: Any) {} // expected-warning {{instance method 'nullableArgument' of type '(Any) -> ()' does not match type '(Any?) -> Void' declared by the header}}
430435

431-
func nonPointerResult() -> CInt! { fatalError() } // expected-error{{method cannot be in an @objc @implementation extension of a class (without final or @nonobjc) because its result type cannot be represented in Objective-C}}
432-
func nonPointerArgument(_: CInt!) {} // expected-error {{method cannot be in an @objc @implementation extension of a class (without final or @nonobjc) because the type of the parameter cannot be represented in Objective-C}}
436+
func nonPointerResult() -> CInt! { fatalError() } // expected-warning{{method cannot be in an @objc @implementation extension of a class (without final or @nonobjc) because its result type cannot be represented in Objective-C}}
437+
func nonPointerArgument(_: CInt!) {} // expected-warning {{method cannot be in an @objc @implementation extension of a class (without final or @nonobjc) because the type of the parameter cannot be represented in Objective-C}}
433438
}
434439

435440
// Intentionally using `@_objcImplementation` for this test; do not upgrade!

0 commit comments

Comments
 (0)