Commit Graph
311 Commits
Author SHA1 Message Date
fdb188ccfd Implement unused pattern bindings, continued (#6518)
Implementation of unused pattern bindings #2022, continued.

Whereas previous PR #6460 took care of parsing, and PR #6479 prepared
the stage by using _ in some test cases, this PR has the the actual
implementation, using a simple dataflow analysis.

---------

Co-authored-by: Burak Emir <bqe@google.com>
Co-authored-by: jonmeow <jperkins@google.com>
2026-02-19 23:33:36 +00:00
Dana Jansens 917a6ea971 Add an interface-with-self generic to each interface and same for constraints (#6667)
Currently each interface has a `Self` facet internally that becomes a
binding to every entity inside the interface: associated constants,
functions, and require decls. Each of these has to be independently
generic as a result. This makes is challenging in extended name lookup
to move into an extended scope of an interface, as we have a specific
for the interface, but the names within require a different specific
that includes a `Self` facet value.

We generalize this relationship by adding a second generic to Interface,
called `generic_with_self`. When we want to work with entities inside
the interface, we move from the interface-without-specific to the
interface-with-self specific by adding a Self to the specific. This is
done independently of any particular entity inside the Interface, as
those entities are now all members of the interface-with-self generic.

Associated constants no longer need a generic of their own, as they do
not have separate generic bindings. Functions retain a generic, but if
the function has no generic arguments, it will have no bindings of its
own now.

Require decls retain a generic so that their specific can be
instantiated separately from the interface. Requiring the interface to
be complete does not require the types in a require decl to be complete
unless it is modified by `extend`. So we allow them to be completed
later by keeping them in a separate generic.

Named constraints look like interfaces and gain the additional inner
generic-with-self, with the same relationship to require decls.

This removes the need for name lookup to perform Substitution of a Self
facet into the extended scope instruction. Instead, the
`SpecificConstant` instruction inserted by a `require` decl is part of
the interface-with-self generic. When looking through a FacetType for
extended scopes, for each interface, we push the scope with the specific
for the interface-with-self. Then the constant value of the
`SpecificConstant` is correctly modified by the provided self
automatically through applying that specific.
2026-02-19 16:24:07 +00:00
Nicholas Bishop 6df9d5ba32 Add initial support for non-type template parameters (#6740)
This adds basic support for using templates with integer parameters.

https://github.com/carbon-language/carbon-lang/issues/6717
2026-02-17 21:34:06 +00:00
Richard Smith 1aa1a2a373 Fix crash when referring to a C++ variable whose type's scope has not been imported. (#6743) 2026-02-16 22:47:01 +00:00
Jon Ross-Perkins 64e3fab43a Skip C++ types when generating Destroy witnesses (#6732)
This TODO had been written before C++ types were generating destroy
implementations, which is resolved now.

Assisted-by: Google Antigravity with Gemini 3 Flash
2026-02-14 00:43:11 +00:00
Geoff Romer 3c324e4877 Add category to parameter format, and share some code. (#6730) 2026-02-13 22:20:05 +00:00
Geoff Romer 1c885a629e Format FormType as "Core.Form" (#6734) 2026-02-13 19:44:21 +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
Nicholas Bishop f292972816 Fix unnecessary duplication in builtins tests (#6711)
This fixes up some mistakes from
https://github.com/carbon-language/carbon-lang/pull/6702. In removing
repeated casts I ended up transforming some test code such that it
duplicated existing lines.
2026-02-09 22:27:42 +00:00
Nicholas Bishop a465018fec Remove SemIR dump from AssertSameType int tests (#6705)
Dropping the SemIR dump significantly decreases the size of these test
files. This is a good tradeoff since the interesting signal from these
tests is provided by `AssertSameType` not causing an error.

```
...n/check/testdata/interop/cpp/builtins.llp64.carbon | 3152 ----------------------
...in/check/testdata/interop/cpp/builtins.lp64.carbon | 3328 ------------------------
2 files changed, 0 insertions(+), 6480 deletions(-)
```
2026-02-09 15:26:30 +00:00
Geoff Romer 7938d9a8d0 Lex/parse support for ->?, :?, and form literals (#6695)
See #5389 (pending) for the language design.
2026-02-07 02:41:22 +00:00
Nicholas Bishop c7a7688d21 Avoid repeated casts in builtins.lp64/llp64 tests to reduce SemIR size (#6702)
This reduces the size of a couple large test files by a few hundred
lines:
```
toolchain/check/testdata/interop/cpp/builtins.llp64.carbon | 4033 +++++++++++++++++++++---------------------------
toolchain/check/testdata/interop/cpp/builtins.lp64.carbon  | 4019 ++++++++++++++++++++---------------------------
2 files changed, 3355 insertions(+), 4697 deletions(-)
```
2026-02-06 19:09:45 +00:00
Geoff RomerandRichard Smith e5b05a1fac ExprCategory for guaranteed-in-place initializing expressions (#6623)
The primary change in this PR is to split the `Initializing` expression
category into separate `ReprInitializing` and `InPlaceInitializing`
categories, depending on whether initialization uses the types
initializing representation, or is guaranteed to be in place. It also
rationalizes and documents the SemIR-level semantics of those categories
(including where #5545's "ephemeral entire reference" category will
fit), and introduces two new inst kinds to close gaps exposed in the
process.

Some additional secondary changes:
- Consistently format the storage arguments of initializers with `to`,
regardless of whether initialization is in-place, and document the `to`
notation.
- Rename some inst kinds and functions, and restructure some of the
code, for clarity and consistency with the new documentation.
- Resolve a TODO to handle more category conversions in
`CategoryConverter`, in order to make it easier to reason about category
conversions.

See #6588 and the review history of this PR for background.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2026-02-04 02:27:12 +00:00
Richard Smith c0b24047dd Interop support for initialization via std::initializer_list. (#6672)
Add a new builtin function `cpp.std.initializer_list.make` that takes an
array and returns a `std::initializer_list`, initialized to refer to
that array. When C++ initialization wants to perform a
`std::initializer_list`-from-array construction, synthesize a
declaration of a matching builtin function and use that to perform the
initialization.

Ideally we would specify this conversion as an impl of `ImplicitAs` in
the prelude instead of hardcoding it in the interop layer, but
unfortunately that's not currently possible, for various reasons -- we
can't make the conversion form-generic, we can't deduce the array length
from the initializer, and we can't deduce against the arguments of
imported C++ class templates yet -- so for now synthesizing a builtin
function on demand is the best we can do.

Assisted-by: Gemini 3 Pro via Antigravity
2026-01-30 22:24:18 +00:00
Ivana Ivanovska 9f69ebf6de Add heterogeneous bitwise operators for CppCompat.Long32 (#6661)
Context: https://github.com/carbon-language/carbon-lang/issues/6275.

Part of https://github.com/carbon-language/carbon-lang/issues/5263.
2026-01-29 16:04:46 +00:00
Ivana Ivanovska de4a2ee6c8 Add missing operators for CppCompat.LongLong64 (#6663)
Adds arithmetic and bitwise operators, compound assignments, and
increment/decrement operations for CppCompat.LongLong64.

Context: https://github.com/carbon-language/carbon-lang/issues/6275.

Part of https://github.com/carbon-language/carbon-lang/issues/5263.
2026-01-28 19:24:21 +00:00
Richard Smith e69c3fd978 Support list initialization of C++ classes that is performed via a constructor call. (#6660)
The general strategy here is to import the constructor with a signature
that directly matches the argument. The intent is that the imported
function will eventually be usable directly as the `ImplicitAs.Convert`
function in a generated `impl`.

For initialization from a tuple, for example `(1, 2)`, we import the
selected constructor with a signature that takes a tuple pattern:

  `fn Class.Class((a: i32, b: i32)) -> Class;`

In order to support that, this PR also adds support in general for tuple
patterns in function signatures. It turns out the implementation was
already very close to allowing this.

Assisted-by: Gemini 3 Pro via Antigravity
2026-01-27 22:04:21 +00:00
Ivana Ivanovska 3757a79f4c Add heterogeneous arithmetic operators for CppCompat.Long32 (#6644)
Context: https://github.com/carbon-language/carbon-lang/issues/6275.

Part of https://github.com/carbon-language/carbon-lang/issues/5263.
2026-01-27 17:39:36 +00:00
Ivana Ivanovska ff38378efc Add comparisons for CppCompat.LongLong64 (#6643)
Context: https://github.com/carbon-language/carbon-lang/issues/6275.

Part of https://github.com/carbon-language/carbon-lang/issues/5263.
2026-01-26 11:29:40 +00:00
Richard Smith 093d5072db Add support for using C++ user-defined conversions via interop (#6646)
When performing an implicit conversion to or from a C++ class type, look
for a C++ implicit conversion, and if that conversion involves a
function call (to a constructor or conversion function), call that
function to perform the conversion.

Note that this is just a first pass at supporting implicit conversions.
There are a lot of other things that can happen in a C++ implicit
conversion, such as aggregate initialization or `std::initializer_list`
initialization that aren't handled here. In addition, we intentionally
leave all standard conversions to Carbon to perform, so that we will
reject conversions such as `i32 -> unsigned` that C++ would select but
Carbon considers to be invalid.

Also support `as` conversions. These are treated analogously, but
perform direct-initialization instead of copy-initialization, so they
also find `explicit` constructors and conversion functions.

In order to give good diagnostics, also track the original C++ source
location for imported C++ functions on the imported version of the
function.

Assisted-by: Gemini 3 Pro via Antigravity
2026-01-25 04:51:25 +00:00
Richard Smith a2e4c31e8e Clean up after combination of #6634 and #6635. (#6640)
We can now cast directly from `T*` to `U*`; stop going via `void*`. Also
remove the conversion impl from `void*` as it's now subsumed by the
general impl.
2026-01-21 21:03:35 +00:00
Ivana Ivanovska c9dbf40f11 Add comparisons for CppCompat.Long32 (#6639)
Support for both homogeneous and heterogeneous comparisons are added for
CppCompat.Long32.

Context: https://github.com/carbon-language/carbon-lang/issues/6275.

Part of https://github.com/carbon-language/carbon-lang/issues/5263.
2026-01-21 19:11:48 +00:00
05ea0e77d9 Map structs and tuples to initializer lists in C++ overload resolution. (#6620)
When performing C++ overload resolution with an argument that is of
Carbon struct or tuple type, form a braced initializer list as the
placeholder argument. Note that this only affects overload resolution;
no new support for actually converting structs or tuples to C++ types is
added. In particular, while this does allow an empty class to be
initialized from `{}`, it does not allow a non-empty C++ class to be
initialized from a struct, as that is not yet supported in general.

---------

Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
Co-authored-by: Geoff Romer <gromer@google.com>
2026-01-21 19:10:10 +00:00
Ivana Ivanovska a448792207 Enable heterogeneous compound assignments for CppCompat.Long32 (#6628)
Context: https://github.com/carbon-language/carbon-lang/issues/6275.

Part of https://github.com/carbon-language/carbon-lang/issues/5263.
2026-01-21 13:27:58 +00:00
Ivana Ivanovska c0e7198995 Implement copying for ULong32, LongLong64, ULongLong64 (#6627)
Context: https://github.com/carbon-language/carbon-lang/issues/6275.

Part of https://github.com/carbon-language/carbon-lang/issues/5263.
2026-01-20 20:36:17 +00:00
Ivana Ivanovska 082b420f6e Provide increment and decrement operators for CppCompat.Long32 (#6622)
Context: https://github.com/carbon-language/carbon-lang/issues/6275.

Part of https://github.com/carbon-language/carbon-lang/issues/5263.
2026-01-19 22:58:56 +00:00
Ivana Ivanovska ec0a8a9b52 Implement copying for CppCompat.Long32 (#6625)
Context: https://github.com/carbon-language/carbon-lang/issues/6275.

Part of https://github.com/carbon-language/carbon-lang/issues/5263.
2026-01-19 15:25:48 +00:00
Ivana Ivanovska c252e7d31e Implement compound assignments for CppCompat.Long32 (#6621)
Only homogeneous compound assignments are supported for now.

Context: https://github.com/carbon-language/carbon-lang/issues/6275.

Part of https://github.com/carbon-language/carbon-lang/issues/5263.
2026-01-19 11:17:18 +00:00
Geoff RomerandCarbon Infra Bot 95eb7b16bb Expose C++ reference returns as Carbon reference returns (#6618)
Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
2026-01-16 18:08:42 +00:00
Richard SmithandGeoff Romer de0ad6730f Fix crash if a member of std::string_view is found in a derived class. (#6604)
Members of `std::string_view` can't be accessed directly, because that
type maps into Carbon's `str` type (`Core.String`), so member access
doesn't find the C++ members. But they can be named via qualified name
lookup into a derived type. That crashed because we didn't expect the
non-Cpp type `Core.String` to be the parent of a Cpp-imported member.

Plus add some more test coverage for related cases (not involving `str`)
that already worked.

---------

Co-authored-by: Geoff Romer <gromer@google.com>
2026-01-15 22:36:18 +00:00
Ivana Ivanovska 9ee2177dd4 Add bitwise homogeneous operators for CppCompat.Long32 (#6584)
Context: https://github.com/carbon-language/carbon-lang/issues/6275.

Part of https://github.com/carbon-language/carbon-lang/issues/5263.
2026-01-15 15:07:14 +00:00
Geoff Romer 4329a83e4c Form-aware textual format for return parameters and arguments (#6588)
The key changes are:
- Function output parameters are now prefixed with `out`, and more
consistently formatted as named parameters.
- Function and inst output arguments are now written as part of the inst
form, rather than as one of the inst arguments.

As a drive-by fix, this also changes `Temporary::storage_id` from
`DestInstId` to `InstId`, because it doesn't represent an output
parameter of the `Temporary` inst itself.

See the review of
[#6532](https://github.com/carbon-language/carbon-lang/pull/6532) and
[this Discord
discussion](https://discord.com/channels/655572317891461132/999638000126394370/1458268977020141589)
for additional background.
2026-01-14 23:27:21 +00:00
Geoff Romer 4a47f1ebeb Remove some uses of ReturnTypeInfo (#6577)
As with #6572, this is a step toward supporting function calls that have
arbitrary numbers of initializing returns.
2026-01-13 17:23:27 +00:00
Geoff Romer e1ec8d42d1 Give ReturnExpr a target only when initialization is in-place (#6570)
Also clarify and enforce that `ConversionTarget::init_id` is used only
as storage for in-place initialization, and correspondingly rename it to
`storage_id`.
2026-01-13 01:20:15 +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
Ivana Ivanovska d1b13194d5 Add arithmetic operators for CppCompat.Long32 (#6573)
`CppCompat.Long32` is a distinct type, mapped to C++ `long` on `LLP64`
(64-bit Windows).

Context: #6275.

Part of #5263.
2026-01-12 11:58:14 +00:00
Richard SmithandCarbon Infra Bot f5bb43bced Stop creating invalid clang identifier names. (#6578)
This doesn't appear to be causing any problems, but seems worth avoiding
anyway.

---------

Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
2026-01-11 21:06:22 +00:00
Richard Smith 935ccce2a6 Fix lowering of imported global variables. (#6567)
*   When a C++ static data member is imported, evaluate its address to a
    constant like we would for a namespace-scope variable.
*   When an imported variable is used in a way that doesn't require its
    type to be complete, emit the variable with an opaque type instead
    of skipping it (and potentially crashing later).
2026-01-11 19:22:43 +00:00
Richard Smith 87e588c334 Add interop support for complement and subscript operators. (#6576)
Also add the code to support interop with simple assignment. This
doesn't yet work because we don't support overloaded simple assignment
in general yet.
2026-01-10 07:50:00 +00:00
Geoff Romer 6985ecb1d4 Replace GetCurrentReturnSlot with GetReturnedVarParam (#6571)
Not all functions have a return slot, and once we have composite forms,
functions will be able to have any number of return slots. Obtaining a
unique return slot for a function only makes sense in `returned var`
handling.
2026-01-10 01:56:32 +00:00
Richard Smith ead7803d60 Simplify importing of C++ global variables. (#6565)
Remove the unnecessary two-phase creation of variables in C++ import. We
don't need to create a placeholder and overwrite it here, so stop doing
so.

Also, add the patterns to the imports table and don't create a
NameBindingDecl. The NameBindingDecl would never be used for anything.
This matches what we do when importing a Carbon variable, and improves
the formatted SemIR output.
2026-01-09 00:16:27 +00:00
Geoff Romer 505b1c86b9 Initial support for return forms (#6556)
The main changes here are:
- Introducing `InitForm` and `RefForm` to represent initializing and
reference forms (the two return forms currently supported by the
parser).
- Introducing the `FormType` singleton inst to represent their type
(i.e. `Core.Form`).
- Emitting an inst representing a function's declared return form as
part of handling the function signature.

The return form inst is currently ignored. Subsequent PRs will expose it
in `SemIR::Function` and use it to determine the form of call
expressions.
2026-01-07 00:54:18 +00:00
Geoff Romer 0e5832d3c2 Model ref tags as insts instead of annotations (#6541)
This continues the implementation of the proposed resolution of #6342.
2026-01-05 22:24:47 +00:00
Chandler Carruth e7eb3b7b5a Consolidate default Clang argument handling (#6545)
This unifies the default Clang arguments between the `clang` subcommand,
the `link` subcommand, and the `ClangInvocation` built for C++ interop.

This sets the stage to integrate either pre-built or on-demand runtimes
flags for both of these. However, this PR should have very little
practical difference. The biggest functional change is wrapping the
default arguments in flags to allow unused flags so that we can build a
collection of flags viable across compile and link.
2026-01-03 17:35:29 +00:00
Richard Smith 531d063596 When importing a trivial destructor from C++, produce a no_op builtin. (#6531)
This avoids us trying to produce a reference to the C++ destructor,
which Clang won't emit because it believes it's unnecessary. This
previously led to link errors.

Fixe #6502.
2025-12-23 05:30:29 +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
Özgür a4b5ab9df9 Reject unqualified private access to base members (#6521)
### Description
Currently, unqualified access to private members of the base class
compiles without error. This is due to `LookupUnqualifiedName` calling
`LookupQualifiedName` internally with `access_info` parameter set to
`std::nullopt`. This causes `IsAccessProhibited` to return `false`
immediately.
This PR fixes this issue.

### Changes
- Added a check where if the `access_info` is null and the current scope
we are looking is an extended scope (parent), initializes the
`access_info` with `highest_allowed_access` set to `Protected`.

Fixes #6239
2025-12-18 19:12:07 +00:00
Richard Smith 2e65d28a16 Support for passing C++ templates as arguments to template template parameters. (#6475)
Allow passing a C++ template as a template template argument to another
C++ template. Does not allow passing a Carbon generic as an argument.

Depends on #6474.
2025-12-16 19:00:49 +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
Jon Ross-Perkins 25f63140e6 Refactor CppWitness as CustomWitness (#6491)
This is in anticipation of using the same construct for all
implementations of `Destroy`, as well as other similar use-cases with
language-defined interfaces.
2025-12-15 19:41:14 +00:00