Skip to content

Commit 4d2ce8a

Browse files
authored
Merge pull request #65685 from beccadax/objc-impl-protocols-5.9
[5.9] Two @objcImpl protocol fixes
2 parents 134eefe + 88f404f commit 4d2ce8a

File tree

6 files changed

+85
-17
lines changed

6 files changed

+85
-17
lines changed

lib/IRGen/GenClass.cpp

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1228,7 +1228,7 @@ namespace {
12281228
const ClassLayout &fieldLayout)
12291229
: IGM(IGM), TheEntity(theUnion), TheExtension(nullptr),
12301230
FieldLayout(&fieldLayout) {
1231-
visitConformances(getClass()->getImplementationContext());
1231+
visitConformances(getClass());
12321232

12331233
if (getClass()->isRootDefaultActor()) {
12341234
Ivars.push_back(Field::DefaultActorStorage);
@@ -1249,7 +1249,7 @@ namespace {
12491249
FieldLayout(nullptr) {
12501250
buildCategoryName(CategoryName);
12511251

1252-
visitConformances(theExtension->getImplementationContext());
1252+
visitConformances(theExtension);
12531253

12541254
for (Decl *member : TheExtension->getImplementationContext()->getMembers())
12551255
visit(member);
@@ -1295,6 +1295,15 @@ namespace {
12951295
/// Gather protocol records for all of the explicitly-specified Objective-C
12961296
/// protocol conformances.
12971297
void visitConformances(const IterableDeclContext *idc) {
1298+
auto dc = idc->getAsGenericContext();
1299+
if (dc->getImplementedObjCContext() != dc) {
1300+
// We want to use the conformance list imported from the ObjC header.
1301+
auto importedIDC = cast<IterableDeclContext>(
1302+
dc->getImplementedObjCContext()->getAsDecl());
1303+
visitConformances(importedIDC);
1304+
return;
1305+
}
1306+
12981307
llvm::SmallSetVector<ProtocolDecl *, 2> protocols;
12991308
for (auto conformance : idc->getLocalConformances(
13001309
ConformanceLookupKind::OnlyExplicit)) {

lib/Sema/TypeCheckDeclObjC.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,9 @@
2828
#include "swift/AST/SourceFile.h"
2929
#include "swift/AST/TypeCheckRequests.h"
3030
#include "swift/Basic/StringExtras.h"
31+
32+
#include "clang/AST/DeclObjC.h"
33+
3134
using namespace swift;
3235

3336
#pragma mark Determine whether an entity is representable in Objective-C.
@@ -3326,9 +3329,25 @@ class ObjCImplementationChecker {
33263329
return Identifier();
33273330
}
33283331

3332+
/// Is this member an `@optional` ObjC protocol requirement?
3333+
static bool isOptionalObjCProtocolRequirement(ValueDecl *vd) {
3334+
if (auto clangDecl = vd->getClangDecl()) {
3335+
if (auto method = dyn_cast<clang::ObjCMethodDecl>(clangDecl))
3336+
return method->isOptional();
3337+
if (auto property = dyn_cast<clang::ObjCPropertyDecl>(clangDecl))
3338+
return property->isOptional();
3339+
}
3340+
3341+
return false;
3342+
}
3343+
33293344
public:
33303345
void diagnoseUnmatchedRequirements() {
33313346
for (auto req : unmatchedRequirements) {
3347+
// Ignore `@optional` protocol requirements.
3348+
if (isOptionalObjCProtocolRequirement(req))
3349+
continue;
3350+
33323351
auto ext = cast<IterableDeclContext>(req->getDeclContext()->getAsDecl())
33333352
->getImplementationContext();
33343353

test/IRGen/Inputs/objc_implementation.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#import <Foundation/Foundation.h>
22

3-
@interface ImplClass: NSObject
3+
@interface ImplClass: NSObject <NSCopying>
44

55
- (nonnull instancetype)init;
66

0 commit comments

Comments
 (0)