@@ -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
2728This proposal updates the criteria for when a facet type is considered
2829"identified." Specifically, it relaxes the requirement for named constraints,
2930allowing 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
3638Under 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
4042This definition creates a circularity problem during the definition of a named
4143constraint. 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
98110compiler 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
105117constraint W {
@@ -112,13 +124,14 @@ This says that `C` must implement `W`, yet `W` is not fully defined. At that
112124line ` W ` is still empty, so it places no requirements on ` C ` . The next line
113125requires 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