Commit Graph
756 Commits
Author SHA1 Message Date
Jon Ross-PerkinsandRichard Smith 6d9ee96584 Misc comment cleanups (#6200)
Just trying to apply a few scattered comment improvements that AI helped
flag.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2025-10-13 18:49:48 +00:00
Richard Smith 72754ff8ea Remove death tests checking for assertions. (#6202)
Fixes #5800 (flaky test timeouts under -c dbg), which were caused by
these death tests being extremely slow because they cause the symbolizer
to run on a large debug binary. Before this change, the test ran for
~30-90s depending on how long the symbolization happened to take; after
this change, it finishes in about 0.4s.

Using death tests here seems a bit excessive, especially as the process
dying in these cases isn't part of the contract of these functions, so
I'm just removing the death tests rather than trying to make them more
efficient. We have death tests in common/ that check our CARBON_CHECK
macros work.
2025-10-12 21:52:55 +00:00
David Blaikie 60b2b7f8c1 Add unit tagging to ClassId (#6195) 2025-10-11 05:36:18 +00:00
Dana Jansens 0679b779fb Return SymbolicBindingType separately in TypeIterator (#6193)
A SymbolicBindingType is going to only have EntityNameId as its field,
and we will use the ScopeStack to use that to find a facet. The
ScopeStack is a check/ thing, so this won't be possible in
SemIR::TypeIterator. And TypeStructure throws away the details for
symbolic types anyways. So this drops the TODO and returns the
EntityName from TypeIterator for any future user who would want it in
check/.
2025-10-10 12:37:37 +00:00
Dana Jansens 93b79f159e Change InstId dumping to hex numbers that include the tag (#6175)
This change makes dumping and debugging work again with InstIds that are
now tagged with the CheckIRId. The textual representation of an InstId
is changed from `irN.instM` back to `instM` but the `M` is now a hex
value with the tag as part of it, which is the same number that is
physically in the `InstId::index` field. This prevents any cases where
we would potentially print incorrect values for large InstIds.

We teach the `dump` command in lldb to parse hex values for InstId so
that we can paste these numbers back into the debugger.
2025-10-08 18:45:35 +00:00
Boaz Brickner 7c13bddc92 C++ interop: Support C++20 operator and overload resolution for expression rewriting (#6171)
This allows to find the spaceship `operator<=>` when a comparison
operator is not available, and `operator==` when `operator!=` is not
available.
Support added to both lookup and overload resolution, by adding
`OperatorRewriteInfo` and propagating it in `CppOverloadSet`.
In case overload resolution chooses to use an operator which requires
rewriting, we emit a `TODO` since rewriting is not yet supported.

Part of #6170.
2025-10-08 06:28:50 +00:00
Jon Ross-Perkins c9bb6b11a4 Use an import_ir prefix and handle special IR values (#6176)
This is to try to improve clarity of values printed when debugging, with
[special values as
requested](https://discord.com/channels/655572317891461132/655578254970716160/1424792667338051756).
2025-10-07 22:54:09 +00:00
Dana Jansens fe020ee08b Make FacetAccessType evaluate to SymbolicBindingType for type-of a BindSymbolicName (#6115)
The SymbolicBindingType refers to the type value that will be
substituted in for the BindSymbolicName, but holds onto the EntityNameId
from the BindSymbolicName instead of (or in addition to, for now) the
instruction.

The EntityNameId will be used to look in the ScopeStack to find the
witnesses either from the BindSymbolicName instruction, or other
instructions that specify `impls` constraints against the EntityName.

This will allow us to have the `T` in `I(T)` resolve to a `.Self`
reference in the type so that we get type equality with the binding's
type: `T:! I(.Self)`.
2025-10-06 18:56:43 +00:00
Boaz Brickner b1c0854948 Add blank lines to group case with the above offset increment in InstNamer::GetScopeIdOffset() (#6165)
This would hopefully help prevent bugs like the one fixed in #6151.
See refactoring discussion in #6159.
2025-10-06 18:20:54 +00:00
Boaz Brickner 5f561282eb Properly set the name for C++ overload set instructions in SemIR (#6156)
This is a followup of #5891.
Part of #5915.
2025-10-06 07:36:28 +00:00
David BlaikieandRichard Smith 12fa65e53c Check for use of InstIds from the wrong SemIR::File (#5997)
Use the `CheckIRId` as a unique identifier for the scope of an `InstId`
- if an `InstId` is created within the scope of one `CheckIRId` it must
not be used in the scope of a different `CheckIRId`.

This is achieved without extra storage, but with false negatives for
large inputs.

When an `InstId` is created, the original index of the `Inst` is XORed
with a tag derived from the `CheckIRId` to produce the final `InstId`.
When the `InstId` is used, the expected tag is XORed with the `InstId`
to get back to the original index - if the tags don't match, the
resulting index will be corrupted, likely too large - resulting in an
out of bounds index CHECK-failure.

(the tag value is derived as such:
* take the CheckIRId
* left shift one bit (padding zero)
* left shift another bit (padding 1 - used to signify that the resulting
`InstId` has a tag combined into it)
* reverse the bits

In this way, the tag is unlikely to overlap with the index for small
test cases - making it possible to separate out the `CheckIRId` from the
index in these cases to provide more meaningful debugging/CHECK
messages, and more informative `SemIR` textual dumping that can now
include the `CheckIRId` along with the `Inst`'s index in the name of an
`inst`)

The test churn here is improved printing as tagged `InstId`s can now,
with best effort (more likely for small test cases where the `CheckIRId`
and the `Inst` index aren't at risk of overlapping from the high and low
bits), render the `CheckIRId` as part of the inst's name. Going from
`instNN` to `irMM.instNN`.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2025-10-02 23:07:36 +00:00
Boaz Brickner 16999a79cc Fix a crash caused by a bug introduced in C++ overloads support in GetScopeIdOffset() (#6151)
After this change, we correctly increment the offset by the next switch
case type.
Before this change, we accidentally incremented the offset by
`functions()` size instead of `cpp_overload_sets()` size and vice versa.
Also sorted the switch cases according to the order of the enum, for
consistency. This might help prevent a future similar incident.

This fix prevents crashing in the newly introduced test
`multiple_too_few_args_calls`.

This also has the side effect of showing `null name` for
`cpp_overload_set_type` and `cpp_overload_set_value`, instead of having
an arbitrary name.
Examples that demonstrate the old name is arbitrary can easily be seen
in tests like `cpp_namespace.carbon` and `decayed_param.carbon`, but
careful review would show that all old names are arbitrary, though often
luckily almost make sense.

We might want to have a proper name for these, but it's beyond the scope
of this crash fixing change.
See #6156.

Part of #5915.
2025-10-02 14:34:34 +00:00
Ivana Ivanovska a24598f069 Lower CppOverloadSetValue (#6101)
Following up on comments from
[#5891](https://github.com/carbon-language/carbon-lang/pull/5891) ([
1](https://github.com/carbon-language/carbon-lang/pull/5891#discussion_r2317244981),
[2](https://github.com/carbon-language/carbon-lang/pull/5891#discussion_r2317266756)).

Lowering `CppOverloadSetValue` as an empty struct value, using
`context.GetLiteralAsValue()`. Also changed its constant kind to
`InstConstantKind::Always`.

Part of https://github.com/carbon-language/carbon-lang/issues/5915
2025-10-01 16:25:05 +00:00
Jon Ross-Perkins 4a6376cf59 Rename/restructure Destroy logic to better reflect #6124 (#6144)
This also does a little restructuring in the same direction, following
#6124.

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

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

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

Note though that this doesn't make any really big changes. It's just
realigning on the leads decision. I'm going this way to try to reduce
name-related churn for other changes.
2025-09-30 20:43:36 +00:00
Dana Jansens a6bb11f1cf Rearrange convert: construct FacetAccessType from a facet value before impl lookup instead of after (#6113)
This makes convert more consistent, it always makes a FacetAccessType
for a facet value, rather than only doing so after lookup returns. The
intention for this is that FacetAccessType will evaluate to
SymbolicBindingType in the future, so this will expose that constant
value to impl lookup instead of the original facet value, which will
avoid impl lookup having to deal with `.Self` or `BindSymbolicName`
specifically.
2025-09-29 22:49:06 +00:00
Richard SmithandDana Jansens 3b6d202730 Implement support for mixed-access overload sets. (#6137)
This turns out to be quite important, as several important standard
library types (such as `std::string`) have mixed-access overload sets
for their constructors as an implementation detail. The overall approach
here is:

- Use the most permissive access to determine the access of the overload
set itself. This affects whether name lookup finds the member name at
all.
- After overload resolution, re-check the access of the selected member,
if it's protected or private.

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
2025-09-26 23:18:16 +00:00
Jon Ross-Perkins 705c95d6e0 Drop fn destroy support (#6136)
`fn destroy` is being removed per decision on #6124. It seems like the
relevant decision will result in no more keyword-based function names,
so this is removing all related support.
2025-09-25 21:56:48 +00:00
Richard SmithandJon Ross-Perkins 1e7b7e53ae C++ interop: support for default arguments. (#6108)
The general strategy here is to force use of a thunk when we want to use
default arguments, and have Clang generate uses of the default arguments
on its side of the thunk.

To support this, change the key type used in `clang_decls` from being
just a `Decl*` to being a pair of `Decl*` and number of parameters in
the case of function decls. Import distinct `SemIR::Function`s for each
number of parameters that's used, and corresponding distinct thunks.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2025-09-24 01:07:59 +00:00
Dana JansensandRichard Smith 82679e6689 Make BindSymbolicName the canonical form of a FacetValue wrapping the BindSymbolicName (#6107)
If a `BindSymbolicName` is converted to `type` and then to its exact
`FacetType`, we get a `FacetValue` wrapping the `BindSymbolicName` but
providing no different information: it has the same witnesses and
`FacetType` as the original `BindSymbolicName`. Yet it is a different
constant value, creating multiple canonical forms with the same meaning.
Now we make that `FacetValue` with the same `FacetType` as the
`BindSymbolicName` it wraps evaluate back to the `BindSymbolicName`,
making it the unique canonical form.

This makes the "shortcut" in convert for avoiding impl lookup when
converting from `FacetAccessType` to `FacetType` in this exact scenario
work the same as doing the full impl lookup.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2025-09-23 22:11:11 +00:00
Jon Ross-Perkins 8004c2d5f6 CalleeFunction -> Callee name adjustments (#6117) 2025-09-23 17:51:31 +00:00
Jon Ross-Perkins 0f7df4ed7e Switch CalleeFunction to a variant (#6104)
Trying to make it easier to see what's intended to be present/correct on
`CalleeFunction` in its various modes.
2025-09-22 22:56:38 +00:00
Jon Ross-Perkins 70cde77f0e Update TypeIterator to use CARBON_KIND_SWITCH (#6105)
Also clean up unnecessary `SemIR::` use in these files.
2025-09-22 15:56:08 +00:00
Jon Ross-Perkins ef1e47cd07 Remove redundant SemIR:: uses in SemIR (#6106)
Also cleaned up some in #6105, which is what got me looking for more.
2025-09-22 15:55:46 +00:00
Dana Jansens b1b79c1bac Set deduce_through to false for FacetType, since we don't deduce through it (#6087)
We decided on 2025-04-02 not to do deduction through facet types,
because types can implement a generic interface multiple times with
different arguments. See:
https://docs.google.com/document/d/1Iut5f2TQBrtBNIduF4vJYOKfw7MbS8xH_J01_Q4e6Rk/edit?pli=1&resourcekey=0-mc_vh5UzrzXfU4kO-3tOjA&tab=t.0#heading=h.95phmuvxog9n

Then we no longer need the case handling `FacetTypeId` in deduce.cpp. We
move the comment over to the definition of the `FacetType::Kind`.

The deduce case was for `FacetTypeId`, not `FacetType`, but `FacetType`
is the only instruction which holds such an Id.
2025-09-18 13:29:53 +00:00
730935691a Support for mapping str to std::string_view in interop. (#6079)
We already did the opposite direction; this enables use of `str` in
overload resolution.

Fixes #6062

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
2025-09-16 23:40:33 +00:00
Richard Smith bac828d244 Add support for char keyword per #5903. (#6078)
Make inst namer and stringify print `Core.Char` and `Core.String` as
`char` and `str` respectively. Plus a few cleanups.
2025-09-16 20:45:01 +00:00
Jon Ross-Perkins 59c4cbcaf1 Treat type modifiers as distinct type structure (#6073)
This came up because `const T` needs destructor support... This change
makes `impl T as Destroy` and `impl const T as Destroy` distinct type
structures. Right now there's no impl lookup fallback (see
[#6068](https://github.com/carbon-language/carbon-lang/issues/6068)); so
when trying to destroy `const T`, there's no way to have an `impl` for
it to find.

In discussion, `MaybeUnformed` and `partial` have similar challenges, so
I'm covering them together.

In type_structure.h, I'm switching to an enum because it felt like an
easier way to be adding more types. I can switch back if preferred,
though then might take a closer look at the `operator==` because that's
kind of verbose.
2025-09-16 20:44:39 +00:00
Richard Smith b44ba47cf3 Don't treat dependent types as having a copy value representation. (#6055)
Add `Dependent` value and initializing representations for types whose
representations are unknown because they are dependent. When generating
SemIR in such cases, use a worst-case initializing representation that
both provides a destination address and also propagates a potential
result value.

Use this to fix incorrect lowering and lowering crashes for specific
functions involving generic types that don't use a copy value
representation.

In lowering, be careful to distinguish between whether the initializing
representation for the generic return type uses a return slot (which
affects whether the SemIR declaration and call have one) and whether the
initializing representation for the specific return type uses a return
slot (which affects whether the LLVM IR declaration and call have one).
2025-09-15 23:59:00 +00:00
Richard Smith 0cafb8f0e4 Store the CppOverloadSetId on CalleeFunction. (#6067) 2025-09-15 21:58:55 +00:00
Jon Ross-PerkinsandDana Jansens 5e3bb523f8 Add builtin functions for destroy, with special requirements in facet types (#6035)
This is in support of a goal of changing the blanket `destroy` impl to
use (roughly):

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

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

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

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

A few alternatives considered were:

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

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
2025-09-15 17:03:43 +00:00
Ivana Ivanovska 12ddfb9c7c [Carbon/C++ interop] Add support for C++ overloaded functions (#5891)
As proposed in [Carbon: C++ interop for overloaded functions and
function
templates](https://docs.google.com/document/d/1KUxumZtNe3mY3TsjW2s_ZADOlAaFlrtsLKHVILtqIaM/edit?tab=t.0),
Clang is used to perform the overload resolution using C++ rules, when
an overloaded C++ set is called from Carbon. Once a function is
selected, it's converted into a Carbon function and called using the
Carbon rules including argument conversions.

A single non-templated function is treated the same way as an overload
set and the same rules apply for its call.
Template functions are not supported yet.

Demo:

a) Non-templated function calls:

```c++
// --- overloads.h

auto foo(int a, short b) -> void;
auto foo(double a) -> void;
auto foo(int a) -> void;
```

```c++
// overloads.cpp

#include "overloads.h"
#include <cstdio>

auto foo(int a, short b) -> void {
  printf("hello from foo_int_short(%d, %d) \n", a, b);
}
auto foo(double a) -> void { printf("hello from foo_double(%f) \n", a); }
auto foo(int a) -> void { printf("hello from foo_int(%d) \n", a); }
```
```c++
library "Main";

import Cpp library "overloads.h";

fn Run() -> i32 {
  Cpp.foo(1.1 as f64);
  return 0;
}
```
```
$ clang -c overloads.cpp 
$ bazel-bin/toolchain/carbon compile main.carbon
$ bazel-bin/toolchain/carbon link overloads.o main.o --output=demo
$ ./demo
hello from foo_double(1.100000) 
```

b) Constructors:
```c++
// --- constructor_overloads.h
class C {
 public:
  C();
  C(int a, int b);
};
```

```c++
// constructor_overloads.cpp
#include "constructor_overloads.h"
#include <cstdio>

C::C() { printf("hello from C() \n"); }
C::C(int a, int b) { printf("hello from C(%d, %d) \n", a, b); }
```
```c++
library "Main";

import Cpp library "constructor_overloads.h";

fn Run() -> i32 {
  let c1: Cpp.C = Cpp.C.C();
  let c2: Cpp.C = Cpp.C.C(1, 2);
  return 0;
}
```

```
$ clang -c constructor_overloads.cpp 
$ bazel-bin/toolchain/carbon compile main.carbon
$ bazel-bin/toolchain/carbon link constructor_overloads.o main.o \--output=demo
$ ./demo
hello from C() 
hello from C(1, 2) 
```


Follow-ups:

- `Cpp.foo({})` - proper handling of struct literals as call args.
- Fix access for overloaded sets.
- Fix tests:
- Method calls: `error: missing object argument in method call
[MissingObjectInMethodCall]` in tests.
    - Fix `toolchain/check/testdata/interop/cpp/import.carbon` test.
    - Fix `enums` support.
    - Fix `str` -> `std::string_view` mapping.


Part of #5915
2025-09-15 12:29:49 +00:00
Elliott KaltandRichard Smith f4bd6e42f9 Replace impl fn with override fn (#6008)
This proposal renames the syntax used to mark an overriding definition
of a virtual method from `impl fn` to `override fn` to avoid ambiguity:
besides indicating an overriding virtual function, it can be parsed as
an "impl" declaration when the construct following "impl" begins with a
lambda introduced by "fn".

Closes #5711

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2025-09-12 23:27:02 +00:00
Jon Ross-PerkinsandRichard Smith 973d721916 Some more edits to EnumBase and EnumMaskBase (#6054)
Adds a unit test, and some smaller edits:

- Remove the `=` when defining names, in order to change `}` placement
by clang-format on uses.
- context:
https://github.com/carbon-language/carbon-lang/pull/6053#discussion_r2343423178
- I believe with `EnumBase` that keeping the `=` had been a deliberate
choice, so this PR is intended to confirm that removing it is okay.
- Delete `EnumMaskBase::name`
- context:
https://github.com/carbon-language/carbon-lang/pull/6053#discussion_r2344233707
- We can't just do nothing because `EnumBase::name` uses indexing that's
incompatible with `EnumMaskBase`.
- Some small comment cleanups.
- Tests don't need to be in the `Carbon` namespace anymore, macros work
fine in other namespaces, but it's still the right namespace.
- Documentation on `EnumBase::name` seems to be referring to a prior
structure, wherein we had a macro defining the function instead of the
`Names` array.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2025-09-12 22:59:37 +00:00
Jon Ross-Perkins 6cc5d7ed2a Add an EnumMaskBase type (#6053)
This is a bit of an experiment to see if there's a reasonable way to
write a shared enum type, rather than writing per-case wrappers for
things like `HasTypeQualifiers` or the printing. I think it's a bit
borderline complexity right now, but I'm not sure I can reduce it much
further.

This changes from things like `Internal::EnumClassName##RawEnum` to
`Internal::EnumClassName##Data::RawEnum` so that the enum entries can
have back references to bit shifts without needing to know the
containing type name. Because I'm trying to reduce duplication between
mask and non-mask enums, I did this to non-mask enums too.

This was motivated by #6035 adding another enum mask (which will grow
more entries, and is intended to switch if this is accepted), but I'm
not using that PR as a base here because I didn't want the merge
dependency.
2025-09-12 18:04:10 +00:00
Dana Jansens 896ef4da0e Include the Name when dumping an instruction with a name (#6051)
If the first argument is an EntityNameId, then dump the name from within
it. In particular this affects dumping BindName and BindSymbolicName.

```
(lldb) dump context non_canonical_query_self_inst_id
inst96: {kind: BindSymbolicName, arg0: entity_name4, arg1: inst<none>, type: type(symbolic_constant35)}
  - name: `T`
  - type: type(symbolic_constant35): I(.Self) where .Self.(I(.Self).X) = (); {kind: FacetType, arg0: facet_type4, type: type(TypeType)}
  - value: symbolic_constant36
  - loc: LocId(<none>)
```
2025-09-11 18:50:35 +00:00
Richard SmithandGeoff Romer 1ec8ac7ef9 Add Copy interface and use it for making copies. (#6034)
Instead of hardcoding which types are copyable, add a `Core.Copy`
interface to perform copying. Move almost all the current copy support
to that interface. Some remaining pieces are still using builtin logic
after this PR:

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

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

---------

Co-authored-by: Geoff Romer <gromer@google.com>
2025-09-10 23:55:55 +00:00
Jon Ross-Perkins b0d93c2393 Use enumerated values in formatter (#6042)
Noticed this was essentially just fetching then discarding the values,
which felt odd to me. I was considering adding an `ids()` function, but
this would leave only 3 spots that'd use it, and the absence seems like
it'll nudge code towards using the value of `enumerate()` when
reasonable.
2025-09-10 18:40:48 +00:00
Jon Ross-Perkins 3f799bd987 Use explicit(false) for implicit construction (#6039)
Echoing what was added in #5608, updating existing uses. Unfortunately
there's divergent behavior for operators versus constructors, so keeping
the nolint on those.
2025-09-10 13:47:59 +00:00
Jon Ross-Perkins b74fdf52de Use typename on templates for consistency. (#6038)
They're essentially equivalent, we just typically write `typename`; even
in the examples here, most have other templates in the same file that
use `typename`.
2025-09-10 13:44:36 +00:00
Jon Ross-Perkins 0518fdebbc Fix potential fingerprint conflict in constraints (#6033)
This uses each vector's size as a barrier between lists, to eliminate
the possibility of incidental collisions between entries of different
lists. This is the same as is done inside `AddBlock`.
2025-09-09 21:44:03 +00:00
Dana Jansens 64139e5d65 Stop using Map for the cache in InstFingerprinter (#6019)
This takes the debug runtime of
`toolchain/check/testdata/interop/cpp/function/arithmetic_types_bridged.carbon`
from 4.7s down to about 4s (so 15% faster overall).

There's still lots of room to improve this test which seems to be
hitting lots of pathological behaviour, but InstNamer is 30% of the
runtime, with fingerprinting's `InstFingerprinter::GetOrCompute`
consuming 10% of cycles. We reduce its impact by using a vector of
vectors instead of a Map for the cache of fingerprints. After this
change InstNamer drops below 24% of the runtime.

Also move the instruction name when giving it to `AllocateName` since it
receives std::string by value, though this doesn't show up in the
profile for the test.
2025-09-08 16:15:10 +00:00
Boaz Brickner b88b53e7e3 C++ interop: Add support for importing globals (#6005)
This supports importing globals in the global scope and within
namespaces, and support for class static data members.

C++ Interop Demo:

```c++
// my_global.h

extern int my_global;
void inc_my_global();
```

```c++
// my_global.cpp

#include "my_global.h"

int my_global = 5;

void inc_my_global() {
  ++my_global;
}
```

```carbon
// main.carbon

library "Main";

import Core library "io";
import Cpp library "my_global.h";

fn Run() -> i32 {
  Core.Print(Cpp.my_global);
  Cpp.inc_my_global();
  Core.Print(Cpp.my_global);
  return 0;
}
```

```shell
$ clang -c my_global.cpp
$ bazel-bin/toolchain/carbon compile main.carbon
$ bazel-bin/toolchain/carbon link my_global.o main.o --output=demo
$ ./demo
5
6
```

Part of #6006.
2025-09-08 08:34:55 +00:00
Chandler Carruth 0691d4827c Update LLVM (#6022)
Notably, this updates past a major AST refactoring and tries to apply
those changes across the toolchain.
2025-09-06 08:36:10 +00:00
Richard Smith db0a00d713 Fix double-destruction of temporaries. (#6010)
Attach the cleanup to the `Temporary` instruction instead of to the
`TemporaryStorage` instruction. We create `TemporaryStorage`
instructions speculatively when creating an initializing expression, and
may overwrite those instructions with other instructions if it turns out
that a temporary is not required. Instead, wait until we finalize the
temporary and create a `Temporary` instruction to register the cleanup.
2025-09-04 19:19:59 +00:00
Richard Smith 51cb078da4 Support lowering of functions with variable binding parameters. (#6012)
Fix a crash when attempting to lower a function with a variable binding
as a parameter. This is a narrowly-targeted fix, and not the right
longer-term approach; more complex patterns as function parameters will
still fail and likely crash.
2025-09-04 15:02:37 +00:00
Richard Smith cb5e2e1597 Improve support for qualification conversions. (#5999)
* Treat `MaybeUnformed` and `partial` as qualifiers, like `const`.
* Allow pointer conversions to add qualifiers.
* Allow unsafe pointer conversions to remove qualifiers.
* Allow conversions on non-reference expressions to drop `const`.
* Allow unsafe conversions on any expression to drop `const`.
* Allow unsafe conversions on non-initializing expressions to drop
  `partial`. For initializing expressions, we should initialize the
  vptr when dropping `partial`; this is not yet supported so we reject.
* Allow conversions on reference expressions to add `MaybeUnformed`.
* Allow unsafe conversions on reference expressions to drop
  `MaybeUnformed`. For non-reference expressions, additional work is
  required, because the value / initializing representation may not
  match between `T` and `MaybeUnformed(T)`, so those are rejected for
  now.
2025-09-03 21:00:12 +00:00
Boaz Brickner 870c5380a0 C++ interop: Support importing binary operator+ (#5996)
Triggered by calling a binary operator with LHS being an imported C++
class type.

Not supported (yet):
* Multiple overloads.
* Other operators.

C++ Interop Demo:

```c++
// hello_world.h

class C {
 public:
  C(int x) : x_(x) {}
  auto x() const -> int { return x_; }

 private:
  int x_ = 0; 
};

auto operator+ (C c1, C c2) -> C;
```

```c++
// hello_world.cpp

#include "hello_world.h"

#include <cstdio>

auto operator+ (C c1, C c2) -> C {
  printf("Adding %d with %d\n", c1.x(), c2.x());
  return C(c1.x() + c2.x());
}
```

```carbon
// main.carbon

library "Main";

import Cpp library "hello_world.h";

fn Run() -> i32 {
  let c1 : Cpp.C = Cpp.C.C(7);
  let c2 : Cpp.C = Cpp.C.C(8);
  let c3 : Cpp.C = c1 + c2;
  let c4 : Cpp.C = c3 + c2;
  return 0;
}

```

```shell
$ clang -c hello_world.cpp
$ bazel-bin/toolchain/carbon compile main.carbon
$ bazel-bin/toolchain/carbon link hello_world.o main.o --output=demo
$ ./demo
Adding 7 with 8
Adding 15 with 8
```

Part of #5995.
2025-09-03 12:01:20 +00:00
Elliott Kalt 58de34e534 Decouple associated constants from let (#5973)
Decouples associated constants from being special cased in let handlers.
Enforces associated constant grammar restrictions in parsing instead of
checking.

Closes #5411
2025-09-02 23:15:26 +00:00
Richard Smith 0e6dd7e701 Add MaybeUnformed(T) type. (#5989)
This type has the same object representation as `T`, but always uses a
pointer type as its value representation. No other semantics are
provided for it yet.
2025-09-02 20:50:49 +00:00
Boaz Brickner b5d86fdb6f Properly dump SemIR for inline C++ imports (#6001)
Dumping SemIR crashed on inline C++ imports and this outputs `import Cpp
inline` instead.
Followup of #5904.
2025-08-29 21:36:10 +00:00