Commit Graph
2435 Commits
Author SHA1 Message Date
Aiden Grossman 5714f4deb2 Use Overload of lookupTarget Accepting Triple (#6205)
The overload accepting a string/llvm::StringRef is deprecated and will
be removed when LLVM 22 branches.
2025-10-13 18:52:49 +00:00
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
Richard Smith e26b6a35c2 Allow instance binding on tuple-valued expressions. (#6203)
Don't expect the right-hand operand of `a.(b)` to always be a tuple
index when `a` is of tuple type; it could also be a method name.

Fixes #6162.
2025-10-11 04:54:13 +00:00
Boaz Brickner 1ac1d11063 C++ Interop: Support reference types in fields and globals (#6187)
Implemented by generalizing the reference type support for parameters
and return values to other use cases.
The changes to the `method.carbon` test are due to to supporting the
reference types but not supporting the necessary conversions.

C++ Interop Demo:

```c++
// global.h

struct C {
  int member = 0;
  int& member_ref = member;
};

extern C& global;
```

```c++
// global.cpp

#include "global.h"

static C static_c;

C& global= static_c;
```

```carbon
// main.carbon

library "Main";

import Core library "io";

import Cpp library "global.h";

fn Run() -> i32 {
  Core.Print(Cpp.global->member);
  ++(*Cpp.global->member_ref);
  Core.Print(Cpp.global->member);
  ++(*Cpp.global->member_ref);
  Core.Print(Cpp.global->member);
  return 0;
}
```

```shell
$ clang++ -stdlib=libc++ -c global.cpp
$ bazel build toolchain:carbon && bazel-bin/toolchain/carbon compile main.carbon
$ bazel-bin/toolchain/carbon link global.o main.o --output=demo
$ ./demo
0
1
2
```

**Without this change**:
```shell
main.carbon:10:14: error: semantics TODO: `Unsupported: var type: C &`
  Core.Print(Cpp.global->member);
             ^~~~~~~~~~
main.carbon:10:14: note: in `Cpp` name lookup for `global`
  Core.Print(Cpp.global->member);
             ^~~~~~~~~~
```

Part of #6006 and #6186.
2025-10-10 23:15:31 +00:00
Boaz Brickner 0365467872 Merge toolchain/check/testdata/interop/cpp/class/struct.carbon into class.carbon (#6198)
The tests are almost identical and test the same logic so basically
duplicated.
The extra coverage that was in `struct.carbon` is added to
`class.carbon`.
One basic test in `struct.carbon` was left just to make sure `struct` is
supported.

Part of #5150.
2025-10-10 22:37:25 +00:00
Boaz Brickner 46c5209f2f C++ Interop: Set location when creating a return pattern (#6185)
This requires changing `ReturnSlotPattern` and `OutParamPattern`
definitions to use untyped node id, so they can have any associated
node.

Follow up of #5197.
Part of #5064.
2025-10-10 15:32:14 +00:00
Boaz Brickner 9441c278df Avoid using clang::UnresolvedSetImpl (#6197)
Avoid relying on implementation details.
Also, use `DeclAccessPair::operator->` instead of `.getDecl()->`.
2025-10-10 15:29:53 +00:00
Alina Sbirlea 96a3c1e41f [Specific coalescing] Do not update canonical when is exists. (#6196)
Only update the canonical for itself if it has no value, otherwise a
"better" canonical was previously added and the chain will be followed
when deleting specifics.
2025-10-10 14:33:03 +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
Boaz Brickner f713964db4 C++ Interop: Set location when creating param patterns (#6184)
Follow up of #5197.
Part of #5064.
2025-10-10 09:00:00 +00:00
Alina Sbirlea fd15949fe5 [Specific coalescing] Remove non-canonical from processing. (#6191)
When a pair of specifics is found to be equivalent, the current logic
would always remove the second one (j indexed) from further processing,
assuming that i was the canonical. That's not always the case, when the
j is the canonical, the i indexed specific should be the one removed.
Update logic to reflect that.
Adding testcase.
2025-10-09 23:51:04 +00:00
Dana Jansens 3d592ebe59 Support member access into the type of (facet as type) expressions as being into the facet's type (#6190)
When we do member access `x.F` we attempt to look into the type of `x`
for `F`. If `x` is a facet, we look at its FacetType to find `F`. We
want `facet` and `facet as type` expressions to be generally treated as
equivalent, so we need to get at the "canonical facet value" of `x` in
order to look into its type. Add a new operation that allows us to
preserve the non-canonical `base_id` in the member access for
diagnostics if no conversion to a canonical facet value was needed.
2025-10-09 22:06:02 +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
Ivana Ivanovska 1fe3316f8e Remove unnecessary TODO (#6188)
When importing the overload set the dependencies are not imported
anymore, so this TODO is unnecessary.

Part of #5915
2025-10-09 11:46:08 +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 c254e9fd75 C++ interop: Correctly report the unsupported param type when using explicit object param (#6179)
This fixes a bug, which seems to have been introduced in #6108.

In the new test, without this change, we will diagnose with
```
error: semantics TODO: `Unsupported: parameter type: ExplicitObjectParam` [SemanticsTodo]
```
2025-10-08 17:01:11 +00:00
Dana Jansens fd74e49fd2 Add tests of .Self given for an interface parameter that has constraints (#6181)
This tests that `.Self` in an interface generic parameter preserves the
facet type information of the binding when returned, and allows compound
member lookup back into that interface.

And add a failing-todo test that `.Self` gets implied constraints which
can be satisfied through `&` for the facet type `I(.Self)` is part of.
2025-10-08 16:51:23 +00:00
Boaz Brickner bfc4d2b127 C++ interop: Add return reference types support (#6178)
This is a follow up of #6082, which added support for reference types,
but not for return types.

C++ Interop Demo:

```carbon
// main.carbon

library "Main";

import Core library "io";

import Cpp inline '''
struct C {
  auto Inc() -> void { ++x; }
  int x = 0;
};
auto GetC() -> C& {
  static C c;
  return c;
}
''';

fn Run() -> i32 {
  Core.Print(Cpp.GetC()->x);
  Cpp.GetC()->Inc();
  Core.Print(Cpp.GetC()->x);
  Cpp.GetC()->Inc();
  Core.Print(Cpp.GetC()->x);
  return 0;
}
```

```shell
$ bazel build toolchain:carbon && bazel-bin/toolchain/carbon compile main.carbon && bazel-bin/toolchain/carbon link main.o --output=demo && ./demo
0
1
2
```

**Without this change**:
```shell
main.carbon:19:14: error: semantics TODO: `Unsupported: return type: C &`
  Core.Print(Cpp.GetC()->x);
             ^~~~~~~~~~
```

Part of #6148.
2025-10-08 16:33:09 +00:00
Dana Jansens ba8ed99eb0 Add failing tests for exposing the value of .Self through an interface (#5957)
We test using .Self in a generic parameter of an interface and as the
value of an associated constant.
2025-10-08 15:53:55 +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
Boaz Brickner 49213b1ca3 Fix Candidataes typo (#6169) 2025-10-07 11:58:06 +00:00
Dana Jansens 2ee2b2f1e3 Move the FacetAccessType special case out of name lookup, and generalize it (#6163)
The `AppendLookupScopesForConstant` function had a special case for
`facet as type` which was overly broad (applying to all callers to the
function when only one caller needs it), and was confusingly overly
specific (applying to `facet as type` but not to `facet` constants).

We clarify all of this by moving it out to member access, and applying
it only to the case of looking into the type of `base_id`. In that case
we are doing member lookup into the facet itself, but since it's
symbolic we don't know the type to look into. And we don't defer the
lookup with a symbolic instruction, so we do the lookup into the facet's
type instead.

We add a helper function in member access, `ExtractFacetTypeForFacet` to
encapsulate this slightly-odd operation. It's odd because it ends up
getting *the type of the type* when the `base_id` has a facet as its
type.

The helper is now built on top of GetCanonicalFacetOrTypeValue() instead
of explicitly looking for FacetAccessType, which makes it work more
generally for any type instructions that represent a facet, including
SymbolicBindingType in the future.

While here document and improve clarity throughout the
`PerformActionHelper` for member access.
2025-10-06 19:06:26 +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
Dana Jansens b99bc00632 Deduce arguments against the canonical facet value (#6158)
When deducing an argument against a type that is `<facet value> as type`
we don't care about the `as type` part of that expression. We want to
find an argument that can convert to the `FacetType` of the facet value
for the generic binding that is the `<facet value>`.

This was done after-the-fact in the Deduce switch, but we move this
canonicalization step to be more explicit and done up front at the start
of the Deduce loop. This:
- Avoids a trip through the Deduce loop for a `FacetAccessType`
parameter, just to deduce through it in the switch, which avoids convert
and creation of extraneous constant values.
- Uses the `GetCanonicalFacetOrTypeValue()` function so that when we add
`SymbolicBindingType` handling to that function it will apply to Deduce
as well correctly, instead of needing to handle both in the switch.
2025-10-03 17:05:19 +00:00
Dana Jansens e3b4482893 Make the GetCanonicalFacetOrTypeValue operation more crisp (#6157)
Previously it performed two kinds of operations, with a boolean
parameter to control whether it would unwrap FacetValue or not. This
made the function hard to explain as "canonicalization".

Now the contract of GetCanonicalFacetOrTypeValue is as follows:
1. For a facet value expression, it returns the canonical value of the
facet value.
2. For a `<facet value> as type` it returns the canonical value of the
`<facet value>`.
3. For other type expressions, it returns the canonical value of the
type.

1 and 2 together collapse together two representations of a facet value
(as a FacetType or as a TypeType) into a single canonical value, which
is important for constant comparison of facet values where the `as type`
is not meant to change the result. This is the case in impl lookups and
`.Self` comparisons.

The step of unwrapping `FacetValue` is only useful in the constant
evaluation of `LookupImplWitness` and is used to collapse *symbolic*
queries on `FacetValue(T)` and on `T` down to a single canonical value,
since they produce the same result later when `T` is replaced with a
facet value or type that can provide a concrete witness. This is now
extensively documented in the constant evaluation of
`LookupImplWitness`.

This change came out of a request/discussion in #6115 (see comment
https://github.com/carbon-language/carbon-lang/pull/6115#discussion_r2383696576).
2025-10-03 15:21:07 +00:00
Jon Ross-Perkins 81c2b3be1a Handle some more errors in interfaces without crashing. (#6155)
This fixes and tests two crashes related to what I was observing [on
#toolchain](https://discord.com/channels/655572317891461132/655578254970716160/1422723976483831848).

The approach to Cpp imports taken in #6086 is problematic because it
returns before the work stack is completed, and doesn't store the
resulting constants. This fixes the approach taken in that PR.
2025-10-03 14:31:45 +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 ce6bf91a83 Avoid extra work when thunk_required is already true in IsCppThunkRequired() (#6150)
Also set `thunk_required` in a more consistent way, to avoid bugs like
the one fixed in #6152.

Part #6148.
2025-10-02 19:11:31 +00:00
Dana Jansens 0c761a9a78 Find the builtin TypeCanAggregateDestroy in the FacetType for facet values (#6119)
When doing impl lookup with a constraint facet type including the
builtin `TypeCanAggregateDestroy`, we look at the type to see if it
satisfies it. However if the type is a facet value, we need to look at
the FacetType to see if the eventual concrete type is going to satisfy
it.

Note that we can do this check up front in the `LookupImplWitness()`
function without creating a symbolic instruction to be modified by
future specifics with a more precise type for the facet value, because
the result of `TypeCanAggregateDestroy` does not actually provide a
witness, so we don't need the final specific type.

This was noticed by removing the "shortcut" in convert for converting a
`FacetAccessType(<symbolic binding>)` to `typeof(<symbolic binding>)`.
By removing the shortcut, we go into impl lookup when checking `impl`
decls containing `TypeCanAggregateDestroy` via deduce.
2025-10-02 18:57:37 +00:00
Boaz Brickner 57c0fde145 Fix C++ thunk triggering for functions with default args which return a simple type (#6152)
Before this change, we wrongly ignore the decision to generate a thunk
for a function with default args by overriding this decision with the
fact the return type by itself doesn't require a thunk.
This causes not generating a thunk which leads to crashing in lowering.
Add tests that show that now thunk is generated in `check` and it no
longer crashes in `lower`.

Follow up of #6108.
2025-10-02 15:16:28 +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
Boaz Brickner a16102b249 Add tests for returning a C++ reference type, rvalue and const reference (#6149)
Part of #6148.
2025-10-02 08:49:10 +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
Hitesh JoshiandHitesh Joshi 0166d8837c Update Documentation to use new expression terminology (#5890)
# Changes

## Terminology Updates
This PR updates documentation to align with the expression phase
terminology changes introduced in
[#2964](https://github.com/carbon-language/carbon-lang/pull/2964):

* **"symbolic value" → "symbolic constant"**: Updated all remaining
instances using find-and-replace

## Scope of Changes
* Focused on documentation that predates the July 2023 terminology
change
* Used git blame history to identify instances likely using the old
"constant" definition
* Manually reviewed each "constant" usage to distinguish between:
- New definition (unchanged): the broader category including symbolic
constants

Closes
[#5599](https://github.com/carbon-language/carbon-lang/issues/5599)

---------

Co-authored-by: Hitesh Joshi <hitesh@mitsu.care>
2025-09-30 20:15:55 +00:00
Jon Ross-Perkins 47081be67a Reduce test sensitivity to small import loc changes (#6145)
Locations are similarly fragile, because adding a comment changes them.
This has made me pause when making prelude changes in #6144, so dropping
them for those cases.

Instruction ids aren't actually that interesting outside debugging, and
can be churny when doing other structural changes. I've seen this in
particular when doing singleton changes, which bump every instruction
id.

Note there are still other ways fragility from locations can crop up.
This shouldn't be considered a complete fix, but hopefully a small
improvement.
2025-09-30 17:20:14 +00:00
Dana Jansens 54b994ceac Simplify member access in facet values (#6146)
Given `fn f(T:! I, x: T)`, we have a facet type `I`, a facet value `T`
and a value `x` of type `FacetAccessType(T)`.

Previously we explicitly handled the case of member access on `x.F`
where the type is a `FacetAccessType` by looking through it at the facet
value, and then at its facet type. This is already something that impl
lookup does for us, so we can remove this special case.

We also previously had a complex branch handling the case `T.F` on a
facet value, because `PerformImplLookup()` in member access is expecting
a `TypeId`, not a facet value. However, the first thing that branch does
is convert the facet value to a type expression, forming a
`FacetAccessType`.

Unfortuntely, when combined, if we had `x.F` we would convert it from a
value of type `FacetAccessType` to a facet value, and then convert that
to a type as a `FacetAccessType` again. We see this extra
`FacetAccessType` disappear from the SemIR after this change.

In this change, we remove both the inlined replacement of
`PerformImplLookup()` and the explicit handling of `FacetAccessType`. We
drive all member access lookups on the `base_id`'s type through a single
`PerformImplLookup()` call. If the `base_id` is a facet value, to get
the TypeId to look into, we convert the facet value to a
`FacetAccessType`, reducing the complex special cases down to a single
line.
2025-09-30 16:27:31 +00:00
Chandler CarruthandDana Jansens 35fb000536 Use a thread pool when building runtimes (#6133)
This parallelizes the compilations and dramatically reduces the time to
build runtimes.

As part of this, teach the driver infrastructure to have an option to
control the use of threads and to build the relevant thread pool and
thread it into the various APIs.

However, it requires our `ClangRunner` to become thread-safe and to
invoke Clang in a way that is thread-safe. This is somewhat challenging
as the code in `clang_main` is distinctly _not_ thread-safe.

To address this, the relevant logic of `clang_main`, especially the CC1
execution, is extracted into our runner and cleaned up to be much more
appropriate in a multithreaded context. Much of this code should
eventually be factored back into Clang, but that will be a follow-up
patch to upstream.

Last but not least, this rearranges the `ClangRunner` API to make a bit
more sense out of the different options for building runtimes, and have
a clean model for which things need to be passed in at which points.

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
2025-09-30 12:54:51 +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
Boaz Brickner 5abd214d9d Set the location for the candidate set when looking up C++ operators (#6138)
This adds location information and prevents crashes in some cases of
template instantiation in operator lookup.

Removed `InCppOperatorLookup` note as it is no longer necessary.

Part of #5995.
2025-09-29 22:45:22 +00:00
Jon Ross-Perkins e1b87ac2e1 Change IndexWith to use a standard binary operator setup (#6127)
This is closer to [the
design](https://github.com/carbon-language/carbon-lang/blob/trunk/docs/design/expressions/indexing.md?plain=1#L55-L64),
just lacking `ref`, but does remove a lot of special-casing done for the
lookup.

The `ErrorInst` changes in `Build*Operator` are to align with what was
being done for `IndexWith`; don't do an interface lookup if the relevant
operand is an error. Otherwise, that becomes visible because some files
have an error operand and don't provide the interface.
2025-09-29 18:17:48 +00:00
Jon Ross-Perkins 49ba8cf3e1 Switch class to use a blanket impl for Destroy (#6125)
Right now, the class destroy impl is incorrectly generated (first
discussed [in
Discord](https://discord.com/channels/655572317891461132/941071822756143115/1418614787449032826)).
If we want it to be correct, deferred definition logic would need to be
added, and the declaration would need to be moved inside the `class`
scope (along with whatever generic logic that needs).

This instead switches to a blanket impl, to avoid creating latent bugs
with generating the `impl` and function body in the wrong scope. This
approach uses the same blanket impl as aggregate destruction that was
added by #6098.

The intent here is to allow progress on other parts of `Destroy`. For
example, under this model the implementation of the function body could
be done as part of lowering the specific.
2025-09-29 16:05:06 +00:00
Boaz Brickner 5705b94da8 Add PerformCallToCppFunction() which calls simplified version of PerformCppOverloadResolution() before calling PerformCallToFunction() (#6122)
Instead of calling `PerformCppOverloadResolution()` and use the complex
return value to call `PerformCallToFunction()`, we call
`PerformCallToCppFunction()` which will call both
`PerformCppOverloadResolution()` and `PerformCallToFunction()`.

Followup of #6112.
Part of #5995.
2025-09-29 14:26:23 +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