diff --git a/include/swift/RemoteInspection/TypeLowering.h b/include/swift/RemoteInspection/TypeLowering.h index 5e5b052ddce62..fbf5bda7e2ae1 100644 --- a/include/swift/RemoteInspection/TypeLowering.h +++ b/include/swift/RemoteInspection/TypeLowering.h @@ -428,6 +428,7 @@ class TypeConverter { const TypeInfo *getThickFunctionTypeInfo(); const TypeInfo *getAnyMetatypeTypeInfo(); const TypeInfo *getDefaultActorStorageTypeInfo(); + const TypeInfo *getRawUnsafeContinuationTypeInfo(); const TypeInfo *getEmptyTypeInfo(); template diff --git a/stdlib/public/RemoteInspection/TypeLowering.cpp b/stdlib/public/RemoteInspection/TypeLowering.cpp index b4a841cc68aa2..b2feda9243452 100644 --- a/stdlib/public/RemoteInspection/TypeLowering.cpp +++ b/stdlib/public/RemoteInspection/TypeLowering.cpp @@ -1602,6 +1602,12 @@ const TypeInfo *TypeConverter::getDefaultActorStorageTypeInfo() { return DefaultActorStorageTI; } +const TypeInfo *TypeConverter::getRawUnsafeContinuationTypeInfo() { + // FIXME: This is a bad approximation + return getReferenceTypeInfo(ReferenceKind::Strong, + ReferenceCounting::Native); +} + const TypeInfo *TypeConverter::getEmptyTypeInfo() { if (EmptyTI != nullptr) return EmptyTI; @@ -2208,6 +2214,8 @@ class LowerType ReferenceCounting::Unknown); } else if (B->getMangledName() == "BD") { return TC.getDefaultActorStorageTypeInfo(); + } else if (B->getMangledName() == "Bc") { + return TC.getRawUnsafeContinuationTypeInfo(); } /// Otherwise, get the fixed layout information from reflection diff --git a/validation-test/Reflection/reflect_UnsafeContinuation.swift b/validation-test/Reflection/reflect_UnsafeContinuation.swift new file mode 100644 index 0000000000000..31fe6acd239bd --- /dev/null +++ b/validation-test/Reflection/reflect_UnsafeContinuation.swift @@ -0,0 +1,57 @@ +// RUN: %empty-directory(%t) +// RUN: %target-build-swift -lswiftSwiftReflectionTest %s -o %t/reflect_UnsafeContinuation +// RUN: %target-codesign %t/reflect_UnsafeContinuation + +// RUN: %target-run %target-swift-reflection-test %t/reflect_UnsafeContinuation | %FileCheck %s --check-prefix=CHECK-%target-ptrsize + +// REQUIRES: reflection_test_support +// REQUIRES: executable_test +// UNSUPPORTED: use_os_stdlib +// UNSUPPORTED: ASAN + +import SwiftReflectionTest + +struct MyValue { + let u: UInt +} + +struct MyError: Error { + let i: Int +} + +@available(SwiftStdlib 5.1, *) +class MyClass { + let cont: UnsafeContinuation + + init(cont: UnsafeContinuation) { + self.cont = cont + } +} + +if #available(SwiftStdlib 5.1, *) { + _ = try await withUnsafeThrowingContinuation { unsafeContinuation in + let myClass = MyClass(cont: unsafeContinuation) + reflect(object: myClass) + unsafeContinuation.resume(returning: MyValue(u: 1)) + } +} + +// CHECK: Reflecting an object. +// CHECK-NEXT: Instance pointer in child address space: 0x{{[0-9a-fA-F]+}} +// CHECK-NEXT: Type reference: +// CHECK-NEXT: (class reflect_UnsafeContinuation.MyClass) + +// CHECK-64: Type info: +// CHECK-64-NEXT: (class_instance size=24 alignment=8 stride=24 num_extra_inhabitants=0 bitwise_takable=1 +// CHECK-64-NEXT: (field name=cont offset=16 +// CHECK-64-NEXT: (struct size=8 alignment=8 stride=8 num_extra_inhabitants=2147483647 bitwise_takable=1 +// CHECK-64-NEXT: (field name=context offset=0 +// CHECK-64-NEXT: (reference kind=strong refcounting=native))))) + +// TODO: 32-bit layout + +doneReflecting() + +// CHECK-64: Done. + +// CHECK-32: Done.