mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-09-24 19:40:10 +01:00
Ensure where requirements in named constraints are visible to lookups (#7299)
Require rewrite and same-type constraints that do not depend on `.Self` to be satisfied when a facet type is identified, since those constraints may not be found later.
This commit is contained in:
@@ -29,6 +29,8 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
|
||||
- [Facet types](#facet-types)
|
||||
- [Identified facet types](#identified-facet-types)
|
||||
- [Named constraints](#named-constraints)
|
||||
- [Rewrites and same-type constraints in a named constraint](#rewrites-and-same-type-constraints-in-a-named-constraint)
|
||||
- [Constraints that don't depend on `.Self`](#constraints-that-dont-depend-on-self)
|
||||
- [Subtyping between facet types](#subtyping-between-facet-types)
|
||||
- [Combining interfaces by anding facet types](#combining-interfaces-by-anding-facet-types)
|
||||
- [Interface requiring other interfaces](#interface-requiring-other-interfaces)
|
||||
@@ -1110,6 +1112,75 @@ class ImplementsS {
|
||||
}
|
||||
```
|
||||
|
||||
### Rewrites and same-type constraints in a named constraint
|
||||
|
||||
A `require` statement may include rewrite or same-type constraints. In the case
|
||||
of `extend require`, the rewrites are
|
||||
[preserved as such](appendix-rewrite-constraints.md#combining-constraints-with-extend).
|
||||
But otherwise, any rewrite constraint in the
|
||||
[identified facet type](#identified-facet-types) of the `require` is
|
||||
[treated as a same-type constraint](appendix-rewrite-constraints.md#combining-constraints-with-require-and-impls)
|
||||
instead.
|
||||
|
||||
### Constraints that don't depend on `.Self`
|
||||
|
||||
> **TODO:** Link to section explaining when identifying a facet type happens when
|
||||
> [#5168: Forward `impl` declaration of an incomplete interface](/proposals/p005168-forward-impl-declaration-of-an-incomplete-interface.md)
|
||||
> is applied to these docs.
|
||||
|
||||
When identifying a facet type, we collect all constraints found in the facet
|
||||
type and named constraints. Each constraint must depend on `.Self` in some way
|
||||
in order to be found in future impl lookups involving the facet being
|
||||
constrained. Thus, if there is no dependency on `.Self` in a constraint, it must
|
||||
be satisfied immediately for the identify to complete successfully.
|
||||
|
||||
```carbon
|
||||
constraint N(T: type) {
|
||||
require impls Z where .Z1 = {};
|
||||
}
|
||||
```
|
||||
|
||||
When the above named constraint is identified as part of a facet type as
|
||||
`C impls N(.Self)`, the resulting requirement `Z where .Z1 = {}` is only
|
||||
constraining `C`, and not `.Self` from the top-level top-level facet type. So we
|
||||
require that `C impls (Z where .Z1 = {})` is already true in order to successfully
|
||||
identify.
|
||||
|
||||
```carbon
|
||||
interface Z(V: type) {
|
||||
let Z1: type;
|
||||
let Z2: type;
|
||||
}
|
||||
|
||||
constraint M(T2: type, U2: type) {
|
||||
extend require impls Z(U2) where .Z1 = {} and .Z2 == ();
|
||||
}
|
||||
|
||||
interface Y {
|
||||
fn YY();
|
||||
}
|
||||
|
||||
class C;
|
||||
|
||||
fn F(U: Y where C impls Z(.Self) where .Z1 = {} and .Z2 == (),
|
||||
T: Y where C impls M(.Self, U)) {
|
||||
// Member access into `T` causes its type to be identified, which succeeds.
|
||||
// The identified facet type requires
|
||||
// `C impls Z(U) where .Z1 = {} and .Z2 == ()` which is true from the facet
|
||||
// type of `U`.
|
||||
T.YY();
|
||||
}
|
||||
|
||||
fn G(U: Y where C impls Z(.Self),
|
||||
T: Y where C impls M(.Self, U));
|
||||
// ❌ Error: The type of `T` can not be identified.
|
||||
// Member access into `T` causes its type to be identified, which fails.
|
||||
// The identified facet type requires
|
||||
// `C impls Z(U) where .Z1 = {} and .Z2 == ()` which we don't know to be
|
||||
// true here.
|
||||
T.YY();
|
||||
```
|
||||
|
||||
### Subtyping between facet types
|
||||
|
||||
There is a subtyping relationship between facet types that allows calls of one
|
||||
|
||||
Reference in New Issue
Block a user