Skip to content

Commit 88b75cd

Browse files
authored
Merge pull request swiftlang#18575 from dcci/existentialmetatypes
2 parents 0e2a591 + 242338c commit 88b75cd

File tree

2 files changed

+27
-2
lines changed

2 files changed

+27
-2
lines changed

lib/RemoteAST/RemoteAST.cpp

Lines changed: 22 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1216,6 +1216,26 @@ class RemoteASTContextConcreteImpl final : public RemoteASTContextImpl {
12161216
std::move(valueAddress));
12171217
}
12181218

1219+
Result<std::pair<Type, RemoteAddress>>
1220+
getDynamicTypeAndAddressExistentialMetatype(RemoteAddress object) {
1221+
// The value of the address is just the input address.
1222+
// The type is obtained through the following sequence of steps:
1223+
// 1) Loading a pointer from the input address
1224+
// 2) Reading it as metadata and resolving the type
1225+
// 3) Wrapping the resolved type in an existential metatype.
1226+
auto pointed = Reader.readPointedValue(object.getAddressData());
1227+
if (!pointed)
1228+
return getFailure<std::pair<Type, RemoteAddress>>();
1229+
auto typeResult = Reader.readTypeFromMetadata(*pointed);
1230+
if (!typeResult)
1231+
return getFailure<std::pair<Type, RemoteAddress>>();
1232+
auto wrappedType = ExistentialMetatypeType::get(typeResult);
1233+
if (!wrappedType)
1234+
return getFailure<std::pair<Type, RemoteAddress>>();
1235+
return std::make_pair<Type, RemoteAddress>(std::move(wrappedType),
1236+
std::move(object));
1237+
}
1238+
12191239
/// Resolve the dynamic type and the value address of an existential,
12201240
/// given its address and its static type. For class and error existentials,
12211241
/// this API takes a pointer to the instance reference rather than the
@@ -1227,9 +1247,9 @@ class RemoteASTContextConcreteImpl final : public RemoteASTContextImpl {
12271247
if (!staticType->isAnyExistentialType())
12281248
return getFailure<std::pair<Type, RemoteAddress>>();
12291249

1230-
// TODO: implement support for ExistentialMetaTypes.
1250+
// Handle the case where this is an ExistentialMetatype.
12311251
if (!staticType->isExistentialType())
1232-
return getFailure<std::pair<Type, RemoteAddress>>();
1252+
return getDynamicTypeAndAddressExistentialMetatype(object);
12331253

12341254
// This should be an existential type at this point.
12351255
auto layout = staticType->getExistentialLayout();

test/RemoteAST/existentials.swift

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,3 +46,8 @@ enum MyError : Error {
4646
// CHECK-NEXT: MyError
4747
let q : Error = MyError.a
4848
printDynamicTypeAndAddressForExistential(q)
49+
50+
// Case five: existential metatypes.
51+
// CHECK-NEXT: Any.Type
52+
let metatype : Any.Type = Any.self
53+
printDynamicTypeAndAddressForExistential(metatype)

0 commit comments

Comments
 (0)