Commit Graph
1758 Commits
Author SHA1 Message Date
oli-ej 5ae3dcaa92 allow trailing commas in a struct pattern after an _ field (#8074)
Following a leads decision
(https://github.com/carbon-language/carbon-lang/issues/7404), this PR
adds support for trailing commas in a struct pattern where it was
previously only allowed after a full field.
2026-11-03 22:02:33 +00:00
Nicholas Bishop 66f03aecb1 Export class friends to C++ (#8068) 2026-11-03 18:28:21 +00:00
Dana Jansens 9fb428d713 Ensure specific in ImplWitness has resolved definition before accessing witness table (#8040)
When impl lookup results in an `ImplWitness`, either directly or later
through `LookupImplWitness` evaluating to an `ImplWitness` inside some
specific, it represents a dependency on the eval blocks of the
`ImplDecl` that the `ImplWitness` comes from. The `ImplWitness` contains
a `SpecificId` of the `ImplDecl`, and the constants in the witness table
must be viewed through that `SpecificId`. The constants may depend on
the declaration or the definition block of the `ImplDecl`'s specific, so
any use of the witness table from `ImplWitness` requires the specific
from the `ImplWitness` to be fully resolved: both the decl and
definition blocks.

The specific declaration block is always resolved immediately when
forming a specific id, so there's nothing to do there. And things are
simple when the `ImplWitness` returned from impl lookup is concrete. We
would simply resolve the specific definition directly in the evaluation
of `LookupImplWitness`.

But when the `ImplWitness` is symbolic, meaning there's a dependency on
generic parameters in its referenced specific, then we have a dependency
on resolving the specific definition in the `ImplWitness` for every
specific that gets applied to the `ImplWitness`, eventually resulting in
a concrete specific.

Previously we attempted to do this by representing a dependency edge
from the eval block containing the `ImplWitness` instruction to the
definition block of the specific inside the `ImplWitness`. We
represented this dependency edge with the `RequireSpecificDefinition`
instruction.

The challenge with the `RequireSpecificDefinition` instruction was
ensuring it always landed in the _same eval block_ as the one holding
the symbolic `ImplWitness`. Ultimately, we've found a way to do this
without the `RequireSpecificDefinition`. The witness table is accessed
through `ImplWitnessAccess`, so we resolve the specific definition
before each access to the witness table. If the definition is already
resolved, this just costs a lookup of the Specific from the value store.

We document the other things we tried, which don't work or were too
complex, below.

In PR #6236, we added the `RequireSpecificDefinition` instruction in the
eval of `LookupImplWitness`, but this is too late. If impl lookup
resolved to a symbolic `LookupImplWitness`, the `LookupImplWitness` is
added some eval block. Later, we form specifics and re-evaluate that
eval block, and the `LookupImplWitness` can evaluate to an
`ImplWitness`. Adding the `RequireSpecificDefinition` instruction at
this point inserts the instruction into whatever generic's eval block
happens to be on the top of the generic stack, not the eval block of the
generic we are building a specific for. And indeed we can't add
instructions to a generic's eval block later like this, as it would be
missing from specifics that were already resolved for the generic. This
incorrect insertion shows up as a crash in eval at the CHECK introduced
but commented out in [eval.cpp in
#7981](https://github.com/carbon-language/carbon-lang/blob/56d9bbc40add1e9263f2f9b2555c3a27292d1725/toolchain/check/eval.cpp#L3507-L3512).
This is covered by the
`require_specific_impl_definition_through_specific_instantiation.carbon`
test.

We tried moving the insertion of `RequireSpecificDefinition` to be
earlier - at the point where the `LookupImplWitness` is constructed, in
the `LookupImplWitness()` function, instead of inside evaluation. This
seemed like a straightforwardly correct answer, as the eval block that
contains the `LookupImplWitness` will then also contain the
`RequireSpecificDefinition`. However, this can cause us to lose the
`RequireSpecificDefinition` entirely. Because it's a separate
instruction, not an operand of `LookupImplWitness`, it does not get
treated as a dependency of the witness. When we do an impl lookup inside
an `alias`, we build a generic for the alias and then discard it. This
discards the eval block containing the `LookupImplWitness`. Then, in an
enclosing generic, we refer to the constructed `AliasDecl` instruction,
which pulls all its dependent operands into the enclosing eval block.
This pulls in the `LookupImplWitness` into the enclosing eval block, but
it does not preserve the `RequireSpecificDefinition`. This is covered by
the
`require_specific_impl_definition_from_lookup_impl_witness_in_class_definition.carbon`
test.

We tried having `ImplWitness` evaluation resolve the specific definition
of the specific `ImplDecl` it refers to. This seems like the simplest
approach by far as we should always be working with the correct eval
block and nothing can get lost. However it does not work because of the
recursive nature of `ImplWitness`. The `ImplWitness` instruction appears
in the declaration of an `ImplDecl`, and the `ImplWitness` holds a
`SpecificId` for that same `ImplDecl`. When building a specific
`ImplDecl`, we evaluate the `ImplWitness` in the `ImplDecl`'s
declaration block which then immediately resolves the specific
definition before the declaration is finished. This leads to missing
instructions in the specific definition. In short, this puts the
dependency edge to the `ImplDecl`'s specific inside the `ImplDecl`
itself, which is problematic.

We tried wrapping `ImplWitness` in another instruction,
`ImplWitnessUse`. Inside the `ImplDecl` declaration there is still
`ImplWitness`, but then in the definition there is `ImplWitnessUse` and
that is what is returned from the evaluation of `LookupImplWitness`. The
`ImplWitnessUse` is an `ImplWitness` plus it ensures the specific
referred to by the witness has its definition resolved. However this
breaks constant comparisons, as we get different witnesses inside an
impl versus outside.

The first iteration of this PR's solution had us insert the
`RequireSpecificDefinition` into the eval block when we sniffed a
`LookupImplWitness` instruction, however that missed cases where impl
lookup immediately resolved to a symbolic `ImplWitness`, which is why we
now sniff for the `ImplWitness` in the eval block. This is covered by
the
`require_specific_impl_definition_from_symbolic_impl_in_class_definition.carbon`
test.

We also originally made a mistake of not inserting
`RequireSpecificDefinition` when inside the impl definition that the
`ImplWitness` refers to. But we can form specifics ImplWitness values
through function signatures, and these must add the dependency edge on
that specific ImplDecl definition. This is covered by the
`require_specific_impl_definition_from_inside_impl_definition.carbon`
test.

Finally, we did have a working solution. It was to sniff instructions
added to the eval block of a generic, and when an `ImplWitness` is added
to the eval block (it is implied that it is symbolic), also add a
`RequireSpecificDefinition` to that eval block immediately. We also
resolved the definition of a specific referred to by `ImplWitness` when
`LookupImplWitness` evaluates to `ImplWitness` to cover the concrete
witness case. This complicated the construction of the eval block
immensely, however. It caused a situation where adding one inst to the
eval block actually adds two, which we needed to avoid when importing.
And it required inst-kind specific behaviour in the very general
construction of an eval block, completely outside of eval itself.
2026-11-03 14:15:14 +00:00
David BlaikieandChristopher Di Bella d99b767dde Export fields of imported Carbon classes to C++ (#8021)
When a Carbon class from another library was used from C++, its fields
were never exported, so C++ member access failed with 'no member named'.
The class scope of an imported class holds import references rather than
`FieldDecl`s, so `LookupClassFieldByStructField` didn't find them.
Resolve scope entries to their constant `FieldDecl`, load the import
references before exporting fields, and consistently key exported fields
by the `FieldDecl`.

Unfortunately `SemIR::LookupClassFieldByStructField` can't call
`LoadImportRef` because `SemIR::LookupClassFieldByStructField` is in
`SemIR` and `LoadImportRef` needs a `Check::Context` (and `check`
depends on `sem_ir`, not the other way around, so `sem_ir` can't use
check). So instead, make a `Check::LookupClassFieldByStructField` that
wraps the `SemIR` version, and does the `LoadImportRef`

Assisted-By: Claude

---------

Co-authored-by: Christopher Di Bella <cjdb.ns@gmail.com>
2026-11-02 20:37:01 +00:00
Dana Jansens be0f11be95 Build a generic scope around where expressions (#8062)
A `where` expression can have symbolic references to `.Self` inside it,
but those references do not represent symbolic instructions that should
be part of an enclosing generic eval block. They are internal details of
the facet type, and as such they are PeriodSelfSymbolic, not Symbolic.
The WhereExpr evaluation is careful to produce a Symbolic constant value
only if it has symbolic dependencies on the LHS of the `where`, which
avoids leaking the symbolic nature of `.Self` into he facet type's
constant value.

But until now, those PeriodSelfSymbolic insts could still leak into the
enclosing eval block if they ended up in an operand of a Call
expression. A compile-time Call expr evaluates to a TemplateSymbolic
phase constant if it's not concrete, which includes PeriodSelfSymbolic,
because we don't want to evaluate the Call expr until the `.Self` gets
replaced during identify. But that means the Call constant value, and
its operands including PeriodSelfSymbolic constants, all end up in the
eval block. We fix this by making Call evaluate to a PeriodSelfSymbolic
phase if its input phase is PeriodSelfSymbolic. This keeps the RHS of
the `where` expression self-contained. If the facet type is concrete,
then it doesn't add any instructions to the enclosing eval block (which
may not exist at all in a non-generic context). Regardless, when we
identify the facet type and replace `.Self`, the dependent Call
expression will be rebuilt as well and it will evaluate as appropriate.

We also enclose the `where` expression in its own generic scope. This
means that instructions which are not part of the facet type do not end
up in an eval block. They may be symbolic instructions, and they will
not get updated by a specific when it's applied the enclosing generic
anymore. But since they are not part of the facet type their
substitution is not required.

The new test had an incorrectly elided SpecificImplFunction instruction
in the resulting semir, as SubstPeriodSelf was using the location of the
input canonical instructions as the location for the results which
resulted in an instruction without a location. We fix that by using
`loc_id_` in the subst rebuild.

Formatting now saw the initialization of a value from an `eval fn` call
to a function in a witness table, so it needed to be taught to look
through ImplWitnessAssociatedConstant (which is what we find in the
witness table).
2026-11-02 20:05:00 +00:00
Chandler CarruthandRichard Smith 68569d234d Improve lexer and parser diagnostic locations (#7990)
Lexer diagnostics used a single `const char*` as their source location,
which only allowed pointing at a single character rather than a run of
characters. This limited the underlining of unrecognized tokens, and
also made escape sequence diagnostics particularly strange by stopping
at whatever point the lexer discovered the error and pointing only at
that location. For example: `"\w"` was reported at the `w`, and `"\x"`
at the closing `"`.

This change tries to always keep the primary location of a diagnostic
the point at which typing (inserting or deleting) might fix the error.
So for `"\x"`, `\x` is underlined, but the position is at the `"` as
that's where you would type a hex code.

The lexer's emitter now takes a special lexing source location that
represents either a single position _between_ two characters, a single
character, or a range of the source buffer. The lexer diagnostics are
updated to construct these for the character range as appropriate.

Parser diagnostics for a missing token were located at the _next_ token,
which is particularly confusing for terminators like missing `;`s. Now
they are located at a position after the previous token, with or without
a space depending on the token, but typically on the same line.
Diagnostics still sort by how far the parser has read.

The parser diagnostics for unclosed groups also now attaches a label to
the opening token when it is on a separate line. And the diagnostics for
mismatched indent in a multi-line string attaches a label to the closing
`'''` that establishes that indent.

There are likely more location improvements we should do here, but this
seemed like a reasonable incremental improvement and is what Claude
found when doing an initial audit. One example where I think we should
make further improvements is around suggesting raw identifiers when we
find an unexpected `Cpp` or `Core` or `base`. We do this consistently
now, but raw identifiers should be rare. A TODO is added for these
cases.

Assisted-by: Claude Code

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2026-11-01 06:22:00 +00:00
Chandler Carruth c608c35e12 Rework the initial terminal rendering into the form the design landed on (#7994)
There were a number of iterations on the design that weren't reflected
in the initial port to the terminal rendering library. This PR tries to
complete the rendering side of things to match the design we landed on:
code-focused, with messages attached by lines to the code, and condensed
as much as possible to avoid the vertical space.

It also improves the styling to make things more visually
distinguishable such as adding a `->` to the main error line, and making
the underlines and connectors for it have a heavy weight (when the font
supports that).

Another major change is having multiple messages on a single line be
drawn in source lexical order. This requires the connectors to cross
without joining, but makes it easier to read the messages.

This PR also has some refactorings to enable these improvements, and a
_number_ of improvements to comment prose and terminology to try and
avoid jargon and make things read more naturally. Sorry for the fact
that Claude left a bunch of this mannerly language in comments despite
my efforts, but I'm continuing to try and drive the prose towards
something direct and simple to read. Some of the terminology
improvements also needed to be made in the design doc and those have
been made here.

Note that I don't think this rendering is perfect or should be viewed as
final. I'm happy to iterate on it further, and have a few adjustments in
mind already, but would like to focus this on getting the
_implementation_ of the current rendering design in place, and then we
can make targeted changes or tweaks as needed. For example, I'm not yet
fully happy with the rendering when messages are too long and we move
them all the way to the left, but am leaving that for a follow-up.

Assisted-by: Claude Code
2026-10-31 06:10:03 +00:00
oli-ej c6b54b57e2 Add check support for struct patterns (#7876)
Implements check and pattern matching support for struct patterns.

This PR implements complete patterns, and leaves `_` field handling for
future work.
2026-10-30 21:03:16 +00:00
Nicholas Bishop 54f37b35bd Fix Carbon methods always being exported as public to C++ (#8063)
Add access tests for private fields and methods, in both regular classes
and generic.

Modify `BuildCppToCarbonThunkDecl` to properly set the access rather
than always using public.

Also add `static` to a method that isn't used outside export.cpp.
2026-10-30 20:06:21 +00:00
Richard Smith 6d51427790 Add tests for generic terse function declarations. (#8051)
We have test coverage for both features in isolation, but it seems
worthwhile having coverage for the combination of the two.
2026-10-28 15:33:40 +00:00
Dana Jansens a450026679 Clarify the infinitely recursive types through interop test (#8046)
This test generates an infinite recursion between Carbon and C++ making
a new type at each step through the recursion, producing an infinite
number of types. We improve the test in a few ways:
- Remove direct dependencies on min_prelude parts, we should just depend
on a single min_prelude, and not `import Core` explicitly.
- Remove a dependency on `i32` so we rely on less prelude.
- Remove the use of pointers, which currently introduce a dependency on
`Optional`, so we rely on less prelude. Instead use a generic `Wrap(T)`
type that we nest repeatedly to generate types.
- Add some comments and expand function names to help explain the
behaviour being tested

Now the test just depends on the convert.carbon prelude, which makes it
much simpler when running under a debugger.
2026-10-27 20:58:00 +00:00
Christopher Di Bella 05a7ecbd34 Move SubobjectDestroy and SelfDestruct out of interface Destroy (#7942)
Determining that a type has trivial destruction requires checking
whether all of its subobjects have trivial destruction and whether its
type has a custom witness for `Destroy.Op`. This isn't possible when
`Destroy` is the custodian for `Destroy.Op` and `SubobjectDestroy.Op`,
so we need to make `SubobjectDestroy` its own interface.

`Destroy.SelfDestruct` becomes a standalone function because it depends
on `SubobjectDestroy` and `Destroy` being implemented, and is also
responsible for generating any custom witnesses for both interfaces.
Making `SelfDestruct` an interface was experimented with, but this
required a blanket impl that caused issues for facet types.

`Destroy` depends on `SubobjectDestroy` to be implemented. We'd ideally
use `require impls SubobjectDestroy`, but it isn't complete yet, and it
also causes problems when `Destroy` is implemented inside the class
definition. We work around this by temporarily renaming the `Destroy`
interface to `DestroyImpl`, and introducing a constraint called
`Destroy` so that user code doesn't need to write `Core.SubobjectDestroy
& Core.Destroy`.
2026-10-26 21:35:01 +00:00
Christopher Di Bella 57bf903ef1 Keep resolving generics and templates until they're all resolved (#7957)
`FinishAst` resolves C++ template instantiation. Template instantiation
can complete Carbon types, generate thunks, and call generic functions.
These operations can add new entries to `definitions_required_by_use()`.
Similarly, resolving any of those can generate more C++ templates that
need instantiating. This change moves `FinishAst` ahead of
`CheckRequiredDefinitions` and loops until no new Carbon definitions
have been added. This prevents later passes from crashing when
evaluating specifics on unresolved generics or uninstantiated templates.

`FinishAst` also disconnects the AST. Subsequent definitions and `impl`s
may depend on C++ interop, so the AST must remain connected until all
the Carbon end-of-file checks complete. We achieve this by decoupling
AST disconnection from finalisation.

Assisted-by: Antigravity with Gemini
Assisted-by: Antigravity with Claude Opus 5.5 Max
2026-10-26 20:52:43 +00:00
Nicholas Bishop 56d9bbc40a Support C++ friend declarations for Carbon generic classes (#8026) 2026-10-26 17:09:43 +00:00
Lucile Rose Nihlen c7de727575 Adds support for exporting default values for concrete parameters of generic functions. (#8019)
Adds support for exporting both the generic function decl with concrete
default arguments to clang, as well as exporting the monomorphized
concrete function def.

This required adding the `SpecificId` to the exported global variable
name, to avoid duplicate names in the global vars. I also now set up an
evaluated context in `clang_sema` when declaring the default arg
expression with clang, to avoid the problem of emitting concrete AST
expressions in an unevaluated context from the in-progress template
function decl context when exporting default values for generics.

Note: Default values for generic parameters of generic functions are not
yet supported.
2026-10-26 16:21:41 +00:00
Lucile Rose Nihlen 427c448dcd Simplify the generic function default values test. (#8027)
As demonstrated in #8020, removes an extraneous
dependency on `Core.Copy` in favour of a locally
declared interface.
2026-10-24 01:34:40 +00:00
Dana Jansens bcb236e6cd Some comment fixups from #7401 (#7421) 2026-10-23 19:59:09 +00:00
Nicholas Bishop 6f6a01f859 Support C++ friend declarations for Carbon classes (#8018)
When importing a C++ class, check for friend declarations for types and
add them to the Carbon class's `friend_scopes`.
2026-10-23 17:07:13 +00:00
Nicholas BishopandChristopher Di Bella 434c564a94 Fix crash when diagnosing an invalid qualified name access (#8012)
If a generic class inherits from a private parent (as allowed in C++),
and attempts to access a member of that private parent, an error should
be diagnosed via `DiagnoseInvalidQualifiedNameAccess`.

A couple changes are needed to make that work, because the access
constant in this case is not a `ClassType`. Instead, it's a
`StructValue` of type `ParameterizedClassType`. So, use
`TryGetTypeIdForTypeConstantId` instead of `GetTypeIdForTypeConstantId`
(to get `None` instead of asserting on a non-type constant), and allow
getting the class ID from both `ClassType` and `ParameterizedClassType`.

---------

Co-authored-by: Christopher Di Bella <cjdb.ns@gmail.com>
2026-10-22 19:13:10 +00:00
Dana Jansens 2c39bd57d3 Simplify the generic_facet.carbon test a bit (#8020)
Drop dependencies on the prelude so it can be debugged with no prelude
import if needed. Ensure the return type of MakeC is used in C++ since
it's part of the imported function signature.
2026-10-22 18:37:13 +00:00
Lucile Rose Nihlen 3dbf76af0d Add some support for exporting constrained generic types to C++ (#8017)
Adds a check for constrained facet types and extracts the type from the
constraints before supplying it for conversion to C++ types. Adds a test
for this functionality.
2026-10-22 17:26:25 +00:00
Lucile Rose Nihlen 503f09037d Add support for default values for non-generic parameters of generic functions. (#8011)
A first step in expanding support for default values for parameters in
generic functions.

Adds code to parameter type deduction to include default values for
absent call arguments. In support of that, this PR also generalizes a
function from `export.cpp` that is useful to extract a default
`ConstantId` value from an arbitrary function paramater pattern.
2026-10-21 21:03:39 +00:00
Christopher Di Bella 04f456dddd Handle SpecificConstant in FindStorageArgForInitializer (#8010)
`FindStorageArgForInitializerInSpecific` is missing a `SpecificConstant`
case, and crashes due to the function not expecting `SpecificConstant`.
`SpecificConstant` should be handled by this function, as it derives its
expression category from the instruction it wraps.

Consider this example:

```carbon
interface I {}
interface J {}
constraint C {
  extend require impls I & J;
}
```

Calls, such as `I & J`, are initializing expressions. `extend require
impls` wraps the call in a `SpecificConstant`. This code crashes when
asking for its storage, such as during formatting for `--dump-sem-ir`.

This commit adds a case for `SpecificConstant`, deferring to its wrapped
instruction when transitive lookup is allowed, and reports no storage
otherwise.

Assisted-by: Antigravity with Claude Opus 5.5
2026-10-21 20:04:27 +00:00
Dana Jansens ac31fd1985 Give IdentifiedFacetType a more foolproof API (#8008)
The values in `IdentifiedFacetType` may contain `IdentifiedWitness`
instructions, and those insts need to be either converted to
`LookupImplWitness` and evaluated as such, or substituted by the user of
the `IdentifiedFacetType` with witnesses of its own.

This changes the API so that the user must go through a method doing one
of those two things to get to the underlying values in the
`IdentifiedFacetType`, unless they explcitly request to bypass them.

Then we split extend impls requirements out into their own set so that
the user can determine what is being extended _after_ evaluation or
substitution of `IdentifiedWitness` insts. This is critical because we
can not dedupe SpecificInterfaces until after that takes places, as
demonstrated by the test fixed by this PR.
2026-10-21 18:32:30 +00:00
Geoff RomerandDana Jansens 4441c53404 Simplify GetConstantValue (#8005)
- Resolve Specifics eagerly during evaluation. Previous import changes
have made deferral unnecessary. This simplifies the code and unblocks
the next item.
- Overload `GetConstantValue` for all ID kinds, rather than having a
separate `GetConstantValueOrPassThrough` function, so that callers don't
have to choose between them.

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
2026-10-20 23:21:00 +00:00
Dana Jansens db87a84b69 Improve tests and clarify design for observe equivalence chains (#7987)
Update tests for observe equivalence chains to cover more cases and to
better test the things they meant to. The design is clarified to explain
that in an `interface` the types in an equivalence chain must all be
related to that interface except for one.

This is based on #7484 with some followup changes by me.

Co-authored by: ozguronsoy@gmail.com
2026-10-20 21:29:09 +00:00
Dana Jansens eb66bebc35 New specifics formed during identify need to be marked identified (#8003)
We were explicitly marking the specifics of `require` decls as
`identified` when creating them during identify. But the require may
contain calls to other generics internally. And forming the specific for
the `require` can also form new specifics for those calls, if they
depend on `Self`. The resulting specific can have `IdentifiedWitness`
instructions in its arguments, in accesses or FacetValues, etc. Or they
may appear in the decl block as it's resolved. So it's very important
that the specifics be marked `identified`, as those witnesses may only
appear in `identified` specifics. This allows the new
`access_through_nested_specific_in_named_constraint.carbon` test to
succeed without any poisoning errors.

SemIR formatting is changed so that `identified` specifics are more
clearly differentiated where they are used, so that we can see if
`identified` specifics are misused outside of identifying.

Now that we construct more `identified` specifics, we also need to
ensure we remove the `identified` state from specifics that come out of
`EvaluateIdentifiedWitnesses` and `SubstIdentifiedWitnesses`. To do that
we add a new callback method on `SubstInstCallbacks` that we use to
build specifics during subst. Then during those operations, we drop the
`identified` flag from any specific that we form, because we know that
we have also removed any `IdentifiedWitness` instructions because:
- We replace them all from arguments during subst.
- We CHECK that we're not in the middle of identifying before starting
the subst.

However now an `IdentifiedFacetType` is not fully deduped, because it
may contain a non-identified specific that comes from a
`DeclaredFacetType` along with an identified specific that comes from a
named constraint, where they have the same arguments. That results in
the `IdentifiedFacetType` having two specific interfaces when it really
only refers to one. The
`fail_todo_impl_as_constraint_duplicates_interface.carbon` test
demonstrates this, and that we then diagnose an `impl` as invalid since
we find more than one specific interface being extended. To fix this we
need to dedupe and count specific interfaces _after_
substituting/evaluating away the IdentifiedWitnesses. This is left to
future work.
2026-10-20 21:18:50 +00:00
Nicholas Bishop 2e21255855 Partial support for a generic class inheriting from a virtual C++ class (#8007)
This allows a generic class to inherit from a virtual C++ class as long
as the subclass doesn't override any methods. See
toolchain/lower/testdata/interop/cpp/class/import/inherit.carbon for a
working example.

The TODO in `CheckCompleteClassType` is now in
`CarbonExternalASTSource::CompleteType`, and only triggers if virtual
function thunks need to be defined.

A fix in `FileContext::BuildVtable` is also needed: when looking up the
clang decl associated with the vtable, if the class is generic then the
`ClassTemplateSpecializationDecl` associated with the specific is
needed. This required adding `ConstantStore::Get`, since only `const`
access is allowed during lowering.
2026-10-20 20:43:34 +00:00
Lucile Rose Nihlen 9799a23262 Export function default values to C++ (#7988)
Adds code to track default values for function parameters in C++ export,
and to export them as global variables to C++ that are attached to
default value expressions in the clang AST.

Modifes lower to export global variables from another block, and adds
the variable initialization to the `global_init` block so their value
gets set at load time.
2026-10-20 20:38:22 +00:00
Bartłomiej Rosa 505c4ae308 Fix crash building impl witness thunks for constrained generic methods (#7956)
When building an impl witness thunk for a generic associated function,
trailing self-specific arguments could still mention outer interface
parameters (or `Self`) in their types. That left a SymbolicBinding that
did not belong to the thunk's generic, and evaluation aborted instead of
succeeding.

Substitute the outer specific arguments into those trailing arguments
with `SubstConstant` before adjusting bind indices.

Fixes #7919.
2026-10-19 21:10:56 +00:00
Dana Jansens 2b5f90cd74 Diagnose a witness table entry being set to multiple different values (#7996)
If the entry is set to the same value, accept it. If it's a different
value, diagnose it.
2026-10-19 19:35:11 +00:00
David Blaikie 309d3d63c5 Use IndirectIndexWith.Ref for subscripting when available (#7975)
When checking `a[i]` for a non-array type, first try
`IndirectIndexWith.Ref`, falling back to `IndexWith.At`, per the
indexing design. This allows subscripting to produce a reference
expression, so that `a[i] = v` works and non-copyable elements can be
accessed.

Extracted from #7536 (the `Core.Slice` proposal).
2026-10-17 00:14:10 +00:00
Richard Smith e8ffeef7b5 Add tests for generic functions with ref, val, and var auto returns. (#7997)
Assisted-by: Claude via Antigravity
2026-10-16 22:42:21 +00:00
Richard Smith b766aa4d16 Support for terse => function bodies (#7895)
Treat the function as having a `-> auto` return type. Reject calls to
functions that still have a non-deduced `-> auto` return type, and
rewrite the function to have the actual return type once it is known.

Assisted-by: Gemini via Antigravity
2026-10-16 21:48:48 +00:00
Richard Smith d08805f1a6 Fix Carbon:: name leakage across files. (#7973)
Split the `Carbon::` namespace into one semantic namespace tree, plus
one separate lookup-only namespace tree per Carbon file. Use the
semantic namespaces as the parents of entities, but use the lookup-only
namespaces when C++ name lookup names a Carbon namespace, in order to
use a different C++ name lookup table in each Carbon file.

Assisted-by: Gemini via Antigravity
2026-10-16 20:59:16 +00:00
Richard Smith 0d3b606a56 Support calls to generic functions with deduced return types. (#7981)
When a deduced return type depends on the function's generic parameters,
it's computed by the definition's eval block, so resolve the specific's
definition at the call. Calling a specific during its own instantiation,
before the point where its return type is deduced, is diagnosed like any
other use of the function before its return type is known. Also allow
exporting such functions to C++.

Resolving such a specific from within a checked generic can perform
template actions with symbolic arguments. Perform delayed actions in a
discarded generic region so the instructions they create aren't attached
to the generic being checked, and check that evaluating a specific
doesn't add anything to an enclosing generic region.

Assisted-by: Claude via Antigravity
2026-10-16 19:41:02 +00:00
David Blaikie 6d80ceb58e Add the IndirectIndexWith interface to the prelude (#7974)
Matching the API as described in the update in #5434, with a `Ref`
rather than `Addr` function (and `ref` rather than pointer return form).
Also added a blanket `final` impl of `IndexWith` when the element type
impls `Copy` (since `IndexWith` requires copyable elements) - which
differs slightly from the design wording, which doesn't account for the
copyability requirement.

Proposal #5389 (in review) would rework these interfaces, but this
should do for now until that's finalized.

Tested using the interface directly - follow-up change will add the
subscript support to check.

Extracted from #7536 (the `Core.Slice` proposal).
2026-10-16 18:58:39 +00:00
Richard Smith f9c21d769e Improve code and tests for exporting of names to C++ after a lookup failure. (#7984)
Address some review comments from the review of PR#7935 on the changes
from PR#7933.

Consolidate `const_cast`s to a single place with an explanatory comment.
Improve test clarity and organization. Rename lookup-specific helper
function to avoid suggesting it is more broadly applicable.
2026-10-16 16:33:29 +00:00
Dana Jansens 77fc0a3ef3 IdentifiedWitness is not a final witness (#7985)
If we perform impl lookup during identify by resolving a specific, we
can run into IdentifiedWitnesses in a FacetValue. If the witness is the
only one in the FacetValue we may use it as a final witness, which is
not correct. IdentifiedWitness is not a final witness.

To test this, we add a test that places an IdentifiedWitness into a
FacetValue and then uses that facet value to get an associated constant.
If treated as a final witness, we try to do a lookup where the query
self contains the IdentifiedWitness and we crash coming across it in the
TypeIterator. We should never come across an IdentifiedWitness in an
impl lookup query.

The test also shows a case that should work but does not because of
`impl_lookup_no_symbolic_final_lookups`. We set
`impl_lookup_no_symbolic_final_lookups` while collecting witnesses to
avoid cycles in impl lookup. This test fails because of that. It
prevents us from forming a correct specific for the class `C` by
creating a specific where `C.C1` is a symbolic value. Later we try to
form the specific again, where we would see a concrete value for `C.C1`,
but the specific already exists, so we can't get to the concrete value.
2026-10-16 14:09:32 +00:00
Richard Smith 14a3de9ff1 Fix import of val and ref return forms. (#7989)
Importing a function with a `-> val` return form, such as `fn F() -> val
i32`, crashed because `TryResolveInstCanonical` had no case for
`ValueForm`. Also, an imported `RefForm` was given type `type` rather
than `Core.Form`.

Import all three primitive forms with a single function template.

Assisted-by: Claude via Antigravity
2026-10-15 23:54:56 +00:00
Dana Jansens fea77fe598 Be robust against an ErrorInst as the self when identifying (#7986) 2026-10-15 22:19:39 +00:00
Richard Smith 3af25cc1ba Support for -> ref/var/val auto. (#7977)
Extend support for return type deduction to also handle top-level
category specifiers.

Assisted-by: Claude via Antigravity
2026-10-15 21:13:38 +00:00
Dana Jansens f0b030f2c7 Allow the use of early impls constraints when forming a specific using .Self (#7980)
The rules in early impls are stored with frozen `.Self`. However when
forming a specific, we can perform an impl lookup query against a facet
type written outside of the current facet type, which means any `.Self`
in that facet type will _not_ be frozen. In order to compare a witness
from early impls with the non-frozen requirement, we need to thaw what
we get out of the early impls.

However there are also cases where we are doing a lookup against
requirements that are part of the current facet type, so the
requirements are frozen.

Rather than picking one, and having to thaw all impl lookup queries, for
example, we store the frozen and thawed copy of the early impls rule so
that we can satisfy lookup queries that involve either.
2026-10-15 21:03:34 +00:00
Richard Smith 09b79784dc Include the Carbon package name in the exported C++ namespace. (#7935)
When exporting `X` from Carbon package `Foo`, expose it to C++ with
fully-qualified name `Carbon::Foo::X`, not simply `Carbon::X`. This
ensures that C++ mangled names properly distinguish between same-named
Carbon entities in different packages.

Name *lookup* into `Carbon::` still uses the same rules as before: it
finds what a `package.` lookup would find in Carbon. So `X` is named
from C++ as `Carbon::X` still, and a lookup for `Carbon::Foo` fails,
even though `X`'s "true name" is now `Carbon::Foo::X`.

Assisted-by: Gemini via Antigravity
2026-10-15 20:26:05 +00:00
Richard Smith d87891f3a6 Fix diagnostic style issues (#7982)
Remove trailing `.`s and leading capitalization from diagnostics, and
separate clauses with `;` rather than `.`, per
https://docs.carbon-lang.dev/toolchain/docs/diagnostics.html#diagnostic-message-style-guide
2026-10-15 20:15:28 +00:00
Dana Jansens 7beb29f8b2 Use a fallback loc for diagnostics generated on canonical insts (#7967)
We allow using `InstId` as a `LocId` for diagnostics, which works great
in `handle_*` functions, where we are working with non-canonical insts.
And convert and pattern matching often are given non-canonical insts,
which they can use, or pull apart to find some other inst, and use those
as a location for diagnostics. However these operations can also be
called with canonical insts, which have no location. In that case if we
need to diagnose an error, it ends up not being attached to any code at
all. Since we always have a `LocId` somewhere up the call stack, pass it
along and in these places that handle canonical instructions too, use
`GetInstLocationOrFallback()` to get a valid location for diagnostics.

This is also similar to what eval does with its fallback `LocId`.

The result is that many diagnostics now have a location where they had
none before. It also means some insts don't get `<elided>` in formatted
semir for not having a location at all and thus not being in range.
2026-10-15 19:03:10 +00:00
Dana Jansens 3a1db6633c Verify the types in an impls constraint first (#7978)
When the LHS is not a type, or the RHS is not a facet type, that is the
most important error to give, so prioritize that. Only fall back to the
"no .Self present" when the types are correct.

This was especially confusing when the RHS _did_ contain a `.Self` but
was not a facet type.

Add TypeExpr::SetError, as the lack of this was the main reason for the
bad error checking ordering, as setting multiple fields was awkward when
an error was found.
2026-10-15 18:11:48 +00:00
Nicholas Bishop 08b752e888 Add missing fields to ClangDecl::Print (#7949) 2026-10-15 15:23:17 +00:00
Dana Jansens e39bdb7afa Resolve ImplWitnessAccess through the IdentifiedFacetType (#7947)
Instead of only looking for rewrite constraints in the declared facet
type, identify the facet type and collect rewrite constraints from named
constraints as well. This allows rewrites in a named constraint to be
found such as `T: N, U: T.X` where `N` is a named constraint that does
`extend require impls Z where .X = ...`. The type of `U` will be
whatever is specified in the rewrite of `.X` inside `N`.

Note this removes some more uses of SubstPeriodSelf from outside of
identify, which is a progression, as identifying is meant to be the way
to substitute `.Self` generally.
2026-10-15 15:13:47 +00:00
Chandler Carruth 2c9739799b Render diagnostics through the terminal library (#7683)
Diagnostic rendering was part of the data model: `Loc::FormatLocation`
and
`Loc::FormatSnippet` wrote plain text to a stream, so no capability,
color, or
terminal width could reach them.

A diagnostic is now one message with labels, contexts, and location
information
attached, and `Diagnostics::Renderer` draws it into a
`Terminal::Buffer`. The
design is in `toolchain/docs/diagnostics_rendering.md` (#7668),
authoring in
`toolchain/docs/diagnostics.md`.

Before:

```
example.carbon:6:3: error: 1 argument passed to function expecting 0 arguments
  Run0(1);
  ^~~~~~~
example.carbon:3:1: note: calling function declared here
fn Run0() {}
^~~~~~~~~~~
```

After:

```
error: 1 argument passed to function expecting 0 arguments
       ╭─┤ example.carbon:6:3
       ┆
     3 │ fn Run0() {}
       · ─────┬─────
       ·      ╰──┤ calling function declared here
       ┆
->   6 │   Run0(1);
       ·   ───────
       ╰────────────
```

`--no-diagnostic-snippets` gives a compact form, `example.carbon:6:3-9`.
File
tests use it; the rendering tests under `toolchain/diagnostics/testdata`
ask for
snippets.

C++ interop diagnostics are data now rather than text Clang drew:
`SemIR::ClangSourceLocId` names a `clang::SourceRange`, and a Clang
location is
marked as the point it names.

`StreamConsumer` moves to a `:renderer` target that `:emitter` does not
depend
on, keeping `common/terminal` out of `consumer.h`. Capabilities come
from the
file behind the error stream, so tests get plain ASCII.

`renderer_fuzzer` draws diagnostics built from fuzzer bytes with every
capability combination, since a shape the renderer doesn't expect must
never be
why the compiler dies while reporting a problem.

TODOs mark the follow-ups: line weights and crossing lines, wrapping
that keeps
a quoted type whole, and ordering diagnostics that share a byte offset.

Also: `IncorrectExtension`'s hint moves into its message, since its note
had no
location of its own, and `strip_noise` in `check_diagnostics.py` blanks
multi-line `#define`s instead of deleting them.

Assisted-by: Claude Code
2026-10-15 06:08:57 +00:00