The CompleteFacetType value store is now a RelationalValueStore. This
type of store uses some _other_ id as the key for insertion. It allows
checking if values of the _other_ id are present in the store, since
those ids are handed out by another store and will (necessarily) exist
before there is a matching value in the RelationalValueStore.
The lookup for precense of the _other_ id returns the id of a value in
the RelationalValueStore. That id can be used to get the value out of
the store.
For our use case, the RelationalValueStore maps from FacetTypeId to
CompleteFacetTypeId. So you add a CompleteFacetType to the store with a
FacetTypeId. Then you can query with a FacetTypeId to see if there
exists a CompleteFacetTypeId. And if there is, you can use that
CompleteFacetTypeId thereafter to get the CompleteFacetType value from
the store.
This removes the need for ValueStore::GetMutable() and removes the
method. FacetTypeInfo no longer has a field that needs to be carefully
excluded from hash and comparison.
* Add `RequireCompleteFacetType` and `ResolveFacetTypeImplWitness` to
`check::Context`. Goal was to move code from `impl.cpp` (mostly) without
functional changes.
* Complete type information is cached with the facet type, and is stored
in a `complete_facet_types()` table.
* Main functional change is to diagnose attempts to use a rewrite
constraint on an associated function. Some existing diagnostics have
been updated.
* Remove `check::Context::RequireDefinedType`:
* For class types, use `RequireCompleteType`
* For facet types, use `RequireCompleteFacetType`
* Introduce a `SemIR::SpecificInterface` to hold an interface and
specific id pair.
* Keep the specific interface ids in the impl object.
* Avoid some extra copies in `Dump` functions.
* Future work missing from this PR:
* Resolving for member access or actions that require impl lookup.
* Resolving rewrites constraints that refer to non-concrete values.
* Any support for adding implied constraints that result from a `where`
clause (though TODOs have been added).
---------
Co-authored-by: Josh L <josh11b@users.noreply.github.com>
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Co-authored-by: Dana Jansens <danakj@orodu.net>
Symbolic constants are negative values (starting at -3 at the moment)
but instead of having to figure the correct integer value for
MakeConstantId, provide a function to make a symbolic constant directly.
High level, replacing `Id::Invalid` with `Id::None` and `Id::is_valid`
with `Id::has_value` for clarity, as discussed
[here](https://discord.com/channels/655572317891461132/655578254970716160/1331664574545395794).
The `IntId` refactoring is needed together with `AnyIdBase` because it's
also used with `ValueStore`.
Note, trying to be careful not to rewrite `EnumBase::InvalidIndex`, or
`is_valid` in general (e.g., `IdKind::is_valid`).
I've tried to sequence commits here:
1. Automatic replacements:
- `((?:Id|Index)(?: |::|\(|Base(?:\(|::)))Invalid((?:Index)?\W)` ->
`$1None$2`
- `<invalid>` -> `<none>`
- `InvalidNodeId` -> `NoneNodeId`
- `/\*invalid\*/` -> `/*none*/`
- `id((?:_|\(\))(?:\.|->))is_valid` -> `id$1has_value`
2. Manual edits:
- In `int.h` and `int_test.cpp`
- `IntT` has `is_value`, which I'm renaming to `is_embedded_value`.
- Manual edits to comments in this file.
- `AnyIdBase` and `IdBase`
- Declaration of `is_valid` -> `has_value`, `InvalidIndex` ->
`NoneIndex`.
- In `ids.h` and `ids.cpp`
- `is_valid` -> `has_value`
- `// An explicitly invalid ID.` -> `// An ID with no value.`; similar
for index
- Various math on `InvalidIndex` -> `NoneIndex`
- Various mentions of "valid" in comments
- In `value_store.h`, for `IdT::Invalid`, plus one comment
- In `impl.h` and `tokenized_buffer.h`, we had different initialization
of `::None` values (versus `ids.h` syntax) that I fixed manually.
- Spot checks to compile
- Particularly where `is_valid` replacements didn't catch spots due to
different naming.
3. Autoupdate tests
4. verbose.carbon (NOAUTOUPDATE)
5. Comment spot checks
Note there are probably other mentions of "Invalid" that should be swept
up, but I'd like to argue for merging and separating out remaining
cleanup since this is so sweeping (and likely to hit merge conflicts
from churn). We'll probably have lingering mentions of "invalid" for a
bit regardless, just because there are uses of "invalid" in non-Id APIs.
In practice, I am unable to call constructors like `SemIR::InstId` from
a debugger. I first tried to use
https://clang.llvm.org/docs/AttributeReference.html#noinline to make
some non-inline calls to the constructor, but that didn't work:
```
toolchain/sem_ir/dump.cpp:245:23: error: 'noinline' attribute is ignored because there exists no call expression inside the statement [-Werror,-Wignored-attributes]
245 | [[clang::noinline]] return InstId(inst);
|
```
Co-authored-by: Josh L <josh11b@users.noreply.github.com>
Follow-on to #4669 . Did some manual testing, but may have not exercised
all code paths.
---------
Co-authored-by: Josh L <josh11b@users.noreply.github.com>