Commit Graph
1822 Commits
Author SHA1 Message Date
Jon Ross-Perkins 55da026a46 Remove the SemIRLoc typedef (#5299)
Replace SemIRLoc typedef uses with explicitly SemIR::LocId, loc ->
loc_id for consistency.
2025-04-14 14:28:15 +00:00
Jon Ross-Perkins 9759387a13 Collapse GetAbsoluteNodeId overload (#5298)
Since LocId can handle a NodeId, this overload isn't really needed
anymore. Probably helpful to simplify.
2025-04-12 00:30:19 +00:00
Dana Jansens f0663715dd Even more usage of TypeInstId (#5296)
Use TypeInstId in many more places where the instruction is required
to/known to always be a type value. This should be a somewhat exhaustive
set of places, as it covers all instructions given to
GetTypeIdFromTypeInstId().

The things of interest here are:

- Singleton instructions are always of type TypeType, so they are now
TypeInstIds.
- ErrorInst::SingletonInstId gets upcast to be an InstId because it's
sometimes used to define the type of a variable (as in `auto inst_id =
SemIR::ErrorInst::SingletonInstId;` that may hold other InstIds.
- Parse nodes don't really know about TypeInstId, so NodeStack::Push
needs to do some special casing to avoid CHECK failures when given a
TypeInstId but expecting an InstId. We leave a TODO behind here because
the nodes which are being pushed a TypeInstId should probably be taught
to expect that, but such a change is a bit tricky, so too much for this
PR.
2025-04-11 21:47:43 +00:00
Dana JansensandRichard Smith 0e8d354567 Split the witness table into a separate ImplWitnessTable instruction (#5272)
This allows us to import the table for a given impl only once, while we
can import many ImplWitness instructions with different specifics for a
generic impl.

For example in convert_facet_value_to_narrowed_facet_type.carbon we see
that a single witness table is imported for the BitAnd interface, with
multiple witnesses (for different specifics) imported and sharing the
same table.

The ImplWitnessTable now contains a back-link to the Impl the witness is
for, allowing inst namer to name that interface in the textual semir,
and allowing the interface to be found when debugging from a witness.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2025-04-11 20:30:04 +00:00
Dana Jansens c34a8d0a3a Convert remaining type-value InstId fields to TypeInstId (#5294)
After #5280 there are a few more typed instructions that have an `InstId
type_inst_id` that always holds a type value. These are converted to
`TypeInstId` to encode this fact in the type system. The
`ConvertAggregateElement()` function in convert.cpp is now able to
receive `TypeInstId` for a couple arguments as well.

Additionally, the `type_inst_id` field of `StructTypeField` is made into
a `TypeInstId`.

The `TupleType::elements_id` is renamed to `TupleType::type_elements_id`
to try record the fact that it's an InstBlock of type value
instructions. We don't introduce a TypeInstBlockId at this time, but it
might be nice to make blocks of TypeInstIds in the future.

To assist in working with a block of InstId that are type values, two
additional helpers are added to the TypeStore:
- GetBlockAsTypeInstIds which turns an `ArrayRef<InstId>` into a range
of `TypeInstId`
- GetBlockAsTypeIds which turns an `ArrayRef<InstId>` into a range of
`TypeId`

We use these helpers in places that iterate over the
`TupleType::type_elements_id`.
2025-04-11 20:11:03 +00:00
Jon Ross-Perkins 8c3fa80691 Add cc rule wrappers for cc_env (#5277)
Rules executed by bazel don't necessarily have the right environment to
find the symbolizer, which was the intent of `cc_env` setting
`LLVM_SYMBOLIZER_PATH`. So far, this has kind of been a case-by-case
fix, but every so often I'm trying to debug a crash in a test that
doesn't provide it. Rather continuing down this route, instead add
drop-in wrappers for cc rules so that it's hard to forget.

Note `bazel/cc_rules` is intended to mirror `bazel/carbon_rules` and
`bazel/cc_toolchains`, rather than `@rules_cc`.

AFAICT there isn't a great way to add this as a default for the `bazel
run` environment. It's not typically going to be set on its own,
forwarding `$PATH` would be too broad, and the [action
`env_sets`](https://bazel.build/docs/cc-toolchain-config-reference#using-action-config)
I think are not quite what we need (I think those don't include output
execution, only compilation).
2025-04-11 19:58:54 +00:00
Jon Ross-Perkins fe29224016 Refactor LocId to merge in SemIRLoc (#5284)
The main goal of this is to collapse the LocId and SemIRLoc types into a
single type, eliminating the need for APIs to decide which to use. This
originated from discussion about UnwrapSemIRLoc in #5169. Although that
was removed in #5202, it's probably still a good direction for LocId.

This changes the packing of LocId to allow adding InstId, making it
tri-modal: ImportIRInstId, InstId, or NodeId. This has a side-effect of
reducing the available space for ImportIRInstId, although not by much
due to the pre-existing `ImplicitBit` behavior. If needed, we could also
probably play with packing a bit more since `ImplicitBit` really only
applies to `NodeId`, but I was trying to keep the logic a little
simpler. Note `TokenOnlyBit` can still apply to `ImportIRInstId`.

This leaves in place a typedef for SemIRLoc -- I intend to clean that up
separately.

Some Discord discussion is
[here](https://discord.com/channels/655572317891461132/655578254970716160/1353755830058745959).
2025-04-11 13:35:58 +00:00
Jon Ross-PerkinsandRichard Smith 422df75a92 Switch tree-sitter from explorer to toolchain testdata (#5292)
Noticed as part of #5290; `srcs` is needed to make `$(locations)` work.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2025-04-10 23:45:19 +00:00
Dana JansensandRichard Smith cf57c85545 Introduce TypeInstId (#5288)
TypeInstId is an InstId whose constant value has a type of TypeType.
This includes:
- Type value instructions, the `ClassType` or `IntLiteralType`
instructions.
- Constraint value instructions, which are the `FacetType` and
`TypeType` instructions, each of which also have type TypeType.

TypeInstId encodes in the type system that it is safe to convert the
instruction's value to a TypeId, and CHECKs at construction that this
invariant is maintained.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2025-04-10 22:59:02 +00:00
Richard Smith a74ca9071b Remove all remaining uses of TypeIds as instruction operands. (#5280)
In preparation for shifting from `TypeId`s potentially representing
attached types to always representing unattached types, using
[terminology suggested on
Discord](https://discord.com/channels/655572317891461132/963846118964350976/1359286326779973712).
This change causes us to track slightly more type spelling information
through SemIR.

One change that has significant impact on the SemIR output is that we
now build a `struct_type` instruction in each class representing the
types of the fields, including the spelling used for those types. This
is now no longer always identical to the corresponding canonical
`struct_type` for the object representation, so it's built separately
and owned by the class.

Also remove `TypeBlock` support entirely, as its only use was
representing `TupleType`s, which now use an `InstBlock`.
2025-04-10 20:53:42 +00:00
Dana Jansens 1445ec9e4f Remove toolchain/check/testdata/impl/fail_impl_as_scope.carbon (#5289)
The same things are tested in
toolchain/check/testdata/impl/no_prelude/fail_impl_as_scope.carbon,
along with more cases.
2025-04-10 20:06:49 +00:00
Richard Smith 47fa1b5991 Rename StringifyType to reflect that it can stringify non-type constants. (#5285)
Use it to stringify associated constant values in diagnostics. In
passing, add missing support for stringifying bool literals. Note that
there are some cases that it doesn't stringify properly, but that's not
new here; such cases could already be observed when stringifying generic
arguments.
2025-04-10 19:15:27 +00:00
Dana Jansens aec90e3ae1 Rename rewrite_value to rewrite_inst_id to clarify what it's holding (#5286)
Also add a note about the RewriteConstraint insts being canonical
2025-04-10 16:42:24 +00:00
Dana JansensandRichard Smith 76c68153a2 Look for final impl when accessing associated constant in facet (#5269)
While facets may come with a rewrite for an associated constant, they
are symbolic. A final impl has the ability to provide a concrete value
instead, which allows generic code to use the concrete value in place of
the associated constant's (fully qualified) name.

For instance, instead of `I.Type`, the concrete type `()` can be used if
there is an `impl final [T:! type] T as I where .Type = ()` impl.

This does not yet cache the result of the lookups.

Depends on https://github.com/carbon-language/carbon-lang/pull/5255

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2025-04-10 13:48:49 +00:00
Boaz Brickner 68111a994c C++ Interop: Basic C++ record (class/struct/union) import support (#5156)
Focus: Calling static C++ function defined in C++ classes.

Limitations:
* Ignores visibility (public / protected / private).
* No support for: dynamic classes, member methods, data members,
declarations without definitions, importing inheritance.

Based on #5142.

C++ Interop Demo with a class:

```c++
// hello_world.h

namespace some_namespace {

class MyClass {
 public:
  static void hello_world();
};

}  // namespace some_namespace
```

```c++
// hello_world.cpp

#include "hello_world.h"

#include <cstdio>

namespace some_namespace {

void MyClass::hello_world() { printf("Hello World!\n"); }

}  // namespace some_namespace
```

```carbon
// main.carbon

library "Main";

import Cpp library "hello_world.h";

fn Run() -> i32 {
  Cpp.some_namespace.MyClass.hello_world();
  return 0;
}
```

```shell
$ clang -c hello_world.cpp
$ bazel-bin/toolchain/carbon compile main.carbon
$ bazel-bin/toolchain/carbon link hello_world.o main.o --output=demo
$ ./demo
Hello World!
```

Part of #5150.
2025-04-10 08:15:12 +00:00
Richard Smith a91752de60 Represent rewrite constraints in FacetTypeInfo with InstId not ConstantId. (#5281)
This follows the pattern used elsewhere, and allows facet types in eval
blocks to directly reference their operands instead of doing so
indirectly via a `ConstantId` attached to the generic. This prepares us
for making `ConstantId`s always be unattached.

In passing, add a stringified version of the `InstId` to diagnostics in
a couple of places where it seems useful.
2025-04-10 03:56:12 +00:00
Dana Jansens c15dea4fa2 Stop erasing ImplWitnessAssociatedConstant instructions from the witness table (#5283)
Unintentionally, we were adding ImplWitnessAssociatedConstant to the
witness table and then immediately evaluting and replacing it with its
constant value instruction, which is incorrect. The point of the
instruction is to be a symbolic value in the witness table that is a
dependent of the generic impl declaration being built.
2025-04-09 23:03:45 +00:00
Richard Smith 6322c7734e Don't define an unscoped enumeration out of line. (#5282)
The C++ language semantics for doing so are weird and a bit broken.
Under
[CWG1485](https://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1485)
this code may become invalid in the future.
2025-04-09 22:41:31 +00:00
Jon Ross-Perkins a527626d87 Add tests and range enforcement for current LocId use-cases (#5274)
This is trying to document the status quo. Note
https://github.com/carbon-language/carbon-lang/pull/4497 placed
restrictions on a bit, and this is in part flowing back to restrictions
on both NodeId and ImportIRInstId limits.
2025-04-09 17:41:37 +00:00
Alina Sbirlea 7da972b773 Create a single global for the PrintInt format string. (#5275)
Create a single global for the PrintInt format string. Cleaner tests.
2025-04-09 16:47:32 +00:00
Alina Sbirlea 694a329bdd Reuse LLVM global constants. (#5273)
Reuse LLVM global constants: do not generate a new llvm::Global constant
for a pointer to a global constant for the same Carbon const_inst_id,
reuse already generated one.
2025-04-09 16:36:42 +00:00
Ivana Ivanovska 7580df8b8a [Carbon/C++ interop] Add support for int function params (#5197)
Added support for `int` function parameters. Currently only
pass-by-value is supported.

```c++
// hello_int.h;

auto foo_int(int a, int b) -> int;
```

```c++
// hello_int.cpp

#include "hello_int.h"
#include <cstdio>

auto foo_int(int a, int b) -> int {
    printf("a = %i \n", a);
    printf("b = %i \n", b);
    return a + b;
}
```
```c++
// main.carbon

library "Main";

import Cpp library "hello_int.h";
import Core library "io";

fn Carbon_foo(b: i32) {
  Core.Print(b);
}

fn Run() -> i32 {
  Carbon_foo(Cpp.foo_int(2, 8));
  return 0;
}
```

```
$ clang -c hello_int.cpp
$ bazel-bin/toolchain/carbon compile main.carbon
$ bazel-bin/toolchain/carbon link hello_int.o main.o --output=demo
$ ./demo
a = 2 
b = 8 
10
```

Part of  #5064
2025-04-09 11:38:39 +00:00
Richard Smith 1a4d6ca255 Store an InstId instead of a TypeId in UnboundElementType. (#5260)
This gives a slightly simpler representation for `UnboundElementType`s
in eval blocks, and in principle allows us to preserve the spelling of a
field's type into the `UnboundElementType` and thereby into a field
reference, although as of right now this doesn't affect our diagnostic
output in any way.

During error recovery for a field with a non-concrete type, preserve the
type in the `UnboundElementType` regardless. It's not really problematic
to have a non-concrete type there, and this makes it easier to track the
instruction used to specify the type.

This is a step towards switching symbolic types to always be abstract
during type checking.
2025-04-08 22:21:44 +00:00
Richard Smith bfef32b482 Add an EvalOrAddInst function. (#5258)
Use that instead of `AddInstInNoBlock` to get the value of an
instruction when evaluation might depend on the `InstId` but only the
`ConstantId` of the instruction is desired by the consumer.
2025-04-08 21:04:30 +00:00
Dana Jansens d07f70cfb3 Add insts for witness table entries that are unset or associated constants (#5255)
Instead of using None, use an explicit ImplWitnessTablePlaceholder in
the witness table for entries that have not yet been populated, to aid
debugging. This would ensure they would show up very clearly in the
SemIR. This uncovered some `<invalid>` in the SemIR under erroneous
conditions that have now been turned into `<error>`.

Add the ImplWitnessAssociatedConstant instruction which wraps the
canonical instruction found from the constant value of the rewrite
constraint. This ensures that we have an instruction inside the eval
block for a generic impl declaration for each rewrite constraint's
value, which allows Subst to be performed to rewrite the symbolic
constant of the ImplWitnessAssociatedConstant instruction to associate
it with the generic. This will prevent the otherwise orphaned symbolic
constant of the rewrite's value from being used which can not have a
specific applied to them.

While applying the new insts in InitialFacetTypeImplWitness(), rearrange
the function to use less nesting. And avoid using entity names from
imported instructions (as we found is not effective in deduce.cpp) and
use a local instruction by going through the constant value.

This PR is part of the effort to allow a rewrite to name a generic
parameter, such as `impl forall [T:! type] T as Z where .X = T`, however
tests for this involve a final impl so that we can typecheck that the .X
value is a specific T, so the tests will come with that work. This piece
is split off because introducing new instructions causes a lot of SemIR
churn, and I wanted to get that done separately.
2025-04-08 19:10:49 +00:00
Geoff RomerandDana Jansens cda97cb292 Include all symbolic parts in structure comparison (#5247)
Co-authored-by: Dana Jansens <danakj@orodu.net>
2025-04-08 19:02:55 +00:00
Alina Sbirlea 3ccb0b82f8 Add/update lowering tests. (#5254)
Add lowering tests for future redesign.
2025-04-08 17:26:16 +00:00
Boaz Brickner afa29d5e66 Fix clang-tidy: use a ranges version of this algorithm [modernize-use-ranges,-warnings-as-errors] (#5268) 2025-04-08 15:37:52 +00:00
Richard Smith 0631e18184 Provide an InstId when evaluating a constant in cases where one is needed (#5202)
For each kind of instruction, specify whether its constant evaluation
needs an `InstId` or not. If it does, ensure that all constant
evaluation of that instruction provides one. Otherwise, allow calling
into the evaluator without providing an `InstId`.

This allows us to reliably use the `InstId` in evaluation steps that
either need a location or need to look at the original operands of the
instruction prior to evaluation, and also to support `TryEvalInst` calls
safely for instructions whose evaluation does not need an `InstId`.
2025-04-08 00:40:21 +00:00
Jon Ross-Perkins 1ffd56ac3e Use Get*Type in a couple spots (#5257)
These seemed like spots that didn't need to call `TryEvalInst` directly.
I'm relying on tests for coverage. :)
2025-04-07 22:41:27 +00:00
4af0c8f8d1 Implement ...where .Self impls... (#5238)
* Also remove facet type deduction, since we decided against it on
[2025-04-02](https://docs.google.com/document/d/1Iut5f2TQBrtBNIduF4vJYOKfw7MbS8xH_J01_Q4e6Rk/edit?pli=1&resourcekey=0-mc_vh5UzrzXfU4kO-3tOjA&tab=t.0#heading=h.95phmuvxog9n).

---------

Co-authored-by: Josh L <josh11b@users.noreply.github.com>
Co-authored-by: Dana Jansens <danakj@orodu.net>
2025-04-07 20:45:45 +00:00
Geoff Romer 87f0e9723f Rename StateStackEntry to State (#5256)
Also clean up `State` -> `StateKind` in the toolchain docs, which was
missed in #5249.
2025-04-07 18:58:41 +00:00
Richard Smith a45dc42d82 Store an InterfaceId and a SpecificId in AssociatedEntityType. (#5252)
Instead of storing a `TypeId` that always refer to a facet type that
always contains exactly a single interface, store the interface
directly.

Also improve stringification of `LookupImplWitness` and witness access
into it, switching to using newly-added functionality for stringifying
specific interfaces.
2025-04-05 16:08:09 +00:00
David Blaikie 8e7bb2f953 Initialize vptrs to point to vtables (#5244)
Adds a mapping to keep track of vtable LLVM IR decls/defs for use.
Adds the vtable_id to the vtable_ptr initialize instruction for lookup.
Adds emission of vtable declarations for use outside the file that
defines the vtable. (this isn't done lazily, it's done for any imported
class - it could be done lazily & maybe eventually has to be lazy to
handle generics)
2025-04-05 06:11:34 +00:00
Geoff Romer 8c113c1241 Rename Parse::State to Parse::StateKind (#5249)
Also renames variables of that type to match. A follow-up PR will rename
`Parse::StateStackEntry` to `Parse::State`. This is more consistent with
the naming of similar enums elsewhere in the toolchain, and with the
prevailing practice of using `state` rather than e.g. `entry` as the
name of a `StateStackEntry`.

See also discussion
[here](https://discord.com/channels/655572317891461132/963846118964350976/1326280585592700990)
2025-04-05 04:25:00 +00:00
Boaz Brickner 61c705311f Remove unused variable diagnostics_stream (#5239) 2025-04-04 00:33:14 +00:00
Geoff RomerandJosh L 38ce7e3011 Handle EntityNameId::None during evaluation. (#5237)
Fixes a crash bug found by the fuzzer

---------

Co-authored-by: Josh L <josh11b@users.noreply.github.com>
2025-04-04 00:32:36 +00:00
Dana Jansens 6eddf72979 Avoid crashing during associated constant lookup on a runtime facet value (#5243)
Perhaps we will disallow member lookup on and conversion of runtime
facet values. For now, leave a TODO and produce a TODO diagnostic
instead of crashing.
    
Related to #5241.
2025-04-03 22:46:11 +00:00
Boaz Brickner cfdd5fbdb5 Simplify GetAbsoluteNodeIdImpl() by merging while (true) with the first if (#5240) 2025-04-03 22:44:34 +00:00
Richard SmithandDana Jansens bba32900c3 Preserve type sugar in ArrayType, ConstType, and PointerType. (#5235)
Each of these types takes another type as an operand. Instead of storing
that other type as a `TypeId`, store it as an `InstId` so that we can
track how it was written, not only its canonical form.

The canonical constant values of these types continue to store the
canonical constant values of their operands, as normal.

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
2025-04-03 21:14:03 +00:00
Dana Jansens 164310c6b8 Facet values (like type values) can be copied around at runtime (#5242)
Give them a value representation of copy, and allow conversions between
two facet values of the same type to work.

Convert was assuming that facet values are compile time constants, but
thye can also be runtime values. In that case, we have no support for
converting to a different facet value of a different facet type. But if
the types are equal then it's all fine.

In theory it seems that we should be able to convert if the target facet
type can be found through the source value's FacetType. But currently
that happens through impl lookup and it requires constant values. Adding
a test for this.

Related to #5241
2025-04-03 19:34:54 +00:00
Richard Smith c33adfafd3 Replace GetTypeInSpecific with GetTypeOfInstInSpecific. (#5232)
Reduce usage of `GetConstantInSpecific` to a single caller in constant
evaluation, with a TODO to remove that.

This gets us closer to being able to fully perform type-checking against
abstract types instead of types anchored within a particular generic.
2025-04-02 22:52:11 +00:00
Alina Sbirlea 077cf56a8a Emit function definitions in check, for all specifics seen. (#5090)
Emitting definitions in check. This resolves the crash in lowering which
necessitated definitions be emitted.
Some of the test changes need further review.
2025-04-02 21:51:25 +00:00
Richard Smith 6ee1006a61 Update stringifying of array types to match the new array syntax. (#5236) 2025-04-02 21:00:55 +00:00
Richard Smith 8b9f1a8966 Don't re-evaluate imported constants. (#5217)
Trust that import_ref produces constants that are already in their
evaluated form. We still do one pass over the operands to map them into
their canonical constant values. Even that is mostly unnecessary, but
there are a few instructions produced by importing that still need it
for now.
2025-04-02 18:26:36 +00:00
David Blaikie 8847178242 Emit (relative) vtables (#5231)
One of the remaining three steps for proof-of-concept virtual function
lowering (the other two being: initializing vptrs to point to these
tables, and using the vptr+table at call sites).

Introduces a (placeholder?) mangling of vtables as ".$vtable" at the end
of the mangling of the class name.

Uses a scheme similar to clang's relative vtables - though those are
relative to the vtable slot, and this is relative to the start of the
vtable (seemed simpler? though I haven't looked at it in detail, perhaps
in lowering call sites I'll find the relative-to-vtable-slot is nicer,
easy enough to change).
2025-04-02 17:59:08 +00:00
Boaz Brickner feb78e778d Change OutputMapping::Map::io_ from reference to pointer (#5227)
Per [the style
guide](https://github.com/carbon-language/carbon-lang/blob/trunk/docs/project/cpp_style_guide.md#syntax-and-formatting):
* If it is captured and must outlive the call expression itself, use a
pointer and document that it must not be null (unless it is also
optional).
* When storing an object's address as a non-owned member, prefer storing
a pointer.
2025-04-02 17:54:13 +00:00
e9c90af92e Reduce redundant diagnostics (#5234)
* "extending non-facet-type constraint" is already diagnosed by
`ImplAsNonFacetType`
* `impl` declarations with errors in the facet type no longer require
definitions

---------

Co-authored-by: Josh L <josh11b@users.noreply.github.com>
Co-authored-by: Dana Jansens <danakj@orodu.net>
2025-04-02 16:36:14 +00:00
bc439ad092 Forward impl declarations of incomplete facet types (#5219)
Implements some of the changes from proposal #5168.

* The data structure for complete facet types has been repurposed for
identified facet types. Identified facet types are now a concept in the
toolchain, but without named constraint support they are not
substantially different from incomplete facet types.
* Identified facet types keep the list of required specific interfaces
in sorted order, for efficiency improvements in impl lookup. Found
another way to identify the interface to impl (or number of impls if not
1).
* Forward `impl` declarations of identified but incomplete facet types
are allowed unless the facet type has rewrites. An incomplete facet type
with rewrites is already either an error or has more than one interface
and so can't be implemented, so this case can't be exercised very well
yet.
* Forward `impl` declarations of interface without rewrites use a
placeholder inst block for the witness.
* Changed some machinery to use RequireIdentifiedFacetType to access the
interfaces of the facet type so we only need to add support for
expanding named constraints into interfaces in one place.

---------

Co-authored-by: Josh L <josh11b@users.noreply.github.com>
Co-authored-by: Dana Jansens <danakj@orodu.net>
2025-04-02 01:46:27 +00:00
Richard Smith 265968b396 Make evaluation of symbolic bindings simpler and more uniform (#5215)
Factor out logic to evaluate `EntityNameId` instead of duplicating it
between `BindSymbolicName` and `SymbolicBindingPattern`. Remove support
in `SymbolicBindingPattern` for evaluating a pattern to the constant
value of the corresponding binding, which doesn't really make any sense
given that patterns don't generally evaluate to the value that they
matched.

This results in the handling for `SymbolicBindingPattern` being simply
the default handling for an always-constant instruction, so remove the
special case for it entirely and change its constant kind to `Always`.
It's not entirely clear that it makes sense for `SymbolicBindingPattern`
to be treated as a constant when other patterns aren't, but we seem to
be relying on this in various places, so leave it as a constant for now.
Changing it to never be constant will be a smaller change now -- it just
requires changing the `constant_kind`.

The IR changes in the tests are fairly widespread, but mechanical, and
there are two kinds of things changing:

- `symbolic_binding_pattern`s in specifics now evaluate to
`symbolic_binding_pattern`s, not to the argument values. This means in a
few cases we end up with additional `symbolic_binding_pattern`
constants.
- We evaluate the type operand of `symbolic_binding_pattern` now, so an
error in the type will now properly be propagated into an error in the
pattern's constant value.
2025-04-01 20:24:00 +00:00