Skip to content

Commit b35a2a1

Browse files
authored
Merge pull request swiftlang#76309 from mikeash/mirror-thin-metatypes
[Mirror] Handle fields of thin metatypes.
2 parents 4aaf471 + 7d34513 commit b35a2a1

File tree

2 files changed

+66
-0
lines changed

2 files changed

+66
-0
lines changed

stdlib/public/runtime/ReflectionMirror.cpp

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,29 @@ static AnyReturn copyFieldContents(OpaqueValue *fieldData,
171171
auto ownership = fieldType.getReferenceOwnership();
172172
auto *destContainer = type->allocateBoxForExistentialIn(&outValue.Buffer);
173173

174+
// If the field's type is a thin metatype, then there's no actual data at
175+
// fieldData, and we need to obtain the metatype value from the field type.
176+
if (auto *metatype = dyn_cast<MetatypeMetadata>(type)) {
177+
switch (metatype->InstanceType->getKind()) {
178+
case MetadataKind::Struct:
179+
case MetadataKind::Enum:
180+
case MetadataKind::Optional:
181+
case MetadataKind::Tuple:
182+
case MetadataKind::Function:
183+
case MetadataKind::Existential: {
184+
// These kinds don't have subtypes and thus have thin representations.
185+
auto asOpaque = const_cast<OpaqueValue *>(
186+
reinterpret_cast<const OpaqueValue *>(&metatype->InstanceType));
187+
type->vw_initializeWithCopy(destContainer, asOpaque);
188+
return AnyReturn(outValue);
189+
}
190+
191+
default:
192+
// Other kinds have subtypes and will not have a thin representation.
193+
break;
194+
}
195+
}
196+
174197
if (ownership.isStrong()) {
175198
type->vw_initializeWithCopy(destContainer, fieldData);
176199
}

test/stdlib/Mirror.swift

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727
// REQUIRES: reflection
2828

2929
// rdar://96439408
30+
// UNSUPPORTED: back_deployment_runtime
3031
// UNSUPPORTED: use_os_stdlib
3132

3233
import StdlibUnittest
@@ -1669,6 +1670,48 @@ mirrors.test("MetatypeMirror") {
16691670
}
16701671
}
16711672

1673+
class MetatypeExampleClass {}
1674+
class MetatypeExampleSubclass: MetatypeExampleClass {}
1675+
final class MetatypeExampleFinalClass {}
1676+
enum MetatypeExampleEnum {}
1677+
struct MetatypeContainer {
1678+
var before = 42
1679+
var before2 = 43
1680+
var structType = String.self
1681+
var enumType = MetatypeExampleEnum.self
1682+
var tupleType = (Int, String, AnyObject).self
1683+
var functionType = (() -> Void).self
1684+
var classType = MetatypeExampleClass.self
1685+
var subclassType: MetatypeExampleClass.Type = MetatypeExampleSubclass.self
1686+
var finalClassType = MetatypeExampleFinalClass.self
1687+
var existentialType: (any Any).Type = Any.self
1688+
var existentialType2: Any.Type = Any.self
1689+
var after = 45
1690+
}
1691+
1692+
mirrors.test("MetatypeFields") {
1693+
var output = ""
1694+
let container = MetatypeContainer()
1695+
dump(container, to: &output)
1696+
expectEqual("""
1697+
▿ Mirror.MetatypeContainer
1698+
- before: 42
1699+
- before2: 43
1700+
- structType: Swift.String #0
1701+
- enumType: Mirror.MetatypeExampleEnum #1
1702+
- tupleType: (Swift.Int, Swift.String, Swift.AnyObject) #2
1703+
- functionType: () -> () #3
1704+
- classType: Mirror.MetatypeExampleClass #4
1705+
- subclassType: Mirror.MetatypeExampleSubclass #5
1706+
- finalClassType: Mirror.MetatypeExampleFinalClass #6
1707+
- existentialType: Any #7
1708+
- existentialType2: Any #7
1709+
- after: 45
1710+
1711+
""",
1712+
output)
1713+
}
1714+
16721715
//===--- Tuples -----------------------------------------------------------===//
16731716
//===----------------------------------------------------------------------===//
16741717

0 commit comments

Comments
 (0)