Skip to content

Commit 2d6eabf

Browse files
authored
Merge pull request #70708 from tshortli/module-interface-allow-inherited-objc-inits-with-unavailable-in-swift-params
Sema: Allow some references to declarations that are unavailable-in-Swift
2 parents 6e06e51 + 6c1fe81 commit 2d6eabf

File tree

3 files changed

+47
-11
lines changed

3 files changed

+47
-11
lines changed

lib/Sema/TypeCheckAvailability.cpp

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -360,6 +360,27 @@ static bool isInsideCompatibleUnavailableDeclaration(
360360
inheritsAvailabilityFromPlatform(platform, *referencedPlatform));
361361
}
362362

363+
static bool shouldAllowReferenceToUnavailableInSwiftDeclaration(
364+
const Decl *D, const ExportContext &where) {
365+
auto *DC = where.getDeclContext();
366+
auto *SF = DC->getParentSourceFile();
367+
368+
// Unavailable-in-Swift declarations shouldn't be referenced directly in
369+
// source. However, they can be referenced in implicit declarations that are
370+
// printed in .swiftinterfaces.
371+
if (!SF || SF->Kind != SourceFileKind::Interface)
372+
return false;
373+
374+
if (auto constructor = dyn_cast_or_null<ConstructorDecl>(DC->getAsDecl())) {
375+
// Designated initializers inherited from an Obj-C superclass may have
376+
// parameters that are unavailable-in-Swift.
377+
if (constructor->isObjC())
378+
return true;
379+
}
380+
381+
return false;
382+
}
383+
363384
namespace {
364385

365386
/// A class to walk the AST to build the type refinement context hierarchy.
@@ -3038,7 +3059,9 @@ bool swift::diagnoseExplicitUnavailability(
30383059
break;
30393060

30403061
case PlatformAgnosticAvailabilityKind::UnavailableInSwift:
3041-
// This API is explicitly unavailable in Swift.
3062+
if (shouldAllowReferenceToUnavailableInSwiftDeclaration(D, Where))
3063+
return true;
3064+
30423065
platform = "Swift";
30433066
break;
30443067
}
Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,14 @@
11
#import <Foundation/Foundation.h>
22

3-
@interface FrameworkObject : NSObject
4-
- (nonnull instancetype)initWithInvocation:(nullable NSInvocation *)invocation NS_SWIFT_UNAVAILABLE("unavailable");
5-
- (nonnull instancetype)initWithSelector:(nonnull SEL)selector;
6-
- (nonnull instancetype)initWithInteger:(NSInteger)integer;
3+
NS_SWIFT_UNAVAILABLE("unavailable")
4+
@interface UnavailableInSwift : NSObject
75
@end
6+
7+
@interface HasAvailableInit : NSObject
8+
- (nonnull instancetype)initWithUnavailable:(nonnull UnavailableInSwift *)unavailable;
9+
@end
10+
11+
@interface HasUnavailableInit : NSObject
12+
- (nonnull instancetype)initWithUnavailable:(nonnull UnavailableInSwift *)unavailable NS_SWIFT_UNAVAILABLE("unavailable");
13+
@end
14+
Lines changed: 12 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,21 @@
1-
// RUN: %target-swift-emit-module-interface(%t.swiftinterface) %s -I %S/Inputs/inherited-objc-initializers/
2-
// RUN: %target-swift-typecheck-module-from-interface(%t.swiftinterface) -I %S/Inputs/inherited-objc-initializers/
1+
// RUN: %target-swift-emit-module-interface(%t.swiftinterface) %s -I %S/Inputs/inherited-objc-initializers/ -module-name Test
2+
// RUN: %target-swift-typecheck-module-from-interface(%t.swiftinterface) -I %S/Inputs/inherited-objc-initializers/ -module-name Test
33
// RUN: %FileCheck %s < %t.swiftinterface
44

55
// REQUIRES: objc_interop
66

77
import InheritedObjCInits
88

9-
// CHECK: @objc @_inheritsConvenienceInitializers public class Subclass : InheritedObjCInits.FrameworkObject {
10-
public class Subclass: FrameworkObject {
11-
// CHECK-NEXT: @objc override dynamic public init(selector: ObjectiveC.Selector)
12-
// CHECK-NEXT: @objc override dynamic public init(integer: Swift.Int)
9+
// CHECK: @objc @_inheritsConvenienceInitializers public class Subclass2 : InheritedObjCInits.HasAvailableInit {
10+
public class Subclass2: HasAvailableInit {
11+
// CHECK-NEXT: @objc override dynamic public init(unavailable: InheritedObjCInits.UnavailableInSwift)
12+
// CHECK-NEXT: @objc override dynamic public init()
13+
// CHECK-NEXT: @objc deinit
14+
} // CHECK-NEXT:{{^}$}}
15+
16+
// CHECK: @objc @_inheritsConvenienceInitializers public class Subclass1 : InheritedObjCInits.HasUnavailableInit {
17+
public class Subclass1: HasUnavailableInit {
18+
// CHECK-NOT: InheritedObjCInits.UnavailableInSwift
1319
// CHECK-NEXT: @objc override dynamic public init()
1420
// CHECK-NEXT: @objc deinit
1521
} // CHECK-NEXT:{{^}$}}

0 commit comments

Comments
 (0)