Commit Graph
32 Commits
Author SHA1 Message Date
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
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
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
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 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
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
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
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
Richard Smith c297344937 Support conversion between integer types. (#6856)
Add an `IntFitsIn` interface with a custom witness, such that `T impls
IntFitsIn(U)` if `T` is an integer type all of whose values fit
losslessly into the integer type `U`. Use it to constrain implicit
conversions between integer types.

So far, this has not been extended to the
`CppCompat.[U]{Long32,LongLong64}` types, only to `Core.Int(N)` and
`Core.UInt(N)`.

Assisted-by: Gemini 3 Pro via Antigravity
2026-03-10 01:40:16 +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
Richard Smith 980ab7fab3 Fix handling of compatible conversions in initialization. (#6797)
Stop using "performed builtin conversion" as a proxy for whether we
created an initializing expression with a correctly-set storage
argument. That isn't correct in the case where the builtin conversion
creates a new initializing expression without setting its storage, such
as by creating an `AsCompatible` wrapper around an existing initializing
expression.

Instead look at whether the storage argument is a `TemporaryStorage`,
and only overwrite in that case, otherwise assuming that the storage
argument has been set correctly.

This fixes a miscompile that was already visible in our lowering tests!
2026-02-26 18:25:06 +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
Richard Smith 8353965ca3 Allow conversions between all pointer types with unsafe as. (#6635)
Previously we only allowed conversions from `void*` to `U*` this way,
requiring casting via `void*` to get from `T*` to `U*`. That seems like
an unnecessary circumlocution.
2026-01-21 15:47:51 +00:00
Richard Smith 31919afa24 Allow conversion between T* and Cpp.void*. (#6575)
Support an implicit conversion from `T*` to `Cpp.void*` and to `const
Cpp.void*`, and an `unsafe as` conversion in the opposite direction.

In order to support C++ calls taking and returning `void*` (which get
mapped to Carbon `Optional(Cpp.void*)`, also support conversions from
`Optional(T)` to `Optional(U)` if there's a conversion from `T` to `U`.

Fix a bug in `OptionalStorage` for `T*` where its `HasValue` was exactly
backwards.
2026-01-12 16:32:15 +00:00
Özgür 29018f38a6 Fix name mangling of generic impls (#6533)
### Description
Mangling collisions occur when implementing interfaces with generic
parameters. The mangler does not use the specific id, causing the same
symbol `_C[FunctionName].[PackageName]:[InterfaceName].[PackageName]` to
be generated for all of the implementations below:
```carbon
// Generic interface parameters ignored
impl C as I(A)
impl C as I(B)

// Generic class parameters ignored
impl D(A) as I
impl D(B) as I

// Both ignored
impl D(A) as I(A)
impl D(B) as I(B)
```

### Changes
Updated the mangling logic for `SemIR::ClassDecl` and
`SemIR::InterfaceDecl` to include the specific id. Now the mangling
ensures unique symbols for generic implementations using the format:

`_C[FunctionName].[FunctionSpecificId].[PackageName]:[InterfaceName].[InterfaceSpecificId].[PackageName]`.

Closes #6498
2025-12-23 00:36:03 +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
Burak Emir 992d435023 Replace unused bindings with anonymous binding in lower/testdata. (#6479)
This updates lower/testdata to use _ instead of proper names, in order
to avoid the "unused binding" warnings from #2022 which are being
implemented. These changes do not depend on the implementation which
should make everything easier to review.

See #6460 with part 1 of the implementation. It was split upon request
in order to make reviewing easier, the original state of the PR was
updating hundreds of test cases.
The PR has thus been split, part 2 including test cases changes can be
viewed at
https://github.com/burakemir/carbon-lang/tree/unused_pattern_bindings_p2022_impl_part2
... many tests need to be updated, so it seems best to get those tests
out of the way that are not interesting.

These are not all tests in lower/testdata - a few of them are
interesting in the sense that they cannot use '_' because it leads to
failed redeclaration check. This is exactly the scenario described in
#3763 which requires the 'unused' marker. Those are left untouched here
but are updated in
https://github.com/burakemir/carbon-lang/tree/unused_pattern_bindings_p2022_impl_part2
2025-12-17 15:43:04 +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
David BlaikieandDana Jansens a179bd461b Start plumbing through debug info type information with function parameters/return value (#6410)
This adds just enough debug info for i32/int parameters and return
values, with a path forward for adding DWARF type metadata for other
types.

As it happens, return type information is carried separately from
parameter information:
* Return type information is carried in the `type` of the `DISubprogram`
  (as a `DISubroutineType` - which does carry parameter type information
  as well, but that's unused when the DWARF is emitted by LLVM)
* Parameter information is carried by `DILocalVariable`s with a non-zero
  `arg` value (representing the order of function parameters)

In the absence of locations for the parameters (future work), nothing
would usually keep the `DILocalVariable` live/reachable when emitting
DWARF - so for cases where this can happen (for clang, this happens in
optimized builds where all references to the parameter variable might be
optimized away) the variables can be "retained" in a list on the
`DISubprogram` - achieved by passing `AlwaysPreserve` parameter to
`createParameterVariable` (adds them to a list, then that list gets
attached to the `DISubprogram` when it's finalized later)

For now, any unsupported types are emitted as `void*` (except void
return, which is implemented as void) as a placeholder.

Given this example:
```
import Core library "io";
class MyClass {
}
fn Unsupported(v: MyClass) {
}
fn Ret() -> i32 {
  return 42;
}
fn Arg(x: i32) {
  Core.Print(x);
}
fn Run() {
}
```
this is the resulting DWARF:
```
DW_TAG_compile_unit
  DW_AT_name    ("test.carbon")
  DW_TAG_subprogram
    DW_AT_name  ("Unsupported")
    DW_TAG_formal_parameter
      DW_AT_type        (0x00000066 "void *")
  DW_TAG_subprogram
    DW_AT_name  ("Ret")
    DW_AT_type  (0x00000062 "int")
  DW_TAG_subprogram
    DW_AT_name  ("Arg")
    DW_TAG_formal_parameter
      DW_AT_type        (0x00000062 "int")
  DW_TAG_subprogram
    DW_AT_name  ("Run")
  DW_TAG_base_type
    DW_AT_name  ("int")
  DW_TAG_pointer_type
```
And the debugger:
```
(gdb) p Ret()
$1 = 42
(gdb) p Arg(4)
4
$2 = void
```

I'm not sure if there's a way this logic should be merged with the logic
for making the `llvm::Function` type (which the `DISubroutineType`
building code was inspired by/copied from) - since they're done at
different times/places, I don't think there's an easy way to do it in
one pass, but maybe the code can be shared (even if it's run twice) in
some generic `SemIR::Function` type walker.

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
2025-11-25 23:25:09 +00:00
David Blaikie bb9942823f DebugInfo: Emit as "C++" rather than "C" (#6361)
This helps at least lldb handle calling functions (currently the debug
info describes every function as `void()`, so no parameters or return
values are supported) - seems gdb and lldb both depend on demangling to
varying degrees in C code (marking a function as "prototyped" in C in
DWARF does seem to also address this problem).

Given:
```
fn PrintThree() {
  Core.Print(3);
}
```
Before:
```
  (lldb) p PrintThree()
  error: Couldn't look up symbols:
    PrintThree
  Hint: The expression tried to call a function that is not present in
    the target, perhaps because it was optimized out by the compiler.
```
After:
```
  (lldb) p PrintThree()
  3
  (lldb)
```
2025-11-18 18:28:56 +00:00
Richard Smith 8f19f7a7c0 Use the value representation of T as that of MaybeUnformed(T) where possible (#6334)
If the value representation of `T` is a copy representation, but it
copies all of the bits of `T`'s object representation, then it's OK to
use that as the value representation of `MaybeUnformed(T)` too.

This fixes the behavior of interop with nullable pointers, which are
represented as an adapter of `MaybeUnformed(T*)`, and need to be passed
to and returned from functions on the Carbon / C++ boundary as `T*`s.
2025-11-07 16:25:27 +00:00
Richard Smith f2e98c2047 Fix initialization of a variable via an ImplicitAs conversion. (#6327)
We used to generate initialization to a temporary instead, and leave the
variable uninitialized.
2025-11-05 21:05:34 +00:00
Richard Smith 5db1141f52 Allow adding / removing const with ImplicitAs. (#6323)
If `T` implicitly converts to `U`, then:

 * `const T` implicitly converts to `U`,
 * `T` implicitly converts to `const U`, and
 * `T` implicitly converts to `Optional(U)`.
2025-11-05 07:38:09 +00:00
aa69a484eb Add support for running LLVM optimizer. (#6225)
Adds a flag `--optimize=<mode>` that specifies what to optimize for:

* `--optimize=none` turns off the optimizer as much as possible, but
still respects always_inline.
* `--optimize=debug` aims to be the equivalent of `-Og` / `-O1`, and
provides optimizations that don't affect the ability to debug the
program. This is the default.
* `--optimize=size` optimizes for the size of the produced program, and
aims to be the equivalent of `-Oz`.
* `--optimize=speed` optimizes for the execution time of the produced
program, and aims to be the equivalent of `-O3`.

Following the approach taken by Clang, the optimization level feeds into
both the configuration of the LLVM pass pipeline and the attributes
added to function definitions generated by the frontend.

Optimization is performed in a new phase, `optimize`, which runs between
`lower` and `codegen`.

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2025-11-05 00:15:14 +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
Richard Smith 851da43c88 Make Optional support specializing its representation. (#6058)
Switch to using a pair of `MaybeUnformed(T)` and a `bool` as the normal
representation for `Optional(T)`. When `T` is a pointer type, add a
customized representation that uses `MaybeUnformed(T*)`, with a null
representation used for absent values.
2025-10-15 22:34:22 +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
Jon Ross-Perkins 9704dc670e Change the Destroy blanket impls to be more specific (#6098)
The main direction of this change is the edits to `destroy.carbon`
(matching in both prelude and min_prelude).

Previously there was a no-op blanket impl for `Destroy`, which hid all
missing implementations of `Destroy`. This does a few things:

- Sets up builtin aggregate destruction for struct and tuple types as
before, but also adds C++ class types and array types to the same
handling. (all as a TODO for actual implementation)
- Also maybe-unformed destruction, for now at least. (there's a chance I
may try a different approach on this, but the impl lookup wasn't working
as I'd hope in order to write it in code)
- Adds handlers for simple things that are easy to do in code: `type`,
`bool`, pointers. (because these are no-op destruction)
- Redirect `const T` destruction to `T` destruction.

This leaves as future issues:

- `partial T` destruction. (this can't be done similar to `const`
because it only works for non-`final` class types; I think `class`
definitions should just generate what's needed)
- Destruction of other prelude-provided types. (will probably come up as
we implement class destruction, that the adapted builtin type doesn't
implement `Destroy` -- but may end up special-casing that in a way that
moots it)

This moves the `&` operator from `facet_types.carbon` to
`convert.carbon` because more things need to handle type and now that
we're getting separate copy and destroy interfaces. It should be
low-cost (an interface and builtin) so hopefully this is the right
balance for complexity and re-use.

A few tests are also edited in order to focus them more on what they
intend to test, and avoid a `Destroy` dependency.
2025-09-18 22:10:50 +00:00
Richard Smith 6086d6eef2 Make str copyable. (#6083) 2025-09-17 01:04:24 +00:00
Richard Smith 742017c475 Widen integer loads and stores to a multiple of 8 bits. (#5986)
This makes Carbon's loads and stores ABI-compatible with Clang's for
`bool` and `_BitInt(N)`.
2025-08-26 21:49:24 +00:00
Richard Smith 41ed82e033 Add basic support for strings to core, check, and lower. (#5963)
Add a `Core.String` class to the prelude representing a string view, and
rename the `String` keyword to `str` and make it evaluate to
`Core.String`.

`Core.String` is represented as a pair of a pointer to a character
(actually, to the first character of a string, but we don't have a way
of modeling that yet) and a size (which should be pointer-width, but is
currently always a `u64` as we don't have a `usize` equivalent yet).
`Core.String` values are generated directly by the toolchain for string
literal expressions.

This follows the direction established at the recent summit, but the
design implemented here has not been through the proposal process yet.
2025-08-20 00:18:50 +00:00