Skip to content

Commit 724ae70

Browse files
committed
review
1 parent bf16246 commit 724ae70

File tree

1 file changed

+59
-24
lines changed

1 file changed

+59
-24
lines changed

proposals/p6902.md

Lines changed: 59 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
1919
- [Details](#details)
2020
- [Rationale](#rationale)
2121
- [Alternatives considered](#alternatives-considered)
22+
- [Only allow `Self as N` to be identified in a named constraint `N`](#only-allow-self-as-n-to-be-identified-in-a-named-constraint-n)
2223

2324
<!-- tocstop -->
2425

@@ -27,22 +28,22 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
2728
This proposal updates the criteria for when a facet type is considered
2829
"identified." Specifically, it relaxes the requirement for named constraints,
2930
allowing them to be considered identified if they have begun being defined,
30-
rather than requiring them to be fully complete. This change enables `Self`
31-
lookups within a constraint's definition to correctly resolve witnesses based on
32-
prior `require impls` statements in the same scope.
31+
rather than requiring them to be fully complete, when used through the `Self`
32+
facet. This change enables impl lookups with `Self` within a constraint's
33+
definition to correctly resolve witnesses based on prior `require impls`
34+
statements in the definition.
3335

3436
## Problem
3537

3638
Under the rules established in [Proposal #5168](/proposals/p5168.md), a facet
37-
type can be identified only if all its referenced interfaces were declared and
38-
all its named constraints were complete.
39+
type is identified only if all its referenced interfaces are declared and all
40+
its referenced named constraints are complete.
3941

4042
This definition creates a circularity problem during the definition of a named
4143
constraint. If a `require impls` statement inside a named constraint definition
42-
relies on an impl lookup that involves `Self`, that lookup will fail because the
43-
the facet type of `Self` is not identified before the named constraint is
44-
complete. This prevents requirements in a named constraints from depending on
45-
earlier ones.
44+
relies on an impl lookup with `Self`, that lookup will fail because the the
45+
facet type of `Self` is not identified before the named constraint is complete.
46+
This prevents requirements in a named constraint from depending on earlier ones.
4647

4748
## Background
4849

@@ -51,13 +52,24 @@ earlier ones.
5152

5253
## Proposal
5354

54-
We propose redefining the identification criteria for facet types to say that a
55-
facet type is identified if all the interfaces it references are declared and
56-
all of its named constraints are complete **or have begun being defined**.
55+
We propose redefining the identification criteria for facet types.
5756

58-
But we also propose to disallow using a named constraint by name inside its own
59-
definition. This way we can use `Self` to find a witness, but we can not use the
60-
named constraint as a constraint for a `require impls` statement.
57+
A facet type is identified if all the interfaces it references are declared and
58+
all the named constraints it references are complete. Additionally, the facet
59+
type of `Self` in a named constraint is identified even though it is not
60+
complete.
61+
62+
An identified facet type is associated with a known set of interfaces. For the
63+
facet type of `Self` in a named constraint, the set of interfaces is established
64+
by the `require impls` statements before that use of `Self`. This means the
65+
identified facet type of `Self` changes across the definition of a named
66+
constraint.
67+
68+
We also propose to disallow using a named constraint inside its own definition,
69+
except through the type of `Self`. Any other use is diagnosed as an error. This
70+
way we can use `Self` to find a witness, but we can not use the named constraint
71+
as an independent entity, such as within a constraint for a `require impls`
72+
statement.
6173

6274
## Details
6375

@@ -98,8 +110,8 @@ In this example, identifying `W` while it is being defined allows the lookup for
98110
compiler knows `Self` (of type `W`) implements `Y` from the previous
99111
`require impls` statement.
100112

101-
However, without disallowing the use of the named constraint by name, the
102-
following becomes possible:
113+
However, without disallowing the use of the named constraint independent of
114+
`Self`, the following becomes possible:
103115

104116
```carbon
105117
constraint W {
@@ -112,13 +124,14 @@ This says that `C` must implement `W`, yet `W` is not fully defined. At that
112124
line `W` is still empty, so it places no requirements on `C`. The next line
113125
requires that anything implementing `W` must implement `Z`.
114126

115-
To prevent this, we disallow the use of _the name_ `W` inside `W`, while still
116-
allowing the use of `Self`.
127+
To prevent this, we disallow the use of `W` inside `W`, except through the type
128+
of `Self`.
117129

118-
Together these changes allow a named constraint to _provide_ witnesses for facet
119-
values, without allowing the named constraint to become a _requirement_ in a
120-
facet type. To understand the requirements of a named constraint, it must be
121-
complete.
130+
Together these changes allow a named constraint to provide witnesses for facet
131+
values, while ensuring it is clear that those witnesses are being constructed
132+
incrementally by coming from `Self`. And we prevent the use of the named
133+
constraint without going through `Self` since understanding the requirements of
134+
the named constraint generally requires it to be complete.
122135

123136
## Rationale
124137

@@ -133,4 +146,26 @@ statement.
133146

134147
## Alternatives considered
135148

136-
None.
149+
### Only allow `Self as N` to be identified in a named constraint `N`
150+
151+
The rule for when a facet type is identified is written in terms of just a facet
152+
type. Identifying a facet type is really an operation on a self and a facet type
153+
together. So we could change the rule to consider the self and only allow `N` to
154+
be identified in `Self as N`.
155+
156+
This gets us to a similar place as where we are but does disallow:
157+
158+
```carbon
159+
eval fn TypeOf[T:! type](t: T) -> type { return T; }
160+
161+
class C;
162+
163+
constraint N {
164+
require C as TypeOf(Self);
165+
}
166+
```
167+
168+
The rule as stated in this proposal allows the above, since the type of `Self`
169+
can be identified. We allow this because by going through `Self` the developer
170+
acknowledges that the facet type is incremental and not the complete constraint
171+
`N`.

0 commit comments

Comments
 (0)