Skip to content

Commit c892957

Browse files
authored
Merge pull request #41207 from hborla/import-as-any
[Type Resolution] Allow imported existential typealiases to be used as constraints.
2 parents 60f3d8a + 30eb09f commit c892957

File tree

3 files changed

+18
-35
lines changed

3 files changed

+18
-35
lines changed

lib/ClangImporter/ImportType.cpp

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

1053-
// Generic arguments are always imported as existential types.
10541053
Type importedTypeArg = ExistentialType::get(
10551054
ProtocolCompositionType::get(
10561055
Impl.SwiftContext, memberTypes,
@@ -1183,6 +1182,9 @@ namespace {
11831182
}
11841183
}
11851184

1185+
if (bridgedType->isConstraintType())
1186+
bridgedType = ExistentialType::get(bridgedType);
1187+
11861188
return { importedType,
11871189
ImportHint(ImportHint::ObjCBridged, bridgedType) };
11881190
}
@@ -1203,9 +1205,9 @@ namespace {
12031205
members.push_back(proto->getDeclaredInterfaceType());
12041206
}
12051207

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

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

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-
13121288
/// Turn T into Unmanaged<T>.
13131289
static Type getUnmanagedType(ClangImporter::Implementation &impl,
13141290
Type payloadType) {
@@ -1574,11 +1550,6 @@ static ImportedType adjustTypeForConcreteImport(
15741550

15751551
assert(importedType);
15761552

1577-
if (importedType->isConstraintType() &&
1578-
isExistentialContext(importKind)) {
1579-
importedType = ExistentialType::get(importedType);
1580-
}
1581-
15821553
if (importKind == ImportTypeKind::RecordField &&
15831554
importedType->isAnyClassReferenceType() &&
15841555
!importedType->isForeignReferenceType()) {

lib/PrintAsClang/DeclAndTypePrinter.cpp

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

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

18411842
void visitExistentialMetatypeType(ExistentialMetatypeType *MT,

lib/Sema/TypeCheckType.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3499,6 +3499,17 @@ TypeResolver::resolveIdentifierType(IdentTypeRepr *IdType,
34993499
return ExistentialType::get(result);
35003500
}
35013501

3502+
if (!options.isConstraintImplicitExistential()) {
3503+
// Imported existential typealiases, e.g. id<P>, can be
3504+
// used as constraints by extracting the underlying protocol
3505+
// types.
3506+
auto *typeAlias = dyn_cast<TypeAliasType>(result.getPointer());
3507+
if (typeAlias && typeAlias->is<ExistentialType>() &&
3508+
typeAlias->getDecl()->hasClangNode()) {
3509+
return typeAlias->getAs<ExistentialType>()->getConstraintType();
3510+
}
3511+
}
3512+
35023513
// Hack to apply context-specific @escaping to a typealias with an underlying
35033514
// function type.
35043515
if (result->is<FunctionType>())

0 commit comments

Comments
 (0)