Skip to content

Commit bb9487f

Browse files
authored
Merge pull request #18567 from jckarter/array-of-class-bridging-4.2
[4.2] Sema: Apply metatype-to-object conversions even without restriction hints.
2 parents ab5ce2e + cf90584 commit bb9487f

File tree

2 files changed

+58
-0
lines changed

2 files changed

+58
-0
lines changed

lib/Sema/CSApply.cpp

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6992,6 +6992,45 @@ Expr *ExprRewriter::coerceToType(Expr *expr, Type toType,
69926992
}
69936993
}
69946994

6995+
// Coercions from metadata to objects.
6996+
if (auto fromMeta = fromType->getAs<AnyMetatypeType>()) {
6997+
if (toType->isAnyObject()) {
6998+
assert(cs.getASTContext().LangOpts.EnableObjCInterop
6999+
&& "metatype-to-object conversion requires objc interop");
7000+
if (fromMeta->is<MetatypeType>()) {
7001+
assert(fromMeta->getInstanceType()->mayHaveSuperclass()
7002+
&& "metatype-to-object input should be a class metatype");
7003+
return cs.cacheType(
7004+
new (tc.Context) ClassMetatypeToObjectExpr(expr, toType));
7005+
}
7006+
7007+
if (fromMeta->is<ExistentialMetatypeType>()) {
7008+
assert(fromMeta->getInstanceType()->getCanonicalType()
7009+
->getExistentialLayout().requiresClass()
7010+
&& "metatype-to-object input should be a class metatype");
7011+
return cs.cacheType(
7012+
new (tc.Context) ExistentialMetatypeToObjectExpr(expr, toType));
7013+
}
7014+
7015+
llvm_unreachable("unhandled metatype kind");
7016+
}
7017+
7018+
if (auto toClass = toType->getClassOrBoundGenericClass()) {
7019+
if (toClass->getName() == cs.getASTContext().Id_Protocol
7020+
&& toClass->getModuleContext()->getName()
7021+
== cs.getASTContext().Id_ObjectiveC) {
7022+
assert(cs.getASTContext().LangOpts.EnableObjCInterop
7023+
&& "metatype-to-object conversion requires objc interop");
7024+
assert(fromMeta->is<MetatypeType>()
7025+
&& fromMeta->getInstanceType()->is<ProtocolType>()
7026+
&& "protocol-metatype-to-Protocol only works for single "
7027+
"protocols");
7028+
return cs.cacheType(
7029+
new (tc.Context) ProtocolMetatypeToObjectExpr(expr, toType));
7030+
}
7031+
}
7032+
}
7033+
69957034
// Coercions from a type to an existential type.
69967035
if (toType->isAnyExistentialType()) {
69977036
return coerceExistential(expr, toType, locator);
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -typecheck -verify %s
2+
// RUN: %target-swift-frontend(mock-sdk: %clang-importer-sdk) -emit-silgen -verify %s
3+
// REQUIRES: objc_interop
4+
5+
import Foundation
6+
7+
func f(_: [AnyObject]) {}
8+
func g(_: [Protocol]) {}
9+
10+
f([NSString.self, NSObject.self])
11+
12+
@objc protocol P: AnyObject {}
13+
@objc protocol Q: AnyObject {}
14+
15+
func foo(p: P.Type, pq: (P & Q).Type) {
16+
f([p, pq])
17+
}
18+
19+
g([P.self, Q.self])

0 commit comments

Comments
 (0)