Skip to content
Merged
Show file tree
Hide file tree
Changes from 51 commits
Commits
Show all changes
59 commits
Select commit Hold shift + click to select a range
9648270
Filling out template with PR 5434
josh11b May 6, 2025
a0b90c7
Checkpoint progress.
josh11b May 6, 2025
7cc4b32
Checkpoint progress.
josh11b May 12, 2025
bf4930f
Checkpoint progress.
josh11b May 16, 2025
cc0a1f3
Checkpoint progress.
josh11b May 16, 2025
eb2ab64
Checkpoint progress.
josh11b May 16, 2025
a71ba59
Checkpoint progress.
josh11b May 16, 2025
018dda5
Checkpoint progress.
josh11b May 16, 2025
cbacede
Checkpoint progress.
josh11b May 17, 2025
2d6a7a3
Checkpoint progress.
josh11b May 17, 2025
4a87f20
Checkpoint progress.
josh11b May 18, 2025
90d250e
Checkpoint progress.
josh11b May 18, 2025
8151bed
Checkpoint progress.
josh11b May 18, 2025
7172159
Checkpoint progress.
josh11b May 19, 2025
66a6f47
Checkpoint progress.
josh11b May 19, 2025
8060cf7
Checkpoint progress.
josh11b May 19, 2025
4b1584d
Checkpoint progress.
josh11b May 20, 2025
c89d46d
Ready for review
josh11b May 20, 2025
0894f68
Oops, missed a couple of final touches
josh11b May 20, 2025
79d6ddb
Merge remote-tracking branch 'upstream/trunk' into ref
josh11b May 20, 2025
acec7d9
Apply suggestions from code review
josh11b May 21, 2025
626c3ae
Updates inspired by review
josh11b May 21, 2025
319f5eb
Fix incorrect statement
josh11b May 21, 2025
28d8cc2
Changes in response to review
josh11b May 21, 2025
3570dc0
Update proposals/p5434.md
josh11b May 21, 2025
3f654fc
Move indexing changes to the relevant design doc
josh11b May 21, 2025
2a76c74
Incorporate more feedback
josh11b May 21, 2025
2915e39
typo
josh11b May 21, 2025
cf7d94e
Implement suggestion
josh11b May 21, 2025
4075aed
Add small section on completeness
josh11b May 21, 2025
3e13632
Title
josh11b May 22, 2025
0fdf298
Consider alternative category for `=>`
josh11b May 22, 2025
b8cd942
Add alternative
josh11b May 29, 2025
09c9455
Merge alternatives
josh11b May 29, 2025
00b06b0
Improve indexing
josh11b Jun 11, 2025
3abc014
Checkpoint progress.
josh11b Jun 13, 2025
769e122
BindToValue
josh11b Jun 13, 2025
72c79b2
Apply suggestions from code review
josh11b Jun 13, 2025
523022c
Address some feedback
josh11b Jun 13, 2025
a90a7af
Update proposals/p5434.md
josh11b Jun 17, 2025
24c736c
Checkpoint progress.
josh11b Jun 17, 2025
2aca8e8
Merge remote-tracking branch 'refs/remotes/origin/ref' into ref
josh11b Jun 17, 2025
0cac941
Checkpoint progress.
josh11b Jun 18, 2025
38f0f90
Checkpoint progress.
josh11b Jun 18, 2025
7e688a3
Checkpoint progress.
josh11b Jun 18, 2025
7787bd0
Checkpoint progress.
josh11b Jun 18, 2025
37b5c84
Checkpoint progress.
josh11b Jun 18, 2025
a11e69f
Checkpoint progress.
josh11b Jun 18, 2025
c8e37f3
`init`
josh11b Jun 18, 2025
eb1df53
Update custom value representation syntax to use `ref` keyword
josh11b Jul 1, 2025
9ec8a85
Add text to hopefully address confusion, as suggested in review
josh11b Jul 1, 2025
50417f4
Apply suggestions from code review
josh11b Jul 8, 2025
08f332b
Checkpoint progress.
josh11b Jul 8, 2025
1f5129a
Checkpoint progress.
josh11b Jul 20, 2025
90d4ec4
Implement suggestions
josh11b Jul 21, 2025
d14726d
Implement suggestions
josh11b Jul 21, 2025
cfe2a65
Apply suggestions from code review
josh11b Aug 1, 2025
3520180
Add TODO about updating initializing return docs
josh11b Aug 1, 2025
5aa00c7
Fix formatting
josh11b Aug 1, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
44 changes: 17 additions & 27 deletions docs/design/expressions/indexing.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,18 +40,8 @@ implement that interface, or to method calls on `IndexWith` otherwise.
`IndirectIndexWith` provides a final blanket `impl` of `IndexWith`, so a type
can implement at most one of those two interfaces.

