Skip to content

Commit d54fcf5

Browse files
authored
[PrintAsObjC] Handle typealiases in ObjC generics. (#4559)
More specifically, don't try to emit a definition for them. Just fall through to what we do for forward-declarations...which also needed some fixing, to make sure we don't use a Swift typealias as its underlying type but never import the underlying type. https://bugs.swift.org/browse/SR-2352 (cherry picked from commit ea4d110)
1 parent cb109dd commit d54fcf5

File tree

6 files changed

+56
-8
lines changed

6 files changed

+56
-8
lines changed

lib/PrintAsObjC/PrintAsObjC.cpp

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1825,7 +1825,8 @@ class ModuleWriter {
18251825
if (TD == container)
18261826
return;
18271827

1828-
if (finder.isWithinConstrainedObjCGeneric()) {
1828+
if (finder.isWithinConstrainedObjCGeneric() &&
1829+
isa<NominalTypeDecl>(TD)) {
18291830
// We can delay individual members of classes; do so if necessary.
18301831
if (isa<ClassDecl>(container)) {
18311832
if (!tryRequire(TD)) {
@@ -1860,18 +1861,21 @@ class ModuleWriter {
18601861
if (!forwardDeclare(CD)) {
18611862
(void)addImport(CD);
18621863
}
1863-
} else if (auto PD = dyn_cast<ProtocolDecl>(TD))
1864+
} else if (auto PD = dyn_cast<ProtocolDecl>(TD)) {
18641865
forwardDeclare(PD);
1865-
else if (addImport(TD))
1866+
} else if (auto TAD = dyn_cast<TypeAliasDecl>(TD)) {
1867+
(void)addImport(TD);
1868+
// Just in case, make sure the underlying type is visible too.
1869+
finder.visit(TAD->getUnderlyingType());
1870+
} else if (addImport(TD)) {
18661871
return;
1867-
else if (auto ED = dyn_cast<EnumDecl>(TD))
1872+
} else if (auto ED = dyn_cast<EnumDecl>(TD)) {
18681873
forwardDeclare(ED);
1869-
else if (auto TAD = dyn_cast<TypeAliasDecl>(TD))
1870-
finder.visit(TAD->getUnderlyingType());
1871-
else if (isa<AbstractTypeParamDecl>(TD))
1874+
} else if (isa<AbstractTypeParamDecl>(TD)) {
18721875
llvm_unreachable("should not see type params here");
1873-
else
1876+
} else {
18741877
assert(false && "unknown local type decl");
1878+
}
18751879
});
18761880

18771881
if (needsToBeIndividuallyDelayed) {

test/Inputs/clang-importer-sdk/usr/include/objc_generics.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,3 +86,5 @@ void takeGenericClass(__nullable GenericClass<NSString *> *thing);
8686
- (void)doThing:(__nonnull T<Pettable>)thing;
8787
@end
8888

89+
typedef id <Fungible> FungibleObject;
90+

test/PrintAsObjC/Inputs/custom-modules/module.map

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,7 @@ module OverrideBase [system] {
2323
header "override.h"
2424
export *
2525
}
26+
27+
module OtherModule {
28+
// Deliberately empty. Used by depends-on-swift-framework.swift.
29+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import objc_generics
2+
3+
public typealias AliasForFungible = Fungible

test/PrintAsObjC/classes.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -711,6 +711,10 @@ public class NonObjCClass { }
711711
@objc func takeAndReturnGenericClass(_ x: GenericClass<NSString>?) -> GenericClass<AnyObject> { fatalError("") }
712712
// CHECK: - (FungibleContainer<id <Fungible>> * _Null_unspecified)takeAndReturnFungibleContainer:(FungibleContainer<Spoon *> * _Nonnull)x;
713713
@objc func takeAndReturnFungibleContainer(_ x: FungibleContainer<Spoon>) -> FungibleContainer<Fungible>! { fatalError("") }
714+
715+
typealias Dipper = Spoon
716+
// CHECK: - (FungibleContainer<FungibleObject> * _Nonnull)fungibleContainerWithAliases:(FungibleContainer<Spoon *> * _Nullable)x;
717+
@objc func fungibleContainerWithAliases(_ x: FungibleContainer<Dipper>?) -> FungibleContainer<FungibleObject> { fatalError("") }
714718
}
715719
// CHECK: @end
716720

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// RUN: rm -rf %t && mkdir %t
2+
3+
// FIXME: BEGIN -enable-source-import hackaround
4+
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t %S/../Inputs/clang-importer-sdk/swift-modules/ObjectiveC.swift
5+
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t %S/../Inputs/clang-importer-sdk/swift-modules/CoreGraphics.swift
6+
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t %S/../Inputs/clang-importer-sdk/swift-modules/Foundation.swift
7+
// FIXME: END -enable-source-import hackaround
8+
9+
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -emit-module -o %t %S/Inputs/depends-on-swift-framework-helper.swift -module-name OtherModule
10+
11+
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -import-objc-header %S/../Inputs/empty.h -emit-module -o %t %s -module-name main
12+
// RUN: %target-swift-frontend(mock-sdk: -sdk %S/../Inputs/clang-importer-sdk -I %t) -import-objc-header %S/../Inputs/empty.h -parse-as-library %t/main.swiftmodule -parse -emit-objc-header-path %t/main.h
13+
14+
// RUN: %FileCheck %s < %t/main.h
15+
16+
// RUN: %check-in-clang -I %S/Inputs/custom-modules %t/main.h
17+
// RUN: %check-in-clang -fno-modules -Qunused-arguments %t/main.h -include objc_generics.h
18+
19+
// REQUIRES: objc_interop
20+
21+
import Foundation
22+
import objc_generics
23+
import OtherModule
24+
25+
// CHECK-LABEL: @interface Test
26+
public class Test: NSObject {
27+
// CHECK: - (void)testSimpleTypealias:(id <Fungible> _Nonnull)_;
28+
func testSimpleTypealias(_: AliasForFungible) {}
29+
// CHECK: - (void)testGenericTypealias:(FungibleContainer<id <Fungible>> * _Nonnull)_;
30+
func testGenericTypealias(_: FungibleContainer<AliasForFungible>) {}
31+
} // CHECK: @end

0 commit comments

Comments
 (0)