Facet types support rewrite (where .A =...) constraints (#4613)

* Rewrite constraints are stored in a facet type, substituted, imported,
and formatted.
* We now distinguish `.Self` from other symbolic bindings in two ways:
* `.Self` itself now has an invalid compile time binding index (since it
doesn't bind to any of the generic parameters). As a result, we no
longer need to create a generic region in `handle_where.cpp`.
* There is a new phase tracking values that are only symbolic because
they transitively depend on `.Self`. This allows us to give the result
of a `where` expression template phase as long as it doesn't use any
symbolic constants other than `.Self` or other designators.
* `AddConstant` has been removed from `check/context` since it was only
used from `eval`. This meant less plumbing of the phase change.
* Evaluation of `BindSymbolicName` now also performs substitution into
its type.
* Include a bit more information in some diagnostics.
* `StringifyTypeExpr` outputs rewrites, which required adding support
for associated entities as well.
  * Associated entities now have an entity name set when importing.
* Adds tests for some interesting cases with rewrites and uses of
`.Self` mixed with other symbolic constants.

Still to do:
* There is no validation that any particular type satisfies rewrite
constraints.
  * Access to members of a facet type do not see the rewritten values.
* Impls don't recognize whether associated constants have rewrites
setting their values.
  * No support for resolving facet types.

---------

Co-authored-by: Josh L <josh11b@users.noreply.github.com>
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
This commit is contained in:
josh11b
2024-12-03 22:44:39 +00:00
committed by GitHub
co-authored by Josh L Richard Smith
parent dc5edb88fb
commit 33110d096c
44 changed files with 3113 additions and 1446 deletions
+7 -3
View File
@@ -81,7 +81,7 @@ class RebuildGenericConstantInEvalBlockCallbacks final
context_.insts().Get(inst_id));
return true;
}
if (!const_id.is_symbolic()) {
if (!context_.constant_values().DependsOnGenericParameter(const_id)) {
// This instruction doesn't have a symbolic constant value, so can't
// contain any bindings that need to be substituted.
return true;
@@ -104,8 +104,12 @@ class RebuildGenericConstantInEvalBlockCallbacks final
// block.
if (auto binding =
context_.insts().TryGetAs<SemIR::BindSymbolicName>(inst_id)) {
inst_id = Rebuild(inst_id, *binding);
return true;
if (context_.entity_names()
.Get(binding->entity_name_id)
.bind_index.is_valid()) {
inst_id = Rebuild(inst_id, *binding);
return true;
}
}
if (auto pattern =