Commit Graph
640 Commits
Author SHA1 Message Date
Nicholas Bishop e6b1679552 Add support for field initializers (#7238)
In handle_let_and_var.cpp, field initializers are now handled like
regular `var` initializers, by calling `LocalPatternMatch`.

In pattern_match.cpp, `FieldDecl`s with initializers are handled by
storing a value in `SemIR::File::field_initializers()`. This is a new
map where the keys are `FieldDecl` `InstId`s and the map values are
`InstId`s representing the initializer value.

In convert.cpp, `ConvertStructToStructOrClass` now has a `get_default`
function parameter that callers can use to provide a field default.
`ConvertStructToClass` uses this to provide a default from field
initializers.
2026-05-22 02:48:07 +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
Richard Smith be70c092fa Add a text mode for fingerprinting. (#7231)
The intent is to add visibility into how the fingerprint is computed, so
that fingerprinting issues and mangling collisions can be more readily
understood and fixed.

Assisted-by: Gemini via Antigravity
2026-05-19 23:16:51 +00:00
Richard Smith ce080b3549 Support unqualified lookup into extended interfaces from classes and impls (#7217)
When a class extends an interface, referring to a member name of the
interface as an unqualified name should refer to the class's
corresponding associated entity value, not to the associated entity
itself. Similarly, in an `impl`, unqualified names of associated
entities should refer to the `impl`'s corresponding value for that
entity.

To support this, we treat `impl`s as `extend`ing their implemented facet
type, and we make lookups into an extended facet type use the `Self`
type of the extending `impl` or `class` if lookup finds an associated
entity. We already did the latter if the extending entity was an
interface; this extends the existing support for these other cases.
2026-05-19 18:01:54 +00:00
Richard Smith b87f848db4 Fix passing mode computation for methods. (#7225)
We were incorrectly computing the index of the Clang implicit conversion
corresponding to method arguments. This led to wrong code and a crash in
lowering due to a calling convention mismatch.

Fixes #7224.

Assisted-by: Gemini via Antigravity
2026-05-18 20:30:23 +00:00
Nicholas Bishop 773ecdfac6 Implement static var class fields (#7215)
This adds the `static` token to the lexer and parses it as a modifier.

In check, `FullPatternStack::Kind::FieldDecl` is now used for both
static and non-static vars. Static vars get treated basically the same
as `NameBindingDecl`s.

Global initialization is used for static var initializers. To make the
necessary stack information available to `pattern_match.cpp`, the
`full_pattern_stack` and `decl_introducer_state_stack` are now popped
later in `handle_let_and_var.cpp`.

In lowering, each class's body is checked for `VarStorage` insts and
lowered the same as global vars.
2026-05-18 20:09:17 +00:00
David Blaikie 31db4a0931 Export virtual/abstract/override functions as virtual (#7211)
This provides enough to Clang so it can include these new virtual
functions in the vtable of Carbon types derived from C++ types.
2026-05-18 19:04:33 +00:00
josh11bandJosh L 832d46f01b Update LLVM (#7221)
Assisted-by: Google Antigravity

---------

Co-authored-by: Josh L <josh11b@users.noreply.github.com>
2026-05-18 17:06:58 +00:00
David BlaikieandRichard Smith 843323b864 Export virtual functions when exporting a class definition (#7210)
This allows Clang to correctly generate the vtable for the exported
class.

There's still something wrong with new virtual functions in the Carbon
type (left a TODO) - I thought it might be related to not flagging
the CXXMethodDecl as virtual, but my initial experiments don't seem to
back that up, so I'll look into it further separately.

There's also a test regression due to an virtual (well, abstract
specifically, but I think it'd happen with a virtual one too) function
in an abstract class taking `self` by value being rejected since
the abstract class can't be instantiated. Not sure if this is a correct
change - the test's behavior could be preserved by using `ref self`
instnead of `self` in this function. Is that reasonable/expected? Should
we not require a type to be complete when passing by value if we can
compute the value representation without such completeness?

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2026-05-15 23:53:12 +00:00
Richard Smith c9d8b59bbd Handle "gaps" in C++ vtables. (#7206)
Not every entry in a C++ vtable corresponds to a function that we want
to import. For the holes, leave a `SemIR::InstId::None` in the vtable.
Also mark vtables that extend a C++ vtable as being non-Carbon-native so
we don't try to lower them (and crash on the `None` entries).

In particular, we leave holes for destructors, since we don't have
destructor declarations on the Carbon side that need to override them.
2026-05-14 00:38:24 +00:00
Richard Smith 917856aff7 Export Carbon classes as base / final / abstract. (#7191)
* For Carbon `base class C`, export as a regular C++ class.
* For Carbon `class C`, export with the C++ `final` keyword attribute.
* For Carbon `abstract C`, mark the destructor as pure virtual in cases
where no member function is abstract, or emit an error if the destructor
is not virtual.

To support the final point, mark the destructor of an exported class as
virtual if it overrides a virtual destructor from the base class.

In passing, fix a crash exporting fields if the class has an invalid
base type.
2026-05-13 17:48:55 +00:00
Richard Smith c33fb9fc48 Support signature mismatch between virtual fn and override fn. (#7198)
For now, hide `override fn`s from name lookup, so that the base class
version is always used, as the derived-class version does not have its
own vptr entry and so would not do the right thing if a further-derived
class adds a new override. This is implemented via a new access kind of
`Hidden`.

When checking the overriding function, pass in the expected `Self` type
and check the `self` parameter against that; the signature that we
generate for the thunk in the derived class is the base class signature
with the `self` parameter's type changed to the derived class.

When we generate a thunk for a virtual function, the thunk is assigned a
`virtual_index`, and the virtual function itself is not. When the thunk
makes a direct call to the virtual function, recognize this situation by
checking for a `virtual_index`, and perform a non-virtual call if there
isn't one.

Assisted-by: Gemini via Antigravity
2026-05-13 17:40:45 +00:00
Richard Smith 71ba07239f Support pass-by-move when calling a C++ function taking by value. (#7135)
Previously, we picked a single Carbon parameter pattern for each C++
parameter pattern. This doesn't work well in cases where the Carbon
semantics and the C++ semantics are not perfectly aligned. In
particular, when a parameter is passed by value in C++, that might mean
either pass-by-move (which in Carbon would best be modeled by a `var`
pattern, as no other form of parameter would perform a move) or
pass-by-copy (which in Carbon would best be modeled by a value
parameter, as a `var` parameter would force an extra copy).

After this change, we compute a passing mode for each parameter based on
the implicit conversion sequence from the argument to the parameter as
determined by C++ overload resolution, and use that to determine the
Carbon pattern corresponding to each C++ parameter. This results in
potentially generating multiple different thunks for the same C++
function if it's called in different ways, but we already did that to
handle default arguments and list-initialization. The passing modes are
included in the thunk mangling.

Add a new value store for clang decl signatures, which capture the
information about parameter passing mode as well as the other existing
information about different ways that a C++ function might be imported
to Carbon.

Most of the rules for computing passing modes are the same as before:
const references use pass by value, non-const lvalue references use
pass-by-ref, non-const rvalue references use pass-by-var. But for C++
non-reference parameters, pick between pass-by-value and pass-by-var
based on whether the implicit conversion sequence was effectively
performing a copy. Prefer pass-by-value if either would work and they'd
do the same thing. We still use pass-by-value for const references, even
when the argument is an lvalue and we could pass a reference; we may
want to change this in future.

For virtual functions, we try to pick a worst-case passing mode, as we
can only pick a single signature for what goes in the vtable. Calls to
virtual functions will still use a thunk to C++, allowing variance in
the calling convention at call sites. We don't allow variance in the
overriders as we don't implement support for thunks for virtual
functions yet. We currently use pass-by-value for const reference
parameters here, but that should probably change at some point.

Assisted-by: Gemini via Antigravity
2026-05-13 01:44:07 +00:00
Richard Smith dd7cfdb149 Relax alias restrictions. (#7190)
Implement the alias rules from proposal #5389, wherein an alias is
permitted so long as the target has a constant value. While that
proposal is not yet accepted, this seems like a reasonable basis for
further iteration, and will be useful for the examples we're currently
pursuing.
2026-05-12 17:22:44 +00:00
David Blaikie df8b25522e Import C++ vtables (#7174)
This correctly renders the vtable in SemIR, including allowing overrides
in
Carbon-derived-from-C++ classes.

It doesn't work in lowering because clang walks the methods of the
CXXRecordDecl - and we currently don't export anything into the
CXXRecordDecl's methods (we do export the fields) - so that's next.

This also doesn't teach Clang to affirmatively emit the vtable
regardless of the types use in C++ code - or to have Carbon use the
vtable in an object's initialization.
2026-05-11 17:33:08 +00:00
Christopher Di Bella 219d1cdee1 Teach comparison interfaces about C++ operators (#7163) 2026-05-10 21:54:50 +00:00
Viktor 8d907e857e Add regression test for var parameter cleanup from struct literals (#7175)
`param.carbon` already tests cleanup when passing a class value produced
by
`C.Make()` to a `var` parameter. Add the corresponding struct literal
case,
`F({})`, matching the repro from #7168

The issue appears to already be fixed on main so this adds a test to
make sure
the compiler keeps calling `Core.Destroy` for the temporary value after
`F({})`
returns

Closes #7168

Assisted-by: Qwen 3.6
2026-05-08 19:13:52 +00:00
Lucile Rose Nihlen bc1ae703c3 return 0 from Run when it doesn't specify a return value (#7180)
https://carbon.compiler-explorer.com/z/88K9Kh5Wo shows the program
exiting with a garbage value copied from uninitialized memory.

This PR modifies `lower` to detect if the function lowered is the
entry point and doesn't specify a return type. If so, it emits
different LLVM IR to return int32 0, and modifies the lowered
function signature to match the int32 return type.
2026-05-08 19:00:47 +00:00
Richard Smith bc06f6c5ec Mangle the signature decl when mangling a thunk. (#7177)
Fixes mangling collisions when two thunks with the same name (eg, `Op`)
are created in the same context, which in turn would lead to LLVM
verifier failures and miscompiles.

To support this, add a new value store to track a little more
information about thunks beyond what's in the `Function`.
2026-05-07 21:58:29 +00:00
Richard Smith 341901e337 Fix crash if an inst in a pending block needs a cleanup. (#7166)
Insert the cleanup if and when the pending block is inserted, not
eagerly. And if the pending block is inserted by overwriting an existing
instruction, create a cleanup for that instruction rather than for the
instruction in the pending block that we are discarding.

Assisted-by: Gemini via Antigravity
2026-05-04 21:50:13 +00:00
Nicholas Bishop 1bc329af14 Support calling Carbon destructors from C++ (#7143)
A destructor is added to the C++ class definition in
`CarbonExternalASTSource::CompleteType`. The destructor calls a Carbon
function that calls the `Destroy` operator.
2026-05-04 20:28:58 +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
David Blaikie 071ab9f532 Import dynamic-ness of a C++ class (#7141) 2026-05-01 22:53:44 +00:00
Nicholas Bishop f3f039516e Support accessing Carbon class fields from C++ (#7119)
When any field of a Carbon class is access from C++ for the first time,
all fields are exported as `clang::FieldDecl`s (this is necessary
because clang fields have an internal index that is initialized on first
use).

`ClangDeclStore` now provides bidirectional mapping. This allows looking
up a `ClangDeclId` by `InstId`, so when Carbon class fields are exported
they can be looked up that way.
2026-04-29 20:07:10 +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
Richard Smith 0124aae041 Import non-const rvalue references as var parameters. (#7125)
When importing a C++ function with an rvalue reference parameter, we
previously produced a Carbon value parameter. This would lead to the
toolchain believing it could pass the address of a non-expiring object
to the function, which would lead to a use-after-move.

Instead, we now map non-const rvalue reference parameters to Carbon
`var` parameters. This forces the object passed into C++ to be unique
and owned by the call. While that's not an exact match for C++ rvalue
reference parameters, given that it provides "always move" not
"conditionally move", it's the closest match we have at the moment.
2026-04-29 00:28:00 +00:00
Richard Smith 23339bc810 Fix initialization of var parameters. (#7023)
When an initializing expression is used to initialize a var parameter,
we need to create the storage earlier in SemIR than the initializing
expression. To do so, pass a pending block to initialization containing
the var storage.

Also stop using `temporary` for this purpose, since we treat temporaries
as potentially-constant and immutable, but `var` parameters can be
mutated by the callee. We should ideally introduce a new kind of
instruction for this purpose but for now we just use `var_storage`.
2026-04-28 20:10:13 +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
Richard Smith 12cdd406b0 Factor type lowering out of file_context.cpp. (#7099)
This file was getting too big. This seems like a nice, independent chunk
to move elsewhere.

Assisted-by: Gemini via Antigravity
2026-04-24 00:43:18 +00:00
Richard Smith 709776ad1c Support for locations in transitively imported C++ code (#7093)
Instead of treating all C++ code as coming from a single synthetic
`CheckIRId`, track the `SemIR::File` associated with each C++ location.
This is necessary since each `SemIR::File` has a distinct `CppFile` and
therefore distinct `SourceLocation`s and `ClangSourceLocId`s.

Assisted-by: Gemini via Antigravity
2026-04-23 20:11:04 +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
Nicholas Bishop 67648b4d49 Remove "__cpp_thunk" from thunk name for exported functions (#7092)
This makes the behavior consistent between methods and regular
functions, and fixes the behavior with `using` aliases (see new
`using.carbon` test).

As requested in
https://github.com/carbon-language/carbon-lang/pull/7078#discussion_r3121104954.
2026-04-22 18:05:02 +00:00
Dana Jansens 790cb6e6fe Make ImplWitnessAccess inst have constant kind Conditional (#7090)
ImplWitnessAccess can contain a LookupImplWitness instruction as an
operand, which used to be SymbolicOnly but has now become Conditional in
#6915. This opens up the possibility for LookupImplWitness to have a
concrete value, without resolving to a different instruction kind. If
this occurs when it's the operand of an ImplWitnessAccess, and the
access is unable to find a different value to resolve to through the
witness' self type, then the ImplWitnessAccess can also become concrete.

This can happen in particular when:
- You have an ImplWitnessAccess into a `.Self` symbolic in a facet type.
- You convert a concrete type to the facet type.
- The `.Self` is replaced by a concrete type, causing the impl lookup to
be on that concrete type.
- The (now concrete) impl lookup fails to find any impl witness, so it
remains a concrete LookupImplWitness

This results in a diagnostic, as the incoming type does not satisfy the
facet type, but in the meantime we have a concrete ImplWitnessAccess,
which we do not want to crash.

For example in this test:
```carbon
interface I {
  let I1:! type;
}
interface J {}

fn F(T:! I where .I1 impls J) {}

fn G() {
  class C;

  // This identifies `C as (I where .I1 impls J)`, which replaces `.Self.I1`
  // with `C.(I.I1)`. This is a concrete lookup since C and I are both concrete,
  // but it doesn't find anything as there is no impl.
  //
  // As such, the call to F fails to deduce a value for T.
  F(C);
}
```

This PR splits out the change to ImplWitnessAccess from the larger
change of replacing `.Self` in identified facet types (and comparisons
with identified facet types).
2026-04-22 17:11:40 +00:00
Nicholas Bishop 33d534ab31 Support calling Carbon methods from C++ (#7078)
The FunctionDecl created for calling the Carbon thunk now takes a `self`
parameter for non-static methods, and the C++ thunk now passes an extra
argument for that `self` parameter when needed.

The CXXMethodDecl thunk created for calling methods now sets the storage
class appropriate depending on whether the method is static or not.

To reduce the number of parameters being passed around to thunk-building
functions, added a `FunctionInfo` struct and pass that around instead.
2026-04-22 15:09:33 +00:00
Richard Smith f91990aa87 Override Clang class layout for Carbon class types. (#7071)
Use the Carbon-determined size and alignment for Carbon-defined classes,
rather than allowing Clang to work one out for itself using the C++
rules.
2026-04-17 00:03:29 +00:00
Geoff Romer af04d08965 Track declared form with an InstId instead of a ConstantId. (#7072)
This is mainly in order to track a location associated with the form.
2026-04-16 23:14:31 +00:00
Richard Smith a6061d975c Compute type layouts in SemIR / Check (#7066)
Instead of allowing lower to pick whatever type layout it desires,
compute the layouts of types as part of completing the type, and make
lower build types that match that representation.

For now we assume that all pointers are 64-bit, since we don't have
access to target information. We allow tail padding reuse for structs
and tuple types (and by extension, for classes, since they use structs
as their object representation), but not for arrays.

In order to build matching LLVM types, we create LLVM packed structs
where necessary, and we insert inter-field padding on the end of the
previous field so that GEP indexes still always match Carbon's
ElementIndexes.

We don't yet use the computed alignment much in LLVM IR generation -- in
particular, `alloca`s, `load`s, and `store`s should probably use the
computed type alignment, but don't.

Assisted-by: Gemini via Antigravity
2026-04-16 22:37:48 +00:00
Nicholas Bishop 114cf401c2 Support C++ calling Carbon functions with non-() return type (#7051)
For calling non-`()` functions, the Carbon->Carbon thunk now takes an
extra reference parameter and writes the target function's return value
out to that parameter. (At the SemIR level this is how returns already
work, but adding this extra reference parameter is needed so that the
function is lowered correctly.) The C++ thunk now creates a local
variable to be initialized by the Carbon thunk, and then returns that
value to the original C++ caller.
2026-04-16 00:29:38 +00:00
Richard Smith be0c07dc7e Give Carbon -> C++ thunks internal linkage. (#7040)
Also declare them `inline` since we're putting the `always_inline`
attribute on them. Use the `internal_linkage` attribute rather than
`SC_Static` since it's a more precise mechanism and matches what we do
for static member functions in reverse interop (where `SC_Static` means
something else and would not give the function internal linkage).
2026-04-08 21:14:30 +00:00
Richard Smith b74e0d1260 Superficial support for exporting complete class types to C++. (#7029)
We don't yet populate the bases or fields, so the class types show up as
empty classes in C++ for now. But we do allow calls to static member
functions.
2026-04-08 19:29:25 +00:00
Nicholas Bishop 0635f4628f Add support for C++ calling Carbon functions with parameters (#7024)
This works by generating two thunks, one in C++ and one in Carbon. For
example, given this input:
```c++
// Carbon:
fn Callme(f: f32) {}

// C++:
void F() {
  // This will call `Callme__cpp_thunk`
  Carbon::Callme(1.0);
}
```

These functions are generated:
```c++
// Carbon:
fn Callme__carbon_thunk(ref f: f32) {
  // Call the target function.
  Callme(f);
}

// C++:

// C++ declaration for the Carbon thunk.
void Callme__carbon_thunk(float& f);

void Callme__cpp_thunk(float f) {
  // Call the Carbon thunk with args passed by reference.
  Callme__carbon_thunk(f);
}
```

For now, all arguments are passed by reference, even if they are simple
types like pointers or i32.

Functions with non-void return types are not supported yet.
2026-04-07 23:25:57 +00:00
Richard Smith 05ba1d7356 Add a conversion impl from T* to const T* (#7010)
This is already allowed as a builtin conversion, but the impl allows the
generics system to know about it, so that conversions like
`Optional(T*)` to `Optional(const T*)` are allowed. This in turn allows
a C++ `T*` to be implicitly converted to a C++ `const T*` in Carbon
code.
2026-04-03 22:07:53 +00:00
Richard Smith 8e0d856725 Improve InPlaceInitializing conversion. (#7021)
Fix some situations where we'd drop the storage argument when building
an in-place initializing expression. We now guarantee that an expression
with the in-place initializing category always has a storage argument.
2026-04-03 21:28:54 +00:00
Richard SmithandGeoff Romer ea409f7cbf Fix crash lowering call to generic function with concrete type in signature (#7009)
When a function call appears in a generic, and calls another generic
that has a concrete type in its call-site signature, that concrete type
will be completed only in the file that contains the call. The generic
containing the call won't require completeness to be checked again when
forming a specific call, because the type was concrete. This means that
when lowering the call instruction, there is no single file that is
guaranteed to contain complete types for all of the callee's parameters
-- the file containing the specific callee won't necessarily have
completed the concrete parts of the signature, and the files containing
the definition and call won't necessarily have completed the symbolic
parts of the signature.

To handle this, look at both versions of the function when building its
lowered signature -- the version that we saw when forming the `call`
instruction and the version corresponding to the concrete, specific
callee, and combine information from both to form the LLVM function
type.

---------

Co-authored-by: Geoff Romer <gromer@google.com>
2026-04-03 21:24:00 +00:00
rit 912825feaf Add basic test for lowering choice value acquisition (#7014)
Added test for lowering choice value acquisition. Before PR #6992 the
code in issue #6862 would crash/assert saying the instruction
`AcquireValue` is not concrete. I added this test as the fix did not
have one to test this particular case.
2026-04-03 00:01:21 +00:00
Richard Smith 81ed4d829d Perform CppThunkRef conversion as part of category conversion. (#7020)
Instead of recursing back into Convert, make CppThunkRef conversion just
add an extra step to category conversion, performing a copy conversion
followed by an ephemeral reference binding conversion.
2026-04-02 23:39:25 +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
Geoff Romer 0851d657c8 Add comment and test for special case in NameRef lowering (#7008) 2026-04-02 19:13:06 +00:00
Richard Smith be283a0744 Improve handling of incomplete signatures. (#7004)
Assert cleanly if we try to emit a definition or a call of a function
whose signature we were not able to emit exactly. This should make such
issues a lot easier to debug, as we were previously failing in quite
mysterious ways in this case.
2026-04-01 21:49:57 +00:00
Richard Smith dfac728571 Fix pointer sizes in debug info. (#7002)
The size is in bits, so 8 is an unlikely value. Also, don't hardcode a
size, ask the data layout for it.
2026-04-01 16:35:12 +00:00