Commit Graph
286 Commits
Author SHA1 Message Date
fdb188ccfd Implement unused pattern bindings, continued (#6518)
Implementation of unused pattern bindings #2022, continued.

Whereas previous PR #6460 took care of parsing, and PR #6479 prepared
the stage by using _ in some test cases, this PR has the the actual
implementation, using a simple dataflow analysis.

---------

Co-authored-by: Burak Emir <bqe@google.com>
Co-authored-by: jonmeow <jperkins@google.com>
2026-02-19 23:33:36 +00:00
Dana Jansens 917a6ea971 Add an interface-with-self generic to each interface and same for constraints (#6667)
Currently each interface has a `Self` facet internally that becomes a
binding to every entity inside the interface: associated constants,
functions, and require decls. Each of these has to be independently
generic as a result. This makes is challenging in extended name lookup
to move into an extended scope of an interface, as we have a specific
for the interface, but the names within require a different specific
that includes a `Self` facet value.

We generalize this relationship by adding a second generic to Interface,
called `generic_with_self`. When we want to work with entities inside
the interface, we move from the interface-without-specific to the
interface-with-self specific by adding a Self to the specific. This is
done independently of any particular entity inside the Interface, as
those entities are now all members of the interface-with-self generic.

Associated constants no longer need a generic of their own, as they do
not have separate generic bindings. Functions retain a generic, but if
the function has no generic arguments, it will have no bindings of its
own now.

Require decls retain a generic so that their specific can be
instantiated separately from the interface. Requiring the interface to
be complete does not require the types in a require decl to be complete
unless it is modified by `extend`. So we allow them to be completed
later by keeping them in a separate generic.

Named constraints look like interfaces and gain the additional inner
generic-with-self, with the same relationship to require decls.

This removes the need for name lookup to perform Substitution of a Self
facet into the extended scope instruction. Instead, the
`SpecificConstant` instruction inserted by a `require` decl is part of
the interface-with-self generic. When looking through a FacetType for
extended scopes, for each interface, we push the scope with the specific
for the interface-with-self. Then the constant value of the
`SpecificConstant` is correctly modified by the provided self
automatically through applying that specific.
2026-02-19 16:24:07 +00:00
Jon Ross-Perkins 320096da67 Rename import functions as Import instead of Make/Add (#6723)
This was motivated by `MakeFunctionDecl`, which has been added to
function.h as a helper function for making function declarations (an
unintentional naming collision).

I was wondering about renaming these functions to mark them as more
clearly import-specific, reducing the chance of name collisions like
this. Note the `Add` functions renamed here are typically updating an
imported declaration with a definition -- not sure whether `Make...Decl`
+ `Add...Definition` vs `Import...Decl` + `Import...Definition` is
actually losing anything though, since both seem to still require an
understanding of the two-stage import process.

Assisted-by: Google Antigravity with Gemini 3 Flash
2026-02-11 20:32:12 +00:00
Richard Smith 1b2ae912fc Add basic support for eval fn and musteval fn. (#6694)
Add support for compile-time functions. `eval fn` is analogous to C++
`constexpr`, and is evaluated at compile time when it has compile-time
arguments. `musteval fn` is analogous to C++ `consteval`, and requires
that its arguments be available at compile time and is always evaluated
at compile time. For now we require the modifier to match across
redeclarations of the function. The specific modifier syntax here is a
placeholder and not yet part of an approved design.

Limitations: Only very basic support for evaluation is provided. So far
there's no support for mutable state or `if` expressions, but otherwise
control flow and passing and returning values should work. Carbon
evaluation recursion is modeled by C++ recursion for now, so you can
overflow the toolchain stack easily. Functions that use in-place
initialization will generally not work yet, as they are modeled as
passing a non-compile-time-constant reference to a temporary to the
call.

Add missing categorization of `name_binding_decl` as `NotExpr` to match
other similar declaration instructions like `FunctionDecl`, so that we
can uniformly skip over them when they occur within function bodies.

Assisted-by: Gemini 3 Pro and Flash via Antigravity
2026-02-11 02:08:16 +00:00
Jon Ross-Perkins 2c6d9c7f66 Rename type's GetInstId to GetTypeInstId, reflecting returned type (#6708)
Discussed briefly [on
Discord](https://discord.com/channels/655572317891461132/655578254970716160/1470442830118912265),
done to reduce confusion.

Assisted-by: Google Antigravity with Gemini 3 Flash
2026-02-09 22:00:21 +00:00
Dana Jansens f64d084f27 Use the IdentifiedFacetType when mangling an ImplDecl (#6665)
The code was going through the raw `constraint_id` facet type, which
could be a named constraint. To get the interface being impl'd, use the
IdentifiedFacetType.

Import was adding an IdenfiedFacetTypeId for the facet type when
importing an ImplDecl, however it was using an attached self constant.
Then later lookups using `constant_values().GetConstantId(...)` from the
`self_id` would give an unattached constant and not find the
IdentifiedFacetTypeId. So have import do what we do when making an
ImplDecl locally, and use the unattached constant for the
RequireIdentifiedFacetType call.

We add a test of mangling an `impl as` for a named constraint, which
crashes before this change.
2026-01-29 18:02:53 +00:00
Dana Jansens 7f7186c227 Extended name lookup replaces inner Self (#6632)
When doing name lookup into an extended scope of an interface or named
constraint, the containing scope has an inner `Self` facet which can
appear in the specific of the extended scope. For instance a constraint
`N` which requires an interface `Z(Self)`:

```js
constraint N {
  extend require impls Z(Self);
}
```

When doing member lookup into a facet constrained by `N`, we need to
find the specific interface `Z(...)` where the `Self` is replaced by the
self-type the member lookup is happening on in order for impl lookup to
find a witness later.

Inside that specific interface we repeat the name lookup to find an
associated entity. Then to produce a witness we perform impl lookup
against the specific interface that name lookup returned with the
self-type of the member access. So if we do member access into `A:! N`
for a member `F`, like `A.F`, we would be doing impl lookup with a query
self of `A` and looking for the interface `Z(...)` returned from name
lookup.

When impl lookup has a facet as the query self, which we do here as `A`,
it takes its type (a facet type) and identifies it to find all the
required interfaces, and it substitutes the query self into those
specific interfaces for `Self`. If the `Z(...)` we acquired from name
lookup is `Z(Self)` it will fail the lookup for `A as Z(Self)`, since in
the facet type of `A` it finds a witness for `Z(A)` instead.

Thus, we replace the inner `Self` in extended scopes, such as `N`, with
the self-type of the member access, which produces the extended scope
`Z(A)` for this example. This allows the impl lookup for `A as Z(A)` to
find a witness from the facet type of `A`.

In order to do this, we include an instruction for the inner self when
registering the extended scope. Then, when we find the extended scope in
name lookup, we can use its CompileTimeBindIndex to replace any instance
of that `Self` facet with a new facet. If the self-type of member access
is a type, we construct a FacetValue with an empty facet type that
refers to the type.
2026-01-21 17:48:18 +00:00
Dana Jansens 4bb2935770 Look through extend require in an interface or named constraint in name lookup (#6630)
Add the required facet type as an extended scope of the containing
interface/named constraint, and teach name lookup to look for extended
scopes in named constraints.

This makes name lookup work properly when the facet type does not have a
specific that involves `Self`. Support for `Self` needs further work in
another PR.

Note that when an _interface_ requires another interface, this PR lets
us find the name, but we still fail to find a witness for the interface
named through `extend require`, and this is future work. For a named
constraint, things work correctly as the identified facet type chases
through the named constraint and includes the required interface, so
impl lookup is able to provide a witness.
2026-01-20 22:26:10 +00:00
Dana Jansens 32aa7cb1fa Make identifying a facet type an operation on a (self+facet type) pair (#6592)
Identifying a facet type takes both a self and facet type as a pair, and
then encode the self into the IdentifiedFacetType. This makes a
constraint that requires some _other_ type implements an interface
visible in the IdentifiedFacetType. And it will help to enable facet
types with `where T impls Z` for `T` that is not `.Self` in the future.

IdentifiedFacetTypes are now stored in a CanonicalValueStore instead of
a RelationalValueStore as they key is the combination of self and
(declared) facet type together now.

When the self-type is a facet value (has type FacetType) this is most
straightforward. But when it's a type we need to construct a FacetValue
to construct a specific for a require decl, to replace the generic
binding of the symbolic `Self`, which has type FacetType. To do so, we
make a FacetValue with an empty FacetType (equivalent to TypeType). This
prevents any looking for witnesses through the FacetType, which matches
what you can get from a type directly, requiring witnesses to come from
finding an `impl` decl.

Add additional InstNamer logic for such empty facet types so they print
as `<typename>.type.facet` if possible instead of as just `facet_value`.
2026-01-14 17:34:56 +00:00
Geoff Romer a2737a3189 Add Call param patterns to Function (#6586) 2026-01-13 19:30:15 +00:00
Geoff Romer 11d407b4a0 Add form to Function (#6561)
... and use the form to implement support for `ref` returns.
2026-01-08 18:55:53 +00:00
Dana Jansens 30562826b8 Add Inst::IsOneOf to check if an inst is one of a few kinds (#6523)
Adds Inst::IsOneOf which takes a variadic generic parameter pack of
kinds to check against. Also add forwarding functions to TypeStore and
InstStore. Convert uses of the regex `Is<.*\|\|` to IsOneOf.

This is based on #6522
2026-01-07 21:41:05 +00:00
Geoff Romer 505b1c86b9 Initial support for return forms (#6556)
The main changes here are:
- Introducing `InitForm` and `RefForm` to represent initializing and
reference forms (the two return forms currently supported by the
parser).
- Introducing the `FormType` singleton inst to represent their type
(i.e. `Core.Form`).
- Emitting an inst representing a function's declared return form as
part of handling the function signature.

The return form inst is currently ignored. Subsequent PRs will expose it
in `SemIR::Function` and use it to determine the form of call
expressions.
2026-01-07 00:54:18 +00:00
Jon Ross-Perkins c5eba90317 Change Destroy to use a CustomWitness instead of a blanket impl (#6512)
Pursuant to recent decisions on #6124, switch `Destroy` to use a
`CustomWitness` for its implementation. Right now this is manufacturing
no-op implementation functions on each lookup, which obviously isn't
ideal but is intended as a first pass. I'm mostly trying to find the
right balance between updating the approach to reflect new decisions,
while still breaking apart work in a way.

The `CoreInterface` logic is intended to build on `CoreIdentifier`
support. We have a number of additional interfaces that require
specialized logic, and that'll extend pretty far with C++ interop, so it
seemed easiest to have a generic function for it. That's what's
replacing the logic inside C++ interop that was doing string comparisons
(which could have already been moved to `CoreIdentifier`, I just missed
it in my first pass).

This adds `CustomWitness` support because the `Destroy` witnesses can be
imported cross-file. `CustomWitness` was previously only used for C++
types, which don't yet support import, which is why that wasn't
previously an issue. The addition of `query_specific_interface_id` is
similarly needed in order to get correct sorting of witness blocks when
imported.

This PR also removes builtin constraint logic (note this is in a
separate commit to help review; it's not a separate PR because it's
difficult to split apart without tests breaking). This had been made
generic with the expectation that destroy, copy, move, and conversions
would all need related support. Under the new decision, we are not going
to do blanket impls and will instead just manufacture a `CustomWitness`
for everything.

A lot of SemIR fingerprints change, but that's probably because the
addition of `Destroy` on core classes is yielding structural changes.
2025-12-19 18:36:06 +00:00
Geoff Romer bf45b1cbf5 Refactor function return type representation (#6463)
This separates the return type from the return pattern, and replaces the
return pattern with a block of return patterns. This is a step toward
support for `ref` returns (where there's no corresponding return
pattern) and compund-form returns (where there may be multiple return
patterns).
2025-12-10 18:34:23 +00:00
Jon Ross-Perkins 103c49a763 Canonicalize imported witness blocks on FacetValue (#6458)
The test has a more complete explanation of this; witnesses on the
FacetValue must have a canonical ordering.
2025-12-04 00:05:24 +00:00
Dana Jansens 6a60b80508 Remove the FacetTypeId in RequireImpls (#6437)
The FacetTypeId should never be used directly, since the RequireImpls is
a generic and the facet type may be parameterized by generic bindings.
So instead, it should be accessed through GetConstantValueInSpecific,
which works with the facet type InstId that is also already present on
RequireImpls. This change to use GetConstantValueInSpecific was done in
#6435, so the FacetTypeId is now unused except in formatting. So we can
remove it.

This depends on #6435.
2025-12-01 20:34:43 +00:00
Dana Jansens 0cf2448505 Get specific interfaces with correct specific from named constraints (#6435)
When forming an IdentifiedFacetType, we collect interfaces named by
require decls in named constraints that the facet type refers to. These
interfaces come with a specific, but the require decl is inside an named
constraint which may be generic. So we need the specific being applied
to the containing named constraint to also be applied to the require
decl and its target interfaces.

This uncovered that the facet type in require decls was not being
imported correctly, as it was not being attached to the require decl's
generic. This is fixed by making import of RequireImplsDecl multiphase,
so that the decl instruction exists before we resolve the facet type
within it. And by pointing the generic importing machinery to the
RequireImplsDecl, and from there to the RequireImpls structure to get
the generic id.

Then `ImplStore::GetOrAddLookupBucket` can use an IdentifiedFacetType to
correctly get the interface being impl'd, both in the local and the
imported named constraint case. Which allows us to correctly diagnose
redeclarations in the impl file of an impl of an interface through a
named constraint. And to correctly _not_ diagnose them when the specific
in the generic named constraint differs from other decls.
2025-12-01 18:59:02 +00:00
Jon Ross-Perkins 93a8c5230c Ensure a symbolic final impl has a definition produced (#6236)
Right now, the impl lookup can both fail to resolve the specific
definition because it's symbolic, and return a "final" constant because
it's a `final impl`. This is adding an instruction to help ensure the
specific is resolved.

The constant evaluation is fully recursive, but I'm not adding a TODO
since that's a known issue with impl lookup in general.
2025-11-25 18:59:25 +00:00
Jon Ross-Perkins 44d86e11bb Minor uses of import_* in import_ref (#6428)
Just refactoring calls to use shorter names.
2025-11-25 01:08:29 +00:00
Jon Ross-Perkins 167b45ca35 Rewrite pending specifics to use the work stack (#6415)
I was trying to figure out the right way to get specifics to be added to
the work.

Technically, we could keep the pending_specific list; this is taking a
different approach of inserting inside the work stack, which will do
extra work moving entries, although typically that should be expected to
be small. One challenge of `pending_specifics` is that if we would need
to shift them to work after both `Done` (for immediate processing) and
`Retry` (for processing after the current instruction is later revisited
and done). That feels kind of awkward as additional tracking to do.
Also, the common case is probably that there's either 0 or 1 specifics
being added, so an additional vector may be significant overhead. That's
why I leaned more in this direction of just inserting them in the vector
of work.
2025-11-24 21:52:29 +00:00
Jon Ross-PerkinsandDana Jansens 01a7c79c41 Proposing helpers to reduce some facet type boilerplate (#6412)
About the same # of LOC, but maybe less work to analyze correctness?

Versus the template, could also stamp that out in the helper function
and still avoid the duplication of calls before/after HasNewWork.
Similar to how I've left `rewrite_constraints`.

Alternately I'm also kind of tempted to rename GetLocalSpecificInterface
and GetLocalSpecificNamedConstraint to instead be overloaded functions
(or to provide overloaded versions), which would allow this to drop the
function type parameters. But, naming is hard.

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
2025-11-20 23:07:04 +00:00
Jon Ross-Perkins 972854e834 In import, replace MakeSelfSpecific with GetOrAddLocalSpecific (#6409)
This is just making `self_specific_id` behave more consistently with
respect to other specific imports.
2025-11-20 21:44:10 +00:00
Jon Ross-Perkins 8779b8f64b Replace pending generic logic with work stack-based logic (#6404)
This continues work to eliminate pending generics/specifics and get them
to be interleaved with instruction imports. I'm trying to use
`FinishGenericOrDone` here as a way to help ensure that code correctly
handles generics, where the simple alternative would be for each
`TryResolveTypedInst` call `SetGenericData` directly (but which might
make it easier to call the wrong `ResolveResult` function, and we do
need the `GenericId`s to be passed).
2025-11-20 01:02:18 +00:00
Jon Ross-Perkins 6b1ef75ac5 Make generic decl resolution happen during non-pending import flow (#6394)
This is just an incremental step towards removing pending logic. The
rest seems like it'll be more complex due to interdependencies (I've
been poking at behavior).
2025-11-19 21:54:25 +00:00
Jon Ross-Perkins 4a8efd81e3 Rewrite generic binding imports to use AddLoadedImportRef (#6388)
This is part of trying to rewrite pending specific/generic code to make
use of the standard constant resolution flow. The LoadImportRef code was
a particular sticking point due to the recursion it does, which makes it
difficult to adapt over.
2025-11-19 00:56:17 +00:00
Dana Jansens eb0dcc8ce4 Import generic named constraints (#6376)
We add tests showing that `ImplStore::GetOrAddLookupBucket` is doing the
wrong thing for impls of a named constraint, as the impl-file
redeclarations of impls in the api file are not getting flagged as such.
To do the right thing requires us to be able to get the constraint from
a require declaration with the specific of the named
constraint/interface applied, which is future work as described in the
[open discussion
notes](https://docs.google.com/document/d/1Yt-i5AmF76LSvD4TrWRIAE_92kii6j5yFiW-S7ahzlg/edit?tab=t.1ji9ixn9bbnn#heading=h.kijomnov90rz).
2025-11-18 22:32:49 +00:00
Geoff Romer 57a2715f10 Remove support for addr (#6375)
Every test that used `addr` before #6283 should be using `ref` after
this PR. In most cases that was done in #6283, but this PR transitions a
few that I missed in that first pass. In addition, #6283 cloned the old
`addr` tests from `foo.carbon` to `foo_addr.carbon` in order to maintain
test coverage during the transition; this PR removes those cloned tests.
2025-11-18 19:48:58 +00:00
Jon Ross-Perkins fbc7690157 Switch zip to zip_equal where possible (#6389)
There are two uses I'm not converting here, that seem to want the
"shortest" behavior. For everything else, I'm going to `zip_equal` since
it's more restrictive.

I wish `zip` were named `zip_shortest`.
2025-11-18 00:28:06 +00:00
Dana Jansens e62678e682 Identify and complete facet types as needed for p5168 (#6369)
Proposal #5168 defines when a facet type must be identified or complete,
and what it means for an interface and a named constraint to be
identified or complete. This updates the toolchain to match the
requirements.

This implements identification of a facet type to require completed
named constraints and to include any interfaces from named constraints
into the resulting IdentifiedFacetType.

To complete a facet type, each interface in the IdentifiedFacetType, and
any interface named though a require declaration from them, must be
complete.
2025-11-14 19:24:02 +00:00
Dana Jansens 0183fa301f Import named constraints in a FacetType (#6368)
When importing a FacetType instruction, and the FacetTypeInfo, import
requirements on named constraints.
2025-11-14 18:32:16 +00:00
Dana Jansens 0177dc5677 Import contained RequireImpls when importing an Interface or NamedConstraint (#6344)
When importing an Interface or NamedConstraint, walk the block of
`RequireImplsId`s, and for each one:
- Import the RequireImplsDecl from it, which also imports the
`RequireImpls` structure and its id.
- Collect those decls and build a block of `RequireImplsId`s for the
local SemIR to reference from the Interface or NamedConstraint.

The import of RequireImplsDecl is done in a single phase instead of
three, unlike other decls. This is possible since require declarations
have no name, so they can't be referenced by instructions inside them,
thus there's no cycles to concern ourselves with.
2025-11-14 14:31:11 +00:00
Jon Ross-Perkins 877179d6d9 Refactor addition of imported locations and placeholders (#6354)
- Makes a little more use of `MakeImportedLocIdAndInst` instead of
`UncheckedLoc`
- Requires use of `MakeImportedLocIdAndInst` with `ImportIRInstId`;
previously optional
- Relevant `if constexpr` moves to `AddPlaceholderImportedInst`, but is
more narrowly scoped there.
- Refactors out `AddPlaceholderImportedInstInNoBlock` to reduce how many
spots do an explicit `imports().push_back(...)`

I'd also considered removing `MakeImportedLocIdAndInst` where possible,
but went this route so that changes to the expected parse node wouldn't
affect callers. When it's required, `MakeImportedLocIdAndInst` is always
there; when it's conditionally present, changing `Parse::NodeId` between
enforceable and not-enforceable would require refactoring any callsites
that assumed one or the other.
2025-11-13 18:34:13 +00:00
Jon Ross-Perkins 931039dcbc Refactor ResolveResult with its factory methods (#6356)
Right now some of the `ResolveResult` factories are on it, ones that
involve `ImportRefResolver` aren't; this more consistently makes callers
use `ResolveResult::` when returning a result.
2025-11-12 19:13:46 +00:00
Jon Ross-Perkins bf4d59bc20 Move ImportRefResolver function bodies out-of-line (#6355)
This is intended to be a rote refactoring, also dropping a couple
forward declarations that moving function bodies out-of-line renders
unnecessary.
2025-11-12 18:18:31 +00:00
Jon Ross-Perkins faada92cee Refactor AddLoadedImportRef, particularly for types (#6352)
I was looking at this due to the addition of more
`GetAsTypeInstId(AddLoadedImportRef(` in #6344. Looking at
`AddLoadedImportRef`, it also felt like the first declaration would be
clearer if collapsed into its overload (the overload is the only
caller). Note one benefit of using `ImportContext` in
`AddLoadedImportRef` is being able to call
`local_constant_values_for_import_insts` to handle the `GetRawIndex`
code.
2025-11-12 17:26:56 +00:00
Jon Ross-Perkins 8ba0274e81 Call GetAttached less frequently in import (#6350)
This has subtle effects on the number of imported instructions, but
seems more standard for how this code is being written...
`GetLocalConstantId` calls `GetLocalConstantValueOrPush` which does
`local_constant_values_for_import_insts().GetAttached`. So what this is
really doing is causing some intermediate import steps to be skipped.
But per test changes, that doesn't really affect SemIR and will probably
have negligible effect. This *seems* right to me, otherwise I'd expect
we should probably refactor all `GetLocalConstantId(InstId)` calls.
2025-11-12 00:12:46 +00:00
Geoff RomerandRichard Smith 43ffd721a4 Support ref tags on arguments to ref params (#6312)
The issue of whether/how to include `ref` tags in the textual and
in-memory SemIR (see discussion
[here](https://discord.com/channels/655572317891461132/655578254970716160/1431316355742961805))
is left as future work.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2025-11-11 20:30:19 +00:00
Dana JansensandJon Ross-Perkins ff0cea55f6 Add require decls to Interface and NamedConstraint (#6321)
They are not used for impl lookup or verifying anything yet, but now
they appear in the textual semir.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2025-11-11 16:36:15 +00:00
Dana Jansens b2c3e92132 Copy the complete flag when importing a named constraint (#6316)
And don't mark the imported named constraint as an interface scope.
2025-11-05 14:19:17 +00:00
Dana Jansens 30c3a35776 Import the full NamedConstraint from its decl (#6311)
This imports the entire `NamedConstraint` structure when importing
`NamedConstraintDecl`. This will be required to identify a facet type
that contains a named constraint, as we will need to pull the `require`
decls out of the `NamedConstraint` structure to do so.

I tried making the `InterfaceDecl` code path
[templated](https://github.com/carbon-language/carbon-lang/pull/6308#discussion_r2482655927)
to reuse it, but it was a lot of template parameters including field
pointers into `InterfaceDecl`, `GenericInterfaceType`,
`SpecificInterface`, and it was very hard to read so I gave up on that
approach here.
2025-11-03 16:25:41 +00:00
Dana Jansens ed31a6dbe8 Import NamedConstraintDecl instruction names (#6305)
For now, they are imported as their constant value, so there's little to
do, we just need to support getting their NameId. In the future we will
need to import the full named constraint in order to
["identify"](https://github.com/carbon-language/carbon-lang/blob/656150593c1e3fc2b6ccd83c7256a61e4bd04030/proposals/p5168.md#proposed-rules)
them. But we need FacetTypeInfo to hold named constraints first.
2025-10-31 20:23:28 +00:00
Geoff Romer 0811d996e1 Finish renaming BindName and related insts. (#6281)
Resolves the TODO from #6235
2025-10-28 17:17:38 +00:00
David Blaikieandjosh11b 4f1f0fc7c2 Add unit tagging to ImportIRId (#6265)
Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
2025-10-23 17:34:35 +00:00
Geoff Romer 09710d102f Separate binding insts for refs and values (#6235)
This resolves a TODO in `expr_info.cpp` by using the inst kind rather
than the bound value to track the binding's category.

Since we're churning all the `bind_name` insts in testdata anyway, I'm
also taking this opportunity to align the inst naming with the design's
terminology, by calling these insts "bindings" (this aspect of the PR is
dependent on #6231 resolving an ambiguity in that terminology). For
consistency we'll need to rename several other insts as well (see the
TODO on `RefBinding`); I'm deferring that to a separate PR to minimize
the review load, but I think those name changes are in-scope for this
review.
2025-10-23 01:46:24 +00:00
David Blaikie d4a8cb96de Correct format string specifier to match number of parameters (#6266) 2025-10-23 00:30:31 +00:00
Jon Ross-Perkins c7646b74c1 Reduce use of function return type deduction (#6227)
Trying to reduce use where we could have explicit return types because
it should make it a bit quicker to understand what's returned. We've
generally agreed to it for [local
variables](https://github.com/carbon-language/carbon-lang/blob/trunk/docs/project/cpp_style_guide.md#naming-variable-types-and-the-use-of-auto),
but even the [google style
guide](https://google.github.io/styleguide/cppguide.html#Type_deduction)
discourages it and says "Do not use decltype(auto) if a simpler option
will work; because it's a fairly obscure feature, it has a high cost in
code clarity."

(which to one point of discussion, feels like maybe we don't need a
specific rule about this -- the remaining couple uses I see feel like
they're harder to avoid)
2025-10-15 23:02:51 +00:00
Jon Ross-Perkins 9010249936 Remove reallocation assumptions from generic code (#6217)
Rather than assume reallocations can occur, we've switched to providing
stable references, so simplify related code.

Only removing the comment in `BuildGeneric`, no refactoring, because I
don't feel a refactoring would be a significant improvement.
2025-10-14 21:53:48 +00:00
Dana Jansens e682a6660d Avoid adding extraneous local instructions while importing witness table entries (#6180)
When deducing arguments for generic parameters of an `impl`, the
deduction calls `Convert` on the input arguments. Often, the input
argument is a facet, and needs to be converted to a type via
FacetAccessType in order to produce a different facet. These
instructions end up being added to the semir, but only their constant
values are needed for the resulting specific returned from Deduce.

In the best case, these extra instructions are just noise in the semir,
or they just cause instruction names to get differentiated with larger
suffixes.

In the worst case, these extra instructions contain references to
instructions from a generic context, and leak them out of that generic
context and into another. In particular, when importing a
LookupImplWitness instruction, the re-evaluation of it can do deduce
(when the lookup is against a generic `impl`). The instructions created
in Deduce are not part of the import, and end up referring to imported
instructions from the local context, which leads to confusion in the
toolchain, and can crash.

The `import_self_specific.carbon` test demonstrates this. It causes the
`I.F` function to be imported from the `I` interface when building the
witness table for the `impl`. Doing so imports the specific of `C` which
includes a LookupImplWitness for `Self.Accoc` in `I`. The `Self` is a
BindSymbolicName with generic binding index 0, in `I`. When Convert
creates instructions in the generic `impl forall D`, however, they end
up referencing and including this BindSymbolicName into its eval block.
But the generic binding 0 in the `impl` is a very different thing (a
value of type `E`). This confusion leads to crashes.
2025-10-09 16:07:30 +00:00
Dana Jansens fe020ee08b Make FacetAccessType evaluate to SymbolicBindingType for type-of a BindSymbolicName (#6115)
The SymbolicBindingType refers to the type value that will be
substituted in for the BindSymbolicName, but holds onto the EntityNameId
from the BindSymbolicName instead of (or in addition to, for now) the
instruction.

The EntityNameId will be used to look in the ScopeStack to find the
witnesses either from the BindSymbolicName instruction, or other
instructions that specify `impls` constraints against the EntityName.

This will allow us to have the `T` in `I(T)` resolve to a `.Self`
reference in the type so that we get type equality with the binding's
type: `T:! I(.Self)`.
2025-10-06 18:56:43 +00:00