Skip to content

Commit 925ad7b

Browse files
authored
Merge pull request swiftlang#41147 from hborla/import-id-as-any
[ClangImporter] Import `id<P>` as either `any P` or `P` based on context.
2 parents dfb74d5 + fd11d2e commit 925ad7b

File tree

4 files changed

+63
-7
lines changed

4 files changed

+63
-7
lines changed

lib/ClangImporter/ImportType.cpp

Lines changed: 34 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1050,6 +1050,7 @@ namespace {
10501050
if (memberTypes.empty())
10511051
hasExplicitAnyObject = true;
10521052

1053+
// Generic arguments are always imported as existential types.
10531054
Type importedTypeArg = ExistentialType::get(
10541055
ProtocolCompositionType::get(
10551056
Impl.SwiftContext, memberTypes,
@@ -1182,9 +1183,6 @@ namespace {
11821183
}
11831184
}
11841185

1185-
if (bridgedType->isConstraintType())
1186-
bridgedType = ExistentialType::get(bridgedType);
1187-
11881186
return { importedType,
11891187
ImportHint(ImportHint::ObjCBridged, bridgedType) };
11901188
}
@@ -1205,9 +1203,9 @@ namespace {
12051203
members.push_back(proto->getDeclaredInterfaceType());
12061204
}
12071205

1208-
importedType = ExistentialType::get(
1206+
importedType =
12091207
ProtocolCompositionType::get(Impl.SwiftContext, members,
1210-
/*HasExplicitAnyObject=*/false));
1208+
/*HasExplicitAnyObject=*/false);
12111209
}
12121210

12131211
// Class or Class<P> maps to an existential metatype.
@@ -1285,6 +1283,32 @@ static bool isCFAudited(ImportTypeKind importKind) {
12851283
llvm_unreachable("Invalid ImportTypeKind.");
12861284
}
12871285

1286+
/// True if the type can be an existential type in this context.
1287+
static bool isExistentialContext(ImportTypeKind importKind) {
1288+
switch (importKind) {
1289+
case ImportTypeKind::Abstract:
1290+
case ImportTypeKind::Typedef:
1291+
return false;
1292+
case ImportTypeKind::Value:
1293+
case ImportTypeKind::ObjCCollectionElement:
1294+
case ImportTypeKind::Variable:
1295+
case ImportTypeKind::Result:
1296+
case ImportTypeKind::Enum:
1297+
case ImportTypeKind::RecordField:
1298+
case ImportTypeKind::AuditedVariable:
1299+
case ImportTypeKind::AuditedResult:
1300+
case ImportTypeKind::Parameter:
1301+
case ImportTypeKind::CompletionHandlerResultParameter:
1302+
case ImportTypeKind::CFRetainedOutParameter:
1303+
case ImportTypeKind::CFUnretainedOutParameter:
1304+
case ImportTypeKind::Property:
1305+
case ImportTypeKind::PropertyWithReferenceSemantics:
1306+
return true;
1307+
}
1308+
1309+
llvm_unreachable("Invalid ImportTypeKind.");
1310+
}
1311+
12881312
/// Turn T into Unmanaged<T>.
12891313
static Type getUnmanagedType(ClangImporter::Implementation &impl,
12901314
Type payloadType) {
@@ -1550,6 +1574,11 @@ static ImportedType adjustTypeForConcreteImport(
15501574

15511575
assert(importedType);
15521576

1577+
if (importedType->isConstraintType() &&
1578+
isExistentialContext(importKind)) {
1579+
importedType = ExistentialType::get(importedType);
1580+
}
1581+
15531582
if (importKind == ImportTypeKind::RecordField &&
15541583
importedType->isAnyClassReferenceType() &&
15551584
!importedType->isForeignReferenceType()) {

lib/PrintAsClang/DeclAndTypePrinter.cpp

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1835,8 +1835,7 @@ class DeclAndTypePrinter::Implementation
18351835

18361836
void visitExistentialType(ExistentialType *ET,
18371837
Optional<OptionalTypeKind> optionalKind) {
1838-
visitExistentialType(ET, optionalKind,
1839-
/*isMetatype=*/ET->getConstraintType()->is<AnyMetatypeType>());
1838+
visitPart(ET->getConstraintType(), optionalKind);
18401839
}
18411840

18421841
void visitExistentialMetatypeType(ExistentialMetatypeType *MT,
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
@import Foundation;
2+
3+
@protocol P
4+
@end
5+
6+
@protocol Q
7+
@end
8+
9+
typedef id<P, Q> PAndQ;
10+
11+
@interface PAndQProcessor : NSObject
12+
- (void) takesPAndQExistential: (PAndQ)arg;
13+
@end
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: %target-typecheck-verify-swift %clang-importer-sdk -enable-objc-interop -import-objc-header %S/Inputs/explicit_existential.h
2+
3+
// Make sure that 'typedef id<P, Q> PAndQ' imports as a typealias without
4+
// the ExistentialType wrapping the underlying type.
5+
6+
protocol InheritsFromQAndQ : PAndQ {}
7+
8+
func genericOverPAndQ<T : PAndQ>(_: T) {}
9+
10+
func takesSequenceOfPAndQ<T : Sequence>(_: T) where T.Element : PAndQ {}
11+
12+
func takesPAndQExistential(_ x: PAndQ) {
13+
let b = PAndQProcessor()
14+
b.takesPAndQExistential(x)
15+
}

0 commit comments

Comments
 (0)