mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-11-10 12:28:25 +00:00
Determining that a type has trivial destruction requires checking whether all of its subobjects have trivial destruction and whether its type has a custom witness for `Destroy.Op`. This isn't possible when `Destroy` is the custodian for `Destroy.Op` and `SubobjectDestroy.Op`, so we need to make `SubobjectDestroy` its own interface. `Destroy.SelfDestruct` becomes a standalone function because it depends on `SubobjectDestroy` and `Destroy` being implemented, and is also responsible for generating any custom witnesses for both interfaces. Making `SelfDestruct` an interface was experimented with, but this required a blanket impl that caused issues for facet types. `Destroy` depends on `SubobjectDestroy` to be implemented. We'd ideally use `require impls SubobjectDestroy`, but it isn't complete yet, and it also causes problems when `Destroy` is implemented inside the class definition. We work around this by temporarily renaming the `Destroy` interface to `DestroyImpl`, and introducing a constraint called `Destroy` so that user code doesn't need to write `Core.SubobjectDestroy & Core.Destroy`.
40 lines
1.1 KiB
Plaintext
40 lines
1.1 KiB
Plaintext
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
|
|
// Exceptions. See /LICENSE for license information.
|
|
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
|
package Core library "prelude/destroy";
|
|
|
|
import library "prelude/operators/as";
|
|
import library "prelude/operators/bitwise";
|
|
|
|
// TODO: uncomment when `require impls` adds a witness table entry.
|
|
interface SubobjectDestroy {
|
|
fn Op(ref self);
|
|
}
|
|
|
|
// TODO: rename to `Destroy` when `require impls` adds a witness table entry.
|
|
interface DestroyImpl {
|
|
// TODO: uncomment when `require impls` adds a witness table entry.
|
|
// require impls SubobjectDestroy;
|
|
|
|
// TODO: change `Self` to `partial Self`.
|
|
fn Op(ref self);
|
|
}
|
|
|
|
impl forall [T: SubobjectDestroy] T as DestroyImpl {
|
|
fn Op(ref self) = "no_op";
|
|
}
|
|
|
|
constraint Destroy {
|
|
extend require impls SubobjectDestroy & DestroyImpl;
|
|
}
|
|
|
|
// TODO: uncomment when `require impls` adds a witness table entry.
|
|
// impl forall [T: SubobjectDestroy] partial T as Destroy {
|
|
// alias Op = T.Op;
|
|
// }
|
|
|
|
fn SelfDestruct[T: Destroy](ref t: T) {
|
|
t.(DestroyImpl.Op)();
|
|
t.(SubobjectDestroy.Op)();
|
|
}
|