Commit Graph
105 Commits
Author SHA1 Message Date
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
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
Dana Jansens 4261bb2dd2 Track and don't replace active .Self (#7443)
In #7436 we stopped substituting `.Self` when collecting witnesses out
of a facet type. While this was correct, it did not capture all the
cases that need to avoid substituting `.Self`. And it poisoned the
`IdentifiedFacetType` cache by not replacing `.Self` but storing the
result in the cache. This led to incoherent behaviour, where the result
of an impl lookup would change depending on which ones had been done
previously.

Now we use a flag to track for each `.Self` if we're currently
type-checking inside the scope where it was introduced in a facet type.
While inside that scope, identify should not replace the `.Self`. Any
use of it should remain as-is since we don't yet know what value will
replace it. We call this state "frozen" since it should not be modified
by identify. This requires a substitution step when we leave the scope
that introduced the `.Self`, to remove the flag. The flag is set in the
`EntityName` of the `SymbolicBinding`, and is part of the canonical
value, since `.Self` can become part of types, which are constants, and
the flag needs to follow it for correct behaviour.

We also have to ensure the flag is the same when doing comparison with
constants from inside a facet type and constants from outside. For
instance in `(Z where .Z1 = ()) where .Z2 = .Z1`, when we arrive at the
second `.Z1` its `.Self` will be frozen, while the `.Z1 = ()` contains a
non-frozen `.Self`. So we add the frozen flag to the first when storing
it in `where_stack` in order to compare the constant values of the two
`.Z1`.

The `WhereExpr` requirement inst kinds now have an `InstConstantKind` of
`AlwaysUnique` instead of `Never`. This allows us to add them to the
usual InstBlocks, and in an `eval fn` body they have a constant value,
so eval does not fail when trying to call that function. We have to be
careful to not consider `AlwaysUnique` as being actually concrete
though, since their constant value erases `.Self`-dependence. This
allows us to stop special casing them when thawing the requirements
block in a `WhereExpr`, and we can just thaw each `InstId` in the block
in a straightforward manner.

