mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-10-06 08:54:47 +01:00
Replace .Self in facet types (#7097)
This allows `T impls X` constraints to function, since they must contain some reference to `.Self` in order to be valid. This should be sufficient to support the interfaces we need for for loops over C++ range-for-compatible types. We replace `.Self` in the following places: - In a require decl, as we have a specific self facet to replace it with from the declaration, either a user-specified facet or the symbolic `Self`. - When identifying a facet type, as we have a specific self that we are identifying the facet type with. That self gets used for all `.Self` references. - Implicit `.Self` references on the RHS of an `impls` constraint when building a facet type. The `.Self` references there no longer refer to the top level self facet, so replace them with the facet that we now know they refer to, which is found on the LHS of the `where` before the `impls`. - Rewrite constraints in impl lookup when validating them and comparing them with constants from witnesses, which come from identifying a facet type. - Rewrite constraints in ImplWitnessAccess eval when comparing them with constants from witnesses, which come from identifying a facet type. Substitution is done through `SubstPeriodSelf`. It handles replacing `.Self` and `.Self as type`, for a replacement facet that is either of type FacetType or TypeType. Eval currently diagnoses some ambiguous `.Self` references when doing substitution of `.Self` but this is the incorrect place to do it, so there are TODOs about moving this to name lookup. To support these diagnostics there's some additional complexity in `SubstPeriodSelf` that can go away once the TODOs are addressed, such as asking the caller if they want to replace each `.Self`, in order for it to report a diagnostic. There are a number of follow-up work items here: - Some TODO tests. - Remove `SymbolicBindingType` since its intention was to support `.Self` but we don't need it with this approach. - Replace `.Self` in rewrite constraints of require decls. - Replace `.Self` in rewrite constraints of impl as when constructing the witness table. - Reject explicit `.Self` in name lookup when it would be ambiguous. - Officially disallow `.Self.A = B` in rewrite constraints in the design docs, so that we don't have the case where `.A` is allowed but `.Self.A` is not due to ambiguity.
This commit is contained in:
+2
-2
@@ -449,7 +449,7 @@ fn F() {
|
||||
// CHECK:STDOUT: %C.521: type = class_type @C, @C(%OuterParam) [symbolic]
|
||||
// CHECK:STDOUT: %Y.impl_witness.26b: <witness> = impl_witness @C.as.Y.impl.%Y.impl_witness_table, @C.as.Y.impl(%OuterParam) [symbolic]
|
||||
// CHECK:STDOUT: %require_complete.4a2: <witness> = require_complete_type %Y_where.type.b0f [symbolic]
|
||||
// CHECK:STDOUT: %Y.facet: %Y.type.6ae = facet_value %C.521, (%Y.impl_witness.26b) [symbolic]
|
||||
// CHECK:STDOUT: %Y.facet.892: %Y.type.6ae = facet_value %C.521, (%Y.impl_witness.26b) [symbolic]
|
||||
// CHECK:STDOUT: %empty_struct_type: type = struct_type {} [concrete]
|
||||
// CHECK:STDOUT: %complete_type.357: <witness> = complete_type_witness %empty_struct_type [concrete]
|
||||
// CHECK:STDOUT: %Z1.impl_witness: <witness> = impl_witness @empty_tuple.type.as.Z1.impl.%Z1.impl_witness_table [concrete]
|
||||
@@ -829,7 +829,7 @@ fn F() {
|
||||
// CHECK:STDOUT: %Y.impl_witness.loc14_29.2 => constants.%Y.impl_witness.26b
|
||||
// CHECK:STDOUT: }
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: specific @Y.WithSelf(constants.%OuterParam, constants.%Y.facet) {
|
||||
// CHECK:STDOUT: specific @Y.WithSelf(constants.%OuterParam, constants.%Y.facet.892) {
|
||||
// CHECK:STDOUT: !definition:
|
||||
// CHECK:STDOUT: %OuterParam => constants.%OuterParam
|
||||
// CHECK:STDOUT: %Y.assoc_type => constants.%Y.assoc_type.aab
|
||||
|
||||
Reference in New Issue
Block a user