Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Updates to generics design details, part 2 #3253

Merged
merged 20 commits into from
Oct 3, 2023
Merged
Changes from 3 commits
Commits
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
29 changes: 20 additions & 9 deletions docs/design/generics/details.md
Original file line number Diff line number Diff line change
Expand Up @@ -2592,19 +2592,25 @@ this interface while `.Self` refers to the associated facet currently being
defined.

```carbon
interface Container;
constraint SliceConstraint(E:! type, S:! Container);

interface Container {
let ElementType:! type;
let IteratorType:! Iterator where .ElementType = ElementType;

let SliceType:! Container
where .ElementType = ElementType and
// `.Self` means `SliceType`.
.SliceType = .Self;
// `.Self` means `SliceType`.
let SliceType:! SliceConstraint(ElementType, .Self);
josh11b marked this conversation as resolved.
Show resolved Hide resolved

// `Self` means the type implementing `Container`.
fn GetSlice[addr self: Self*]
(start: IteratorType, end: IteratorType) -> SliceType;
}

constraint SliceConstraint(E:! type, S:! Container) {
extend Container where .ElementType = E and
.SliceType = S;
}
```

Note that [naming](#named-constraint-constants) a recursive constraint using the
Expand Down Expand Up @@ -2898,9 +2904,9 @@ interface Edge {
}
interface Node {
let E:! EdgeFor(Self);
fn GetE[self: Self]() -> EdgeT;
fn AddE[addr self: Self*](e: EdgeT);
fn NearN[self: Self](n: N) -> bool;
fn GetE[self: Self]() -> E;
fn AddE[addr self: Self*](e: E);
fn NearN[self: Self](n: Self) -> bool;
}

constraint EdgeFor(NodeT:! Node) {
Expand Down Expand Up @@ -3022,8 +3028,8 @@ fn J[G: Graph](g: G) {
```

the expression `G.E.N.E.N` is one equality away from `G.N.E.N` and so it is
allowed. This is even though `G.N.E.N` isn't the type expression immediately
prior to `G.E.N.E.N`.
allowed. This is true even though `G.N.E.N` isn't the type expression
immediately prior to `G.E.N.E.N`.

After an `observe` declaration, all of the listed type expressions are
considered equal to each other using a single `where` equality. In this example,
Expand Down Expand Up @@ -3148,6 +3154,11 @@ the above example, `Container` defines `ElementType` as having type `type`, but
need to be a bit careful when talking about the type of `ContainerType` when
there is a `where` clause modifying it.
zygoloid marked this conversation as resolved.
Show resolved Hide resolved

> **Future work:** We may want to use a different operator in this case, such as
> `&=`, in place of `impls`, to reflect the change in the type. This is
> analogous to rewrite constraints using `=` instead of `==` to visibly reflect
> the different impact on the type.

An implements constraint can be applied to [`.Self`](#recursive-constraints), as
in `I where .Self impls C`. This has the same requirements as `I & C`, but that
`where` clause does not affect the API. This means that a
Expand Down
Loading