We add the new flag to the instruction's fingerprint and name in
formatted semir.
2026-07-08 18:04:56 +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 ae6846197a Remove trailing () from Core.*Literal and Core.Bool. (#7313)
We exposed `Core.IntLiteral()`, `Core.FloatLiteral()`,
`Core.CharLiteral()`, and `Core.Bool()` as functions as a workaround,
because we had no way to provide the type names without parentheses that
the design requests. But now we can do so, by using an alias. Switch all
of these over from being functions to simply being names of the
corresponding types.

Assisted-by: Gemini via Antigravity
2026-06-05 22:33:30 +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
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
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
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
Dana Jansens 6d2387cb77 Return a NewAnyPhase result for RequireCompleteType with a CompleteTypeWitness value (#6939)
The `CompleteTypeWitness` can be concrete. This avoids making a symbolic
`CompleteTypeWitness` value which itself has a concrete
`CompleteTypeWitness` value with the same operands.
2026-03-20 20:00:08 +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
Geoff Romer 08148f3a3a Refactor AddBindingPattern into composable pieces (#6927)
This is part of some bigger changes in pattern matching, factored out
because it causes some test churn.

Assisted-by: Gemini 3.1 Pro via Antigravity
2026-03-19 19:20:03 +00:00
Jon Ross-Perkins b14015602b Make Destroy.Op functions able to have a body (#6729)
This is iterating on how `Destroy.Op` generates, to start adding body
capabilities. This changes the way the signature is created, and adds a
`CoreWitness` function kind so that mangling can prevent name
collisions. The result is that what _was_ `DestroyOp` is now
`Core.Destroy.Op` or, as can be seen in
toolchain/lower/testdata/interop/cpp/nullptr.carbon,
`_COp.<hash>:core.Destroy.Core` where `:core` is indicating that it's a
core witness (taking a note from `:thunk`).

Assisted-by: Google Antigravity with Gemini 3 Flash
2026-03-02 17:57:31 +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
Dana Jansens fbc8d59d32 Introduce Diagnostics::ContextScope and remove diagnoser callbacks in type completion (#6761)
Introduces `Context` and `SoftContext` messages, which can be introduced
through a `ContextBuilder`:
- The `Context` messages come before the diagnostic in the output.
- The first `Context` message steals the diagnostic level from the main
diagnostic, and turns the main diagnostic into a Note attached to the
context.
- A `SoftContext` message works similarly, but if it's preceeded by a
`Context` or `SoftContext` message, then it is dropped. This can be used
as a default/backup scope when nothing more interesting is provided up
the stack, such as in `TryEvalBlockForSpecific`.

The `ContextBuilder` is provided to a callback through
`Diagnostics::ContextScope`, an RAII type `AnnotationScope` but for
context messages.

This allows a high level operation to provide a context message like
"failed to identify facet type {0}" which will then be used as the error
if a diagnostic is produced during identification, with the latter
diagnostic attached as a note to explain why the contextual operation
failed.

In particular, this allows monomorphization errors (such as an array
bound being negative) to be attached to a higher lever operation instead
of being top-level diagnostics themselves, with the monomorphization
site being a note. This inverts the source code locations that appear in
the diagnostic, so that the top-level diagnostic points to the "user
code" which causes the monomorphization.

This is presented as an alternative strategy to #6753, which plumbed
diagnoser callbacks around to achieve the same goals.

We replace the diagnoser callbacks in type completion and operators with
ContextScope callbacks instead, which now provide better diagnostics for
monomorphization errors. Other callers to MakeSpecific do not yet have
ContextScopes introduced in order to turn monomorphization errors into
more interesting diagnostics.
2026-02-25 15:15:29 +00:00
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
Geoff Romer 3c324e4877 Add category to parameter format, and share some code. (#6730) 2026-02-13 22:20:05 +00:00
Jon Ross-Perkins 74969cab04 Generate non-final Destroy witnesses for symbolics (#6731)
This is related to #6727, but is generally a necessary fix even without
that issue. I'm not adding a specific test of #6727 because it should
also be covered by the tests in #6726.

Assisted-by: Google Antigravity with Gemini 3 Flash
2026-02-13 17:46:50 +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
Jon Ross-Perkins 47e551141f Change the package namespace to use the package name (#6495)
Instead of naming the root namespace `package` (because it's accessed by
the `package` keyword), change it to use the current package name. Note,
buried in the checksum changes,
`toolchain/check/testdata/package_expr/fail_not_found.carbon`:

```
-  // CHECK:STDERR: fail_not_found.carbon:[[@LINE+4]]:16: error: member name `x` not found in `package` [MemberNameNotFoundInInstScope]
+  // CHECK:STDERR: fail_not_found.carbon:[[@LINE+4]]:16: error: member name `x` not found in `Main` [MemberNameNotFoundInInstScope]
```

for:

```
  // CHECK:STDERR:   var y: i32 = package.x;
  // CHECK:STDERR:                ^~~~~~~~~
```

I'll leave it to you if you prefer this; the alternative I see is to
just rename `IsCorePackage` to `IsImportedCorePackage`, and/or change it
to a helper that takes a `Context` and does the right thing with
`parse_tree` (which, I need for `Destroy`-related reasons and was my
default approach).
2025-12-16 01:33:53 +00:00
Richard Smith 154e4012c4 Include the parent scope when fingerprinting an entity name. (#6473)
This is a prerequisite for support for interop with C++ template names.
No behavior change here, except that it sadly changes the fingerprinting
for a lot of tests.
2025-12-08 15:31:13 +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
Geoff Romer 2b8fdf3417 Switch the prelude to use ref instead of addr (#6359) 2025-11-14 00:40:26 +00:00
Jon Ross-PerkinsandDana Jansens 42e2280150 Clean up singleton TypeId use (#6300)
#6289 absentmindedly added fields in more places, and this is undoing
that plus further fixes.

This does some cleanup of types with relation to singletons. For
`TypeType` and `ErrorInst`, they're always complete due to a
`SetComplete` call in `file.cpp`. For `CppVoidType`, it's intended to be
incomplete by construction, and so a `TypeId` should be okay. The intent
though on not generally providing these had been that `GetSingletonType`
needs to be called to get a type to be marked as complete.

In the case of `AutoType`, removing `TypeId`does change a small printing
detail. I think that's old legacy that's just been carried forward.

Otherwise, for both `InstType` and `AutoType`, I've added
`GetSingletonType` calls where they were used in order to ensure
completeness is applied correctly. These calls cause small SemIR
permutations.

This causes `AutoType` to be seen by lowering, so I'm adding a
placeholder for it. Also merging two functions that look like they're
identical in intent -- not sure why they're separate.

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
2025-10-30 22:50:59 +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
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
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
Jon Ross-Perkins 4a6376cf59 Rename/restructure Destroy logic to better reflect #6124 (#6144)
This also does a little restructuring in the same direction, following
#6124.

Leads want `Destroy` to work similarly now for all types. As a
consequence, there doesn't seem to be as much benefit to splitting off
aggregate destruction. In this PR, the `type.destroy` function can now
be expected to destroy anything that's destructible; that means it'll be
usable for the `final fn` once that support is available.

Similarly, this gets rid of the impls other than the single blanket
impl, now using `type.can_destroy`. Since they all need to use the same
function, there's no benefit to splitting approaches. Also, now it can
just be a `final impl` since there should be no need for people to
create specializations -- if this blanket impl applies, it means the
`final fn` is the same.

This also slips in `partial` support since there's no reason to have it
diverge anymore. Also `abstract`, which I'm not sure is broadly testable
since most cases it'd come up, the `abstract` keyword is explicitly
detected/rejected.

Note though that this doesn't make any really big changes. It's just
realigning on the leads decision. I'm going this way to try to reduce
name-related churn for other changes.
2025-09-30 20:43:36 +00:00
Jon Ross-Perkins 47081be67a Reduce test sensitivity to small import loc changes (#6145)
Locations are similarly fragile, because adding a comment changes them.
This has made me pause when making prelude changes in #6144, so dropping
them for those cases.

Instruction ids aren't actually that interesting outside debugging, and
can be churny when doing other structural changes. I've seen this in
particular when doing singleton changes, which bump every instruction
id.

Note there are still other ways fragility from locations can crop up.
This shouldn't be considered a complete fix, but hopefully a small
improvement.
2025-09-30 17:20:14 +00:00
Jon Ross-Perkins 49ba8cf3e1 Switch class to use a blanket impl for Destroy (#6125)
Right now, the class destroy impl is incorrectly generated (first
discussed [in
Discord](https://discord.com/channels/655572317891461132/941071822756143115/1418614787449032826)).
If we want it to be correct, deferred definition logic would need to be
added, and the declaration would need to be moved inside the `class`
scope (along with whatever generic logic that needs).

This instead switches to a blanket impl, to avoid creating latent bugs
with generating the `impl` and function body in the wrong scope. This
approach uses the same blanket impl as aggregate destruction that was
added by #6098.

The intent here is to allow progress on other parts of `Destroy`. For
example, under this model the implementation of the function body could
be done as part of lowering the specific.
2025-09-29 16:05:06 +00:00
Jon Ross-PerkinsandDana Jansens 5e3bb523f8 Add builtin functions for destroy, with special requirements in facet types (#6035)
This is in support of a goal of changing the blanket `destroy` impl to
use (roughly):

```
private fn CanAggregateDestroy() -> type = "type.can_aggregate_destroy";

// Handles aggregate type destruction.
impl forall [AggregateDestroyT:! CanAggregateDestroy()] AggregateDestroyT as Destroy {
  fn Op[addr self: Self*]() = "type.aggregate_destroy";
}
```

That isn't done here because there's still other issues that migrating
raises. What this *does* do is add the builtin functions, and in
particular, support to `FacetTypeInfo` to make `CanAggregateDestroy`
work.

The "special requirement" approach in `FacetTypeInfo` allows us to
support restricting a blanket impl under the current approach of impls.
Maybe we'll find a cleaner approach that can work in the future, but
this fits into the current model by propagating similar to other
requirements. I'm using an enum mask because we have a number of similar
things to add (e.g. copy, move) but I'm not sure we need a full vector.

A few alternatives considered were:

- Supporting syntax more like `where .Self impls
TypeCanAggregateDestroy(.Self, SupportedInterface,
UnsupportedInterface)`. I think it'd be a little cleaner, but requires
better compile-time evaluation in order to assess the type of the call.
Right now it's expected to be a `FacetType` too early to make this work,
and I was concerned about pouring too much more time down this route.
- Providing an actual interface, in particular doing name lookup back
into `Core.` for an interface. This would've added name lookup overhead,
and the question of whether an `impl` exists.
- Generating an interface. This avoids the name lookup, but would still
raise the question of whether an `impl` should also be generated. Work
I've previously done generating interfaces for class destruction also
feels complex to both write and understand (an unfortunate issue).
- Still modeling as an `ImplsConstraint`, for example by defining a
special `InterfaceId::CanAggregateDestroy = -2` similar to what we do on
other ids. I was hesitant because of how this expands the number of
modes of `InterfaceId`, and things for consuming code to watch out for,
for what feels like a relatively niche set of use-cases that are only
interface-like.

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
2025-09-15 17:03:43 +00:00
Richard SmithandGeoff Romer 1ec8ac7ef9 Add Copy interface and use it for making copies. (#6034)
Instead of hardcoding which types are copyable, add a `Core.Copy`
interface to perform copying. Move almost all the current copy support
to that interface. Some remaining pieces are still using builtin logic
after this PR:

* For tuples and structs, builtin logic is used to perform elementwise
copies. This also supports copying *adapters of* tuples and structs,
which seems like it may not be desirable, especially for non-extending
adapters. A `Copy` impl is provided for tuples of at most 2 elements, so
that `Core.Copy` constraints are satisfied, but we can't implement this
generally until we have variadics support, and don't yet have a
mechanism to generalize this to structs.
* For `enum` types imported from C++, builtin logic is used to perform a
copy. This is temporary until we have a mechanism to identify these
types from an impl in the prelude.

One lowering test in `toolchain/lower/testdata/class/generic.carbon` is
disabled for now, as it causes a crash in the lowering code due to an
ABI mismatch between the call signature in the lowered declaration of a
specific function and the call that is generated in the specific callee.
Fixing this is a little involved, and will be done in a separate PR.

---------

Co-authored-by: Geoff Romer <gromer@google.com>
2025-09-10 23:55:55 +00:00
Richard Smith e8cd229e74 When performing an impl lookup, only import impls for related interfaces. (#6040)
This avoids impl lookups involving, say, `Core.Int` pulling in all ~65
impls in "prelude/types/int", which resulted in a lot of unnecessary
importing work, followed by a lot of unnecessary inst namer and inst
formatter work.

Before:
```
Ran 1335 tests in 6186 ms wall time, 146818 ms across threads
  Slowest tests:
  - toolchain/check/testdata/interop/cpp/function/arithmetic_types_bridged.carbon: 5611 ms, 5532 ms in Run
  - toolchain/check/testdata/interop/cpp/function/operators.carbon: 2034 ms, 1981 ms in Run
  - toolchain/check/testdata/primitives/import_symbolic.carbon: 1796 ms, 1786 ms in Run
  - toolchain/lower/testdata/operators/arithmetic.carbon: 1729 ms, 1728 ms in Run
  - toolchain/lower/testdata/function/generic/call_recursive_sccs_deep.carbon: 1700 ms, 1697 ms in Run
[==========] 1335 tests from 1 test suite ran. (682 ms total)
```

After:
```
Ran 1335 tests in 2419 ms wall time, 109587 ms across threads
  Slowest tests:
  - toolchain/check/testdata/interop/cpp/function/arithmetic_types_bridged.carbon: 1748 ms, 1665 ms in Run
  - toolchain/check/testdata/interop/cpp/function/operators.carbon: 1106 ms, 1057 ms in Run
  - toolchain/lower/testdata/function/generic/call_recursive_diamond.carbon: 1044 ms, 1041 ms in Run
  - toolchain/lower/testdata/function/generic/call_recursive_sccs_deep.carbon: 1015 ms, 1012 ms in Run
  - toolchain/lower/testdata/operators/arithmetic.carbon: 998 ms, 997 ms in Run
[==========] 1335 tests from 1 test suite ran. (652 ms total)
```

That's still slower than it should be, but a large improvement
nonetheless.

Fixes #6029
2025-09-10 21:40:27 +00:00
Dana Jansens ed43fd2c1c Give the BindSymbolicName for .Self in a binding pattern a FacetType type (#6036)
If it's just `TypeType` then the `BindSymbolicName` appears directly in
type positions, but if it is replaced with another facet value, then we
would need to insert a `FacetAccessType` around it. By giving it a
`FacetType` type, like other `BindSymbolicName`s we make it consistent
and avoid having to introduce extra instructions.
2025-09-10 17:57:08 +00:00
Jon Ross-Perkins 0518fdebbc Fix potential fingerprint conflict in constraints (#6033)
This uses each vector's size as a barrier between lists, to eliminate
the possibility of incidental collisions between entries of different
lists. This is the same as is done inside `AddBlock`.
2025-09-09 21:44:03 +00:00
Dana JansensandJon Ross-Perkins 4b0e2b03b6 Add the .Self name for the type expression of a compile time binding (#5937)
We add a virtual node (`CompileTimeBindingPatternStart`) as the first
child of `CompileTimeBindingPattern` which holds the identifier
underneath it, so that it is checked just before the type expression of
the `CompileTimeBindingPattern`. When we reach this virtual node during
check, we add `.Self` as a name in the current scope, and when we reach
`CompileTimeBindingPattern` we remove it from scope, which ensures it's
present during only the checking of the type expression for the compile
time pattern.

At the moment the `.Self` has a different type (it's a `TypeType`) than
other `.Self` in the facet type (which are a single `FacetType`), but
the intention is to immediately substitute it out of the facet type
entirely, replacing it with a reference to the compile time binding (a
`BindSymbolicName`) itself. A TODO has been added for this.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2025-08-12 16:27:07 +00:00