Skip to content

Commit f886b38

Browse files
slavapestovhborla
authored andcommitted
ClangImporter: Import 'typedef id<P, Q> Foo' as a constraint type rather than an existential type
We want to be able to use these typealiases both as existential types and as generic constraints, so unwrap the ExistentialType explicitly before setting the underlying type of the typealias. This might not be the best long-term approach, so I added a FIXME comment with my thoughts there. Fixes rdar://problem/88208893.
1 parent 377ca35 commit f886b38

File tree

3 files changed

+38
-0
lines changed

3 files changed

+38
-0
lines changed

lib/ClangImporter/ImportDecl.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2796,6 +2796,16 @@ namespace {
27962796
SourceLoc(), Name,
27972797
Loc,
27982798
/*genericparams*/nullptr, DC);
2799+
2800+
// Unwrap an explicit ExistentialType around the underlying type so that
2801+
// the typealias can be used in a generic constraint context.
2802+
//
2803+
// FIXME: We might want to push this down further into importType(), and
2804+
// once ExistentialType becomes mandatory in the future we want to wrap
2805+
// references to imported typealiases in Sema's resolveType() as well.
2806+
if (auto *existentialType = SwiftType->getAs<ExistentialType>())
2807+
SwiftType = existentialType->getConstraintType();
2808+
27992809
Result->setUnderlyingType(SwiftType);
28002810

28012811
// Make Objective-C's 'id' unavailable.
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)