Skip to content

Define Destroy for class types#7362

Draft
cjdb wants to merge 12 commits into
carbon-language:trunkfrom
cjdb:proposal/destroy-trivial-partial
Draft

Define Destroy for class types#7362
cjdb wants to merge 12 commits into
carbon-language:trunkfrom
cjdb:proposal/destroy-trivial-partial

Conversation

@cjdb

@cjdb cjdb commented Jun 15, 2026

Copy link
Copy Markdown
Contributor

Define the core interfaces Destructor, Destroy, TrivialDestroy, and DynamicDestroy. Describe how destroy works for class types.

@cjdb cjdb added proposal A proposal proposal draft Proposal in draft, not ready for review labels Jun 15, 2026
@cjdb
cjdb force-pushed the proposal/destroy-trivial-partial branch from 4f44217 to 57319f3 Compare June 15, 2026 22:17
@cjdb cjdb changed the title Updating Destroy for trivial and partial types Define Destroy for class types Jul 10, 2026
@cjdb
cjdb marked this pull request as ready for review July 10, 2026 22:39
@cjdb
cjdb requested a review from a team as a code owner July 10, 2026 22:39
@cjdb
cjdb requested review from chandlerc and removed request for a team July 10, 2026 22:39
@github-actions github-actions Bot added proposal rfc Proposal with request-for-comment sent out and removed proposal draft Proposal in draft, not ready for review labels Jul 10, 2026
@cjdb
cjdb force-pushed the proposal/destroy-trivial-partial branch from f03c93c to 819a4fd Compare July 10, 2026 23:25
Comment on lines +93 to +95
Types that do not implement `Destructor` have _isolated trivial destruction_. A
type comprised of subobjects that all have isolated trivial destruction has
_trivial destruction_. See [`TrivialDestroy` interface] below.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I feel like the pair of terms here are a bit hard for me to read clearly. Mostly, I'm worried that a modifying word like "isolated" doesn't leave it clear that subobject destructors may not be trivial...

What do folks think about instead using two distinct terms here, "trivial" and something else for what here is "isolated trivial destruction"? My best initial idea is "simple destruction"?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

"Simple destruction" is decent, but I think the best solution would be to describe trivial destruction in an entirely different way. This paragraph has been one of the hardest to write, because of its recursive nature.

Types that do not implement Destructor have trivial destruction if, and only if, none of their subobjects implement Destructor.

That's the best I can come up with. Alternatively:

Types that do not implement Destructor have trivial destruction if, and only if, all of their subobjects have trivial destruction. Types that implement Destructor do not have trivial destruction.

Thoughts on these alternative phrasings?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A type has trivial destruction if, and only if, neither it, nor any of its subobjects, implement Destructor.

A type has trivial destruction if, and only if, it does not implement Destructor and none of its subobjects implement Destructor.

I think I like this last one the best.

Comment on lines +97 to +101
#### Empty `Destructor.Op()` should be an error

An empty `Destructor.Op()` definition should be an error. We should allow users
to "reserve" non-trivial destruction by providing a spelling that communicates
"no behaviour is intentional" using a clearer syntax.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not clear why we need to do this given that we later make constraining on Destructor an error -- even without impl-ing it, the ability to impl it is still "reserved".

Is there another reason for this?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think this syntax implying that C1 has non-trivial destruction subtle, and that having something a bit more explicit would be helpful.

class C1 {
  impl as Destructor {
    fn Op(self) {}
  }
}

The best we can do without this would be

class C1 {
  impl as Destructor {
    fn Op(self) {
      // C1 has non-trivial destruction, but this destructor
      // is intentionally empty.
    }
  }
}

clarifies that trivial destruction is a property that code can query. The
Leads confirmed this is the case.

## Proposal

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think you need to explain a bit more here in order to bridge from #1154 and the current design's for destruction and your update here. Either here, or in an update to the design docs. For example -- how do these terms map to the very different terms currently in the design? What updates would happen to the design to integrate and connect it with these interfaces? How does it interact with the current design's destroy function?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it be better to describe these in the proposal, or in the design doc?


```carbon
interface Destroy {
private fn Op(ref self);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A bit surprising that this is private -- can it not be called?

Should it be unsafe instead?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Good catch. This should be final (per #6124).

@zygoloid doesn't mention unsafe, but the operation is unsafe. Was this omission intentional?


```carbon
interface DynamicDestroy {
private fn Op(ref self);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This in particular seems a bit odd to be private.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Replaced with final. Same for TrivialDestroy.


This is a successor to [P001154 Destructors](/proposals/p001154-destructors.md).
Several alternatives that were explored in P001154 are proposed in this
document.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think there are a lot of design decisions here that we should probably have alternatives?

@cjdb
cjdb requested a review from chandlerc July 13, 2026 23:05
cjdb added 3 commits July 16, 2026 11:01
The proposal doc is a bit messy right now, but this is a good save
point for `values.md`.
@cjdb
cjdb marked this pull request as draft July 23, 2026 00:05
@cjdb

cjdb commented Jul 23, 2026

Copy link
Copy Markdown
Contributor Author

I've pushed my most recent changes. Feel free to review values.md, but the proposal doc is not in a reviewable state yet.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

proposal rfc Proposal with request-for-comment sent out proposal A proposal

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants