172 Commits
Author SHA1 Message Date
Nicholas Bishop a65c3680ff Special case formatting of None insts in a specific (#7882)
A specific's definition block may contain `InstId::None`, indicating it
has no constant value. Display this as `<not constant>` instead of
`invalid`, to avoid it sounding like an error.
2026-10-01 20:17:55 +00:00
Christopher Di Bella e8fda4519c Enable SubobjectDestroy.Op to destroy tuples (#7842)
This is a partial implementation of #7362.
2026-09-29 17:23:20 +00:00
Richard Smith 8ac36e7daa Improve precedence computation in stringifier. (#7833)
Assisted-by: Claude via Antigravity
2026-09-29 00:55:21 +00:00
Christopher Di Bella 6abcfa24b2 Classify decorated built-in types as trivially destructible (#7847)
Types like constant pointers and `MaybeUnformed(i32)` should have
trivial destruction, but were classified as non-trivially destructible.
2026-09-28 23:16:19 +00:00
Christopher Di Bella b227419d8d Classify classes with no struct fields as trivially destructible (#7846) 2026-09-28 22:39:03 +00:00
Richard Smith c1ca91b67a Stringify support for call instructions. (#7827)
Reconstruct the call syntax from the callee's explicit parameter
patterns, the callee specific, and the call arguments.

Assisted-by: Claude via Antigravity.
2026-09-28 22:23:32 +00:00
Richard Smith d4c7ca4221 Support for dependent initialization in templates (#7801)
Add support for deferring initialization as a template action, and
performing the deferred initialization during template instantiation.

This is substantially more complex than other conversion actions, for
two primary reasons:

* The initializer in the generic may have storage arguments as inputs.
We model an initializing expression as having a "slot" where
initialization writes the location that should be initialized by that
initializing expression, and that needs to be an output of the
initialization action.
* Initialization from a tuple or struct literal needs to recurse into
that literal, and the literal will have been spelled in the generic,
meaning we don't have an `InstId` that can be used to name the specific
version of the initializer as input for nested conversions.

These issues are addressed by introducing two new features to the action
machinery:

In addition to `InstAction`, we now have `MultiInstAction`, which is an
action that produces a tuple of instruction values instead of a single
instruction value. Initialization actions produce one instruction for
the final result, which is spliced at the point of initialization, plus
one instruction for each storage argument, which are spliced into the
storage argument slots in the original generic. During initialization,
if we find one of those splices in the storage argument of an
initializing expression, we return the new storage argument back to the
initialization action to be included in the specific, instead of
overwriting the storage argument in the generic.

Actions whose `PerforrmAction` takes a `SpecificId` as input no longer
perform automatic refinement of their operands to specific instructions.
Instead, the action is given control over when and where it performs
that refinement. In `InitializeAction`, we use this freedom to form a
`SpecificInst` for the initializer in the primary output block, and form
a `SpecificInst` for the target in the target block. When detecting
whether we are initializing from a tuple or struct literal, we step over
the `SpecificInst` and track its `SpecificId`, and if necessary create a
new `SpecificInst` wrapping the sub-initializer when we recurse into the
nested element conversion.

Assisted-by: Claude and Gemini via Antigravity
2026-09-24 23:10:18 +00:00
Christopher Di Bella f7cd39428e Add Destroy.SubobjectDestroy as a temporary replacement for Destroy.Op (#7773)
This change partially implements [PR #7362], which revises how objects
are destroyed. It is a partial implementation for two reasons:

1. This change moves `Destroy.Op`'s current behaviour into
`Destroy.SubobjectDestroy`, but it doesn't add support for objects with
non-trivial destruction.
2. `Destroy.SubobjectDestroy` is a workaround for `require impls
SubobjectDestroy`. We aren't able to use the latter until the dependents
add their requirements' implementations to their own witness tables.

[PR #7362]: https://github.com/carbon-language/carbon-lang/pulls/7362
2026-09-24 00:06:28 +00:00
Dana Jansens fcae9610bd Make SemIR::TypeType be an empty FacetType instruction (#7813)
The type `type` is now a `FacetType` inst with no constraints. This
brings the model implemented in the toolchain into better alignment with
the language design. The `SemIR::TypeType` struct remains as a scope for
holding the `TypeInstId`, `ConstantId`, and `TypeId` constants, but is
not an `InstKind` anymore.

The `TypeType` inst looks a lot like singletons, but there are many
`FacetType` insts so it doesn't quite fit that model. So we put it
alongside singletons with a fixed inst id but refer to it as a more
general "builtin" inst that is not a singleton.
`Namespace::PackageInstId` is similar, and we group it with `TypeType`
conceptually as another builtin instruction with a fixed id.

No conversion is needed anymore to use a `type` as a facet, since types
also have a `FacetType` type. This simplifies and removes a number of
helpers and branches throughout the code.

The `TypeType` inst is now part of the constant store, so we end up
printing it in the constants block in every test. But it's also named
`type` rather than `%type` to preserve the majority of existing
formatting behaviour, though this does look different from other
constants.

Assisted-by: Opus 5 was used to generate a first draft and validate the
refactoring. Though nearly everything non-trivial the tool wrote has
been modified or rewritten.
2026-09-22 15:04:40 +00:00
Richard Smith 59c1d6ff39 Remove refine_inst_action and its splices. (#7769)
This action was created to wrap any `MetaInstId` operand of an action
instruction. This served two purposes:

1) It had a special hook in `OperandIsDependent` to allow it to be
   performed while it had a dependent operand (the reference to the
   instruction in the generic).
2) It created a `specific_inst` so that the downstream action saw an
   instruction in the specific instead of one in the generic.

These are both replaced: the special case in `OperandIsDependent` for
`RefineInstAction` is replaced by a special case for `MetaInstId`s in
general, and the `SpecificInst` is now created as part of performing the
downstream action, rather than as a separate step carried out
beforehand.

This simplifies the produced SemIR and reduces the number of splices
significantly. It also prepares us to handle actions like
initialization, where we don't actually want to create `SpecificInst`s
immediately in the location where the action is performed, because they
actually belong somewhere else in the IR.

Assisted-by: Claude Opus 5 and Gemini via Antigravity
2026-09-16 01:21:00 +00:00
Dana Jansens 4416f3525b Canonicalize generated functions for Core witnesses (#7729)
Use a single `SemIR::Function` per `Core` interface method, whether it's
generated locally or imported. This prevents generating duplicate
functions, which lead to different types when the witness appears in a
`FacetValue` as part of a specific for a class.

We use a `CanonicalValueStore` of `GeneratedFunction` objects that allow
finding an existing FunctionId for a `Generated` special function before
(re-)generating it. Mangling for `Generated` functions is also moved to
use the values from the `GeneratedFunction`'s canonicalization key, so
that we have a consistent source of truth for the unique ID of a
`Generated` function across all files.

New tests are in
`toolchain/check/testdata/impl/custom_witness/destroy.carbon`.
2026-09-15 16:02:13 +00:00
Richard Smith 5a07a14fe9 Support for lowering templates (#7727)
Add basic support for lowering templates: we can now lower `SpliceInst`
in the case where the generic and specific are from the same file (and
we don't support importing templates from other files yet in general).
In order for this to work, lowering needs to be able to query the
expression category, and to handle instructions that appear to be
(template) constants in the generic but turn out to be non-constant in
the specific, so support for that is added.

Switch `type_of_inst` from being added as an action inst to being added
as a normal inst, since it's not an action and the old approach led to a
crash in lowering.
2026-09-08 18:39:57 +00:00
Richard Smith 812cc1e032 Add SpecificInst to represent a specific version of a template-dependent instruction (#7726)
Replace `refine_type_action` with `refine_inst_action`, and generate a
`specific_inst` instead of an `as_compatible` to represent the specific
version of an instruction that's used as an input to a template action.
This gives us a place to handle other properties of the instruction that
might vary from generic to specific beyond its type, such as its
constant value and its expression category.

For now, we provide a non-template-dependent constant value to the
`specific_inst` in addition to the non-template-dependent type we have
traditionally provided. This doesn't seem to matter for any current
actions, but sets us up to better handle future actions. The
`specific_inst` representation also allows downstream consumers of the
instruction to track which specific they should be requesting
information from. Providing a correct expression category for
`specific_inst` will be handled in a future PR.
2026-09-08 16:01:09 +00:00
Richard Smith 01815b6c47 Fix refinement of call action operands. (#7710)
Two somewhat related fixes. The first is call-specific for now (because
it's the first action to take a `MetaInstId`), and the second is general
across all actions, but it seems like calls are the easiest place to hit
it.

1) Add support for refining inst blocks as action operands. Refine all
   the insts in the block, using the appropriate InstId-derived type.
2) When an action operand is a `MetaInstId` referring to an unattached
   constant, form a corresponding attached constant. This comes up when
   forming (for example) an implicit `AddWith(%T)` call, where the `%T`
   operand is an unattached constant.

This causes us to form correct specifics in more cases, where previously
we formed specifics that contained values that were still
template-dependent.

This unfortunately causes some existing template tests to produce more
errors, but those errors reflect cases where we were previously silently
doing the wrong thing.
2026-09-02 20:36:18 +00:00
Richard Smith 2209a3477e Step through splices when checking for a bound method. (#7700)
`GetCallee` is sometimes called on a spliced instruction, and is
checking its exact inst operand to see if it's a `BoundMethod`. This
fails if the `BoundMethod` is wrapped in another instruction, such as a
splice. Normally our approach for such a situation would be to
constant-evaluate the operand, but that doesn't work here because the
`BoundMethod` will be non-constant if its bound `self` is. So instead we
now step through splice instructions manually when looking for the
`BoundMethod`.
2026-09-02 15:19:59 +00:00
Nicholas Bishop f519cccaf2 Add CallAction to allow deferring calls (#7682)
Calls with template callee or args can now be deferred via an
InstAction. This allows code like this to check:

```carbon
import Cpp inline '''
template<typename T>
struct C {};
''';

fn F(generic T: type) {
  let unused c: Cpp.C(T) = Cpp.C(T).C();
}
```
2026-08-28 18:00:58 +00:00
Nicholas Bishop 7f3584a123 Support constant InstActions (#7671)
Treat `InstConstantKind::InstAction` the same as
`InstConstantKind::ConstInstAction`. Drop `ConstInstAction`, since the
two now behave the same.

Fix eval for specifics in a couple places to handle `InstId::None`.
2026-08-24 18:05:15 +00:00
Richard Smith 6eb900dff5 Add template action for compound member access. (#7657)
This allows various templated constructs to get further through
checking, but typically we hit another unsupported action such as a
conversion or call, so it's not enough to make much work.
2026-08-20 15:45:02 +00:00
Christopher Di BellaandRichard Smith 4ea5ef45dd Skip ImplWitnessTable::elements_id when generating fingerprints (#7629)
Implementing interface modifiers causes an infinite loop when generating
fingerprints because the witness value generates a fingerprint that's
dependent on something dependent on the witness value. We've debugged
this to the witness table's `elements_id` field.

This hack is a workaround for creating a new block type whose value is
not codependent with its identity.

Co-authored-by: Richard Smith <richard@metafoo.co.uk>

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2026-08-11 22:39:30 +00:00
Dana Jansens a5ba0a0f45 Use GetConstantValueInSpecific to get the impl's specific interface after deduction (#7584)
During impl lookup, for each (generic) impl candidate, we form a
specific for that impl by deducing its generic arguments. Then we
compare the query interface against the impl's specific interface. That
comparison needs the deduced arguments applied to the impl's specific
interface. Previously we were doing this by getting the impl's
constraint facet type with the impl's specific applied (via
`GetConstantValueInSpecific()`) and then identifying that facet type
with the impl's deduced self.

Identify is a fairly expensive operation. It runs subst, trying to
replace `.Self` references. It walks named constraints. It collects
require declarations. We're looking at making it do _more_ in the future
too, including rewrite constraint resolution and collecting rewrite and
same-type constraints. For this reason we have a cache to make it cheap
on the second run, but it's still a very heavyweight operation to
involve in impl lookup, when all we want is to apply the impl's specific
to its target interface.

We almost have all the information we need to avoid the identification
step. We have the impl's specific after deduction. And we have the
SpecificInterface that the impl is targeting in the `Impl` struct. When
we form the specific for the impl itself, we resolve the declaration
block and form new constant values for all instructions in there, but
that does not cover the SpecificInterface that we're storing in the
`Impl` struct. So we add a new instruction to the impl's eval block,
which will be symbolic when the impl is generic and the target interface
depends on a generic parameter. And we store the `InstId` in the `Impl`
struct. This allows us to gets its constant value later with the impl's
specific applied. From that constant value we can then pull out the
SpecificInterface that the impl is targeting.
2026-07-30 19:59:10 +00:00
Richard Smith a8afc45ed5 Omit empty observe: blocks from formatted SemIR. (#7487)
Also add SemIR ranges to observe test, removing 5K lines of
uninteresting SemIR output.
2026-07-13 20:38:19 +00:00
Chandler Carruth 8be274cf60 Replace :! binding syntax with phase keywords and contextual defaults (#7479)
Implement the toolchain side of proposal #7254, removing the `:!`
binding
syntax for generic and template parameters in favor of the keywords
`generic`,
`template`, and `runtime` plus contextual defaults for phase.

For valid programs this is semantics-preserving: each binding resolves
to the
same phase, and produces the same SemIR, as it did under `:!`/`:`. The
parser
derives a binding's phase from its syntactic context plus any explicit
phase
keyword; new diagnostics and error recovery for misused keywords are
described
below.

Implementation details for each component:

- Lexer: remove the `:!` (`ColonExclaim`) token, move its virtual
parse-node
  budget onto `:`, and add the `generic` and `runtime` keywords.
- Parser: thread a `BindingContext` (`ExplicitParam`, `DeducedParam`, or
`CompileTimeEntityParam`) from declaration introducers down through
parameter
lists to each binding pattern, using a one-token lookahead to
distinguish a
name-qualifier parameter list from a declaration's own final list.
Parameters
of a compile-time entity (`class`, `interface`, `constraint`, `choice`,
`alias`, `export`, `namespace`) and deduced `[]` parameters default to
checked
generic; explicit function parameters and local bindings default to
runtime.
`HandleBindingPattern` resolves the phase from that context plus the
keyword: a
`generic` keyword needs no node of its own (the phase is carried by the
  binding's node kind), while a `runtime` keyword is preserved as a
`RuntimeBindingName` node so `check` can name it in a diagnostic. A
phase
keyword that is merely redundant with the contextual default is
diagnosed
  here, without invalidating the parse tree.
- Check: a phase keyword that is invalid for its context (for example
`runtime`
on a checked-generic parameter) is diagnosed here, and recovers by
building an
error binding that still introduces the name so that later uses of it do
not
  produce cascading errors.

The removed `:!` syntax is now rejected as an ordinary parse error.

The `form`/`:?`/`->?` ("extended types") portion of proposal #7254 is
left for a
separate change.

Assisted-by: Claude Code
2026-07-11 01:22:44 +00:00
Özgür T. ÖnsoyandDana Jansens 08385adeb5 Implement checking observe declarations (#6709)
This adds SemIR structs and implements building `observe` lists, as well
as naming, formatting, and importing `observe` declarations.

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
2026-07-08 17:07:10 +00:00
Geoff Romer 8945305dfc Emit NameBindingDecl after the initializer (if any) (#7467)
In some cases the pattern block can depend on the initializer, so it
must be sequenced after it. See #7469 for a more detailed explanation of
why this is necessary.
2026-07-07 19:18:33 +00:00
Geoff Romer 0460f6b7ba Label VarStorage as var_storage instead of var (#7447)
This makes the textual format clearer and more self-explanatory, and
avoids ambiguity about whether this inst refers to the storage or the
pattern.
2026-07-02 01:02:19 +00:00
Geoff Romer e4b0903d2e Remove ValueBinding and RefBinding (#7427)
These inst kinds are now redundant with `WrapperBinding`.
2026-06-29 17:41:23 +00:00
Geoff RomerandRichard Smith e023f75254 Implement thunking in terms of constant evaluation (#7332)
The bulk of this change is changing most pattern insts to be `Always`
rather than `AlwaysUnique` constants, so that they can be wrapped in
`SpecificConstant`s to perform substitution. That then lets thunking
rely much more on `SpecificConstant` wrappers instead of deep-copying
the inst tree with modified types.

This approach to thunking should scale better, particularly as things
like form generics make function signatures more complex, because we can
leverage the existing support for constant evaluation and substitution.
Unfortunately, applying this approach to binding patterns will require
more work; see the TODO near the top of `thunk.cpp` for details.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2026-06-13 00:22:00 +00:00
Chandler Carruthandjosh11b 7871237c15 Move self to the explicit () parameter list (proposal #7016) (#7272)
Implements proposal #7016: `self` moves from the deduced implicit list
(`fn F[self: Self]()`) to the front of the explicit list. Its type may
be written explicitly (`fn F(self: Self)`) or omitted, in which case it
defaults to `Self` (`fn F(self)`, `fn F(ref self)`); `self` in the
implicit list is rejected.

Throughout checking, `self` is modeled as the first explicit parameter.
Because a method is just a function whose first parameter is `self`, it
can also be called as an ordinary function with the receiver passed
explicitly (`Type.M(obj, ...)`), not only as `obj.M(...)`. A new
`SemIR::CallArgParamPatterns` helper chooses the parameters matched
against the explicit arguments, excluding a leading `self` only when it
is supplied as a method-call receiver; arity checking, conversion, and
generic deduction use it. The resulting SemIR and lowering are
unchanged: `self` is still `call_param0`, and witnesses, thunks, and
vtables are unaffected.

An omitted `self` type is parsed as a `SelfBindingPattern` node with no
type expression; checking synthesizes the `Self` type so it behaves
exactly like `self: Self`. However, the exact spelling used must match
between a forward declaration and a definition, following #3763's rules
around declaration matching.

Generated functions, thunks, and C++ interop import/export build `self`
as the first explicit parameter, and the `self`-type override (e.g.
Derived->Base for a virtual override) applies to the explicit `self`.
Placement is validated by new diagnostics: `SelfInImplicitParamList`,
`SelfNotFirstParam`, and `SelfOutsideParamList`. The benchmark source
generator and the documentation adopt the `(self)` shorthand; the
prelude, the examples, and the test data are migrated in the following
commits.

Assisted-by: Claude Code with Claude Opus 4.7

---------

Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
2026-06-10 15:30:43 +00:00
Richard Smith cefa0397bb More fixes to package and library fingerprinting. (#7297)
Fix import logic to make all imported packages be children of the
`NameScopeId::Package` scope. Previously, indirectly-imported packages
would end up as children of their importing package's scope, which
resulted in them not being treated as packages at all, and in particular
not being fingerprinted as packages.

Fixing that caused a failure in the fingerprinting logic as we started
to encounter packages with no correspoding import scopes. Instead of
looking for import scopes, use a simpler mechanism to map packages to
their package names, and clean up.

Unfortunately the latter change churns all the fingerprints again :(
Hopefully this is the last time for a while.
2026-06-04 17:41:46 +00:00
Richard Smith f5e9c61f11 Don't include the library name in most fingerprints. (#7292)
When we import from another library in the same package, its entities
end up with our library as their parent scope, resulting in cross-file
fingerprint mismatches. Instead, only include the library ID when
fingerprinting either a package-private entity or an `ImportIRId` that
refers to a particular `SemIR::File`.
2026-06-02 19:31:30 +00:00
Dana Jansens e7ed217d4e Require all constraints in where to have a designator (#7282)
Instead of requiring just one to have a designator, require each one.
You can't write `(type where A == B) & (type where C == .Self)` because
`A == B` has no designator. If the two facet types are combined into a
single `where` syntactically, their meaning does not change, and what we
allow should not change either. That is, `type where A == B and C ==
.Self` should be rejected since `A == B` does not contain a designator.

The design is also updated to make this clear.
2026-06-02 17:11:59 +00:00
Richard Smith 05cc09daca Fix cross-package signature mismatches. (#7232)
Fixes link failures when referencing a symbol involving a fingerprint
from a different package.

Previously we included the `Namespace`'s `import_id` as part of its
fingerprint, which caused local and imported namespaces to get different
fingerprints. We now store the `import_id` on the `NameScope` instead of
on the `Namespace` inst to avoid this problem.

Also, when we reach a package-level `NameScopeId`, consistently
fingerprint it as a (package name, library name) pair. Previously the
fingerprinting depended on whether it was imported or not, as an
imported `NameScopeId` had a parent scope (the current package). We need
to include the library name here so that private entities with the same
name in different libraries have different fingerprints.
2026-05-21 00:02:29 +00:00
Dana Jansens f8dd4d85bf Do not treat impls in different scopes as redeclarations (#7161)
An impl in a different scope, with the same parameters, will overlap and
get diagnosed for that later by the [prioritization
rule](https://docs.carbon-lang.dev/docs/design/generics/details.html#prioritization-rule),
if they are not in a match_first block. But they are not considered as
redeclarations.

See [proposal
p5366](https://github.com/carbon-language/carbon-lang/blob/62b94f79322039acc3fc8e175896a64a32df470e/proposals/p5366.md)
for the rule.
2026-05-04 19:11:51 +00:00
Geoff Romer 4c9049346d Replace form insts with actions (#7100)
See
[here](https://docs.google.com/document/d/1rWcueFwIfZox6GKVGxiUG4cBzjrZ6djXiIDGyJDtrE4/edit?tab=t.0)
for the design doc.

This also removes the default value of the `result_type_inst_id`
parameter of `HandleAction`, moves it before the action in the parameter
list, and documents it. This solves two problems:
- The default made it easy to forget, leading to unnecessary
`TypeOfInst` instructions.
- When it was present, putting it after the fairly "bulky" action
argument tended to make the callsite harder to read.
2026-04-29 18:13:42 +00:00
Dana Jansens 554b1b8d10 Remove SymbolicBindingType (#7114)
This inst was meant to support tracking the depth of a `.Self` facet,
but we have now implemented substitution of `.Self` in facet type
identification, and in eval of where expressions, without needing to
track the depth.

See history here:
-
[2025-06-30](https://docs.google.com/document/d/1Yt-i5AmF76LSvD4TrWRIAE_92kii6j5yFiW-S7ahzlg/edit?tab=t.0#heading=h.4qd5dkyfn2k3)
-
[2025-07-07](https://docs.google.com/document/d/1Yt-i5AmF76LSvD4TrWRIAE_92kii6j5yFiW-S7ahzlg/edit?tab=t.0#heading=h.7urbxcq23olv)
- #6026
2026-04-27 19:04:59 +00:00
Geoff RomerandChandler Carruth 49c7288619 Restructure return declaration handling (#7076)
- A function with a return declaration always has exactly one
`ReturnSlotPattern`, representing the whole return declaration (whereas
previously that was omitted for value and reference returns).
- The `ReturnSlotPattern` always has a subpattern with the same form.
`OutParamPattern` already plays that role for initializing forms, and
`TuplePattern` will play that role for tuple forms. This change
introduces `ValueReturnPattern` and `RefReturnPattern` to represent
value and reference return forms.
- As before, the `ReturnSlotPattern` has a corresponding `ReturnSlot`
that represents the output that is initialized by a `return` statement.
Its structure parallels the structure of the `ReturnSlotPattern`, so we
need `ValueReturn` and `RefReturn` insts that correspond to
`ValueReturnPattern` and `RefReturnPattern`.

This is a step toward supporting generic return forms, where the
`ReturnSlotPattern`'s subpattern may be an action: this change ensures
that evaluating the action for a specific form produces the same SemIR
as if the form were concrete to begin with. More speculatively, this
should simplify the implementation of `return` statements with compound
return forms.

---------

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2026-04-22 23:38:21 +00:00
Dana Jansens d1dc8e820d Resolve the specific definition for a function that is evaluated (#7034)
The function body may make use of values from the specific, so the
specific definition must be resolved before the function is evaluated.
2026-04-07 21:53:54 +00:00
Dana Jansens f483a28f2f Refactor WhereExpr evaluation into smaller helper functions (#7006)
This splits off the functionality to handle the base facet type,
rewrites, and impls constraints into separate functions.

We use the Context instead of EvalContext throughout, as the goal is to
move this code to EvalConstantInst in time. That means we do not apply
specifics to the functions in the requirements inst block. That is fine
because WhereExpr never evaluates to an WhereExpr, so this instruction
never survives as a constant value long enough to be re-evaluated with a
specific applied to it.
2026-04-07 13:52:56 +00:00
Jon Ross-Perkinsandjonmeow 9266ced4e3 Improve CanDestroyType to handle remaining cases (#6943)
This is only fixing the decision about *whether* to produce a witness.
Implementation of the witness is still a TODO, though where a body is
generated, it should also precisely reflect where one _needs_ to be
generated.

Note the tests:

- toolchain/lower/testdata/function/generic/import_core_witness.carbon
- toolchain/lower/testdata/function/generic/import_unused_def.carbon

These tests can probably be produced _without_ Core.Destroy, but I found
the essence of them while trying to build //examples with Core.Destroy
and a simpler minimization wasn't striking me.

Assisted-by: Google Antigravity with Gemini

---------

Co-authored-by: jonmeow <jperkins@google.com>
2026-04-02 22:54:58 +00:00
Nicholas Bishop 396756c151 Handle Temporary values when const-evaling AcquireValue (#6992)
This will be used for const-evaling functions. Splitting into a separate
commit since it touches a lot of test files, and a couple fail_todo
tests are no longer failing.
2026-03-31 15:50:54 +00:00
Nicholas Bishop bf6a14ac39 Support Temporary constants (#6983)
Evaluate `Temporary` constants to a `Temporary` with the `storage` field
set to `None`.
2026-03-30 19:07:46 +00:00
Dana Jansens a0416a1250 Don't finish the non-canonical instruction created in EvalOrAddInst (#6972)
EvalOrAddInst has to create a non-canonical instruction for evaluating a
few typed insts, such as LookupImplWitness which uses an InstId to
provide a location for diagnostics.

But the output of the function is a ConstantId. We do not have access to
the non-canonical InstId after the function returns. But if the constant
value was symbolic, it was being attached to the inst, and the inst
would be added to the eval block of the enclosing generic. This
needlessly added semir for a symbolic value.

The ConstantId returned by EvalOrAddInst can be used immediately, such
as to evaluate an ImplWitnessAccess. In that case, the final evaluated
result is all we need to keep in semir.

If the ConstantId needs to be replaced by specifics, it is only as part
of some other instruction, since ConstantIds themselves are not modified
by specifics, instructions are. In that case, the canonical instruction
in the constant value would have been added to some other (now symbolic)
instruction, which would be replaced by a specific.

This has no functional change, but it reduces runtime overhead and semir
output for LookupImplWitness and ImplWitnessAccess.
2026-03-27 19:29:34 +00:00
Geoff Romer 18f87e4f79 Include the type in the location of binding insts (#6963) 2026-03-26 18:43:29 +00:00
Dana Jansens d6be20641c Use earlier require decls inside a named constraint to provide witnesses for Self (#6915)
Performing a lookup against `Self` inside the definition of the named
constraint leads to cycles, as described in the document [Self
contradictions in Named
Constraints](https://docs.google.com/document/d/17rn2XmME8o2MM4OJqatSVuMa1iYZ1PAgcNrf0PXR9Q4/edit?tab=t.0).
To prevent those cycles, this change introduces a large refactoring of
impl lookup.

The impl lookup done inside eval is reduced to only performing
monomorphization. That is it:
- Only looks for an provides final witnesses.
- Is not allowed to identify the facet type of the query self.
- Returns either a final witness or None (or an error)

The paths for finding non-final witnesses are now done outside of eval,
directly in the initial `LookupImplWitness()` function. If no final
witness it found through eval, the resulting non-final
`LookupImplWitness` instruction witness is returned. It does not produce
cycles to identify the facet type of query self outside of eval, since
that does not result in repeating the identification when resolving
specifics of the named constraint or require decl.

Move the ArrayStack for Context::require_impls_stack into a new class
which tracks a NamedConstraintId (or InterfaceId) for each frame of
RequireImplsIds, so that in type completion we always can find the
correct frame for a given named constraint which is still being defined,
in order to find the RequireImplsIds in the in-progress definition.
2026-03-26 15:26:56 +00:00
Richard Smith 37b238fa28 Make C++ types impl Core.Default. (#6962)
C++ classes that are default-constructible now implement `Core.Default`
by calling the default constructor.
2026-03-25 21:07:24 +00:00
Richard Smith 965879a9a9 Support for in-place return in eval fn. (#6954)
Ignore storage arguments when evaluating a call, like we do for other
kinds of instruction. Create a placeholder constant to represent each
out parameter so that it can be used in the function body to form more
storage arguments.

Assisted-by: Gemini 3.1 Pro via Antigravity
2026-03-25 16:03:44 +00:00
Richard SmithandGeoff Romer ce50f181f1 Add an interface for initialization of vars without an explicit initializer (#6934)
When a `var` is not explicitly given an initializer, initialize it in
one of two ways:

* If its type implements the new interface `Core.Default`, call
`Core.Default.Op` to initialize it.
* Otherwise, if its type implements `UnformedInit`, leave it in an
unformed state. For now, this is always an uninitialized state, but that
will change in the future.
* If neither of those apply, the `var` declaration is ill-formed.

This is a step towards implementing leads decision #6739 and proposals
#257 and #5913.

Assisted-by: Gemini 3.1 Pro via Antigravity

---------

Co-authored-by: Geoff Romer <gromer@google.com>
2026-03-19 23:46:06 +00:00
Jon Ross-Perkins 610094ccfd Make included files insert before main files (#6899)
This is so that the last file is more likely what we're trying to
compile in tests. Just splitting out the churn-y change of reordering.

Assisted-by: Google Antigravity with Gemini
2026-03-12 21:01:16 +00:00
Dana Jansens cea52ad2d8 Format the InterfaceWithSelf and NamedConstraintWithSelf generic name with its ".WithSelf" suffix (#6798)
We used the ".WithSelf" suffix when formatting a parent scope, but
missed the suffix when formatting the scope name on its own.
2026-02-27 13:50:56 +00:00
Richard Smith f9ab963bd6 Add a type_literal instruction to represent syntactic type literals. (#6781)
This allows us to capture the location at which a type literal was used,
even in the cases where we don't otherwise need to create a new
instruction to represent the type such as for `char` or `str`.

The logic used to build the underlying type is now marked as desugaring.
For cases such as `iN`, this causes the call to `Core.Int` to no longer
be added as a dedicated IR instruction, and instead its constant value
is used directly as the value of the `type_literal`. This results in
this being on balance a reduction in the size of the IR.

This also fixes a crash in C++ interop when using a `char` literal as a
template argument. The crash was caused by the template argument not
having an associated location when mapping to a C++ location. See
changes to check/testdata/interop/cpp/template/type_param.carbon for an
example that used to crash before this change.

Update alias handling to allow an alias to point at any type literal,
reinstating support for aliases for type literals such as `bool` and
`i32` that had previously worked but stopped working when we
transitioned those types to being defined in the prelude. See changes to
toolchain/check/testdata/alias/builtins.carbon.

All the test changes other than the two mentioned above are mechanical
autoupdate changes switching to the new instruction.
2026-02-26 20:10:50 +00:00