-
Notifications
You must be signed in to change notification settings - Fork 1.5k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge branch 'trunk' into lookup-multi
- Loading branch information
Showing
367 changed files
with
4,089 additions
and
3,744 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,175 @@ | ||
# Destructor syntax | ||
|
||
<!-- | ||
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 | ||
--> | ||
|
||
[Pull request](https://github.com/carbon-language/carbon-lang/pull/5017) | ||
|
||
<!-- toc --> | ||
|
||
## Table of contents | ||
|
||
- [Abstract](#abstract) | ||
- [Problem](#problem) | ||
- [Background](#background) | ||
- [Proposal](#proposal) | ||
- [Not directly callable](#not-directly-callable) | ||
- [Future work](#future-work) | ||
- [Extend syntax to allow explicit marking of _trivial_ destructors](#extend-syntax-to-allow-explicit-marking-of-trivial-destructors) | ||
- [Decide whether to desugar destructors to interfaces](#decide-whether-to-desugar-destructors-to-interfaces) | ||
- [Copy and move functions](#copy-and-move-functions) | ||
- [Rationale](#rationale) | ||
- [Alternatives considered](#alternatives-considered) | ||
- [Destructor syntax options](#destructor-syntax-options) | ||
- [Destructor name options](#destructor-name-options) | ||
|
||
<!-- tocstop --> | ||
|
||
## Abstract | ||
|
||
Fix destructor syntax ambiguity by switching to `fn destroy` mirroring standard | ||
function syntax. This is a purely syntactic change, maintaining destructor | ||
semantics. | ||
|
||
## Problem | ||
|
||
The | ||
[accepted destructor syntax](https://github.com/carbon-language/carbon-lang/blob/trunk/docs/design/classes.md#destructors) | ||
includes out-of-line definitions such as: | ||
|
||
```carbon | ||
class MyClass { | ||
destructor [addr self: Self*]; | ||
} | ||
destructor MyClass [addr self: Self*] { ... } | ||
``` | ||
|
||
The implicit parameter here could be interpreted as either an implicit parameter | ||
for `MyClass` or an implicit parameter for the destructor. How should | ||
ambiguities like this be resolved? | ||
|
||
For comparison, note a generic might look like: | ||
|
||
```carbon | ||
class GenericClass[T:! type](N:! T) { ... } | ||
destructor GenericClass[T:! type](N:! T) [addr self: Self*] { ... } | ||
``` | ||
|
||
The toolchain is able to parse this in constant time, but only because the lexer | ||
will pair brackets, so we can do lookahead at the bracket in `GenericClass[` for | ||
the closing `]`, and look past that for the `(` versus `{`. However, this is | ||
arbitrary lookahead and may be significantly less efficient in other parsers | ||
that people might want to use with Carbon, such as tree-sitter. | ||
|
||
## Background | ||
|
||
- Proposal | ||
[#1154: Destructors](https://github.com/carbon-language/carbon-lang/pull/1154) | ||
- Leads question | ||
[#4999: Out-of-line destructor syntax ambiguity](https://github.com/carbon-language/carbon-lang/issues/4999) | ||
- [2025-02-25 Toolchain minutes](https://docs.google.com/document/d/1Iut5f2TQBrtBNIduF4vJYOKfw7MbS8xH_J01_Q4e6Rk/edit?resourcekey=0-mc_vh5UzrzXfU4kO-3tOjA&tab=t.0#heading=h.vootuzze8e8e) | ||
|
||
In particular, we are discussing destruction as possibly similar to copy and | ||
move syntax, and trying to create a consistency between the functions. | ||
|
||
## Proposal | ||
|
||
Destructor syntax will use standard function syntax, with `destroy` as a keyword | ||
for the function name. | ||
|
||
For example, in contrast with [problem examples](#problem): | ||
|
||
```carbon | ||
class MyClass { | ||
fn destroy[addr self: Self*](); | ||
} | ||
fn MyClass.destroy[addr self: Self*]() { ... } | ||
class GenericClass[T:! type](N:! T) { ... } | ||
fn GenericClass[T:! type](N:! T).destroy[addr self: Self*]() { ... } | ||
``` | ||
|
||
It is invalid to add other implicit or explicit parameters to the `destroy` | ||
function. | ||
|
||
### Not directly callable | ||
|
||
Although the syntax of `fn destroy` looks similar to a regular function, the | ||
functions are not designed to be directly callable. This does not add support | ||
for `my_var.destroy()`. See Proposal #1154, alternative | ||
[Allow functions to act as destructors](/proposals/p1154.md#allow-functions-to-act-as-destructors) | ||
for details. | ||
|
||
## Future work | ||
|
||
### Extend syntax to allow explicit marking of _trivial_ destructors | ||
|
||
Discussion has indicated potential utility in syntax to make the expectation of | ||
a trivial destructor _explicit_. This would allow a declarative way of ensuring | ||
no member accidentally caused a type to have non-trivial destruction. | ||
|
||
Still, this requires a further extension of syntax that isn't proposed at this | ||
time. Both determining syntax for such a feature and motivating it fully are | ||
left as future work. | ||
|
||
### Decide whether to desugar destructors to interfaces | ||
|
||
Under this proposal, `fn destroy` remains a special function. We may want to | ||
make it desugar to an interface implementation, but even if we do so, the terse | ||
destructor syntax seems likely to remain. There are concerns about the | ||
ergonomics of requiring an `impl` in order to add a destructor to a type, and | ||
decisions would need to be made for how virtual destructors should be handled. | ||
|
||
### Copy and move functions | ||
|
||
This proposal is set up for consistency with a possible `fn copy` and `fn move`, | ||
but those will be evaluated as part of copy and move semantics. | ||
|
||
## Rationale | ||
|
||
- [Software and language evolution](/docs/project/goals.md#software-and-language-evolution) | ||
- Eliminates ambiguity in `destructor` syntax, by creating consistency | ||
with `fn` syntax. | ||
- Claiming `destroy` as a keyword is considered to be a good balance. | ||
- Syntax choices, particularly with the keyword as a function name, should | ||
not create a barrier for desugaring to an interface approach for | ||
destructions. | ||
- [Code that is easy to read, understand, and write](/docs/project/goals.md#code-that-is-easy-to-read-understand-and-write) | ||
- Consistency with `fn` syntax should improve readability. | ||
- Features that impact data layout are consistently written like member | ||
declarations. | ||
|
||
## Alternatives considered | ||
|
||
### Destructor syntax options | ||
|
||
The ambiguity between `destructor MyClass [...]` out-of-line destructor syntax | ||
and implicit parameters for generics is a sufficient barrier to change syntax. | ||
We do not want parsing Carbon to require arbitrary lookahead. | ||
|
||
`fn destroy` was preferred because it builds on existing `fn` syntax. | ||
|
||
Although adding a `.`, as in `destructor MyClass.[...]`, was brought up, it | ||
didn't present interesting advantages over `fn destroy`. | ||
|
||
### Destructor name options | ||
|
||
We expect more name conflicts with C++ code using the `destroy` keyword than | ||
with the `destructor` keyword, for example with | ||
[`std::allocator::destroy`](https://en.cppreference.com/w/cpp/memory/allocator/destroy), | ||
or visible | ||
[searching LLVM code](https://github.com/search?q=repository%3Allvm%2Fllvm-project+language%3Ac%2B%2B+symbol%3A%2F%28%3F-i%29%5Edestroy%24%2F&type=code). | ||
|
||
Still, the phrasing of `destroy`, particularly if we have `copy` and `move` to | ||
match, is preferred. Raw identifier syntax (`r#destroy`) is expected to be | ||
sufficient for name conflicts. | ||
|
||
`fn delete` was mentioned as an option reusing current keywords, but declined | ||
due to the "heap allocated" implication of `delete`. | ||
|
||
Non-keyword names were considered as part of proposal | ||
[#1154: Destructors](https://github.com/carbon-language/carbon-lang/pull/1154), | ||
and the trade-off considerations still apply. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.