mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
IRGen: Use deinit to destroy move-only structs that have them.
The `deinit` takes full responsibility for destroying the value, using the user-defined deinit body and implicitly destroying any remaining resources not consumed during the deinit. Remaining to do after this patch: - Run the deinit for enums - Pass generic arguments for generic move-only types - Handle deinits that take their parameter indirectly - Teach value witness layout about when types are move-only and/or have deinits, so that we don't attempt to give move-only types standard value witness tables or share box metadata with copyable payloads
This commit is contained in:
@@ -250,6 +250,18 @@ namespace {
|
||||
return fields[0].getTypeInfo().isSingleRetainablePointer(expansion, rc);
|
||||
}
|
||||
|
||||
void destroy(IRGenFunction &IGF, Address address, SILType T,
|
||||
bool isOutlined) const override {
|
||||
// If the struct has a deinit declared, then call it to destroy the
|
||||
// value.
|
||||
if (tryEmitDestroyUsingDeinit(IGF, address, T)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, perform elementwise destruction of the value.
|
||||
return super::destroy(IGF, address, T, isOutlined);
|
||||
}
|
||||
|
||||
void verify(IRGenTypeVerifierFunction &IGF,
|
||||
llvm::Value *metadata,
|
||||
SILType structType) const override {
|
||||
@@ -748,6 +760,7 @@ namespace {
|
||||
/// A type implementation for loadable struct types.
|
||||
class LoadableStructTypeInfo final
|
||||
: public StructTypeInfoBase<LoadableStructTypeInfo, LoadableTypeInfo> {
|
||||
using super = StructTypeInfoBase<LoadableStructTypeInfo, LoadableTypeInfo>;
|
||||
public:
|
||||
LoadableStructTypeInfo(ArrayRef<StructFieldInfo> fields,
|
||||
unsigned explosionSize,
|
||||
@@ -814,6 +827,18 @@ namespace {
|
||||
const StructFieldInfo &field) const {
|
||||
llvm_unreachable("non-fixed field in loadable type?");
|
||||
}
|
||||
|
||||
void consume(IRGenFunction &IGF, Explosion &explosion,
|
||||
Atomicity atomicity, SILType T) const override {
|
||||
// If the struct has a deinit declared, then call it to consume the
|
||||
// value.
|
||||
if (tryEmitConsumeUsingDeinit(IGF, explosion, T)) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Otherwise, do elementwise destruction of the value.
|
||||
return super::consume(IGF, explosion, atomicity, T);
|
||||
}
|
||||
};
|
||||
|
||||
/// A type implementation for non-loadable but fixed-size struct types.
|
||||
|
||||
Reference in New Issue
Block a user