The `Addr` methods of these interfaces, which are used to form durable reference
expressions on indexing, must return a pointer and work similarly to the
[pointer dereference customization interface](/docs/design/values.md#dereferencing-customization).
The returned pointer is then dereferenced by the language to form the reference
expression referring to the pointed-to object. These methods must return a raw
pointer, and do not automatically chain with customized dereference interfaces.

**Open question:** It's not clear that the lack of chaining is necessary, and it
might be more expressive for the pointer type returned by the `Addr` methods to
be an associated facet with a default to allow types to produce custom
pointer-like types on their indexing boundary and have them still be
automatically dereferenced.
The `Ref` methods of these interfaces, which are used to form durable reference
expressions on indexing, must return by `ref`.

## Details

Expand All @@ -64,13 +54,13 @@ Its semantics are defined in terms of the following interfaces:
```
interface IndexWith(SubscriptType:! type) {
let ElementType:! type;
fn At[self: Self](subscript: SubscriptType) -> ElementType;
fn Addr[addr self: Self*](subscript: SubscriptType) -> ElementType*;
fn At[bound self: Self](subscript: SubscriptType) -> let ElementType;
fn Ref[bound ref self: Self](subscript: SubscriptType) -> ref ElementType;
}

interface IndirectIndexWith(SubscriptType:! type) {
require Self impls IndexWith(SubscriptType);
fn Addr[self: Self](subscript: SubscriptType) -> ElementType*;
fn Ref[bound self: Self](subscript: SubscriptType) -> ref ElementType;
}
```

Expand All @@ -79,11 +69,11 @@ rewritten based on the expression category of _lhs_ and whether `T` is known to
implement `IndirectIndexWith(I)`:

- If `T` implements `IndirectIndexWith(I)`, the expression is rewritten to
"`*((` _lhs_ `).(IndirectIndexWith(I).Addr)(` _index_ `))`".
"`(` _lhs_ `).(IndirectIndexWith(I).Ref)(` _index_ `)`".
- Otherwise, if _lhs_ is a
[_durable reference expression_](/docs/design/values.md#durable-reference-expressions),
the expression is rewritten to "`*((` _lhs_ `).(IndexWith(I).Addr)(` _index_
`))`".
the expression is rewritten to "`(` _lhs_ `).(IndexWith(I).Ref)(` _index_
`)`".
- Otherwise, the expression is rewritten to "`(` _lhs_ `).(IndexWith(I).At)(`
_index_ `)`".

Expand All @@ -93,18 +83,18 @@ implement `IndirectIndexWith(I)`:
final impl forall
[SubscriptType:! type, T:! IndirectIndexWith(SubscriptType)]
T as IndexWith(SubscriptType) {
let ElementType:! type = T.(IndirectIndexWith(SubscriptType)).ElementType;
fn At[self: Self](subscript: SubscriptType) -> ElementType {
return *(self.(IndirectIndexWith(SubscriptType).Addr)(index));
where ElementType = T.(IndirectIndexWith(SubscriptType).ElementType);
fn At[bound self: Self](subscript: SubscriptType) -> let ElementType {
return self.(IndirectIndexWith(SubscriptType).Ref)(index);
}
fn Addr[addr self: Self*](subscript: SubscriptType) -> ElementType* {
return self->(IndirectIndexWith(SubscriptType).Addr)(index);
fn Ref[bound ref self: Self](subscript: SubscriptType) -> ref ElementType {
return self.(IndirectIndexWith(SubscriptType).Ref)(index);
}
}
```

Thus, a type that implements `IndirectIndexWith` need not, and cannot, provide
its own definitions of `IndexWith.At` and `IndexWith.Addr`.
its own definitions of `IndexWith.At` and `IndexWith.Ref`.

### Examples

Expand All @@ -114,8 +104,8 @@ An array type could implement subscripting like so:
class Array(template T:! type) {
impl as IndexWith(like i64) {
let ElementType:! type = T;
fn At[self: Self](subscript: i64) -> T;
fn Addr[addr self: Self*](subscript: i64) -> T*;
fn At[bound self: Self](subscript: i64) -> let T;
fn Ref[bound ref self: Self](subscript: i64) -> ref T;
}
}
```
Expand All @@ -126,7 +116,7 @@ And a type such as `std::span` could look like this:
class Span(T:! type) {
impl as IndirectIndexWith(like i64) {
let ElementType:! type = T;
fn Addr[self: Self](subscript: i64) -> T*;
fn Ref[bound ref self: Self](subscript: i64) -> ref T;
}
}
```
Expand Down
7 changes: 5 additions & 2 deletions docs/design/values.md
Original file line number Diff line number Diff line change
Expand Up @@ -640,6 +640,9 @@ specialized constructs given the specialized nature of these operations.

### Reference types

TODO: This section needs to be updated to reflect
[proposal #5434](/proposals/p5434.md).

Unlike C++, Carbon does not currently have reference types. The only form of
indirect access are pointers. There are a few aspects to this decision that need
to be separated carefully from each other as the motivations and considerations
Expand Down Expand Up @@ -883,8 +886,8 @@ keyword. It isn't final at all and likely will need to change to read well.
The provided representation type must be one of the following:

- `const Self` -- this forces the use of a _copy_ of the object.
- `const Self *` -- this forces the use of a [_pointer_](#pointers) to the
original object.
- `ref` -- this forces the use of a [_pointer_](#pointers) to the original
object.
- A custom type that is not `Self`, `const Self`, or a pointer to either.

If the representation is `const Self` or `const Self *`, then the type fields
Expand Down
Loading
Loading