Compare commits

...
Author SHA1 Message Date
Chandler Carruth 733b76efea Add a permissions restriction
Assisted-by: Antigravity with Gemini
2026-04-24 02:09:42 +00:00
Richard Smith 69d745c6d7 Don't allow merging PRs with the dependent label. 2026-04-22 20:15:37 +00:00
Chandler Carruth d6a741f208 Add bootstrapping flags to the build system (#7084)
This takes the bootstrap support that was added and makes it available
under convenient user-facing flags for while we're doing development.

For example, to build a bootstrap compiler and use it to build and run
the tests under `//common/...` you can now use:

```
bazel test --//:bootstrap_stage=1 --//:bootstrap_exec_config=true //common/...
```

This will use the stage1 bootstrap compiler, and it will build that
compiler in the exec config (so it is optimized and the above even works
when cross-building with Bazel).

Assisted-by: Antigravity with Gemini
2026-04-21 00:59:10 +00:00
Dana Jansens 1e3906177c Update the name of the bazel target to build the nightly tarball (#7080)
The target was renamed in `82fad290285baf9763132a13b1f73de1e7919074`
from `//toolchain/install:carbon_toolchain_tar_gz_rule` to
`//toolchain/install:carbon_toolchain_tar_gz`
2026-04-20 17:59:55 +00:00
Dana Jansens 5e2f693db1 Preserve ErrorInst in TryGetTypeIdForTypeConstantId (#7079)
An ErrorInst::ConstantId constant can be used as a type, and should
result in an ErrorInst::TypeId
2026-04-20 17:11:53 +00:00
David BlaikieandGeoff Romer 1cc699ddda Make heterogenous hash table lookup opt-in (#6950)
This still only works if the hash of the distinct types are identical
(so it still doesn't address the derived pointer v base pointer case -
well, not in the way we would want to address it, we could use this
change to make derived pointer and base pointer not compare equal, but
that's not very ergonomic)

I think in a follow up maybe I can use a `TranslatingKeyContext` to
translate `Derived*` to `Base*` in general.

No test coverage for this change, since it's a no-compile situation and
we don't seem to generally do no-compile tests.
    
Discovered while working on #6940

---------

Co-authored-by: Geoff Romer <gromer@google.com>
2026-04-18 01:32:39 +00:00
Geoff Romer ad0a4ea8a4 Restructure action-dependence APIs (#7074)
- Rename `ActionIsDependent` to `ActionIsPerformable` (with negated
meaning), because that name is more concrete and, um, actionable.
- Replace `OperandIsDependent` with `OperandDependence`, which returns a
`ConstantDependence` instead of a bool. We need this additional
generality for handling form actions, where we sometimes need to ask
whether something has _any_ dependence, not just whether it has template
dependence.
2026-04-17 19:03:21 +00:00
Richard Smith f91990aa87 Override Clang class layout for Carbon class types. (#7071)
Use the Carbon-determined size and alignment for Carbon-defined classes,
rather than allowing Clang to work one out for itself using the C++
rules.
2026-04-17 00:03:29 +00:00
Geoff Romer e7626f46cc Get rid of AddPatternInst (#7075)
Instead, use the inst category to select the right block stack. This
simplifies the API for adding insts, and in subsequent changes it will
enable certain inst kinds like `SpliceInst` to seamlessly function as
either procedural insts or pattern insts.
2026-04-16 23:31:31 +00:00
Geoff Romer af04d08965 Track declared form with an InstId instead of a ConstantId. (#7072)
This is mainly in order to track a location associated with the form.
2026-04-16 23:14:31 +00:00
Richard Smith a6061d975c Compute type layouts in SemIR / Check (#7066)
Instead of allowing lower to pick whatever type layout it desires,
compute the layouts of types as part of completing the type, and make
lower build types that match that representation.

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

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

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

Assisted-by: Gemini via Antigravity
2026-04-16 22:37:48 +00:00
Chandler Carruth 896338d281 Remove duplicate file and fix to include the bin directory (#7073)
Noticed this when testing the Carbon toolchain with a more complex
environment, don't have any way to observe this at the moment in Bazel
though.

Assisted-by: Antigravity with Gemini
2026-04-16 21:42:06 +00:00
Chandler Carruth d8fe95cccb Test and fix make-variable expansion in our toolchains (#7070)
This worked correctly in the system Clang toolchain, but was not
configured correctly in the Carbon toolchains. The test is designed to
let us cover all of these.

Assisted-by: Antigravity with Gemini
2026-04-16 21:08:37 +00:00
Geoff Romer df33276f6b Revert accidental change from #7063 (#7069) 2026-04-16 20:31:54 +00:00
Chandler Carruth 327cb2396a Add a Bazel skill (#7061)
Hopefully this significantly reduces how often agents try to run `bazel`
directly without repeatedly including that in prompts. Also tried to
generally give useful skills for building, testing, and running things.

Also added a specific admonition to the `AGENTS.md` as there is a chance
that agents don't think they need to look at any skills for "standard"
build system commands like `bazel`, as those are "trivial". It seems
like a small chunk of context to spend to avoid churning with bad build
commands.

Assisted-by: Antigravity with Gemini
2026-04-16 18:58:34 +00:00
Richard Smith 1d5113649b Allow non-constant calls to constexpr functions. (#7067)
These turn up frequently in real-world code, for example when converting
a mutable global `Cpp.std.string_view` to a `Cpp.std.string`. Only
reject a non-constant call if the callee is `consteval`, not if it's
`constexpr`.
2026-04-16 17:10:48 +00:00
Chandler Carruth cdfa57f230 Pull in a fix to the new compile commands system (#7068)
This pulls in my PR:
https://github.com/wolfd/bazel-compile-commands/pull/3

Fixes #7065

Assisted-by: Antigravity with Gemini
2026-04-16 16:58:29 +00:00
Richard Smith 46f46a538d Preliminary reverse interop support for base classes. (#7059)
Create a Clang AST representation of the base specifier.
2026-04-16 00:29:40 +00:00
Nicholas Bishop 114cf401c2 Support C++ calling Carbon functions with non-() return type (#7051)
For calling non-`()` functions, the Carbon->Carbon thunk now takes an
extra reference parameter and writes the target function's return value
out to that parameter. (At the SemIR level this is how returns already
work, but adding this extra reference parameter is needed so that the
function is lowered correctly.) The C++ thunk now creates a local
variable to be initialized by the Carbon thunk, and then returns that
value to the original C++ caller.
2026-04-16 00:29:38 +00:00
rit 7c94878c10 fixed a crash when lowering a ref return initialized by value expression (#7049)
Restructured `else-if` into `InitForm` case so that diagnostics are
emitted correctly and does not lead to a crash.
Conversation:
https://discord.com/channels/655572317891461132/1052653651895779359/1492278198405431397

Closes #6891
2026-04-15 20:52:56 +00:00
Chandler Carruth 82fad29028 Switch to conventionally use a name parameter for a macro (#7053)
This is important to allow tools like buildozer to manipulate macro
invocation.
2026-04-15 05:18:25 +00:00
Chandler CarruthandDana Jansens 26ddada3ae Switch from Bazel platforms to build settings (#7052)
The runtimes and bootstrap Bazel logic was previously built around
defining custom Bazel platforms constrained with `constraint_settings`.
The use of platforms added significant complexity, including the need to
"save" and "restore" the original platform, and other complexity
stemming from changing the platform as a whole.

This PR switches to use the simpler tool of build settings, and
`target_settings` on the toolchain rather than platform compatibility.
This remove the entire need to save and restore the platform, and also
generally simplifies things.

This PR also fixes some bugs in the bootstrap that were hidden by the
use of platforms, such as the need to carefully manage the different
inputs to the runtimes build so that generated inputs pick up the
correct exec configuration -- the exec transition happened to do this
"automatically", but it seems better to handle explicitly. And it cleans
up an extraneous copy of `carbon_runtimes.bzl` that snuck in somehow.

Assisted-by: Antigravity with Gemini

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
2026-04-14 21:52:48 +00:00
Geoff Romer bab35c114e Remove the leading /proc/self/cwd/ from file paths in the debug info. (#7060)
Some tools like VS Code don't understand `/proc/self/cwd` in places like
terminal stack dumps, but do understand paths relative to the workspace
root.
2026-04-14 19:34:32 +00:00
Chandler Carruth 96529e16bd Fully switch to the new compilation database system (#7057)
This has been working really well for me, is incredibly faster than the
other approach, and some commits continue to hit bugs in the old system
where files that aren't even going to be run through `clangd-tidy` end
up tripping up the execution. Hopefully all of that is resolved with the
new version.
2026-04-14 13:41:33 +00:00
Richard Smith 43867a678b Reverse interop support for type aliases. (#7043)
Allow any type that has a mapping from Carbon to C++ to be exposed to
C++ via name lookup. This also exposes the logic to export Carbon
classes to C++ to apply during type mapping, which gives very slight
support for passing Carbon types to C++ functions from Carbon, but not
really enough to sensibly test yet.

Depends on #7042.
2026-04-14 00:18:33 +00:00
Richard Smith 5b1de7633c Use the raw import ID, not the tagged ID, as an array index. (#7058)
Previously we'd create a *huge* array here as the tagged ID produced a
very large index value, and spend multiple seconds allocating it and
filling it with zeroes the first time `GetCppLocation` was called.

Reduces test runtime from 26s -> 6s wall time, 450s -> 320s total time
on my machine for `-c dbg`.
2026-04-13 23:53:25 +00:00
Richard Smith f31e1685fd Only export each class or namespace to C++ once. (#7042)
Instead of exporting a class or namespace each time a new C++ name
lookup discovers it, track that we have exported the entity on its name
scope, and if a new name lookup finds the same entity, produce the same
clang declaration.
2026-04-13 19:43:44 +00:00
Christopher Di BellaandDana Jansens 3cdb159067 consistently uses the caller's specific to get the callee's pattern type id (#7036)
`DoVarPreWorkImpl` was provided an incorrect pattern type while trying
to match `var` parameters, which caused the toolchain to crash in
`Convert`. This commit changes `DoVarPreWorkImpl`'s API so it derives
the pattern type from the work item's pattern ID, rather than relying on
an external source.

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
2026-04-13 17:41:54 +00:00
Dana Jansens 12d7574636 Include extended named constraints in the type of .Self for a where clause (#7048)
The `.Self` should see all extended constraints from the LHS of the
`where`, which is both interfaces and named constraints.
2026-04-10 18:05:22 +00:00
Dana JansensandRichard Smith cc5a42691e Add where T impls X constraints into the FacetTypeInfo (#7038)
This makes them part of the identified facet type, and we can see the
constraints as part of stringify and format output.

But this does not do enough to make them useful yet: Any `T impls X`
constraint must contain a reference to `.Self` somewhere. And `.Self`
references do not get substituted, so neither `T(.Self) impls X` and `T
impls X(.Self)` will match against an incoming facet value derived from
an `impl T(U) as X` or `impl T as X(U)`, since `U` and `.Self` are never
the same thing until `.Self` can be substituted.

Now that impl lookup runs into facet values containing `.Self` (a
symbolic binding), such as in `C(.Self)`, we were crashing assuming the
type of `.Self` is a FacetType, but it can be `type` in the case of
`type where C(.Self) impls...`. Instead, use an empty facet type for the
type of `.Self` so it is always a facet. This assists with substituting
other facets into it, without having to insert an extra FacetAccessType.
`MakePeriodSelfFacetValue()` now enforces this requirement.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2026-04-10 14:29:36 +00:00
Chandler Carruth 19efec93be Fix missing runtimes file in the installation (#7044)
Fixes #7031

Also switches the previous symlinks test to be a more full integration
test. While a bit slow, it does seem worthwhile to have something that
tests things end-to-end, both with the prebuilt runtimes and the
on-demand runtimes. This test is already reasonably well separated from
the rest of the toolchain so incremental development shouldn't be
negatively impacted. And since we turned off ASan by default, it isn't
completely infeasibly expensive.

Assisted-by: Antigravity with Gemini
2026-04-09 21:49:19 +00:00
Chandler Carruth 3db691ecef Add ASan to post-merge CI and improve the action structure for GitHub (#7012)
Note that this will require changing the branch protections to use new
names for all of the checks and be somewhat disruptive. There aren't any
really good ways I could find of fixing this. Some options that I
explored:

- Have a single `pre-merge` workflow file that contains all of the other
workflows, splitting as much of the logic as we can into re-usable
files. This would basically merge testing, `pre-commit`, and
`clangd-tidy` checking into a single workflow file. However, it would
also delay the pre-commit suggestions action to only run once _all_ of
these finish, rather than as soon as pre-commit finishes.

- Serialize `pre-commit` and the rest of `pre-merge` to get the effect
of the above option but without the downside. Instead, the downside
would be serializing some of our actions.

- Have a single `pre-merge` workflow that triggers whenever any of the
other workflows completes, and have it check whether all the others have
completed. It will fail until it reaches that point. This requires
passing in GitHub keys to the workflow so that it can check the status
of other checks, and documentation online seems to indicate it is
sometimes flaky, I assume because of racing triggers of events or
check-status not being guaranteed consistent in the queries.

- Have a single `pre-merge` workflow that polls, waiting for all the
other workflows to finish using some Python logic. This requires
building and maintaining code to poll GitHub, keys to authorize that
polling, and handling all of the failure modes of a polling operation --
timeouts, network issues, etc.

Maybe there are others, but not sure what they look like. Suggestions
welcome here.

I'm hesitant to either delay the pre-commit suggestions or serialize
pre-commit execution. And the complexity or flakiness of the other two
options seem worse than having to re-work the branch protections each
time the naming here changes. But interested if folks think a different
direction would be better.

Assisted-by: Antigravity with Gemini
2026-04-09 20:37:23 +00:00
Dana JansensandChandler Carruth 6cc08ae6e6 Remove SymbolicBinding step in TypeIterator (#7039)
TypeIterator has both SymbolicType and SymbolicBinding and these overlap
in their meaning. Clarify the API by removing SymbolicBinding and just
using SymbolicType for `SymbolicBinding` insts and when they are
converted to `type` to make a `SymbolicBindingType` inst. Add the
EntityNameId to the SymbolicType for when it is available, when the
instruction is just a simple reference to a binding.

---------

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2026-04-09 13:25:16 +00:00
Richard Smith ab977ee04d Bump vscode extension to 0.0.8. (#7041) 2026-04-09 00:06:39 +00:00
Richard Smith be0c07dc7e Give Carbon -> C++ thunks internal linkage. (#7040)
Also declare them `inline` since we're putting the `always_inline`
attribute on them. Use the `internal_linkage` attribute rather than
`SC_Static` since it's a more precise mechanism and matches what we do
for static member functions in reverse interop (where `SC_Static` means
something else and would not give the function internal linkage).
2026-04-08 21:14:30 +00:00
Dana Jansens b79d9adeca Avoid crashing in custom witness for FacetTypes and symbolic object representations (#7033)
The type must be complete to look for a witness for Destroy. Do this
check through type completion rather than just checking to see if the
ClassInfo says the definition is closed, since completing the type has
side effects (resolves the self specific definition).

Then look for whether the class is abstract through the CompleteTypeInfo
instead of just looking at the inheritance type on ClassInfo, like type
completion does.

Last, FacetTypes are trivially destroyed just like TypeType.
2026-04-08 20:09:03 +00:00
Richard Smith b74e0d1260 Superficial support for exporting complete class types to C++. (#7029)
We don't yet populate the bases or fields, so the class types show up as
empty classes in C++ for now. But we do allow calls to static member
functions.
2026-04-08 19:29:25 +00:00
dependabot[bot] 9f1a0c816c Bump addressable from 2.8.7 to 2.9.0 in /website in the bundler group across 1 directory (#7037)
Bumps the bundler group with 1 update in the /website directory:
[addressable](https://github.com/sporkmonger/addressable).

Updates `addressable` from 2.8.7 to 2.9.0
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/sporkmonger/addressable/blob/main/CHANGELOG.md">addressable's
changelog</a>.</em></p>
<blockquote>
<h2>Addressable 2.9.0 <!-- raw HTML omitted --></h2>
<ul>
<li>fixes ReDoS vulnerability in Addressable::Template#match (fixes
incomplete
remediation in 2.8.10)</li>
</ul>
<h2>Addressable 2.8.10 <!-- raw HTML omitted --></h2>
<ul>
<li>fixes ReDoS vulnerability in Addressable::Template#match</li>
</ul>
<h2>Addressable 2.8.9 <!-- raw HTML omitted --></h2>
<ul>
<li>Reduce gem size by excluding test files (<a
href="https://redirect.github.com/sporkmonger/addressable/issues/569">#569</a>)</li>
<li>No need for bundler as development dependency (<a
href="https://redirect.github.com/sporkmonger/addressable/issues/571">#571</a>,
<a
href="https://github.com/sporkmonger/addressable/commit/5fc1d93">5fc1d93</a>)</li>
<li>idna/pure: stop building the useless <code>COMPOSITION_TABLE</code>
(removes the <code>Addressable::IDNA::COMPOSITION_TABLE</code> constant)
(<a
href="https://redirect.github.com/sporkmonger/addressable/issues/564">#564</a>)</li>
</ul>
<p><a
href="https://redirect.github.com/sporkmonger/addressable/issues/569">#569</a>:
<a
href="https://redirect.github.com/sporkmonger/addressable/pull/569">sporkmonger/addressable#569</a>
<a
href="https://redirect.github.com/sporkmonger/addressable/issues/571">#571</a>:
<a
href="https://redirect.github.com/sporkmonger/addressable/pull/571">sporkmonger/addressable#571</a>
<a
href="https://redirect.github.com/sporkmonger/addressable/issues/564">#564</a>:
<a
href="https://redirect.github.com/sporkmonger/addressable/pull/564">sporkmonger/addressable#564</a></p>
<h2>Addressable 2.8.8 <!-- raw HTML omitted --></h2>
<ul>
<li>Replace the <code>unicode.data</code> blob by a ruby constant (<a
href="https://redirect.github.com/sporkmonger/addressable/issues/561">#561</a>)</li>
<li>Allow <code>public_suffix</code> 7 (<a
href="https://redirect.github.com/sporkmonger/addressable/issues/558">#558</a>)</li>
</ul>
<p><a
href="https://redirect.github.com/sporkmonger/addressable/issues/561">#561</a>:
<a
href="https://redirect.github.com/sporkmonger/addressable/pull/561">sporkmonger/addressable#561</a>
<a
href="https://redirect.github.com/sporkmonger/addressable/issues/558">#558</a>:
<a
href="https://redirect.github.com/sporkmonger/addressable/pull/558">sporkmonger/addressable#558</a></p>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/sporkmonger/addressable/commit/0c3e8589b23d4402903a9b4e1fdeba4e43c52ca4"><code>0c3e858</code></a>
Revving version and changelog</li>
<li><a
href="https://github.com/sporkmonger/addressable/commit/91915c1f7aafa3e2c9f42e2f4e21d948c7a861b8"><code>91915c1</code></a>
Fixing additional vulnerable paths</li>
<li><a
href="https://github.com/sporkmonger/addressable/commit/a091e39ff02fc321b21dea3a0df585bef2ba3744"><code>a091e39</code></a>
Add many more adversarial test cases to ensure we don't have any ReDoS
regres...</li>
<li><a
href="https://github.com/sporkmonger/addressable/commit/463a819665a3b85ce5ce894c90bd7bfa3b9d2e15"><code>463a819</code></a>
Regenerate gemspec on newer rubygems</li>
<li><a
href="https://github.com/sporkmonger/addressable/commit/0afcb0b9672bee301e5e96ed850fec05b2fcabb0"><code>0afcb0b</code></a>
Improve from O(n^2) to O(n)</li>
<li><a
href="https://github.com/sporkmonger/addressable/commit/c87f768f22ab00376ed2f8cb106f59c9d0652d3a"><code>c87f768</code></a>
Fix a ReDoS vulnerability in URI template matching</li>
<li><a
href="https://github.com/sporkmonger/addressable/commit/0d7e9b259fb0940d1a85064b04f678a7984409a5"><code>0d7e9b2</code></a>
Fix links for 2.8.9 in CHANGELOG (<a
href="https://redirect.github.com/sporkmonger/addressable/issues/573">#573</a>)</li>
<li><a
href="https://github.com/sporkmonger/addressable/commit/e2091200b31553f19248eb871f071852409796f8"><code>e209120</code></a>
Update version, gemspec, and CHANGELOG for 2.8.9 (<a
href="https://redirect.github.com/sporkmonger/addressable/issues/572">#572</a>)</li>
<li><a
href="https://github.com/sporkmonger/addressable/commit/387587492b6536748ed12a11c3fdb44a48885f28"><code>3875874</code></a>
Reduce gem size by excluding test files (<a
href="https://redirect.github.com/sporkmonger/addressable/issues/569">#569</a>)</li>
<li><a
href="https://github.com/sporkmonger/addressable/commit/3e57cc6018f94231aabb47fd341acd1b40f1e71a"><code>3e57cc6</code></a>
CI: back to <code>windows-2022</code> for MRI job</li>
<li>Additional commits viewable in <a
href="https://github.com/sporkmonger/addressable/compare/addressable-2.8.7...addressable-2.9.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=addressable&package-manager=bundler&previous-version=2.8.7&new-version=2.9.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/carbon-language/carbon-lang/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-04-08 19:05:36 +00:00
Geoff Romer 6f02354d62 Fix malformed split (#7035) 2026-04-08 00:31:43 +00:00
Nicholas Bishop 0635f4628f Add support for C++ calling Carbon functions with parameters (#7024)
This works by generating two thunks, one in C++ and one in Carbon. For
example, given this input:
```c++
// Carbon:
fn Callme(f: f32) {}

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

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

// C++:

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

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

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

Functions with non-void return types are not supported yet.
2026-04-07 23:25:57 +00:00
Dana Jansens d1dc8e820d Resolve the specific definition for a function that is evaluated (#7034)
The function body may make use of values from the specific, so the
specific definition must be resolved before the function is evaluated.
2026-04-07 21:53:54 +00:00
Dana Jansens e1f30669af Remove TODO in impl lookup for discarding unused witnesses (#7032)
In #6972 we stopped finishing instructions added just for EvalOrAddInst,
which prevents adding the instruction to the containing generic eval
block.
2026-04-07 18:11:08 +00:00
Dana Jansens f483a28f2f Refactor WhereExpr evaluation into smaller helper functions (#7006)
This splits off the functionality to handle the base facet type,
rewrites, and impls constraints into separate functions.

We use the Context instead of EvalContext throughout, as the goal is to
move this code to EvalConstantInst in time. That means we do not apply
specifics to the functions in the requirements inst block. That is fine
because WhereExpr never evaluates to an WhereExpr, so this instruction
never survives as a constant value long enough to be re-evaluated with a
specific applied to it.
2026-04-07 13:52:56 +00:00
Richard Smith cc4fd39238 Support round-tripping entities through C++ and Carbon. (#7022)
Use the same C++ -> Carbon map for both interop directions, and when
importing an entity from Carbon -> C++, check whether it was originally
a C++ entity and if so return the original.

Assisted-by: Gemini via Google Antigravity
2026-04-07 08:10:21 +00:00
Chandler Carruth 013a417ea5 Add the static keyword to various syntax highlighting (#7026)
This follows #7016 which suggests using `static var` for non-instance
class data members.

Assisted-by: Antigravity with Gemini
2026-04-06 19:32:24 +00:00
Chandler Carruth 8fd4156616 Update tree_sitter for the new self syntax and static var (#7025)
This implements p7016 for tree_sitter. It also updates the build and
source file to allow this to build successfully and documents how to
successfully run these tests with Bazel given that it is fundamentally
not hermetic.

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

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

---------

Co-authored-by: Geoff Romer <gromer@google.com>
2026-04-03 21:24:00 +00:00
Chandler Carruth fed9e8c878 Create skills for using the gh tool (#7019)
This covers basic usage and using it to make API calls to GitHub. It
also works to establish some reasonable safety guards to avoid
inappropriate commands.

Also introduces a skill specifically for ingesting the content in GitHub
issues using the command line tool. This is especially useful as
otherwise agents may try to browse the web version of an issues that is
significantly slower and harder to ensure the agent correctly gets all
of the context into its window and is able to leverage it.

This also disables the Google documentation style checking for agent
skills, as we want to instead try to follow the conventions, phrasing,
and other patterns that map best for agents' training sets. For example,
this avoids replacing `repo` with `repository` and avoids replacing
`e.g.` with `for example`. While these replacements make lots of sense
for our human-facing documentation, the agent-facing docs probably
benefit from being terse and using the exact patterns that agents are
trained on.

Assisted-by: Antigravity with Gemini
2026-04-03 20:35:39 +00:00
Dana JansensandChandler Carruth 451b50a3ad Add storage for <type> impls <facettype> in the FacetTypeInfo (#7005)
We don't yet actually add any in check, but this adds the storage for
them, and capabilities to import them, evaluate them, substitute into
them with specifics, name them, format them, and stringify them.

---------

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2026-04-03 00:19:57 +00:00
rit 912825feaf Add basic test for lowering choice value acquisition (#7014)
Added test for lowering choice value acquisition. Before PR #6992 the
code in issue #6862 would crash/assert saying the instruction
`AcquireValue` is not concrete. I added this test as the fix did not
have one to test this particular case.
2026-04-03 00:01:21 +00:00
Richard Smith 81ed4d829d Perform CppThunkRef conversion as part of category conversion. (#7020)
Instead of recursing back into Convert, make CppThunkRef conversion just
add an extra step to category conversion, performing a copy conversion
followed by an ephemeral reference binding conversion.
2026-04-02 23:39:25 +00:00
Jon Ross-Perkinsandjonmeow 9266ced4e3 Improve CanDestroyType to handle remaining cases (#6943)
This is only fixing the decision about *whether* to produce a witness.
Implementation of the witness is still a TODO, though where a body is
generated, it should also precisely reflect where one _needs_ to be
generated.

Note the tests:

- toolchain/lower/testdata/function/generic/import_core_witness.carbon
- toolchain/lower/testdata/function/generic/import_unused_def.carbon

These tests can probably be produced _without_ Core.Destroy, but I found
the essence of them while trying to build //examples with Core.Destroy
and a simpler minimization wasn't striking me.

Assisted-by: Google Antigravity with Gemini

---------

Co-authored-by: jonmeow <jperkins@google.com>
2026-04-02 22:54:58 +00:00
Dana Jansens 1fa7a64cd4 Add missing named constraints and self in facet type debugger dump (#7018) 2026-04-02 20:50:59 +00:00
Dana Jansens 562b423830 Always dump summaries (single line output) on bulleted details lines (#7017)
The debugger dump format looks something like

```
id: summary
 - detail 1
 - detail 2
```

But if the detail is a full Dump of some other id, then the details
start to combine and get confusing. For instance if you Dump an
interface id as the detail, you get

```
id: summary
  - interface id: summary
  - complete: yes  <-- about the interface
  - detail 2  <-- not about the interface
```

This mixes the contents of multiple Dumps and is super confusing. So
introduce DumpFooSummary for everything that is dumped on a bulleted
details line, and always use the summary version in that situation.
2026-04-02 20:19:57 +00:00
Richard Smith 6f0ec37a8b Make C++ enum types impl Core.Copy. (#7013)
Remove special-case handling in conversion logic for C++ enum types,
synthesize a custom witness of `Core.Copy` using the `primitive_copy`
builtin function.
2026-04-02 19:23:42 +00:00
Geoff Romer 0851d657c8 Add comment and test for special case in NameRef lowering (#7008) 2026-04-02 19:13:06 +00:00
Chandler Carruth 07afa07127 Fix missing include for std::log2 (#7015)
Some standard libraries require this include for the code to compile.
2026-04-02 18:27:46 +00:00
Chandler Carruth f7a767a77b Update LLVM (again) to pick up a workaround crashes the compiler when building with ASan (#7011)
Assisted-by: Antigravity with Gemini
2026-04-02 01:23:21 +00:00
Richard Smith be283a0744 Improve handling of incomplete signatures. (#7004)
Assert cleanly if we try to emit a definition or a call of a function
whose signature we were not able to emit exactly. This should make such
issues a lot easier to debug, as we were previously failing in quite
mysterious ways in this case.
2026-04-01 21:49:57 +00:00
Jon Ross-Perkins cd6ab7ce8e Switch jj settings to 'jj config set' because of repo (#7007)
jj moved the repo config outside the repo. The config.toml might exist
as a symlink in older repos (probably migration), but not clean repos.
So, overall, just switching the advice setup to make it a bit more
robust with config locations.

Also adding "trunk" to the repo config.

Assisted-by: Google Antigravity with Gemini
2026-04-01 21:36:56 +00:00
Nicholas Bishop 0075d530b9 Support const eval when calling a C++ thunk (#6947)
This makes it possible to do const eval when calling a constexpr C++
function with params and return types other than 32/64-bit integers.

Most of the new logic is in `MaybeModifyCppThunkCallForConstEval`, which
is called by `MakeConstantForCall`. This checks if the callee is a C++
thunk (using a new `SpecialFunctionKind::CppThunk` variant), and if so
it:
* Changes the callee from the C++ thunk to the thunk's callee
* Remaps parameters that are passed by pointer to the thunk to the
underlying value
* Drops the return value parameter, if present
2026-04-01 21:34:41 +00:00
Richard SmithandJon Ross-Perkins 5b7c908e8b Add documentation for setting up jj b a. (#6996)
This gives a setup where `jj b a` / `jj bookmark advance` can reliably
be used to advance a bookmark for a github pull request, without
advancing other bookmarks such as `trunk` or pointing the bookmark at an
empty commit.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2026-04-01 16:46:14 +00:00
Chandler Carruth 2bbcfa5e1a Remove ASan from the default build mode (#7003)
Also increases the default optimization to `-Og` which is likely to give
faster turn-around time which is what we want to optimize for here. This
should also _substantially_ shrink binary sizes, etc.

ASan is still available via `--config=asan`, and is added to the CI
infrastructure. However, my current thought is to only run it after push
rather than in PRs and in the merge queue.
2026-04-01 16:45:53 +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
Dana Jansens 8f3b057179 Don't qualify names after a . in an ImplWitnessAccess when stringifying (#7000)
After the `.` comes a member of the target of the ImplWitnessAccess.
It's already qualified, don't add the namespace/package to the name.
2026-04-01 15:24:57 +00:00
Dana Jansens 17180558e5 Diagnose where clause without a designator (#6995)
> We don’t allow a where constraint unless it applies a restriction to
the current type. This means referring to some
[designator](https://docs.carbon-lang.dev/docs/design/generics/details.html#kinds-of-where-constraints),
like .MemberName, or
[.Self](https://docs.carbon-lang.dev/docs/design/generics/details.html#recursive-constraints).


https://docs.carbon-lang.dev/docs/design/generics/details.html#constraints-must-use-a-designator
2026-04-01 04:16:35 +00:00
Chandler Carruth 39eac6f277 Update LLVM and fix a couple of API usages (#6998)
The `TemplateArgLocInfo` change is more interesting than usual as this
isn't enforced in the type system, and only shows up as a crash.
2026-04-01 00:00:11 +00:00
Chandler Carruth 2787089247 Switch to a Bazel-based runtimes build, and add bootstrapping (#6989)
This also switches to a more Bazel-based install layout, skipping the
FHS-based synthetic layout. The FHS-based layout is still reconstructed
explicitly when building an installable tar-ball.

The biggest change is to configure the just-built install as a Bazel
toolchain, including allowing it to build its own runtime libraries as
native Bazel libraries. This removes the need for a monolithic runtimes
build, all of that code logic is removed.

This should also pave the way to using the just-built toolchain for
doing a full 3-stage bootstrap. Building the 2nd stage is included here
as it was a particularly effective way to test that the Bazel
integration was fully working. Adding a 3rd-stage check for stability is
future work, but should be pretty easy.

There is a down-side: this uses the busybox to do the runtimes
compilation, which means they will be re-built after ~any change to
Carbon. However, the integration with Bazel should largely pay for this,
and we can continue to factor the tests away from depending on built
runtimes in most cases.

Now that we're building and testing the runtimes more directly, this
surfaced a problem with the layout of runtimes on macOS that is fixed
here. All of the Darwin OSes use a custom layout for their resource
directory compared to other targets. We now model this in both the C++
built runtimes and the Bazel built runtimes.

Assisted-by: Gemini via Antigravity
2026-03-31 23:38:03 +00:00
Richard Smith 3578dd6b91 Avoid copying Lower::FunctionInfo. (#7001)
This type is not small and contains two `SmallVector`s.
2026-03-31 22:58:42 +00:00
Richard Smith 8b59e85b16 Add support for inline Cpp declarations. (#6994)
For #6830, add support for inline C++ fragments as a declaration rather
than as a packaging directive. For now, this uses `inline Cpp
<string-literal>;` as syntax. The prior `import Cpp inline
<string-literal>;` is left alone for the time being. We can decide
separately whether to remove that.

`inline Cpp` requires that there was at least one `import Cpp`. It's not
clear to me if that's the right design long-term, but it seems
reasonable for now.

Assisted-by: Gemini via Google Antigravity
2026-03-31 22:27:43 +00:00
Geoff RomerandRichard Smith 47e9d62fd5 Model thunk call as a pattern match (#6988)
This makes the thunk-call logic more general and more supportable by
reusing the existing pattern-matching logic.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2026-03-31 21:50:06 +00:00
Geoff Romer f4260feee4 Clean up pattern matching (#6987)
The key changes here are:
- The different kinds of pattern match are represented as alternatives
of a `variant`, instead of enumerators of an `enum`, so that they can
hold their own state instead of having a bunch of conditionally-usable
members of `MatchContext`.
- The public API of `MatchContext` is a `Match` operation that's applied
to a single pattern and scrutinee; the worklist is no longer directly
accessible.
- `Match` has a counterpart `MatchWithResult` that returns the result of
matching the pattern.
- `Context` is now a member of `MatchContext` instead of a parameter to
most of its methods.
2026-03-31 20:38:42 +00:00
Geoff Romer aec2534e9d Fix formatting of compound-type variable declarations in macros (#6997)
By default clang-format interprets function-like macro invocations as
function calls. E.g. the argument of `CARBON_KIND(llvm::ListSeparator*
sep)` is interpreted as an expression, meaning the `*` is an infix
binary operator, so it inserts a space before the `*`. This change
teaches clang-format that `CARBON_KIND(x)` and
`CARBON_ASSIGN_OR_RETURN(x)` rewrite to `x`, which is close enough to
the truth to enable it to format them correctly. See the [clang-format
docs](https://clang.llvm.org/docs/ClangFormatStyleOptions.html#macros)
for details.
2026-03-31 19:41:26 +00:00
Richard Smith 2e0d9dc709 Add syntax highlighting for SemIR. (#6958)
This applies to files named *.semir, but more interestingly also to
Carbon source lines starting `// CHECK:STDOUT:`.

Assisted-by: Gemini 3.1 Pro via Antigravity
2026-03-31 18:49:02 +00:00
Nicholas Bishop 396756c151 Handle Temporary values when const-evaling AcquireValue (#6992)
This will be used for const-evaling functions. Splitting into a separate
commit since it touches a lot of test files, and a couple fail_todo
tests are no longer failing.
2026-03-31 15:50:54 +00:00
Nicholas Bishop bf6a14ac39 Support Temporary constants (#6983)
Evaluate `Temporary` constants to a `Temporary` with the `storage` field
set to `None`.
2026-03-30 19:07:46 +00:00
Dana Jansens 9ed045ec25 Add a link to the docs on testing the toolchain to CONTRIBUTING.md (#6981)
It takes a bit of work to track down instructions on running file tests
and autoupdate. Add a link to them directly from CONTRIBUTING.md, since
all searches start there.
2026-03-28 06:21:14 +00:00
Dana Jansens 2318294eb5 Add tests for name lookup through named constraints (#6979)
Tests combinations of extend and impls in a facet type and inside a
named constraint. Name scopes are only extended if the named constraint
extends an interface, and the facet type extends the named constraint.
2026-03-28 04:15:24 +00:00
Richard Smith d9b901394b Add agent skill for producing toolchain tests. (#6986)
Assisted-by: Gemini via Google Antigravity
2026-03-28 00:48:08 +00:00
Richard Smith 181a592b8c Support for parsing expression patterns (#6977)
When parsing a pattern, if we encounter something that isn't pattern
syntax, try parsing as an expression instead. We only need one-token
lookahead to distinguish pattern syntax from expression syntax.

Track a precedence group through pattern parsing so that we can allow
different kinds of expressions in a top-level pattern (such as the
operand of `let`) and in a nested pattern (such as a subpattern of a
tuple pattern or within grouping parens). For example, we do not allow
`case if ...`, and for now I've chosen to also not allow logical or
relational operators at the top level of a pattern, so `case 1 + 1` is
OK, but `case 1 == 1` and `case true and false` require parentheses.
This decision should be ratified or revisited by a design proposal.

Very basic check support is also provided, only sufficient to form an
`ExprPattern` instruction and nothing beyond that. For now, all pattern
matching against an `ExprPattern` fails with a TODO error. To support
that, I've switched from calling `BeginSubpattern` in the parent handler
of a pattern and `EndSubpatternAs*` in the pattern handler itself to
calling both functions in parent handlers, with `EndSubpattern`
converting an expression into an expression pattern where needed.

Depends on #6976.

Assisted-by: Gemini via Google Antigravity
2026-03-28 00:06:06 +00:00
Nicholas Bishop 1ef35e8299 Fix name mangling for Carbon functions called from C++ (#6984)
Since this requires using the `Mangler` class from `toolchain/check`,
moved it from `toolchain/lower` to `toolchain/sem_ir`.

The mangled name is then attached to the `FunctionDecl` with an
`AsmLabelAttr`.
2026-03-27 22:52:11 +00:00
Richard Smith aa8e96ac72 Fix skill file to parse correctly. (#6985)
The license header needs to go after the YAML in order for it to parse.
2026-03-27 21:46:08 +00:00
Dana Jansens 5503f643c6 Introduce typed-inst accessors for ConstantValueStore (#6980)
Add `InstIs`, `GetInstAs`, and `TryGetInstAs` which act on the
underlying constant instruction in a constant value, to save an explicit
call to `GetInstId`.

```carbon
context.insts().GetAs<InstT>(context.constant_values().GetInstId(const_id))
```
can now be written as simply
```carbon
context.constant_values().GetInstAs<InstT>(const_id)
```

For future work, we might provide `GetInst()` so that
`context.insts().Get(context.constant_values().GetInstId(const_id)` can
be shortened also.
2026-03-27 21:41:04 +00:00
Richard SmithandGeoff Romer 899e54de36 Treat (pattern) as grouping parens. (#6976)
Do not treat it as a 1-tuple pattern as we used to. The design indicates
that `(pattern)` is invalid, but this appears to be an oversight, and
grouping parens appear to be the intended interpretation.

---------

Co-authored-by: Geoff Romer <gromer@google.com>
2026-03-27 21:13:57 +00:00
Jon Ross-Perkins a2ba7f1262 Have Specific track whether regions contain errors (#6982)
This removes some loops in type completion, but is motivated by the
thought that eval probably wants to query it.

Assisted-by: Google Antigravity with Gemini
2026-03-27 19:36:52 +00:00
Jon Ross-Perkins 2b1fe7c292 Small improvements to RuntimeVerified logic (#6973)
The `NodeKind` vs `InstKind` naming seems to be an old mistake.

I'm cleaning up to specific `ImportRef` handling after verifying those
were the only actual cases where inst kinds won't be compatible (or are
always compatible, depending on your point of view).

Assisted-by: Google Antigravity with Gemini
2026-03-27 19:32:12 +00:00
Dana Jansens a0416a1250 Don't finish the non-canonical instruction created in EvalOrAddInst (#6972)
EvalOrAddInst has to create a non-canonical instruction for evaluating a
few typed insts, such as LookupImplWitness which uses an InstId to
provide a location for diagnostics.

But the output of the function is a ConstantId. We do not have access to
the non-canonical InstId after the function returns. But if the constant
value was symbolic, it was being attached to the inst, and the inst
would be added to the eval block of the enclosing generic. This
needlessly added semir for a symbolic value.

The ConstantId returned by EvalOrAddInst can be used immediately, such
as to evaluate an ImplWitnessAccess. In that case, the final evaluated
result is all we need to keep in semir.

If the ConstantId needs to be replaced by specifics, it is only as part
of some other instruction, since ConstantIds themselves are not modified
by specifics, instructions are. In that case, the canonical instruction
in the constant value would have been added to some other (now symbolic)
instruction, which would be replaced by a specific.

This has no functional change, but it reduces runtime overhead and semir
output for LookupImplWitness and ImplWitnessAccess.
2026-03-27 19:29:34 +00:00
Christopher Di Bella c68c4007ab removes unused parameters from deep stack (#6971)
`best_impl_type_structure` and `best_impl_loc_id` are required to solve
the problem discussed in #6166. We don't address that issue issue yet.
Requiring them to be propagated through any function depending on
`GetFunctionId` is very tedious.

This commit removes them from `GetFunctionId` until we have a clear
design for how they should be used.
2026-03-27 16:59:25 +00:00
cui 1f7d8e4675 Fix ValueStore::GetRawIndex DCHECK to use id.index in diagnostic (#6975)
## Summary

`ValueStore::GetRawIndex` formatted the first `CARBON_DCHECK` with
`index` before the local `index` is declared. Use `id.index` so the
diagnostic matches the condition being checked.

## Test plan

- `bazelisk build //toolchain/base:base` (or `//toolchain/...` as
appropriate)
2026-03-27 12:48:46 +00:00
cui 557039648b Fix FacetTypeInfo::Print guard for self impls named constraints (#6974)
## Summary

Fixes a copy-paste bug in `FacetTypeInfo::Print`: the "self impls named
constraint" section was gated on `self_impls_constraints.empty()`
instead of `self_impls_named_constraints.empty()`.

## Test plan

- `bazelisk build //toolchain/sem_ir:sem_ir` (not run in this
environment; no Bazel installed)
2026-03-27 12:17:12 +00:00
Richard Smith 786e02cb3e clang-format: Turn off trailing commas in braced lists lint. (#6978)
Our codebase does not conform to this rule, and it's causing havoc for
automated tooling that tries to "fix" it.
2026-03-27 12:03:58 +00:00
Geoff Romer 262e24a2a0 Remove indirection through NameRefs when building a thunk call (#6965)
This reduces the SemIR size of the thunk call, and ensures that the
emitted SemIR remains correct if `pretty_name_id` is not populated.
2026-03-26 19:17:05 +00:00
Geoff Romer 18f87e4f79 Include the type in the location of binding insts (#6963) 2026-03-26 18:43:29 +00:00
Nicholas Bishop 85da6cae01 Support calling simple Carbon functions from C++ (#6967)
For now, only functions with no parameters and a `()` return type are
supported.
2026-03-26 18:14:39 +00:00
Dana Jansens d6be20641c Use earlier require decls inside a named constraint to provide witnesses for Self (#6915)
Performing a lookup against `Self` inside the definition of the named
constraint leads to cycles, as described in the document [Self
contradictions in Named
Constraints](https://docs.google.com/document/d/17rn2XmME8o2MM4OJqatSVuMa1iYZ1PAgcNrf0PXR9Q4/edit?tab=t.0).
To prevent those cycles, this change introduces a large refactoring of
impl lookup.

The impl lookup done inside eval is reduced to only performing
monomorphization. That is it:
- Only looks for an provides final witnesses.
- Is not allowed to identify the facet type of the query self.
- Returns either a final witness or None (or an error)

The paths for finding non-final witnesses are now done outside of eval,
directly in the initial `LookupImplWitness()` function. If no final
witness it found through eval, the resulting non-final
`LookupImplWitness` instruction witness is returned. It does not produce
cycles to identify the facet type of query self outside of eval, since
that does not result in repeating the identification when resolving
specifics of the named constraint or require decl.

Move the ArrayStack for Context::require_impls_stack into a new class
which tracks a NamedConstraintId (or InterfaceId) for each frame of
RequireImplsIds, so that in type completion we always can find the
correct frame for a given named constraint which is still being defined,
in order to find the RequireImplsIds in the in-progress definition.
2026-03-26 15:26:56 +00:00
Dana JansensandRichard Smith 4a0c1ddd8e Identification of a named constraint during definition (#6902)
Allow partially identifying a named constraint inside its definition,
and allow the query self in an impl lookup with a non-identified facet
type to be used to provide witnesses from that facet type. This allows
impl lookup on `Self` to find `require` decls that have been written
earlier in the named constraint, so that the named constraint to be used
to provide witnesses from inside its definition.

But disallow an incomplete named constraint from being part of an
identified facet type, to prevent forming facet values that store a
witness set that can be invalidated as the named constraint adds
interfaces to its identified facet type.

This was discussed in open discussion [on
2026-03-12](https://docs.google.com/document/d/1mjllGO3ZCL4qGt9uJHUtcxKoHAGEY7Y999ie4EtBWB8/edit?tab=t.0#heading=h.1dvbbrp5a6t3).

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2026-03-26 14:24:45 +00:00
Jon Ross-Perkins 5ae3629e49 Change GEMINI.md to AGENTS.md (#6969)
Per https://antigravity.google/changelog, supported in 1.20.5. Also note
https://agents.md

Assisted-by: Google Antigravity with Gemini
2026-03-26 01:00:13 +00:00
Jon Ross-Perkins 25b85a55ae Remove myself from SECURITY.md (#6964)
Assisted-by: Google Antigravity with Gemini
2026-03-26 00:52:16 +00:00
dependabot[bot] 15dabbfb0d Bump requests from 2.32.4 to 2.33.0 in /github_tools in the pip group across 1 directory (#6968)
Bumps the pip group with 1 update in the /github_tools directory:
[requests](https://github.com/psf/requests).

Updates `requests` from 2.32.4 to 2.33.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/psf/requests/releases">requests's
releases</a>.</em></p>
<blockquote>
<h2>v2.33.0</h2>
<h2>2.33.0 (2026-03-25)</h2>
<p><strong>Announcements</strong></p>
<ul>
<li>📣 Requests is adding inline types. If you have a typed code base
that uses Requests, please take a look at <a
href="https://redirect.github.com/psf/requests/issues/7271">#7271</a>.
Give it a try, and report any gaps or feedback you may have in the
issue. 📣</li>
</ul>
<p><strong>Security</strong></p>
<ul>
<li>CVE-2026-25645 <code>requests.utils.extract_zipped_paths</code> now
extracts contents to a non-deterministic location to prevent malicious
file replacement. This does not affect default usage of Requests, only
applications calling the utility function directly.</li>
</ul>
<p><strong>Improvements</strong></p>
<ul>
<li>Migrated to a PEP 517 build system using setuptools. (<a
href="https://redirect.github.com/psf/requests/issues/7012">#7012</a>)</li>
</ul>
<p><strong>Bugfixes</strong></p>
<ul>
<li>Fixed an issue where an empty netrc entry could cause malformed
authentication to be applied to Requests on Python 3.11+. (<a
href="https://redirect.github.com/psf/requests/issues/7205">#7205</a>)</li>
</ul>
<p><strong>Deprecations</strong></p>
<ul>
<li>Dropped support for Python 3.9 following its end of support. (<a
href="https://redirect.github.com/psf/requests/issues/7196">#7196</a>)</li>
</ul>
<p><strong>Documentation</strong></p>
<ul>
<li>Various typo fixes and doc improvements.</li>
</ul>
<h2>New Contributors</h2>
<ul>
<li><a href="https://github.com/M0d3v1"><code>@​M0d3v1</code></a> made
their first contribution in <a
href="https://redirect.github.com/psf/requests/pull/6865">psf/requests#6865</a></li>
<li><a href="https://github.com/aminvakil"><code>@​aminvakil</code></a>
made their first contribution in <a
href="https://redirect.github.com/psf/requests/pull/7220">psf/requests#7220</a></li>
<li><a href="https://github.com/E8Price"><code>@​E8Price</code></a> made
their first contribution in <a
href="https://redirect.github.com/psf/requests/pull/6960">psf/requests#6960</a></li>
<li><a href="https://github.com/mitre88"><code>@​mitre88</code></a> made
their first contribution in <a
href="https://redirect.github.com/psf/requests/pull/7244">psf/requests#7244</a></li>
<li><a href="https://github.com/magsen"><code>@​magsen</code></a> made
their first contribution in <a
href="https://redirect.github.com/psf/requests/pull/6553">psf/requests#6553</a></li>
<li><a
href="https://github.com/Rohan5commit"><code>@​Rohan5commit</code></a>
made their first contribution in <a
href="https://redirect.github.com/psf/requests/pull/7227">psf/requests#7227</a></li>
</ul>
<p><strong>Full Changelog</strong>: <a
href="https://github.com/psf/requests/blob/main/HISTORY.md#2330-2026-03-25">https://github.com/psf/requests/blob/main/HISTORY.md#2330-2026-03-25</a></p>
<h2>v2.32.5</h2>
<h2>2.32.5 (2025-08-18)</h2>
<p><strong>Bugfixes</strong></p>
<ul>
<li>The SSLContext caching feature originally introduced in 2.32.0 has
created
a new class of issues in Requests that have had negative impact across a
number
of use cases. The Requests team has decided to revert this feature as
long term
maintenance of it is proving to be unsustainable in its current
iteration.</li>
</ul>
<p><strong>Deprecations</strong></p>
<ul>
<li>Added support for Python 3.14.</li>
<li>Dropped support for Python 3.8 following its end of support.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/psf/requests/blob/main/HISTORY.md">requests's
changelog</a>.</em></p>
<blockquote>
<h2>2.33.0 (2026-03-25)</h2>
<p><strong>Announcements</strong></p>
<ul>
<li>📣 Requests is adding inline types. If you have a typed code base
that
uses Requests, please take a look at <a
href="https://redirect.github.com/psf/requests/issues/7271">#7271</a>.
Give it a try, and report
any gaps or feedback you may have in the issue. 📣</li>
</ul>
<p><strong>Security</strong></p>
<ul>
<li>CVE-2026-25645 <code>requests.utils.extract_zipped_paths</code> now
extracts
contents to a non-deterministic location to prevent malicious file
replacement. This does not affect default usage of Requests, only
applications calling the utility function directly.</li>
</ul>
<p><strong>Improvements</strong></p>
<ul>
<li>Migrated to a PEP 517 build system using setuptools. (<a
href="https://redirect.github.com/psf/requests/issues/7012">#7012</a>)</li>
</ul>
<p><strong>Bugfixes</strong></p>
<ul>
<li>Fixed an issue where an empty netrc entry could cause
malformed authentication to be applied to Requests on
Python 3.11+. (<a
href="https://redirect.github.com/psf/requests/issues/7205">#7205</a>)</li>
</ul>
<p><strong>Deprecations</strong></p>
<ul>
<li>Dropped support for Python 3.9 following its end of support. (<a
href="https://redirect.github.com/psf/requests/issues/7196">#7196</a>)</li>
</ul>
<p><strong>Documentation</strong></p>
<ul>
<li>Various typo fixes and doc improvements.</li>
</ul>
<h2>2.32.5 (2025-08-18)</h2>
<p><strong>Bugfixes</strong></p>
<ul>
<li>The SSLContext caching feature originally introduced in 2.32.0 has
created
a new class of issues in Requests that have had negative impact across a
number
of use cases. The Requests team has decided to revert this feature as
long term
maintenance of it is proving to be unsustainable in its current
iteration.</li>
</ul>
<p><strong>Deprecations</strong></p>
<ul>
<li>Added support for Python 3.14.</li>
<li>Dropped support for Python 3.8 following its end of support.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/psf/requests/commit/bc04dfd6dad4cb02cd92f5daa81eb562d280a761"><code>bc04dfd</code></a>
v2.33.0</li>
<li><a
href="https://github.com/psf/requests/commit/66d21cb07bd6255b1280291c4fafb71803cdb3b7"><code>66d21cb</code></a>
Merge commit from fork</li>
<li><a
href="https://github.com/psf/requests/commit/8b9bc8fc0f63be84602387913c4b689f19efd028"><code>8b9bc8f</code></a>
Move badges to top of README (<a
href="https://redirect.github.com/psf/requests/issues/7293">#7293</a>)</li>
<li><a
href="https://github.com/psf/requests/commit/e331a288f369973f5de0ec8901c94cae4fa87286"><code>e331a28</code></a>
Remove unused extraction call (<a
href="https://redirect.github.com/psf/requests/issues/7292">#7292</a>)</li>
<li><a
href="https://github.com/psf/requests/commit/753fd08c5eacce0aa0df73fe47e49525c67e0a29"><code>753fd08</code></a>
docs: fix FAQ grammar in httplib2 example</li>
<li><a
href="https://github.com/psf/requests/commit/774a0b837a194ee885d4fdd9ca947900cc3daf71"><code>774a0b8</code></a>
docs(socks): same block as other sections</li>
<li><a
href="https://github.com/psf/requests/commit/9c72a41bec8597f948c9d8caa5dc3f12273b3303"><code>9c72a41</code></a>
Bump github/codeql-action from 4.33.0 to 4.34.1</li>
<li><a
href="https://github.com/psf/requests/commit/ebf71906798ec82f34e07d3168f8b8aecaf8a3be"><code>ebf7190</code></a>
Bump github/codeql-action from 4.32.0 to 4.33.0</li>
<li><a
href="https://github.com/psf/requests/commit/0e4ae38f0c93d4f92a96c774bd52c069d12a4798"><code>0e4ae38</code></a>
docs: exclude Response.is_permanent_redirect from API docs (<a
href="https://redirect.github.com/psf/requests/issues/7244">#7244</a>)</li>
<li><a
href="https://github.com/psf/requests/commit/d568f47278492e630cc990a259047c67991d007a"><code>d568f47</code></a>
docs: clarify Quickstart POST example (<a
href="https://redirect.github.com/psf/requests/issues/6960">#6960</a>)</li>
<li>Additional commits viewable in <a
href="https://github.com/psf/requests/compare/v2.32.4...v2.33.0">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=requests&package-manager=pip&previous-version=2.32.4&new-version=2.33.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/carbon-language/carbon-lang/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-26 00:40:18 +00:00
Jon Ross-Perkins 25793358c3 Remove jonmeow from pre-commit config (#6966)
Removing this exception before I forget it's there

Assisted-by: Google Antigravity with Gemini
2026-03-25 23:01:20 +00:00
Richard Smith 37b238fa28 Make C++ types impl Core.Default. (#6962)
C++ classes that are default-constructible now implement `Core.Default`
by calling the default constructor.
2026-03-25 21:07:24 +00:00
Jon Ross-Perkins 311670c84a Improve vscode extension ownership (#6960)
Updates the way to access vscode marketplace for publishing. I've
adjusted CarbonInfraBot's attached email to match.

The `#editor-integrations` change is for inconsistent markdown handling
by MS...
https://marketplace.visualstudio.com/items?itemName=carbon-lang.carbon-vscode
looks fine at the moment, but I was seeing rendering as a title -- maybe
a bug that won't be rolled out, but backticks seem fair here.

Assisted-by: Google Antigravity with Gemini
2026-03-25 20:29:09 +00:00
Richard Smith 965879a9a9 Support for in-place return in eval fn. (#6954)
Ignore storage arguments when evaluating a call, like we do for other
kinds of instruction. Create a placeholder constant to represent each
out parameter so that it can be used in the function body to form more
storage arguments.

Assisted-by: Gemini 3.1 Pro via Antigravity
2026-03-25 16:03:44 +00:00
David Blaikie 415cd6f8f0 Reverse Interop: Class declarations (#6955)
Generate class declarations for Carbon classes referenced from C++

Based on #6940, review from eb62070a01
onwards
2026-03-25 04:50:08 +00:00
Richard Smith 7345f4e860 Use a per-file width for the line number gutter. (#6959)
In in the VSCode extension, use the same width for the per-split line
number gutter across all splits. This makes the visuals more consistent.
2026-03-24 21:55:48 +00:00
Richard Smith 29a8b315d3 Improve vscode line number display for test files. (#6957)
In the Carbon vscode extension, in /testdata/ files with file splits,
add a line number column within the split next to the line number column
for the overall file line number.

Assisted-by: Gemini 3.1 Pro via Antigravity
2026-03-24 21:34:03 +00:00
Jon Ross-Perkins e0305684b0 Add MakeVerifiedLocIdAndInst for runtime validation (#6942)
This follows up on a discussion about wanting to use `Any*` inst
clusters to handle boilerplate construction, with the issue that
`UncheckedLoc` use removes validation. Some context is at
https://github.com/carbon-language/carbon-lang/pull/6930#discussion_r2963157428.

This folds in `MakeImportedLocIdAndInst` because the logic is related,
particularly for `LocId` values which are `ImportIRInstId`, and it
eliminates questions of what the right function is to use.

This uncovers an error in the `NodeKind` associated with
`FormBindingPattern`. For now I'm just adding a TODO regarding that.

Assisted-by: Google Antigravity with Gemini
2026-03-24 20:56:44 +00:00
David BlaikieandJon Ross-Perkins 2af5f971da Reverse Interop: Nested namespace support (#6940)
Start recording the clang::DeclContext* -> InstId mapping for use in
later operations.

The test update includes removing the initial fail_* test because I
hadn't thought about the use of namespace aliases as a way to test for
the presence of a namespace without the failure caused by not finding
the thing inside the namespace.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2026-03-24 19:55:25 +00:00
Nicholas Bishop f9e1806c4a Improve diagnostics for EvaluateAsConstantExpr (#6956)
Initialize the `Diag` field `EvalResult` to get notes from clang when
`EvaluateAsConstantExpr` fails, then emit them using clang's diagnostic
infrastructure.

Also set valid source locations in a couple places, otherwise clang's
diagnostics code crashes.
2026-03-24 19:40:09 +00:00
Geoff Romer e0c6800ab3 Reverse nesting structure of parameter patterns (#6930)
See
[here](https://docs.google.com/document/d/1rWcueFwIfZox6GKVGxiUG4cBzjrZ6djXiIDGyJDtrE4/edit?tab=t.0#heading=h.7mi143mdhr2h)
for an overview of the changes and their rationale.

Assisted-by: Gemini 3.1 Pro via Antigravity
2026-03-23 20:38:20 +00:00
a345a74145 prepares vscode extension for open-vsx (#6834)
We'd like to add the Carbon vscode extension to open-vsx.org so it's
available on vscode-compatible projects (see #6766). This commit
updates documentation so that we're recommending the correct package,
and updates our dependencies to ensure users have the latest security
patches.

---------

Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2026-03-23 16:57:54 +00:00
Chandler Carruth 86d05b598b Move the logic for preparing the installed runtimes files to its own (#6946)
directory

This cleans up the `//toolchain/install/BUILD` file and the tree
generally to be more focused on arranging the actual installation rather
than preparing inputs to that installation.

I picke `//toolchain/runtimes` so we can put other runtimes preparation
logic there, but open to any other suggested organization.

There are other runtimes things that would in theory make sense to move
such as the `prebuilt_runtimes` logic, but a subsequent PR will delete
those and so I'm leaving them where they are for now.
2026-03-23 16:39:45 +00:00
cui 7b6e3dfbb0 Fix ReadlinkSlow buffer when lstat reports zero size (#6948)
When the symlink target length from lstat was 0, the code resized the
buffer using status.size() instead of buffer_size, so the first
allocation stayed empty instead of using MinBufferSize. Align the resize
with the buffer_size path used for readlinkat.
2026-03-23 16:28:51 +00:00
Dana Jansens 17657d0586 CHECK if a SymbolicOnly instruction produces a concrete value of the same inst type (#6938)
The contract for SymbolicOnly is that the instructions are only allowed
to have a symbolic value unless their value is a different instruction
type.
2026-03-23 16:15:56 +00:00
dependabot[bot] 3ef991466d Bump flatted from 3.3.2 to 3.4.2 in /utils/vscode in the npm_and_yarn group across 1 directory (#6944)
Bumps the npm_and_yarn group with 1 update in the /utils/vscode
directory: [flatted](https://github.com/WebReflection/flatted).

Updates `flatted` from 3.3.2 to 3.4.2
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/WebReflection/flatted/commit/3bf09091c3562e17a0647bc06710dd6097079cf7"><code>3bf0909</code></a>
3.4.2</li>
<li><a
href="https://github.com/WebReflection/flatted/commit/885ddcc33cf9657caf38c57c7be45ae1c5272802"><code>885ddcc</code></a>
fix CWE-1321</li>
<li><a
href="https://github.com/WebReflection/flatted/commit/0bdba705d130f00892b1b8fcc80cf4cdea0631e3"><code>0bdba70</code></a>
added flatted-view to the benchmark</li>
<li><a
href="https://github.com/WebReflection/flatted/commit/2a02dce7c641dec31194c67663f9b0b12e62da20"><code>2a02dce</code></a>
3.4.1</li>
<li><a
href="https://github.com/WebReflection/flatted/commit/fba4e8f2e113665da275b19cd0f695f3d98e9416"><code>fba4e8f</code></a>
Merge pull request <a
href="https://redirect.github.com/WebReflection/flatted/issues/89">#89</a>
from WebReflection/python-fix</li>
<li><a
href="https://github.com/WebReflection/flatted/commit/5fe86485e6df7f7f34a07a2a85498bd3e17384e7"><code>5fe8648</code></a>
added &quot;when in Rome&quot; also a test for PHP</li>
<li><a
href="https://github.com/WebReflection/flatted/commit/53517adbefe724fe472b2f9ebcdb01910d0ae3f0"><code>53517ad</code></a>
some minor improvement</li>
<li><a
href="https://github.com/WebReflection/flatted/commit/b3e2a0c387bf446435fec45ad7f05299f012346f"><code>b3e2a0c</code></a>
Fixing recursion issue in Python too</li>
<li><a
href="https://github.com/WebReflection/flatted/commit/c4b46dbcbf782326e54ea1b65d3ebb1dc7a23fad"><code>c4b46db</code></a>
Add SECURITY.md for security policy and reporting</li>
<li><a
href="https://github.com/WebReflection/flatted/commit/f86d071e0f70de5a7d8200198824a3f07fc9c988"><code>f86d071</code></a>
Create dependabot.yml for version updates</li>
<li>Additional commits viewable in <a
href="https://github.com/WebReflection/flatted/compare/v3.3.2...v3.4.2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=flatted&package-manager=npm_and_yarn&previous-version=3.3.2&new-version=3.4.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/carbon-language/carbon-lang/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-23 15:09:36 +00:00
cui 44f2a68ee0 Fix iN/uN type literal width check for multiples of 8 (#6949)
The diagnostic requires bit widths to be multiples of 8, but the test
used a mask of 3 (lower two bits), which only enforces multiples of 4.
Use a mask of 7 so values like 12 incorrectly pass the check.
2026-03-22 02:03:48 +00:00
Jon Ross-Perkins 81215e873e Add missing library in test (#6945)
Adding a library to lower the odds of tripping someone up in the future
(I don't plan to modify this file now)

Assisted-by: Google Antigravity with Gemini
2026-03-20 23:07:21 +00:00
bc38deb16c adds witness support for associated types (#6937)
This commit creates an instance for any associated types in an interface
with a custom witness table. This unlocks interfaces designed for C++
interop that rely on arbitrary return types. For example,
`CppUnsafeDeref` becomes usable as of this commit.

This commit may have also implemented support for non-type associated
constants, but since we're lacking a practical test case, they're still
marked as TODO for the time being.

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2026-03-20 22:03:52 +00:00
Dana Jansens 6d2387cb77 Return a NewAnyPhase result for RequireCompleteType with a CompleteTypeWitness value (#6939)
The `CompleteTypeWitness` can be concrete. This avoids making a symbolic
`CompleteTypeWitness` value which itself has a concrete
`CompleteTypeWitness` value with the same operands.
2026-03-20 20:00:08 +00:00
Geoff Romer 000b4f3fa5 Handle errors in form binding without crashing. (#6936)
Closes #6920
2026-03-20 18:25:00 +00:00
Richard Smith e06eb8f532 Create a placement operator new directly. (#6941)
Instead of injecting code to declare an `operator new`, generate AST for
it directly. In order to use this, directly generate a `CXXNewExpr`
rather than asking Clang to build one.

This is less of a hack, and doesn't visibly leak an `operator new`
declaration that inline C++ code or template instantiations might see.
It also avoids generating a warning in C++26 and later that the
`constexpr` declaration of `operator new` is used but not defined.

Assisted-by: Gemini 3.1 Pro via Antigravity
2026-03-20 16:50:37 +00:00
Geoff Romer 8e824d02be Restructure pattern matching to support producing results (#6929)
See
[here](https://docs.google.com/document/d/1rWcueFwIfZox6GKVGxiUG4cBzjrZ6djXiIDGyJDtrE4/edit?tab=t.0#heading=h.o26vowcup0iq)
for the motivation. Note that this change only provides the
infrastructure for producing and consuming results; the actual usage is
in a separate PR.

Assisted-by: Gemini 3.1 Pro via Antigravity
2026-03-20 16:47:04 +00:00
Geoff Romer 8e5b358ec2 Add the form ID to FormParamPattern (#6928)
This enables some nice simplifications, and it's also a step toward a
broader restructuring of binding and parameter patterns.

Assisted-by: Gemini 3.1 Pro via Antigravity
2026-03-20 01:08:38 +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
Christopher Di BellaandDana Jansens fd2d210c63 changes LookupCppImpl's return to handle multiple associated entities (#6916)
`LookupCppImpl` handles exactly one function ID, so core interfaces with
multiple associated entities were regarded as unsupported. This commit
adds support for a single associated function with a single associated
constant.

Note: associated constants are still TODO.

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
2026-03-19 22:03:39 +00:00
Geoff Romer 08148f3a3a Refactor AddBindingPattern into composable pieces (#6927)
This is part of some bigger changes in pattern matching, factored out
because it causes some test churn.

Assisted-by: Gemini 3.1 Pro via Antigravity
2026-03-19 19:20:03 +00:00
Dana Jansens 10beae2c20 Avoid crashing if a C++ type was used to look for an IntFitsIn witness (#6924)
Originally this was handled in LookupCppImpl in the switch on the
CoreInterface, but in subsequent refactorings it was lost, and we now
assume we are always looking for a C++ witness and CHECK that the
interface is not `IntFitsIn`.

Refactor LookupCppImpl to have a single switch up front on the
CoreInterface enum, instead of multiple. It's a quick early out for
`IntFitsIn` and delegates work to helper functions specific to each
other CoreInterface value.
2026-03-19 18:34:45 +00:00
Geoff Romer 6d1130f657 Allow no-op conversions on incomplete types. (#6926)
This resolves some todos, and makes `Convert` safer to call, which
unblocks some changes in pattern matching that I'm working on.

Assisted-by: Gemini 3.1 Pro via Antigravity
2026-03-19 17:08:23 +00:00
David Blaikie 14b72f16da SemIR::Namespace->clang::NamespaceDecl interop (#6935)
Rough-in with TODO for caching and scoping/nesting, this only handles
top level namespaces and doesn't nest them appropriately.
2026-03-18 23:33:49 +00:00
Jon Ross-Perkins 7b3f120f97 Make Any* macros reusable (#6933)
Use parens to delay macro expansion to address the comma separator case,
allowing reuse in AnyBindingOrExportDecl. Also add
CARBON_INST_CATEGORY_ANY_EXPAND to reduce some boilerplate.

Assisted-by: Google Antigravity with Gemini
2026-03-18 19:27:46 +00:00
Nicholas Bishop 0482b27c6b Support more types in MapConstantToAPValue by refactoring code out of ConvertArgToTemplateArg (#6923)
This doesn't change any of the current tests, but will be useful for
calling constexpr functions with bool/float params.
2026-03-18 16:11:42 +00:00
Richard SmithandDana Jansens 98e2567524 Add a skill to produce a summary report for changes to testdata files. (#6925)
Example output from Gemini:
https://gist.github.com/zygoloid/b4aaaf919173d639cf0ffa90fd0898e4

Assisted-by: Gemini 3.1 Pro via Antigravity

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
2026-03-18 16:05:10 +00:00
Jon Ross-Perkins d47b6221ae Fix invalid digit caret (#6921)
Stumbled on this playing with numeric literals

Assisted-by: Google Antigravity with Gemini
2026-03-17 18:13:55 +00:00
Dana Jansens 87fc05750b Test that a named constraint can't be used inside its definition through an alias to its name (#6922)
We only want to allow using the named constraint through `Self`, as
proposed in #6902.
2026-03-17 17:31:20 +00:00
Jon Ross-Perkins 2e32f309eb Small improvements to APInt handling (#6918)
I was looking for uses of APInt that care about the bit width we're
using, just searching for uses of "64", since #6908 started applying the
minimum with of 64 bits more explicitly.

- numeric_literal.cpp: piping through the sign bit request, allowing
`exponent` to assume it's already 64-bit (putting the CHECK in to just
expose the logic, keeping it outside the `if` because the `if` is an
edge case and I was thinking to avoid edge case inconsistencies slipping
by)
- inst_fingerprinter.cpp: reducing logic to copy words

Assisted-by: Google Antigravity with Gemini
2026-03-17 17:11:30 +00:00
Geoff Romer 1d71e7a707 Change .size() == 0 to .empty() (#6917)
This resolves a readability-container-size-empty clang-tidy finding.
2026-03-17 11:35:04 +00:00
Jon Ross-PerkinsandChandler Carruth 613a139bef Add support for octal numbers (#6909)
This implements the leads decision made in #6821, proposal #6910. The
proposal is pending, but I figured it's relatively safe to just do given
the decision.

Assisted-by: Google Antigravity with Gemini

---------

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2026-03-16 21:28:37 +00:00
Jon Ross-Perkins c5761d2d16 Improve parsing large integers (#6908)
Though I started this thinking about performance of parse of large
decimal integers, I extended it to generally improve performance of
integer values (TBH I hadn't expected such a difference for binary/hex,
but I'll take it).

Note I think tests change because I'm making subtle changes to bit
widths. The changes themselves appear harmless to me, but happy to make
changes if it'd help.

Bumping up the number of digits by 10x because it's not really a
performance issue anymore (eh, maybe somebody will want to specify a
256-byte value in binary). But, at a certain point it still seems like a
mistake if somebody has that many digits in a row.

Fixes #980

Highlighting benchmark differences:
```diff
- BM_ComputeValue_IntDecimalN/1           37.1 ns         37.1 ns     18887116
+ BM_ComputeValue_IntDecimalN/1           21.9 ns         21.9 ns     31902433
- BM_ComputeValue_IntDecimalN/10000 1251228680 ns   1250457559 ns            1
+ BM_ComputeValue_IntDecimalN/10000     458818 ns       458626 ns         1523
- BM_ComputeValue_IntBinaryN/1            29.0 ns         29.0 ns     24058533
+ BM_ComputeValue_IntBinaryN/1            22.2 ns         22.1 ns     31566949
- BM_ComputeValue_IntBinaryN/10000     1390557 ns      1389782 ns          506
+ BM_ComputeValue_IntBinaryN/10000       16402 ns        16396 ns        42744
- BM_ComputeValue_IntHexN/1               34.0 ns         34.0 ns     20562432
+ BM_ComputeValue_IntHexN/1               22.4 ns         22.4 ns     31238055
- BM_ComputeValue_IntHexN/10000        5387942 ns      5385262 ns          130
+ BM_ComputeValue_IntHexN/10000          39249 ns        39233 ns        17859
```

Benchmark before:
```
----------------------------------------------------------------------------
Benchmark                                  Time             CPU   Iterations
----------------------------------------------------------------------------
BM_Lex_Float                            10.6 ns         10.6 ns     66138191
BM_Lex_Int                              15.5 ns         15.4 ns     45149703
BM_Lex_IntDecimalN/1                    3.11 ns         3.11 ns    225524908
BM_Lex_IntDecimalN/10                   11.8 ns         11.8 ns     56719805
BM_Lex_IntDecimalN/100                   102 ns          102 ns      6867468
BM_Lex_IntDecimalN/1000                  943 ns          942 ns       745313
BM_Lex_IntDecimalN/10000                9465 ns         9461 ns        73970
BM_ComputeValue_Float                   61.6 ns         61.6 ns     11377463
BM_ComputeValue_Int                      106 ns          106 ns      6587381
BM_ComputeValue_IntDecimalN/1           37.1 ns         37.1 ns     18887116
BM_ComputeValue_IntDecimalN/10          87.7 ns         87.7 ns      7960837
BM_ComputeValue_IntDecimalN/100         7963 ns         7956 ns        88858
BM_ComputeValue_IntDecimalN/1000     1212577 ns      1211906 ns          578
BM_ComputeValue_IntDecimalN/10000 1251228680 ns   1250457559 ns            1
BM_ComputeValue_IntBinaryN/1            29.0 ns         29.0 ns     24058533
BM_ComputeValue_IntBinaryN/10           69.4 ns         69.4 ns     10108642
BM_ComputeValue_IntBinaryN/100           963 ns          962 ns       726982
BM_ComputeValue_IntBinaryN/1000        21562 ns        21551 ns        32506
BM_ComputeValue_IntBinaryN/10000     1390557 ns      1389782 ns          506
BM_ComputeValue_IntHexN/1               34.0 ns         34.0 ns     20562432
BM_ComputeValue_IntHexN/10              70.4 ns         70.4 ns      9953165
BM_ComputeValue_IntHexN/100             1474 ns         1473 ns       472776
BM_ComputeValue_IntHexN/1000           61818 ns        61762 ns        11363
BM_ComputeValue_IntHexN/10000        5387942 ns      5385262 ns          130
```

Benchmark after:
```
----------------------------------------------------------------------------
Benchmark                                  Time             CPU   Iterations
----------------------------------------------------------------------------
BM_Lex_Float                            10.9 ns         10.9 ns     63993114
BM_Lex_Int                              15.1 ns         15.1 ns     46869766
BM_Lex_IntDecimalN/1                    3.16 ns         3.16 ns    220923300
BM_Lex_IntDecimalN/10                   12.2 ns         12.2 ns     57731654
BM_Lex_IntDecimalN/100                   102 ns          102 ns      6875516
BM_Lex_IntDecimalN/1000                  942 ns          942 ns       742359
BM_Lex_IntDecimalN/10000                9353 ns         9350 ns        75096
BM_ComputeValue_Float                   44.9 ns         44.9 ns     15619691
BM_ComputeValue_Int                     48.9 ns         48.9 ns     14361507
BM_ComputeValue_IntDecimalN/1           21.9 ns         21.9 ns     31902433
BM_ComputeValue_IntDecimalN/10          30.3 ns         30.3 ns     23134117
BM_ComputeValue_IntDecimalN/100          224 ns          223 ns      3092567
BM_ComputeValue_IntDecimalN/1000        5834 ns         5830 ns       117469
BM_ComputeValue_IntDecimalN/10000     458818 ns       458626 ns         1523
BM_ComputeValue_IntBinaryN/1            22.2 ns         22.1 ns     31566949
BM_ComputeValue_IntBinaryN/10           32.9 ns         32.9 ns     21306927
BM_ComputeValue_IntBinaryN/100           198 ns          198 ns      3545277
BM_ComputeValue_IntBinaryN/1000         1671 ns         1669 ns       419656
BM_ComputeValue_IntBinaryN/10000       16402 ns        16396 ns        42744
BM_ComputeValue_IntHexN/1               22.4 ns         22.4 ns     31238055
BM_ComputeValue_IntHexN/10              47.8 ns         47.7 ns     14694407
BM_ComputeValue_IntHexN/100              436 ns          436 ns      1609794
BM_ComputeValue_IntHexN/1000            3966 ns         3962 ns       177109
BM_ComputeValue_IntHexN/10000          39249 ns        39233 ns        17859
```

Assisted-by: Google Antigravity with Gemini
2026-03-16 20:00:51 +00:00
Nicholas Bishop 943cd41924 Support constexpr pointers (#6907)
This moves the LValue path code from macros.cpp to constant.cpp, so that
it can be called from `MapAPValueToConstant`. TODO messages are updated
accordingly to avoid referring to macros. Added a constexpr pointer test
to `constexpr.carbon` to show the result of this change.
2026-03-16 19:19:20 +00:00
Jon Ross-Perkins c006013e0c Change multi-input error to warning (#6914)
Mainly so that Compiler Explorer's command line doesn't need to change.

Assisted-by: Google Antigravity with Gemini
2026-03-16 17:35:58 +00:00
dependabot[bot] aeed8f608b Bump undici from 6.21.3 to 6.24.0 in /utils/vscode in the npm_and_yarn group across 1 directory (#6911)
Bumps the npm_and_yarn group with 1 update in the /utils/vscode
directory: [undici](https://github.com/nodejs/undici).

Updates `undici` from 6.21.3 to 6.24.0
<details>
<summary>Release notes</summary>
<p><em>Sourced from <a
href="https://github.com/nodejs/undici/releases">undici's
releases</a>.</em></p>
<blockquote>
<h2>v6.24.0</h2>
<h1>Undici v6.24.0 Security Release Notes (LTS)</h1>
<p>This release backports fixes for security vulnerabilities affecting
the v6 line.</p>
<h2>Upgrade guidance</h2>
<p>All users on v6 should upgrade to <strong>v6.24.0</strong> or
later.</p>
<h2>Fixed advisories</h2>
<ul>
<li>
<p><a
href="https://github.com/nodejs/undici/security/advisories/GHSA-2mjp-6q6p-2qxm">GHSA-2mjp-6q6p-2qxm</a>
/ CVE-2026-1525 (Medium)<br />
Inconsistent interpretation of HTTP requests (request/response smuggling
class issue).</p>
</li>
<li>
<p><a
href="https://github.com/nodejs/undici/security/advisories/GHSA-f269-vfmq-vjvj">GHSA-f269-vfmq-vjvj</a>
/ CVE-2026-1528 (High)<br />
Malicious WebSocket 64-bit frame length handling could crash the
client.</p>
</li>
<li>
<p><a
href="https://github.com/nodejs/undici/security/advisories/GHSA-4992-7rv2-5pvq">GHSA-4992-7rv2-5pvq</a>
/ CVE-2026-1527 (Medium)<br />
CRLF injection via the <code>upgrade</code> option.</p>
</li>
<li>
<p><a
href="https://github.com/nodejs/undici/security/advisories/GHSA-v9p9-hfj2-hcw8">GHSA-v9p9-hfj2-hcw8</a>
/ CVE-2026-2229 (High)<br />
Unhandled exception from invalid <code>server_max_window_bits</code> in
WebSocket permessage-deflate negotiation.</p>
</li>
<li>
<p><a
href="https://github.com/nodejs/undici/security/advisories/GHSA-vrm6-8vpv-qv8q">GHSA-vrm6-8vpv-qv8q</a>
/ CVE-2026-1526 (High)<br />
Unbounded memory consumption in WebSocket permessage-deflate
decompression.</p>
</li>
</ul>
<h2>Not applicable to v6</h2>
<ul>
<li><a
href="https://github.com/nodejs/undici/security/advisories/GHSA-phc3-fgpg-7m6h">GHSA-phc3-fgpg-7m6h</a>
/ CVE-2026-2581 affects <code>&gt;= 7.17.0 &lt; 7.24.0</code> only.</li>
</ul>
<h2>Affected and patched ranges (v6)</h2>
<ul>
<li>CVE-2026-1525: affected <code>&lt; 6.24.0</code>, patched
<code>6.24.0</code></li>
<li>CVE-2026-1528: affected <code>&gt;= 6.0.0 &lt; 6.24.0</code>,
patched <code>6.24.0</code></li>
<li>CVE-2026-1527: affected <code>&lt; 6.24.0</code>, patched
<code>6.24.0</code></li>
<li>CVE-2026-2229: affected <code>&lt; 6.24.0</code>, patched
<code>6.24.0</code></li>
<li>CVE-2026-1526: affected <code>&lt; 6.24.0</code>, patched
<code>6.24.0</code></li>
</ul>
<h2>References</h2>
<ul>
<li>GitHub Security Advisories: <a
href="https://github.com/nodejs/undici/security/advisories">https://github.com/nodejs/undici/security/advisories</a></li>
<li>NVD CVE-2026-1525: <a
href="https://nvd.nist.gov/vuln/detail/CVE-2026-1525">https://nvd.nist.gov/vuln/detail/CVE-2026-1525</a></li>
<li>NVD CVE-2026-1528: <a
href="https://nvd.nist.gov/vuln/detail/CVE-2026-1528">https://nvd.nist.gov/vuln/detail/CVE-2026-1528</a></li>
<li>NVD CVE-2026-1527: <a
href="https://nvd.nist.gov/vuln/detail/CVE-2026-1527">https://nvd.nist.gov/vuln/detail/CVE-2026-1527</a></li>
<li>NVD CVE-2026-2229: <a
href="https://nvd.nist.gov/vuln/detail/CVE-2026-2229">https://nvd.nist.gov/vuln/detail/CVE-2026-2229</a></li>
<li>NVD CVE-2026-1526: <a
href="https://nvd.nist.gov/vuln/detail/CVE-2026-1526">https://nvd.nist.gov/vuln/detail/CVE-2026-1526</a></li>
</ul>
<h2>v6.23.0</h2>
<h2>⚠️ Security Release</h2>
<!-- raw HTML omitted -->
</blockquote>
<p>... (truncated)</p>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/nodejs/undici/commit/8873c947271faf1ebc455bdc6158ecbc022ecfa9"><code>8873c94</code></a>
Bumped v6.24.0</li>
<li><a
href="https://github.com/nodejs/undici/commit/411bd01a42e7917009bbf686f7628b99d67bbce9"><code>411bd01</code></a>
test(websocket): use node:assert for Node 18 compatibility</li>
<li><a
href="https://github.com/nodejs/undici/commit/844bf59699d778944f78a24ae819c0e8f295766e"><code>844bf59</code></a>
test: fix http2 lint regressions in backport</li>
<li><a
href="https://github.com/nodejs/undici/commit/a444e4f13e8958b4e1ac42bc0d53ace7fba0a9c1"><code>a444e4f</code></a>
test: stabilize h2 and tls-cert-leak under current test runner</li>
<li><a
href="https://github.com/nodejs/undici/commit/dc032a1050d5489b8ce9b4c22aafba98a942f87b"><code>dc032a1</code></a>
fix: h2 CI (<a
href="https://redirect.github.com/nodejs/undici/issues/4395">#4395</a>)</li>
<li><a
href="https://github.com/nodejs/undici/commit/4cd3f4b3a2ef910ba728c47ae78294d956410450"><code>4cd3f4b</code></a>
test: increase bitness in <code>test/fixtures/*.pem</code> (<a
href="https://redirect.github.com/nodejs/undici/issues/3659">#3659</a>)</li>
<li><a
href="https://github.com/nodejs/undici/commit/7df6442194b7a54e9ac734335e6e0a56a9bc6666"><code>7df6442</code></a>
fix: adapt websocket frame-limit handling for v6 parser</li>
<li><a
href="https://github.com/nodejs/undici/commit/4e0179ae643e6f4380f24cc3683c1b1ca2afb094"><code>4e0179a</code></a>
fix: reject duplicate content-length and host headers</li>
<li><a
href="https://github.com/nodejs/undici/commit/5a97f0893b53ba7d1d5549d3df7e55d9c2673f89"><code>5a97f08</code></a>
Fix websocket 64-bit length overflow</li>
<li><a
href="https://github.com/nodejs/undici/commit/e43e898603dd5e0c14a75b08b83257598d664a39"><code>e43e898</code></a>
fix: validate upgrade header to prevent CRLF injection</li>
<li>Additional commits viewable in <a
href="https://github.com/nodejs/undici/compare/v6.21.3...v6.24.0">compare
view</a></li>
</ul>
</details>
<details>
<summary>Maintainer changes</summary>
<p>This version was pushed to npm by [GitHub Actions](<a
href="https://www.npmjs.com/~GitHub">https://www.npmjs.com/~GitHub</a>
Actions), a new releaser for undici since your current version.</p>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=undici&package-manager=npm_and_yarn&previous-version=6.21.3&new-version=6.24.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/carbon-language/carbon-lang/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-16 15:54:05 +00:00
Jon Ross-Perkins 8b907b5a60 Support octal literals (#6910)
Support octal literals, mainly for migrating Unix file permissions.
Reflects leads decision #6821.
2026-03-14 00:50:58 +00:00
6f1f59a385 Initial Reverse Interop implementation (#6901)
Add a clang::ExternalASTSource to begin exposing Carbon entities to
Clang - initially only a single `Carbon` top level namespace.

Subsequent work will add Carbon entities to this namespace.

Likely this CarbonExternalASTSource will be refactored into another
file, tie into/reference SemIR::File and CppFile, etc eventually - but
that'll wait for future patches.

If there's mechanical problems with the current implementation - how I'm
creating the new NamespaceDecl, etc - I'm all ears. It's very much in
the "it seems to work" state, not much more than that.

This does break Clang Modules (header modules, C++20 modules,
precompiled headers, etc) since they're implemented as an
ExternalASTSource as well, and Clang's ASTContext only supports one
ExternalASTSource at a time. To fix that regression we'll need to
implement some kind of ExternalASTSource multiplexing support - either
in Clang or Carbon (unclear which).

This regression of modules support can be observed by the following:
`A.h`
```
inline void f1() { }
```
`module.modulemap`
```
module A {
  header "A.h"
  export *
}
```
`test.carbon`
```
import Cpp inline '''
// Hardcode the pragma to ensure this isn't silently falling back to
// textual inclusion.
void f2() {
  f1();
}
''';
```
```
carbon compile test.carbon -- -I . -fmodules -fimplicit-modules -fmodules-cache-path=module_cache
```

I wrote a `file_test` test for this, but it doesn't /quite/ work because
`file_test` provides an in-memory filesystem for tests to make them more
hermetic, but Clang's Filesystem abstrtaction is for reading only - so
the module that's written out successfully can't be found when it needs
to be read back in - so the test doesn't pass as a baseline. Clang does
have support for `llvm::vfs::OutputBackend` which allows virtualizing
output - which I guess we could tie together with the InMemoryFilesystem
we use for input to make such a test work. But I guess that's not worth
the effort here?

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2026-03-13 23:04:49 +00:00
Dana Jansens 27cc14848a Use a single work queue in RequireIdentifiedFacetType (#6904)
Use a single vector instead of two. This reduces the number of memory
allocations required.
2026-03-13 22:16:41 +00:00
Jon Ross-Perkins fbe917b949 Create a UnifiedDiffMatcher to make golden test failures easier to understand (#6897)
Right now I think everyone has the habit of doing an autoupdate then
using source control for a diff. This is offering an option of better
diff output from the test.

For example:

```
TEST: toolchain/driver/testdata/fail_flush_errors.carbon !
Ran 1 tests in 81 ms wall time, 8 ms across threads
testing/file_test/file_test_base.cpp:264: Failure
Value of: SplitOutput(test_file.actual_stderr)
Expected: matches elements with union diff
  Actual: { "fail_flush_errors.carbon:22:3: error: name `undeclared1` not found [NameNotFound]", "  undeclared1;", "  ^~~~~~~~~~~", "", "fail_flush_errors.carbon:31:3: error: `Core.String` implicitly referenced here, but package `Core` not found [CoreNotFound]", "  \"undec\\x6Cared2\";", "  ^~~~~~~~~~~~~~~~", "", "fail_flush_errors.carbon:35:3: error: name `undeclared2` not found [NameNotFound]", "  undeclared2;", "  ^~~~~~~~~~~", "", "fail_flush_errors.carbon:43:3: error: name `undeclared3` not found [NameNotFound]", "  undeclared3;", "  ^~~~~~~~~~~", "", "" }, union diff (- expected, + actual):
=== diff in expected elements 0 to 2:
+ fail_flush_errors.carbon:22:3: error: name `undeclared1` not found [NameNotFound]
    undeclared1;
    ^~~~~~~~~~~

=== diff in expected elements 4 to 9:
    "undec\x6Cared2";
    ^~~~~~~~~~~~~~~~

+ fail_flush_errors.carbon:35:3: error: name `undeclared2` not found [NameNotFound]
    undeclared2;
    ^~~~~~~~~~~

=== diff end

Stack trace:
  0x55e476d29efd: Carbon::Testing::FileTestCase::TestBody()
  0x55e476dbd1f2: testing::internal::HandleExceptionsInMethodIfSupported<>()
  0x55e476dbcf57: testing::Test::Run()
  0x55e476dbf0bf: testing::TestInfo::Run()
... Google Test internal frames ...


To test this file alone, run:
  bazel test //toolchain/testing:file_test --test_arg=--file_tests=toolchain/driver/testdata/fail_flush_errors.carbon

testing/file_test/file_test_base.cpp:277: Failure
Failed
Autoupdate would make changes to the file content. Run:
bazel run //toolchain/testing:file_test -- --autoupdate --file_tests=toolchain/driver/testdata/fail_flush_errors.carbon
Stack trace:
  0x55e476d2a5f0: Carbon::Testing::FileTestCase::TestBody()
  0x55e476dbd1f2: testing::internal::HandleExceptionsInMethodIfSupported<>()
  0x55e476dbcf57: testing::Test::Run()
  0x55e476dbf0bf: testing::TestInfo::Run()
... Google Test internal frames ...

[  FAILED  ] ToolchainFileTest.toolchain/driver/testdata/fail_flush_errors.carbon, where GetParam() = toolchain/driver/testdata/fail_flush_errors.carbon (93 ms)
```

Assisted-by: Google Antigravity with Gemini
2026-03-13 21:39:21 +00:00
Dana Jansens bad9beddc7 Diagnose using named constraint's name inside its definition (#6906)
Using a named constraint inside itself is problematic:
- If there were not require decls written above, it identifies as an
empty set. This makes `Z(Self)` essentially disappear in the identified
facet type, which produces "no use of Self" diagnostics while the user
can see a use of Self in the code.
- It won't include require decls that are written after, and so `require
T impls Z` won't actually enforce that `T` impls all of `Z`.

Previously this was an error because using the named constraint would
require it to be identified, and it's not identified until it is
complete. But this will change in proposal #6902. So that proposal also
includes changes to preserve diagnostics for incorrect use of a named
constraint before it's complete, which is implemented here.

Discussed in open discussion [on
2026-03-12](https://docs.google.com/document/d/1mjllGO3ZCL4qGt9uJHUtcxKoHAGEY7Y999ie4EtBWB8/edit?tab=t.0#heading=h.1dvbbrp5a6t3).

The new tests exposed a bug where we're not copying named constraints in
a facet type on the RHS of `where .Self impls` into the facet type on
the left, which is now fixed. The
`fail_require_impls_incomplete_self_in_period_self_impls.carbon` test
would not diagnose its error without this fix.
2026-03-13 16:54:58 +00:00
Jon Ross-Perkins 6706162582 Error when passing multiple input files with --output (#6896)
Fixes #6895

Note this is just a short-term fix to avoid confusion, as the compile
structure needs to change on the whole.

Assisted-by: Google Antigravity with Gemini
2026-03-13 16:07:12 +00:00
Christopher Di Bella ffe8f8f67d Revert "refactors LookupCppImpl to handle multiple associated functions (#6816)" (#6900)
We discussed whether associated functions should be processed in a
general manner. Since many associated functions will have some amount of
unique processing, we're probably better off not having a general
utility, and we can return to the original `CoreInterface`, which was
much simpler in design.

This reverts commit 4d0003765d.
2026-03-13 15:09:42 +00:00
Dana Jansens 5d1973ab93 Support --remote in new_proposal script with jj (#6903) 2026-03-12 21:57:56 +00:00
Jon Ross-Perkins 610094ccfd Make included files insert before main files (#6899)
This is so that the last file is more likely what we're trying to
compile in tests. Just splitting out the churn-y change of reordering.

Assisted-by: Google Antigravity with Gemini
2026-03-12 21:01:16 +00:00
Christopher Di BellaandRichard Smith 4df2b6ea9d adds checking support for CppUnsafeDeref witness (#6890)
Iterators, smart pointers, optional, and expected types depend on
`operator*`. This commit adds `CppUnsafeDeref` as a core interface, with
an associated function, so that the compiler can dereference
user-defined C++ types.

Things not implemented in this commit:

* `operator*` overload resolution
* SemIR lowering

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2026-03-12 18:02:34 +00:00
Jon Ross-Perkins 1e9708e2cc Update python version for black (#6877)
This is making it consistent with other places we set a Python version:
- contribution_tools.md
- .python-version
- bench_runner.py
- build-setup-common/action.yml

Assisted-by: Google Antigravity with Gemini
2026-03-12 16:45:58 +00:00
Dana Jansens 4c69a1baf0 Use min-prelude in fail_assoc_const_alias.carbon (#6894)
Remove the local `Core` package from the test file and use the
`convert.carbon` min-prelude.
2026-03-12 16:10:23 +00:00
Nicholas Bishop c1fd771242 Support calling constexpr functions at compile time (#6878)
Example:

```carbon
import Cpp inline '''
constexpr int f(int a, int b) { return a + b; }
''';

let a: array(i32, Cpp.f(1, 2)) = (1, 2, 3);
```
2026-03-12 01:45:31 +00:00
Chandler CarruthandDana Jansens 5d41529590 Introduce a Bazel-integrated build for the installed runtimes (#6872)
This shifts the Bazel toolchain configuration of our installation to
build all of the Clang runtimes Carbon uses on-demand natively in Bazel.
We export the information about how to build into a generated Starlark
file, and emit BUILD files and Starlark logic into the installation to
orchestrate the build.

This requires some complex management of Bazel toolchains -- we need to
first set-up a "runtimes toolchain" that doesn't have runtimes of its
own, but can be used to _build_ runtimes. Then we build the runtimes
using that toolchain, and assemble them into the standard layout for a
Carbon runtimes tree. Finally we configure the _actual_ toolchain with
this built tree.

Currently, this is only setup for the installed toolchain, but I plan to
factor this runtimes build into one that can be used directly as well to
break up the monolithic runtimes build step into Bazel-integrated build
of the runtimes. This will also serve as the foundation for adding
bootstrapping support directly to our Bazel build.

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
2026-03-12 01:24:56 +00:00
Richard Smith 0a4fd2cb7e Fix thunk generation for &&-qualified methods. (#6881)
Use the object parameter type when creating a reference to the thunk
parameter so that we create an xvalue rather than an lvalue for the
`*this` expression in the thunk.
2026-03-11 20:34:18 +00:00
Richard Smith 2e5b195813 Make {} as Class an initializing expression. (#6882)
Previously we forced a temporary materialization, resulting in it being
treated as an ephemeral reference expression. This change allows

```carbon
var x: Class = {} as Class;
```

even when `Class` is not copyable.
2026-03-11 20:21:21 +00:00
Nicholas Bishop 6ac561afe9 Add "Fixing conflicts with trunk" to code_review.md (#6889) 2026-03-11 19:30:20 +00:00
Jon Ross-Perkins 70c401f85f Updates the llvm-raw commit to HEAD as of 2026-03-09 (#6879)
Test changes are the result of autoupdate_testdata.py

Assisted-by: Google Antigravity with Gemini
2026-03-11 14:47:40 +00:00
Richard Smith 39fd358059 Map Carbon value expressions to const-qualified C++ prvalues. (#6880)
In C++ overload resolution, when mapping a Carbon value expression into
a C++ argument, produce a const-qualified argument where possible. This
has two effects:

* Overload resolution does not consider non-const-qualified member
functions to be viable for a prvalue self any more. This is desirable
since such functions are not actually callable with a prvalue self, and
permits overload resolution to pick a const-qualified overload instead.

* Overload resolution does not allow a Carbon value expression to be
passed to a C++ `T&&` parameter any more. This is desirable since it's
not correct to move from a value expression. Previously we allowed this
and moved from the value!
2026-03-11 03:42:19 +00:00
Geoff Romer ba6257891e Remove ValueParamPattern case from deduction (#6869)
This case is redundant: when deducing against a runtime parameter
pattern, the type is all that matters, and the type is added to the
deduction earlier. Additionally deducing the same argument against
parameter's subpattern just creates duplicate work, because the
subpattern has the same type.
2026-03-10 21:15:38 +00:00
Ilya 6304df1db9 Fix crash in character literal lexing (#6805)
When lexing a hash-prefixed character literal, the lexer assumed that
the hash level of escape sequences inside the literal was zero, which
allowed unclosed escape sequences inside the literal which crashed the
compiler.

Closes #6799
2026-03-10 20:25:29 +00:00
Richard Smith 99bde2acb3 Refactor match parse nodes. (#6870)
Use the same node kind for the body of `case` and `default` handlers. We
don't need to distinguish these in check, so don't create extra node
kinds for them.

In order to make the nodes properly delimited, make the label (`case
...` or `default`) nodes be children of the `=>` node rather than
siblings. This allows us to use the node kind of the `=>` as the
bracketing node for the complete handler, rather than having two
different bracketing node kinds, one for each kind of label.
2026-03-10 20:04:28 +00:00
Chandler Carruth 9e2d0a887f Factor out textual headers from libcxx and libcxxabi (#6863)
Also cleans up how the filegroups from these rules are organized --
separately tracking srcs, hdrs, and textual-srcs.
2026-03-10 07:48:08 +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
Geoff RomerandJon Ross-Perkins 18cfeb7476 Add support for ->? return forms (#6849)
This includes checking and lowering for concrete form literals. Support
for symbolic forms is future work.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2026-03-09 22:30:16 +00:00
Chandler Carruth 5ad9b1a35d Lift builtins build logic into Starlark (#6859)
This moves the most complex of the logic fully into Starlark: both the
many different platform sources list, and the overriding of generic
files with architecture specific files.

This also fixes significant bugs in the AArch64 build where we were
skipping numerous files: all of the outlined atomics and `emupac.cpp`.
This PR forcibly disables `emupac.cpp` as fixing that will require a
more significant change.
2026-03-09 19:41:11 +00:00
Jon Ross-Perkins a1b6f1c4bd Allow uploads.github.com (#6866)
Reported at
https://discord.com/channels/655572317891461132/707150492370862090/1480625413808984136

Assisted-by: Google Antigravity with Gemini
2026-03-09 18:21:08 +00:00
Jon Ross-Perkins 3e3a97593d Remove obsolete llvm patch (#6865)
#6771 removed the use of this patch, but not the patch itself.

Assisted-by: Google Antigravity with Gemini
2026-03-09 15:55:21 +00:00
Jon Ross-Perkins 4b076291c9 pre-commit autoupdate (#6845)
Assisted-by: Google Antigravity with Gemini
2026-03-09 15:49:11 +00:00
Jon Ross-Perkins bee2633946 Try out wolfd_bazel_compile_commands (#6851)
Noticed this in bazel central registry, I'm interested in trying it out.
It's using a faster approach, but leaving the other around for the
moment in case it doesn't work out well.

Assisted-by: Google Antigravity with Gemini
2026-03-09 15:34:43 +00:00
Jon Ross-Perkins 1a47c02e5d Update tool versions in script_utils (#6852)
Assisted-by: Google Antigravity with Gemini
2026-03-09 15:34:23 +00:00
Nicholas Bishop 8a4888c3df Support assigning to a struct field through a macro (#6843)
Example:

```carbon
import Cpp inline '''
struct B {
  int c;
};
struct A {
  B b;
};
A a;
#define m a.b.c
''';

fn F() {
  Cpp.m = 2;
}
```
2026-03-09 15:31:16 +00:00
Dana JansensandChandler Carruth 744b1290cf Roll LLVM b20d7d02..6811a83c815 (#6844)
Roll LLVM to `6811a83c81500ee373adfc0d9978ff9625a4cf1c`.

This includes https://github.com/llvm/llvm-project/pull/183831 which
moved the functionality of `finish()` on `DiagnosticConsumer`s into the
destructors, and removed the `finish()` method. So, our callers to
`finish()` are migrated to cause the destructor to run at that time
instead.

---------

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2026-03-09 15:00:21 +00:00
Jon Ross-Perkins 6b2d55d289 Adjust tool usage notes (#6853)
Trying to work on some behaviors:

- Using `black` to format Python files (using `pre-commit` makes better
use of allow-listed commands)
- Writing Python code over 80 columns (adding more style notes)
- Running `bazel` (being more emphatic about `bazelisk`, splitting tool
usage out to its own skill to try making clear it's not
toolchain-specific)

Assisted-by: Google Antigravity with Gemini
2026-03-09 14:56:41 +00:00
Nicholas Bishop cdcd3ab66c Handle pack expansion for dependent non-type template params (#6850)
https://github.com/carbon-language/carbon-lang/issues/6717
2026-03-09 14:49:31 +00:00
Jon Ross-Perkins 0dac40e793 Update clangd-tidy endpoint whitelist (#6855)
Missed in #6848 (had it sitting in my workspace uncommitted, apparently
have gotten too used to jj; using git here)

Assisted-by: Google Antigravity with Gemini
2026-03-09 03:23:22 +00:00
Jon Ross-Perkins f27f8838d0 Switch llvm-raw to a git_override rule (#6854)
By using git_override, we get some validation from the sha, while
removing the sha256 on the .tar.gz which has been brittle lately. Note
the difference between downloading via sha is this still locally
validates content.

Versus something like #6844, this doesn't update the llvm version, just
how we get it.

Assisted-by: Google Antigravity with Gemini
2026-03-07 03:30:43 +00:00
Jon Ross-Perkins 6786edd6ff Update action versions (#6848)
In addition to the general updates, this switches to a required python
3.10 for pre-commit (3.9 is losing support from black).

Note endpoints for build actions are expanding significantly: see
https://app.stepsecurity.io/github/carbon-language/carbon-lang/actions/runs/22779388360?tab=recommendations&jobId=66080970460
for example, I think just the sources are being increased as a
side-effect of updates (and possibly also things not performing as well
as they should have before).

Similarly allowing sudo in pre-commit because it was actually causing
errors in part of build setup, which used sudo to remove files.

Assisted-by: Google Antigravity with Gemini
2026-03-06 22:19:44 +00:00
Jon Ross-Perkins 53c257d2e2 Switch libpfm and boost.unordered to BCR versions (#6847)
Assisted-by: Google Antigravity with Gemini
2026-03-06 21:57:23 +00:00
Geoff RomerandDavid Blaikie 2e155567bd Disallow :? within var (#6812)
Co-authored-by: David Blaikie <dblaikie@gmail.com>
2026-03-06 21:08:22 +00:00
Jon Ross-Perkins 53729325a0 Update bazel module versions (#6846)
Adds a script that queries bazel central registry and other sources to
get the latest versions. Gemini generated something similar on the fly
for checks, and I figured it's helpful to formalize.

```
- BCR:
  - abseil-cpp: 20260107.1
  - bazel_skylib: 1.9.0
  - google_benchmark: 1.9.5
  - googletest: 1.17.0.bcr.2
  - libpfm: 4.13.0
  - platforms: 1.0.0
  - protobuf: 34.0.bcr.1
  - re2: 2025-11-05.bcr.1
  - rules_bazel_integration_test: 0.37.1
  - rules_cc: 0.2.17
  - rules_pkg: 1.2.0
  - rules_python: 1.9.0
  - rules_shell: 0.6.1
  - tcmalloc: 0.0.0-20250927-12f2552
  - tree-sitter-bazel: 0.26.5
  - zlib-ng: 2.0.7
  - zstd: 1.5.7.bcr.1
- GitHub Tag:
  - libpfm: v4.13.0
- Git HEAD:
  - bazel_clang_tidy: c4d35e0d0b838309358e57a2efed831780f85cd0
  - hedron_compile_commands: abb61a688167623088f8768cc9264798df6a9d10
```

Assisted-by: Google Antigravity with Gemini
2026-03-06 20:48:46 +00:00
21291b4cc3 Remove InitForm::index (#6817)
This ensures that equal forms always have equal representations (because
the index depends on how the form is used, not on the value of the form
itself).

As a byproduct, also remove `NextCallParamIndex`.

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Nicholas Bishop <nicholasbishop@google.com>
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
Co-authored-by: Dana Jansens <danakj@orodu.net>
Co-authored-by: Boaz Brickner <brickner@google.com>
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
Co-authored-by: MK4070 <60286678+MK4070@users.noreply.github.com>
Co-authored-by: Christopher Di Bella <cjdb@google.com>
2026-03-06 17:35:48 +00:00
Jon Ross-PerkinsandRichard Smith 2327b62b5f Add jj and AI notes to contribution tools (#6841)
Giving both of these their own sections under optional tools because I'm
mainly doing this to share example configs.

Assisted-by: Google Antigravity with Gemini

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2026-03-06 16:13:00 +00:00
Jon Ross-Perkins 97af347490 Switch GEMINI.md to skills (#6842)
This is a refactoring to .agent/skills structure, which should also work
for more AI assistants.

Assisted-by: Google Antigravity with Gemini
2026-03-05 23:30:12 +00:00
Jon Ross-PerkinsandRichard Smith 1257ef2fd0 More GEMINI.md file work (#6840)
We may want to split some out to skills, I'm just trying to merge in
some info of my own now.

Assisted-by: Google Antigravity with Gemini 3 Flash

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2026-03-05 21:35:40 +00:00
josh11bandJosh L c837c004bc Fix comment to match case of parameter name (#6839)
Co-authored-by: Josh L <josh11b@users.noreply.github.com>
2026-03-05 21:20:44 +00:00
Richard Smith 6a650941d2 Don't run clang to link when fuzzing. (#6835)
The clang driver is too easy to crash with fuzzer-generated command
lines, and it's not interesting to find those bugs.
2026-03-05 20:01:44 +00:00
Richard Smith bf6f21b8e9 Add a GEMINI.md. (#6838)
Assisted-by: Gemini 3 Pro via Antigravity
2026-03-05 19:56:13 +00:00
Christopher Di BellaandCarbon Infra Bot a9f1e17ecb codifies Carbon specifier and qualifier order (#6831)
The Carbon style guide prefers `const` to be on the left wherever
possible, and also has a de-facto standard for specifier order. Since
the order of specifiers and qualifiers tends to become a part of
muscle-memory, deferring the checking of this to tooling should lift a
small burden on both contributors and reviewers.

---------

Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
2026-03-05 19:04:21 +00:00
Nicholas Bishop e5957037fb Support assigning to a variable through an imported macro (#6827)
Support assigning to a variable through an imported macro

Example:

```carbon
import Cpp inline '''
int v = 1;
#define m v
''';

fn F() {
  Cpp.m = 2;
}
```
2026-03-05 18:24:32 +00:00
Jon Ross-Perkins 002b7c74ea Support CARBON_KIND with Any types (#6828)
This uses the `CARBON_KIND_ANY(AnyImportRef, auto import_ref):` syntax
that seemed to be favored [on
Discord](https://discord.com/channels/655572317891461132/655578254970716160/1478486848207720478).

This converted uses in the `sem_ir` directory to show it works
initially, then added `check` for full coverage plus validating the
`SemIR::` namespace discard.

Note in inst_namer.cpp, AnyBindingPattern includes FormBindingPattern
which wasn't previously handled.

I'm disabling clang-format because I think it formats with readability
issues, e.g.:

```
#define CARBON_KIND_ANY_EXPAND_AnyBinding(X, SEP)                        \
  X(::Carbon::SemIR::AliasBinding)                                       \
  SEP X(::Carbon::SemIR::FormBinding) SEP X(::Carbon::SemIR::RefBinding) \
      SEP X(::Carbon::SemIR::SymbolicBinding)                            \
          SEP X(::Carbon::SemIR::ValueBinding)
```

Since `SEP` is typically a comma, it's also a nuisance to treat as an
argument to `X` (which could get better results).

Assisted-by: Google Antigravity with Gemini 3 Flash
2026-03-05 01:20:37 +00:00
Christopher Di BellaandGeoff Romer 4d0003765d refactors LookupCppImpl to handle multiple associated functions (#6816)
`LookupCppImpl` is used to find associated functions for a witness. As
some witnesses contain multiple associated functions, we need robust
mechanims for looking up C++ components.

The logic in `LookupCppImpl` is primarily concerned with finding exactly
one C++ declaration at a time. In order to handle witnesses with more
than one associated function, we move the bulk of `LookupCppImpl` to a
new function called `FindCppAssociatedFunction`. This frees up
`CppLookupImpl` to delegate to `FindCppAssociatedFunction` when a
witness has only one associated function, and to functions that are able
to compose multiple associated functions.

---------

Co-authored-by: Geoff Romer <gromer@google.com>
2026-03-04 20:56:25 +00:00
Christopher Di Bella b28e899a8c refactors PerformCppOverloadResolution to take CppOverloadSet (#6829)
`PerformCppOverloadResolution` computes an overload set from a
`CppOverloadSetId`, but the compiler sometimes needs to synthesise a
local overload set for witnesses. `PerformCppOverloadResolution` now
requires callers to produce the `CppOverloadSet` to address this
problem.
2026-03-04 19:02:33 +00:00
1c7a4030ab Parse invalid lambdas without crashing (#6826)
Fixes a compiler crash that occurs when a malformed lambda is provided
as an operand to an operator that strictly expects an expression

Changes:
- Emits an `InvalidParse` dummy node at the current position to act as a
placeholder for the missing body
- Changed state transitions so that `LambdaIntroducer` gets properly
wrapped into a `Lambda` node


Closes #6823

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
2026-03-04 14:57:48 +00:00
Richard SmithandCarbon Infra Bot 15680ba101 Support calling functions with explicit template arguments. (#6814)
Treat the initial sequence ofarguments in a call to a C++ function up to
and including the last argument that is a type or template as being the
explicit template arguments for the call, rather than rejecting them
because they can't be converted to the parameter types.

Implements the current direction on leads issue #6768, except that no
syntax for explicitly annotating an argument as being a template
argument is provided.

---------

Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
2026-03-03 00:26:33 +00:00
Geoff RomerandJon Ross-Perkins 6dba8ee111 Remove index fields from ParamPatterns (#6815)
This is a step toward removing the index from `InitForm`, so that equal
form values always have equal representations.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2026-03-03 00:19:47 +00:00
9ff6b0a682 C++ Interop: API importing and semantics (#6358)
This proposal defines the concrete technical mechanisms for C++
interoperability. It specifies the precise syntax and semantics for
importing
C++ APIs. This includes the `import Cpp library "..."` and implicitly
importing
C++ built-in entities, and the establishment of the `Cpp` package as the
dedicated namespace for all imported entities.

This PR also includes high level language C++ Interop design and the
basics of importing C++ APIs and function calling.
Leaving plenty of TODOs to make it easier to fill in more details in
followups.

Part of #4666.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
2026-03-02 22:35:47 +00:00
Nicholas Bishop 069c6f4447 Refactor TryEvaluateMacroToConstant to simplify and dedup code (#6820)
For integral and float types, `TryEvaluateMacroToConstant` now calls
`MapAPValueToConstant` to directly convert from an APValue, rather than
converting the `APValue` to an expression and importing it with
`MapConstant`.

`MapConstant` is still used, but only for string literals and nullptrs.
Since it's only used by `TryEvaluateMacroToConstant`, moved it to
`macros.cpp` and removed the code for other types of expressions.
2026-03-02 21:00:07 +00:00
Dana Jansens 6359e3f550 Dedupe self values in identify facet type (#6819)
The self value can be a facet-value or a facet-value-as-type. The self
value used in `require` decls is the former. The the self value used for
identifying the facet type is the latter, we end up with two different
required interfaces in the identified facet type: one for each self
value.

Always canonicalize the self value to a facet value in identification.
Then dedupe the list of extend interfaces when constructing the
`IdentifiedFacetType` before counting them. And then impl lookup needs
to canonicalize its query self for comparing with the result from the
`IdentifiedFacetType`.
2026-03-02 19:09:10 +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
Nicholas Bishop 2389590230 Support pointer template params (#6810)
https://github.com/carbon-language/carbon-lang/issues/6717
2026-03-02 16:07:23 +00:00
dependabot[bot] ef0bb898ac Bump minimatch from 3.1.3 to 3.1.5 in /utils/vscode in the npm_and_yarn group across 1 directory (#6818)
Bumps the npm_and_yarn group with 1 update in the /utils/vscode
directory: [minimatch](https://github.com/isaacs/minimatch).

Updates `minimatch` from 3.1.3 to 3.1.5
-
[Changelog](https://github.com/isaacs/minimatch/blob/main/changelog.md)
- [Commits](https://github.com/isaacs/minimatch/compare/v3.1.3...v3.1.5)

---
updated-dependencies:
- dependency-name: minimatch
  dependency-version: 3.1.5
  dependency-type: indirect
  dependency-group: npm_and_yarn
...

Signed-off-by: dependabot[bot] <support@github.com>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-03-02 15:08:58 +00:00
Özgür 067378ba37 Fix syntax errors in docs observe examples (#6813) 2026-02-27 23:07:24 +00:00
Geoff Romer 34764d0d0e Fix issues from #6745 (#6811)
- Typo in the definition of `Core.Form`
- Resolved TODO to add test coverage
- Restored lexicographic order in a switch
2026-02-27 22:47:00 +00:00
Nicholas Bishop 3b49b51956 Support bool template params (#6808)
https://github.com/carbon-language/carbon-lang/issues/6717
2026-02-27 19:22:08 +00:00
Jon Ross-Perkins 93faac45af Mark mangled enclosed entities (#6809)
This overlapped a little with `Destroy` work; adding the `:enclosed`
identifier (similar to `:thunk`) just to make it easier to identify. I
believe the TODO still applies.

Assisted-by: Google Antigravity with Gemini 3 Flash
2026-02-27 19:05:10 +00:00
Dana Jansens cea52ad2d8 Format the InterfaceWithSelf and NamedConstraintWithSelf generic name with its ".WithSelf" suffix (#6798)
We used the ".WithSelf" suffix when formatting a parent scope, but
missed the suffix when formatting the scope name on its own.
2026-02-27 13:50:56 +00:00
Richard SmithandDavid Blaikie d5ec82e7ac Don't crash if clang setup fails. (#6804)
Defer creating the CppContext until we have all of its components, so
that we know they're not null. Don't track the action on the context,
since it's not a reliable way of getting back to the compiler invocation
on failure. Don't flush the diagnostics emitter from the emitter
destructor since the derived class emitter will already have been
destroyed at that point. Distinguish between clang setup failing and
clang merely producing errors, and don't connect the check context to
clang if clang setup failed.

---------

Co-authored-by: David Blaikie <dblaikie@gmail.com>
2026-02-27 02:44:08 +00:00
Nicholas Bishop a6a0e55167 Support float template params (#6801)
https://github.com/carbon-language/carbon-lang/issues/6717
2026-02-27 01:30:40 +00:00
Richard Smith 41dd256d56 Support for initialization of classes with abstract base classes. (#6802)
When initializing `.base` in class initialization, use `partial Base` as
the destination type rather than `Base`. Treat `partial Base` as not
being abstract even when `Base` is.

Allow conversion from a `partial T` initializer to a `T` initializer.
Store the vptr while performing the conversion. Do not store the vptr
when performing a `partial T` initialization, only when performing a
non-partial `T` initialization.
2026-02-27 01:27:25 +00:00
Richard Smith be88dfd744 Formatter: don't crash on unexpected SemIR. (#6787)
The formatter is used as a debugging tool, so shouldn't crash if the
SemIR is in an unexpected shape.
2026-02-27 01:02:53 +00:00
Richard Smith b83dcd4348 Fix backtrace symbolization. (#6803)
We previously set `LLVM_SYMBOLIZER_PATH` to a bogus path ending
`.../binllvm-symbolizer`. Because this var was set, LLVM's symbolizer
lookup would also skip looking in `$PATH`, so this was causing
symbolization to never happen unless `LLVM_SYMBOLIZER_PATH` was
explicitly set in the environment.
2026-02-26 23:15:04 +00:00
bf9219d30e Check support for form literals and :? bindings (#6747)
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
2026-02-26 23:01:24 +00:00
Richard Smith f9ab963bd6 Add a type_literal instruction to represent syntactic type literals. (#6781)
This allows us to capture the location at which a type literal was used,
even in the cases where we don't otherwise need to create a new
instruction to represent the type such as for `char` or `str`.

The logic used to build the underlying type is now marked as desugaring.
For cases such as `iN`, this causes the call to `Core.Int` to no longer
be added as a dedicated IR instruction, and instead its constant value
is used directly as the value of the `type_literal`. This results in
this being on balance a reduction in the size of the IR.

This also fixes a crash in C++ interop when using a `char` literal as a
template argument. The crash was caused by the template argument not
having an associated location when mapping to a C++ location. See
changes to check/testdata/interop/cpp/template/type_param.carbon for an
example that used to crash before this change.

Update alias handling to allow an alias to point at any type literal,
reinstating support for aliases for type literals such as `bool` and
`i32` that had previously worked but stopped working when we
transitioned those types to being defined in the prelude. See changes to
toolchain/check/testdata/alias/builtins.carbon.

All the test changes other than the two mentioned above are mechanical
autoupdate changes switching to the new instruction.
2026-02-26 20:10:50 +00:00
Nicholas Bishop 96f163f114 Support floats in MapAPValueToConstant (#6800)
This allows `constexpr float` to be properly imported as a constant.
2026-02-26 19:48:19 +00:00
Özgür d11ee4b2b1 Implement parsing observe declarations (#6674)
This implements parsing of the
[`observe`](https://docs.carbon-lang.dev/docs/design/generics/details.html#observing-a-type-implements-an-interface)
declarations.

- Added states and node kinds.
- Added node categories.
- Added a diagnostic for invalid keywords/operators.
- Implemented parser state handlers.
- Added structs to `typed_nodes.h`.
- Added parser tests.
2026-02-26 19:21:19 +00:00
Jon Ross-Perkins 34651f429f Clean up some of the TODOs in unused.carbon (#6794)
Fixes ordering (using DIAGNOSTIC_ON_SCOPE). Removes an obsolete TODO to
add an error that's adjacent to the indicated error.

Also moves the file to patterns: it was the only file in `dataflow`, and
patterns also contains the related underscore binding tests.

Assisted-by: Google Antigravity with Gemini 3 Flash
2026-02-26 18:57:15 +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-PerkinsandChandler Carruth 17897bb05d Add transient error retries to bazel integration tests (#6796)
e.g. for failures like
https://github.com/carbon-language/carbon-lang/actions/runs/22418738440/job/64911093548

We work around this similarly in run_bazel.py already; this is mirroring
over some of the logic (sharing would require work on Python's set up).

Assisted-by: Google Antigravity with Gemini 3 Flash

---------

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2026-02-26 17:36:51 +00:00
Ivana Ivanovska d9570b4d37 Carbon/C++ Interop: Importing C/C++ object-like macros (#6676)
A proposal for importing C/C++ object-like macros into Carbon.

Based on the design doc: [Carbon: C++ interop for C/C++ object-like
macros](https://docs.google.com/document/d/1CCB05gi3uHfDAXUy6DvOHxsn0spXcSrL_2Ye9QOSwrs/edit?tab=t.0).

Part of https://github.com/carbon-language/carbon-lang/issues/6303
2026-02-26 01:07:58 +00:00
Jon Ross-Perkins 3163af2563 Prevent CARBON_DIAGNOSTIC_ON_SCOPE from use with notes (#6795)
Just a small validation, to avoid irrelevant uses.

Assisted-by: Google Antigravity with Gemini 3 Flash
2026-02-25 23:42:32 +00:00
Jon Ross-Perkins 3df256cfa9 Rewrite the FormatterChunks API (#6784)
This is a refactoring change with no output changes.

The chunk logic already separates the concepts of "nodes with children"
and "nodes with content" in practice, but it's not obvious in the API.
This rewrites the logic to make the separation clearer.

This also subtly takes advantage of the API to avoid creating lots of
empty chunks... Right now, there's always an empty chunk between two
tentative chunks. With this change, it lazily creates a chunk only when
`out()` is used (which it often isn't), which should substantially
reduce the number of chunks created.
2026-02-25 23:18:09 +00:00
Richard Smith c5931a036d Add subdirectories for some of the check class tests (#6790)
We had around a hundred files in check/testdata/class. Move some of them
to subdirectories to make them a bit more manageable. This still leaves
nearly 50 unorganized test files, but it's at least an improvement.
2026-02-25 22:05:02 +00:00
Jon Ross-PerkinsandDana Jansens c6bc033af8 Add a SemIR scope for generated entities (#6792)
This currently doesn't include much, but we expect to be generating more
entities, such as `Destroy`, which I'm aiming to get more clearly
categorized here instead of `imports`.

Assisted-by: Google Antigravity with Gemini 3 Flash

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
2026-02-25 22:00:59 +00:00
Dana Jansens af368dbadd Add a test that shouldnt diagnose identify during deduce (#6782) 2026-02-25 21:04:08 +00:00
Nicholas Bishop 157de6e370 Support dependent non-type template parameters (#6791)
https://github.com/carbon-language/carbon-lang/issues/6717
2026-02-25 20:50:04 +00:00
Dana Jansens 142596b49c Diagnose unidentified type-of-self in impl lookup query (#6769)
The type of the query self is looked into for a witness, but that type
may be unable to be identified. For example when the query is against
`Self` inside the declaration of a named constraint. Before this PR, we
would crash when identification failed. Now we produce a diagnostic.

This makes `RequireIdentifiedFacetType` take a `ContextScope` callback
(like it used to with an `AnnotationScope` callback) since all callers
now expect to handle diagnostics, and can provide useful context.

This is a followup to #6761.
2026-02-25 20:23:21 +00:00
Dana Jansens fbc8d59d32 Introduce Diagnostics::ContextScope and remove diagnoser callbacks in type completion (#6761)
Introduces `Context` and `SoftContext` messages, which can be introduced
through a `ContextBuilder`:
- The `Context` messages come before the diagnostic in the output.
- The first `Context` message steals the diagnostic level from the main
diagnostic, and turns the main diagnostic into a Note attached to the
context.
- A `SoftContext` message works similarly, but if it's preceeded by a
`Context` or `SoftContext` message, then it is dropped. This can be used
as a default/backup scope when nothing more interesting is provided up
the stack, such as in `TryEvalBlockForSpecific`.

The `ContextBuilder` is provided to a callback through
`Diagnostics::ContextScope`, an RAII type `AnnotationScope` but for
context messages.

This allows a high level operation to provide a context message like
"failed to identify facet type {0}" which will then be used as the error
if a diagnostic is produced during identification, with the latter
diagnostic attached as a note to explain why the contextual operation
failed.

In particular, this allows monomorphization errors (such as an array
bound being negative) to be attached to a higher lever operation instead
of being top-level diagnostics themselves, with the monomorphization
site being a note. This inverts the source code locations that appear in
the diagnostic, so that the top-level diagnostic points to the "user
code" which causes the monomorphization.

This is presented as an alternative strategy to #6753, which plumbed
diagnoser callbacks around to achieve the same goals.

We replace the diagnoser callbacks in type completion and operators with
ContextScope callbacks instead, which now provide better diagnostics for
monomorphization errors. Other callers to MakeSpecific do not yet have
ContextScopes introduced in order to turn monomorphization errors into
more interesting diagnostics.
2026-02-25 15:15:29 +00:00
Jon Ross-Perkins e2bdbe8507 Make semir scope labels only print when non-empty (#6780)
This shifts logic a little so that empty top-level scopes are printed
less often. This affects imports mainly for now, but should be expected
to affect the soon-to-be-added generated scope more significantly.

Assisted-by: Google Antigravity with Gemini 3 Flash
2026-02-25 00:28:59 +00:00
dependabot[bot] c46cd65bd0 Bump minimatch from 3.1.2 to 3.1.3 in /utils/vscode in the npm_and_yarn group across 1 directory (#6788)
Bumps the npm_and_yarn group with 1 update in the /utils/vscode
directory: [minimatch](https://github.com/isaacs/minimatch).

Updates `minimatch` from 3.1.2 to 3.1.3
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/isaacs/minimatch/commit/00c323b188b704e5d4bc534ecec2268cfa70a32a"><code>00c323b</code></a>
3.1.3</li>
<li><a
href="https://github.com/isaacs/minimatch/commit/30486b2048929264f44d18822891cfffa02af78b"><code>30486b2</code></a>
update CI matrix and actions</li>
<li><a
href="https://github.com/isaacs/minimatch/commit/9c31b2d4e0af72a6c2d2d62c5dbc2247da669802"><code>9c31b2d</code></a>
update test expectations for coalesced consecutive stars</li>
<li><a
href="https://github.com/isaacs/minimatch/commit/46fe687857cf02f6cf45469cc593b97e11b10c96"><code>46fe687</code></a>
coalesce consecutive non-globstar * characters</li>
<li><a
href="https://github.com/isaacs/minimatch/commit/5a9ccbda64befc5d94b965534dbea2853c92aebd"><code>5a9ccbd</code></a>
[meta] update publishConfig.tag to legacy-v3</li>
<li>See full diff in <a
href="https://github.com/isaacs/minimatch/compare/v3.1.2...v3.1.3">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=minimatch&package-manager=npm_and_yarn&previous-version=3.1.2&new-version=3.1.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/carbon-language/carbon-lang/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-24 23:44:29 +00:00
Nicholas Bishop f210f4ab04 Add initial support for importing C++ constexprs as Carbon constants (#6770)
This allows a C++ constexpr to be used as an argument to a non-type
template parameter.

https://github.com/carbon-language/carbon-lang/issues/6717
2026-02-24 20:59:24 +00:00
Jon Ross-Perkins 1a3f762dba Factor out FormatterChunks logic (#6779)
I'm looking at making `constants { ... }` etc omitted when empty,
because in turn I'm looking at adding a third section, and seeing more
boilerplate empty sections just seems awkward to me. This PR starts down
the path by factoring out the chunk logic, which I may want to refactor
further.

This changes the `size_t` chunk id into a wrapped type for type safety.

This PR is just a refactoring, and doesn't make any behavior changes.

Assisted-by: Google Antigravity with Gemini 3 Flash
2026-02-24 19:07:31 +00:00
little KitchenandRichard Smith 8edd5eb9a1 fix: reject {} initialization for non-aggregate C++ classes (#6675)
## Summary

Fixes the toolchain incorrectly allowing `{}` initialization for
non-aggregate C++ classes.

## Problem

When importing an empty C++ class, the toolchain was treating it as a
Carbon empty struct, which allowed initialization from `{}`. This is
incorrect for non-aggregate classes (e.g., those with user-declared
constructors).

```carbon
import Cpp inline '''
struct X { X(); };  // non-aggregate (has user-declared constructor)
''';

fn Make() {
  var x: Cpp.X = {};  // incorrectly accepted, should be rejected
}
```

## Solution

Added a check for `clang_def->isAggregate()` in `ImportClassObjectRepr`
so that only aggregate classes get the empty struct representation.

**Before:**
```cpp
if (clang_def->isEmpty() && !clang_def->getNumBases()) {
```

**After:**
```cpp
if (clang_def->isEmpty() && !clang_def->getNumBases() &&
    clang_def->isAggregate()) {
```

## Testing

Added test file
`toolchain/check/testdata/interop/cpp/class/non_aggregate_init.carbon`
with:
- Non-aggregate class (`struct X { X(); }`) - should reject `{}`
initialization
- Aggregate class (`struct Y {}`) - should accept `{}` initialization

Note: I couldn't run tests locally due to clang version requirements
(needs >= 19, have 17). The CI should validate the changes.

Closes #6669

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2026-02-24 18:19:50 +00:00
Jon Ross-Perkins 9915e155a3 Replace clang version with regex (#6778)
Also replace some `.*`'s that seem like they should stay non-empty with
`.+`.

Assisted-by: Google Antigravity with Gemini 3 Flash
2026-02-24 00:38:27 +00:00
Geoff Romer 4a0cf6c1fb Track the start of a signature more accurately (#6760)
This change ensures that a function signature always starts with an
`IdentifierNameMaybeBeforeSignature` node (renamed from
`IdentifierNameBeforeParams`), even in the case of function declarations
like `fn F -> T` that have no parameter list. As a consequence, this
ensures that we push new entries onto `pattern_block_stack` and
`full_pattern_stack` when we start processing the function signature.
2026-02-23 22:46:03 +00:00
Chandler Carruth 375a736c42 Update LLVM to a more recent commit (#6771)
This includes the major version bump and some changes to output in
various tests.
2026-02-23 20:30:55 +00:00
Nicholas Bishop 393e6e4f9a Fix typos in eval_inst.h (#6775) 2026-02-23 16:48:23 +00:00
Roopesh SandRichard Smith 41f47c0e87 Fix crash on generic call to local function (#6671) (#6679)
## Summary
- Avoid crash in `MangleInverseQualifiedNameScope` by skipping missing
name scopes (local functions have no parent scope).
- Add regression test:
toolchain/lower/testdata/function/generic/local_function.carbon.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2026-02-20 22:16:18 +00:00
Chandler CarruthandRichard Smith c3eb393c6a Split build information for CRT into Starlark (#6765)
This isn't as interesting as others, as it only involves compile
options.

It also adds a missing flag of `-fno-lto` as these objects can't be
LTO-ed.

---------

Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2026-02-20 10:35:53 +00:00
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
Richard Smith bea24a8bee Never ask the mangler to mangle a C++ declaration. (#6764)
This cleans up some logic that was left behind when we stopped emitting
C++ function declarations ourselves. We would ask our mangler for a
mangling for a C++ function declaration and then not use it.
2026-02-19 21:56:28 +00:00
Dana Jansens e991657e1d Use the canonical instructions to get SpecificIds in GetCallee (#6726)
GetCallee returns a structure with SpecificIds in it, and then those
specifics are used to later get constant values. This is fine when those
specifics are canonical, but it's problematic when they are not, because
non-canonical specifics (from a generic eval block) do not ever have any
resolved decl/defn blocks.

Formatting in particular works with non-canonical instructions when it
formats a generic eval block. We want to be able to format the block,
but those specifics are not useful for constant value mapping/lookup.
GetCallee grabs (non-canonical) instruction ids out of other
instructions. When getting a SpecificId out of an instruction, it should
map that instruction to the canonical value first. This means the
specific will be resolved and can be used for constant value mapping
later.

Fixes #6677
2026-02-19 20:36:35 +00:00
Geoff Romer 6a3529f4b5 Add Core.Form to prelude (#6745)
Unfortunately, currently it has to be a function rather than a constant.
2026-02-19 19:26:56 +00:00
Chandler CarruthandJon Ross-Perkins e00394ea92 Teach the link subcommand to accept Clang-style LDFLAGS (#6741)
Add an optional additional set of positional parameters that can be
passed to the `link` subcommand for Clang-style (or GCC-style)
`LDFLAGS`. These can _also_ contain object files, etc., and in fact it
is useful to allow them to contain object files in order to integrate
the `carbon link` subcommand into a build system that mixes both link
flags and object files. This at least happens with Bazel, and I suspect
is common.

Eventually, it would be nice to have sufficient semantics to handle all
the varieties of links we want without resorting to this escape hatch,
but that's likely a long way away and so it seems especially useful to
allow falling back to Clang's flags as needed for now.

This does somewhat directly surface the Clang implementation detail in
the command line syntax, but I don't see a lot of good alternatives.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2026-02-19 17:00:40 +00:00
Dana Jansens 46fb941b3c Don't create ErrorInst in Convert without producing a diagnostic (#6762)
While convert has the option to avoid diagnostics, when that flag is
false, ErrorInst results must also produce a diagnostic. Otherwise we
end up with errors in the semir but not error provided to the user.

The new diagnostics reveal that a number of tests for abstract types
were passing incorrectly. They had errors in the semir but no
diagnostics. A TODO is added in convert to allow an abstract conversion
target type when not initializing.
2026-02-19 16:36:57 +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
Chandler Carruth e5b094fdad Start moving runtimes building logic into Starlark (#6701)
The goal here is to be able to construct a build of the runtimes
directly in Bazel, or by emitting `BUILD` files, or by emitting into C++
code and using that on-demand. For that, we want a single source of
truth, and that source in Starlark.

This should also make the information more generally useful, and so I'm
moving as much as I can into the LLVM Bazel build. Apologies as that
makes the diffs extra annoying.

I do plan on upstreaming the Bazel parts of this, but would like to get
everything working in Carbon and stabilized first.

While here, I've also made a change suggested for the future in the
initial review by lifting the C++ template out of a string literal in
the `.bzl` file, and into an actual separate C++ file.

This only moves libc++, libc++abi, and libunwind. I want to get those
three working end-to-end before I work on the builtins or `crtbegin` and
`crtend`, as those have a bunch of additional complexity.

This also only uses the info in the C++ on-demand build. It seemed like
a reasonable increment to start code review, and my plan is to work on
other build strategies in a follow-up PR. If that doesn't work, let me
know and I'll come back once I have at least a second use of the info
here.
2026-02-19 07:47:56 +00:00
Prabhat Sachdeva a5a4c756a7 Only treat top-level Run in Main as the entry point (#6757)
Fix IsEntryPoint to only recognize `Run` as the program entry point when
it is declared at package scope in the `Main` package, not when it
appears inside a namespace or via C++ interop.

Closes #6755
2026-02-18 22:17:15 +00:00
Chandler Carruth 82e4c3a8af Add response file expansion to the busybox and improve -Xcarbon (#6750)
When the response file contains the subcommand itself, or when there are
`-Xcarbon` flags within the response file that we need to re-organize,
we need to hoist the expansion into the busybox itself.

I've left the response file expansion in the `ClangRunner` so that
library users can still use them, including in the VFS of the runner.

It's also useful to handle `-Xcarbon`-style flags even when using
subcommands rather than a symlink to the busybox: build systems often
have a facility to append flags, but appending doesn't let us inject
flags easily into the `carbon` driver itself. So this PR moves the
`-Xcarbon` reorganization to happen in all cases, and to insert them
before the first subcommand or positional parameter. When teaching Bazel
to link by running `carbon link ...` commands, this lets us do things
like `bazel build --linkopt=-Xcarbon=-v` to enable verbose logging.

I've not added a test here as we don't really have much testing of the
busybox. I can move the current symlinks test to be more of an
integration test of the busybox logic if desired, but would be a
somewhat larger change and maybe worth separating out. This will end up
tested in the Bazel example in a subsequent PR that starts using it in
the installed crosstool configuration.
2026-02-18 13:39:23 +00:00
Richard Smith 108277c3f3 Support if expressions in eval fn. (#6725)
Add support for `BranchWithArg` and `BlockArg` during compile-time
function execution. We only track the most recent block arg value for
now, because that's all we need -- we never look at a block argument for
any block other than the current one.

Also refactor `FunctionExecContext` to better encapsulate the blocks
list.
2026-02-18 13:32:45 +00:00
Richard Smith 768582d8d3 Propagate some target options from Clang to Carbon's target. (#6759)
Turn a few section options on by default in Clang's options, and
propagate the setting from Clang to Carbon. These settings can't be
different between the two sides of the compilation, so merging the
behavior of Carbon's defaults and Clang's flags seems best.
2026-02-18 03:14:31 +00:00
Jon Ross-Perkins de3147ce3e Note issue on C++ fingerprint TODO (#6758)
Link: #6728
2026-02-18 00:14:14 +00:00
Richard Smith 2cee87683e Allow more signatures for Main.Run. (#6751)
Allow an argc parameter and an argv parameter to be passed. For now we
check that argc is an i32 and argv is a pointer. The rules here are not
yet decided -- see #6735 -- but we should at least allow C-style access
to argv for now in order to unblock experimentation.
2026-02-18 00:06:04 +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
Geoff Romer 8a8dd01302 Correct stray instance of "value binding" to new terminology. (#6754) 2026-02-17 20:48:08 +00:00
Geoff Romer f21e0e17ac Introduce ExprCategory::Dependent (#6744)
This is needed to model things like the category of `x` in the body of
`fn Foo(F:! Core.Form, x:? F)`, where the category of `x` is determined
by the concrete value of `F` (see #5389 for the design of `:?`
bindings).

This will be used in a follow-up PR.
2026-02-17 20:28:15 +00:00
Geoff Romer f1b6e818d1 Rename FormExpr fields for clarity/consistency. (#6746) 2026-02-17 17:10:35 +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
dependabot[bot] 0300d35cf6 Bump qs from 6.14.1 to 6.14.2 in /utils/vscode in the npm_and_yarn group across 1 directory (#6749)
Bumps the npm_and_yarn group with 1 update in the /utils/vscode
directory: [qs](https://github.com/ljharb/qs).

Updates `qs` from 6.14.1 to 6.14.2
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/ljharb/qs/blob/main/CHANGELOG.md">qs's
changelog</a>.</em></p>
<blockquote>
<h2><strong>6.14.2</strong></h2>
<ul>
<li>[Fix] <code>parse</code>: mark overflow objects for indexed notation
exceeding <code>arrayLimit</code> (<a
href="https://redirect.github.com/ljharb/qs/issues/546">#546</a>)</li>
<li>[Fix] <code>arrayLimit</code> means max count, not max index, in
<code>combine</code>/<code>merge</code>/<code>parseArrayValue</code></li>
<li>[Fix] <code>parse</code>: throw on <code>arrayLimit</code> exceeded
with indexed notation when <code>throwOnLimitExceeded</code> is true (<a
href="https://redirect.github.com/ljharb/qs/issues/529">#529</a>)</li>
<li>[Fix] <code>parse</code>: enforce <code>arrayLimit</code> on
<code>comma</code>-parsed values</li>
<li>[Fix] <code>parse</code>: fix error message to reflect arrayLimit as
max index; remove extraneous comments (<a
href="https://redirect.github.com/ljharb/qs/issues/545">#545</a>)</li>
<li>[Robustness] avoid <code>.push</code>, use <code>void</code></li>
<li>[readme] document that <code>addQueryPrefix</code> does not add
<code>?</code> to empty output (<a
href="https://redirect.github.com/ljharb/qs/issues/418">#418</a>)</li>
<li>[readme] clarify <code>parseArrays</code> and
<code>arrayLimit</code> documentation (<a
href="https://redirect.github.com/ljharb/qs/issues/543">#543</a>)</li>
<li>[readme] replace runkit CI badge with shields.io check-runs
badge</li>
<li>[meta] fix changelog typo (<code>arrayLength</code> →
<code>arrayLimit</code>)</li>
<li>[actions] fix rebase workflow permissions</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/ljharb/qs/commit/bdcf0c7f82387c18ac8fabfccd2f440645cef47b"><code>bdcf0c7</code></a>
v6.14.2</li>
<li><a
href="https://github.com/ljharb/qs/commit/294db90c812ddbe7d7a35d5687c505fd21a2d6a2"><code>294db90</code></a>
[readme] document that <code>addQueryPrefix</code> does not add
<code>?</code> to empty output</li>
<li><a
href="https://github.com/ljharb/qs/commit/5c308e5516c270a78caa6f278465914090f91ec6"><code>5c308e5</code></a>
[readme] clarify <code>parseArrays</code> and <code>arrayLimit</code>
documentation</li>
<li><a
href="https://github.com/ljharb/qs/commit/6addf8cf738d529c54d91f6f3ffb6c1be91bbfdc"><code>6addf8c</code></a>
[Fix] <code>parse</code>: mark overflow objects for indexed notation
exceeding <code>arrayLimit</code></li>
<li><a
href="https://github.com/ljharb/qs/commit/cfc108f662326d6ab540f3545ef0b832baf83cdf"><code>cfc108f</code></a>
[Fix] <code>arrayLimit</code> means max count, not max index, in
<code>combine</code>/<code>merge</code>/`pars...</li>
<li><a
href="https://github.com/ljharb/qs/commit/febb64442a80e49200211fa38d3c96b58024ac77"><code>febb644</code></a>
[Fix] <code>parse</code>: throw on <code>arrayLimit</code> exceeded with
indexed notation when `thr...</li>
<li><a
href="https://github.com/ljharb/qs/commit/f6a7abff1f13d644db9b05fe4f2c98ada6bf8482"><code>f6a7abf</code></a>
[Fix] <code>parse</code>: enforce <code>arrayLimit</code> on
<code>comma</code>-parsed values</li>
<li><a
href="https://github.com/ljharb/qs/commit/fbc5206c25b4d1851cea683f02c10756c521d15a"><code>fbc5206</code></a>
[Fix] <code>parse</code>: fix error message to reflect arrayLimit as max
index; remove e...</li>
<li><a
href="https://github.com/ljharb/qs/commit/1b9a8b4e78c6aff4c22fa559107227f02fd0216a"><code>1b9a8b4</code></a>
[actions] fix rebase workflow permissions</li>
<li><a
href="https://github.com/ljharb/qs/commit/2a35775614e0fb46ac8a3060201a32a7c23a7fda"><code>2a35775</code></a>
[meta] fix changelog typo (<code>arrayLength</code> →
<code>arrayLimit</code>)</li>
<li>Additional commits viewable in <a
href="https://github.com/ljharb/qs/compare/v6.14.1...v6.14.2">compare
view</a></li>
</ul>
</details>
<br />


[![Dependabot compatibility
score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=qs&package-manager=npm_and_yarn&previous-version=6.14.1&new-version=6.14.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)

Dependabot will resolve any conflicts with this PR as long as you don't
alter it yourself. You can also trigger a rebase manually by commenting
`@dependabot rebase`.

[//]: # (dependabot-automerge-start)
[//]: # (dependabot-automerge-end)

---

<details>
<summary>Dependabot commands and options</summary>
<br />

You can trigger Dependabot actions by commenting on this PR:
- `@dependabot rebase` will rebase this PR
- `@dependabot recreate` will recreate this PR, overwriting any edits
that have been made to it
- `@dependabot show <dependency name> ignore conditions` will show all
of the ignore conditions of the specified dependency
- `@dependabot ignore <dependency name> major version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's major version (unless you unignore this specific
dependency's major version or upgrade to it yourself)
- `@dependabot ignore <dependency name> minor version` will close this
group update PR and stop Dependabot creating any more for the specific
dependency's minor version (unless you unignore this specific
dependency's minor version or upgrade to it yourself)
- `@dependabot ignore <dependency name>` will close this group update PR
and stop Dependabot creating any more for the specific dependency
(unless you unignore this specific dependency or upgrade to it yourself)
- `@dependabot unignore <dependency name>` will remove all of the ignore
conditions of the specified dependency
- `@dependabot unignore <dependency name> <ignore condition>` will
remove the ignore condition of the specified dependency and ignore
conditions
You can disable automated security fix PRs for this repo from the
[Security Alerts
page](https://github.com/carbon-language/carbon-lang/network/alerts).

</details>

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
2026-02-16 22:45:34 +00:00
Richard Smith 773837e1bb Ask Clang to emit C++ global variables. (#6748)
Don't emit them ourselves. This was leading to our emitted variable
being renamed away from the proper symbol name, leading to link errors.

Fixes #6742.
2026-02-14 03:07:48 +00:00
Geoff RomerandChandler Carruth f289592dfa Clarify and partially enforce inst-order precondition on splicing (#6722)
Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2026-02-14 01:40:51 +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 b3d57aff7a Diagnose if a NodeIdOneOf argument isn't a typed node. (#6738) 2026-02-13 22:44:23 +00:00
Geoff Romer 3c324e4877 Add category to parameter format, and share some code. (#6730) 2026-02-13 22:20:05 +00:00
611aba3cc2 Clang IRGen in Carbon (#6641)
Clang performs the equivalent of Carbon's `lower` progressively,
interleaved with parsing/semantic analysis. This is in conflict with
Carbon's phase-based approach and leads to bugs in missing functionality
in Clang's generated IR during Carbon/C++ interop.

I surveyed other uses of Clang's APIs (originally written up in
[this](https://docs.google.com/document/d/1wi85FRiWh4X9A-gCYMVGKR40-q5fM6-3JaSpePk-XCY/edit?tab=t.0#heading=h.j7j8nwhzao5n)
doc - though the contents in this proposal are now more complete than
the doc) to better understand how Clang's constraints might effect
projects and how they've addressed them. In the mean time, Carbon
changes made more stable approaches viable that were eventually
implemented in #6569.

This proposal then aims to formalize the analysis that lead to #6569 for
posterity in case these design decisions need to be revisited in the
future.

---------

Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2026-02-13 21:48:10 +00:00
Geoff Romer 1c885a629e Format FormType as "Core.Form" (#6734) 2026-02-13 19:44:21 +00:00
Dana Jansens 9a90f19c60 Add two tests for how a non-self require decl in an interface connects (#6737)
A non-self require decl in an interface does not mean that a type
implementing that interface also implements the required interface. But
it does mean that whatever the self-type is will implement the required
interface.
2026-02-13 18:47:48 +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
ÖzgürandDana Jansens 2184663511 Improve vscode syntax highlighting (#6543)
This PR improves the vscode syntax highlighting.

- Added `comment` keys.
- Added highlighting of invalid numbers such as `0x`, `0b`, `0xa`, etc.
- Restricted highlighting of numeric type literals to common types to
avoid highlighting identifiers such as `i1`.
- Changed the highlighting of named operators (e.g., `as`).
- Added `char` and `str` to type literals.
- Added `const` to modifier keywords.
- Removed `addr` keyword.
- Refactored some rules to use `begin`/`end` to handle line breaks.
- Added highlighting to `choice` values as `enum` values.
- Updated the rules for matching `types`.
- Added highlighting to rhs of `adapt`, `alias`, `choice`, `constraint`,
`impl`, `interface`, `as`, and `impls`.
    - Added highlighting to rhs of bindings.
    - Added highlighting to function return types.
- Updated the rules for matching `functions`.
- Updated the rules for matching `variables`.
- Added highlighting unidentified words as `variable`. 
- Added examples and before/after screenshots.

| Before | After |
| :---: | :---: |
| <img width="424" alt="before"
src="https://github.com/user-attachments/assets/e84d0ff9-237b-40c2-845b-ec550b8f7bea">
| <img width="431" alt="now"
src="https://github.com/user-attachments/assets/2c18640b-318a-4cd5-952c-bad61d3fdbca">
|

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
2026-02-13 16:50:18 +00:00
Chandler CarruthandJon Ross-Perkins b267ec85cf Reduce ../ traversal in busybox logic (#6721)
This removes support for strange symlink structures _within_ an
install-shaped tree, but AFAIK, that is not one of the (frustratingly
many) cases where we need them. Avoiding this significantly shortens and
reduces repetition in the commandline formed by the busybox, and also
appears to work better when running the busybox from inside a Bazel
checkout.

The motivation here is to fix issues that arose when more heavily using
the installed toolchain with the example Bazel project. As more of that
functionality lands, this should also be tested there.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2026-02-13 09:29:19 +00:00
Geoff Romer 7f29436d4e Restore the name of GetCompileTimeBindValue. (#6733)
It had been renamed to GetCompileTimeAcquireValue in #6281 due to an
overzealous find/replace.
2026-02-13 00:54:23 +00:00
Jon Ross-PerkinsandChandler Carruth d39fdfcfad char redesign (#6710)
- Add a `char` type literal mapping to `Core.Char` and equivalent to
C++'s
    `char`.
    -   8 bits, unsigned, treated as a single UTF-8
[code unit](https://en.wikipedia.org/wiki/Character_encoding#Code_unit).
-   Add a `Core.CharLiteral` type for character literals, similar to
    `Core.IntLiteral`.
- Allow operations for `char` and `Core.CharLiteral` which reinforce the
    "character" concept, versus an integer value.
-   Revokes and replaces
[#1964: Character
Literals](https://github.com/carbon-language/carbon-lang/pull/1964).

Assisted-by: Google Antigravity with Gemini 3 Flash

---------

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2026-02-12 16:56:09 +00:00
Geoff Romer 3719d200d6 Drop redundant parameter from ConsumeAndAddCloseSymbol (#6724) 2026-02-12 01:56:15 +00:00
Jon Ross-Perkins 320096da67 Rename import functions as Import instead of Make/Add (#6723)
This was motivated by `MakeFunctionDecl`, which has been added to
function.h as a helper function for making function declarations (an
unintentional naming collision).

I was wondering about renaming these functions to mark them as more
clearly import-specific, reducing the chance of name collisions like
this. Note the `Add` functions renamed here are typically updating an
imported declaration with a definition -- not sure whether `Make...Decl`
+ `Add...Definition` vs `Import...Decl` + `Import...Definition` is
actually losing anything though, since both seem to still require an
understanding of the two-stage import process.

Assisted-by: Google Antigravity with Gemini 3 Flash
2026-02-11 20:32:12 +00:00
Jon Ross-PerkinsandGeoff Romer e2f451dc9c Update adding features (#6719)
Trying to update obsolete mentions in the "adding features" info (this
is just a skim, I may have mistakes and/or missed items).

Assisted-by: Google Antigravity with Gemini 3 Flash

---------

Co-authored-by: Geoff Romer <gromer@google.com>
2026-02-11 19:43:12 +00:00
Chandler Carruth 8b967943d3 Move the build-runtimes option up to the top-level driver (#6720)
Multiple subcommands all need the ability to disable on-demand runtime
building, and this may be needed outside of using _prebuilt_ runtimes.
For example, with Bazel the plan is to not build runtimes at all and
have Bazel provide them as native Bazel libraries.

Updates the `link` subcommand to respect this flag when running Clang to
perform links.

We didn't have any real testing of the `link` subcommand, in part
because it was difficult -- it would try to link runtime libraries. Now
that we can prevent building them on demand, we can use that to test the
link command. That in turn helped uncover a couple of bugs that are
fixed here.

1) The `driver_env_` member of the `Driver` was re-used across
   `RunCommand` invocations. Some of its fields are constant across
   these, others can be updated, and still more are not necessarily
   something we would expect to be re-used. This fixes that by removing
   the `driver_env_` member, and replacing it with members for just the
   fields of `DriverEnv` that we want to set initially based on the
   construction of the `Driver` object. This causes multiple, sequential
   `RunCommand` calls to not clobber or erroneously inherit state.

2) The temporary directory support in the driver unittest didn't allow
   the driver to observe the things it wrote to the temporary directory.
   This PR updates the test logic to create an overlay VFS so that both
   the in-memory test inputs are observed, but so are the real files
   written into the temporary directory.

3) The Clang runner, when asked to run Clang without runtimes would
   still attempt to include runtimes in any link command. This isn't
   quite what we want, as the whole reason to use this without building
   runtimes is to reuse ones built in some other way and potentially in
   some other location. For now, this PR uses a hack to suppress these
   issues so that we can have a basic test, but in the future we'll need
   a better solution here.

4) The driver test didn't include the actual driver in the install data.
   The test even worked around this, but it makes it impossible to link
   reliably as the `lld` binary isn't available. This adds the data
   dependency and updates the test to the available digest, etc.
2026-02-11 19:16:38 +00:00
Jon Ross-Perkins 628b6c8a73 Inject IntAsSelect into example diagnostic (#6718)
Assisted-by: Google Antigravity with Gemini 3 Flash
2026-02-11 19:10:21 +00:00
Jon Ross-PerkinsandChandler Carruth 45b3f47349 Diagnostic sorting (#6699)
Change `SortingConsumer` from sorting by last processed token
(per-phase) to
additionally allow diagnostics to request sorting by start position
(line and
column) when the last processed token is the same.

Assisted-by: Google Antigravity with Gemini 3 Flash

---------

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2026-02-11 17:14:16 +00:00
Jon Ross-Perkins 13d5fe9eed Move toolchain alternatives to proposals (#6716)
As part of using the evolution process with the toolchain, alternatives
should
be in proposals. This proposal migrates existing alternatives here.

Assisted-by: Google Antigravity with Gemini 3 Flash
2026-02-11 17:10:12 +00:00
Richard Smith 1b2ae912fc Add basic support for eval fn and musteval fn. (#6694)
Add support for compile-time functions. `eval fn` is analogous to C++
`constexpr`, and is evaluated at compile time when it has compile-time
arguments. `musteval fn` is analogous to C++ `consteval`, and requires
that its arguments be available at compile time and is always evaluated
at compile time. For now we require the modifier to match across
redeclarations of the function. The specific modifier syntax here is a
placeholder and not yet part of an approved design.

Limitations: Only very basic support for evaluation is provided. So far
there's no support for mutable state or `if` expressions, but otherwise
control flow and passing and returning values should work. Carbon
evaluation recursion is modeled by C++ recursion for now, so you can
overflow the toolchain stack easily. Functions that use in-place
initialization will generally not work yet, as they are modeled as
passing a non-compile-time-constant reference to a temporary to the
call.

Add missing categorization of `name_binding_decl` as `NotExpr` to match
other similar declaration instructions like `FunctionDecl`, so that we
can uniformly skip over them when they occur within function bodies.

Assisted-by: Gemini 3 Pro and Flash via Antigravity
2026-02-11 02:08:16 +00:00
2d5e5e9692 Expression form basics (#5545)
This proposal introduces the concept of a _form_, which is a
generalization of
"type" that encompasses all of the information about an expression
that's
visible to the type system, including type and expression category.
Forms can be
composed into _tuple forms_ and _struct forms_, which lets us track the
categories of individual tuple and struct literal elements.

The proposal PR also adds `ref` bindings to the pattern matching
documentation,
but that is not part of the proposal itself; it's just bringing the
documentation
up to date with proposal
[#5434](https://github.com/carbon-language/carbon-lang/pull/5434).

---------

Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Co-authored-by: Carbon Infra Bot <carbon-external-infra@google.com>
2026-02-10 17:44:50 +00:00
Karthik Bhattar 09b9746251 Fix SIGSEGV when comparing member without self (#6707)
This fixes a crash when a member is compared without `self.`.

**Repro:**
```carbon
class Stack {
  fn Empty[self: Self]() -> bool {
    return size == 0;
  }

  var size: i32;
}
```

Prior to this change, this path crashed with a fatal in
[type_iterator.cpp](https://github.com/carbon-language/carbon-lang/blob/7938d9a8d0556498754feb12695776702984c235/toolchain/sem_ir/type_iterator.cpp)
due to an unhandled type instruction.

This was caused by `TypeIterator::ProcessTypeId` not handling
`UnboundElementType`.

**What changed:**
- Handle `UnboundElementType` in `TypeIterator::ProcessTypeId`.
- Added a regression check in
[fail_unbound_field.carbon](https://github.com/carbon-language/carbon-lang/blob/7938d9a8d0556498754feb12695776702984c235/toolchain/check/testdata/class/fail_unbound_field.carbon)
for `field == 0`.

Closes #6703
2026-02-10 00:10:33 +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
Jon Ross-Perkins 2c6d9c7f66 Rename type's GetInstId to GetTypeInstId, reflecting returned type (#6708)
Discussed briefly [on
Discord](https://discord.com/channels/655572317891461132/655578254970716160/1470442830118912265),
done to reduce confusion.

Assisted-by: Google Antigravity with Gemini 3 Flash
2026-02-09 22:00:21 +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 1382a8645a Replace convert_checked with convert in some ImplicitAs impls (#6704)
`convert_checked` is for conversions that are checked at compile time.
Since these conversions do not require a constant value they should use
`checked` instead.

(Split out from
https://github.com/carbon-language/carbon-lang/pull/6673, explanation of
convert/convert_checked derived from the [Jan 20, 2026 meeting
notes](https://docs.google.com/document/d/1YlxEOJ0r-o19o19TCJbFl4Ln1U88yn_Vj23y1Hr5vTk/edit?tab=t.tjeylv584s7j#heading=h.ih31dlc0ma58).)
2026-02-06 21:50:59 +00:00
Jon Ross-Perkins 70614da67e Add jj support to new_proposal.py (#6700)
Also scrutinizing how it runs from another directory, because that's
what I did to test these changes. Switching to the repo root is to make
it easier to just look for ".jj".

Assisted-by: Google Antigravity with Gemini 3 Flash
2026-02-06 19:53:35 +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
Jon Ross-PerkinsandIvana Ivanovska 68182ba37b C++ interop type mapping for integer and floating-point literals (#6668)
Provides bidirectional mappings for types of integer and floating-point
literals
between Carbon and C++. For example, given a literal `123`, defines the
interop
type.

Co-authored-by: Ivana Ivanovska <iivanovska@google.com>
2026-02-06 16:10:07 +00:00
Jon Ross-Perkins 1d0bf72508 Fix pluralization mismatch on compile_time_binding/s (#6696)
Assisted-by: Google Antigravity with Gemini 3 Flash
2026-02-05 23:50:35 +00:00
Jon Ross-Perkins f0e04c89c3 Share more function logic between custom/thunk/C++ functions. (#6690)
I need to do more work on the custom witness functions. This is trying
to make it easier to see the differences between the approaches before I
resume work there (e.g. this helps flag a possible reason I was having
trouble switching definitions when it came to generics, I think those
are mishandled right now).

This changes the thunk test because it was doing
`CheckFunctionDefinitionSignature` in a different order from
`handle_function.cpp`, and I think `handle_function.cpp` is more
canonical here (changing that affects tests with defined functions).

Assisted-by: Google Antigravity with Gemini 3 Flash
2026-02-05 18:44:55 +00:00
Dana Jansens 7d97389642 Add .swp vim file name to the .gitignore (#6693) 2026-02-05 16:14:40 +00:00
Geoff Romer 8efb4aa989 Resolve "DO NOT SUBMIT" comment (#6692)
Whoops.
2026-02-05 01:18:57 +00:00
Jon Ross-Perkins 45e4c71703 Add a way for diagnostics to sort on more than last_byte_offset. (#6687)
The intent is that `last_byte_offset` is still the main sorting key.
Diagnostics issued normally (e.g. in an expression) will keep sorting
the same, and come before the new diagnostic sort. Diagnostics issued at
the end of a scope (e.g. `unused`) can request sorting by their start
location, and would become interleaved through that.

Choosing "on scope" because I think that's the main way we'll use this
functionality (on scope changes); can always rename later if usage
expands.

Assisted-by: Google Antigravity with Gemini 3 Flash
2026-02-04 21:13:13 +00:00
Dana JansensandJon Ross-Perkins c860c178d4 Add 2025 conference talks to the README and note some upcoming ones in 2026 (#6689)
Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
2026-02-04 20:58:28 +00:00
Dana Jansens f63d0a6266 When re-declaring, find the original decl of an associated function in an interface (#6688)
Functions in an interface definition are wrapped in an AssociatedEntity
instruction, which the logic for finding a previous declaration must
unwrap to find the FunctionDecl.

This is controlled by the NameScope::is_interface_definition() flag,
which is true for interfaces, and causes this extra wrapping to occur
when adding the function to the scope.
2026-02-04 19:22:35 +00:00
Jon Ross-Perkins 45ca3d28f5 Drop "diagnostic" from some filenames in the "diagnostics" folder (#6686)
Mainly because "sorting_diagnostic_consumer" is legacy, since
`SortingDiagnosticConsumer` became `SortingConsumer`. Also better
reflecting contents of these files.

Where I'm not renaming, I'm less positive about dropping "diagnostics"
from "file_diagnostics" and "null_diagnostics" (which contain both a
consumer and emitter, and "null.h" seems like poor naming), so not doing
that here. Also "diagnostic.h" contains `struct Diagnostic`, so is a
decent fit.

Assisted-by: Google Antigravity with Gemini 3 Flash
2026-02-04 17:24:55 +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
Nicholas Bishop 2980e6bcbb Fix typo in CONTRIBUTING.md (#6685) 2026-02-03 20:51:43 +00:00
Jon Ross-Perkins 917ce5bd6b Fix a duplicate diagnostic on incomplete return types. (#6684)
For example, see toolchain/check/testdata/class/fail_incomplete.carbon
for the diagnostic changes. `IncompleteTypeInFunctionReturnType` should
remain, while the redundant `IncompleteTypeInFunctionParam` is removed.

Note I'm deliberately trying to validate the return type after other
parameters, because I think that's the better user experience. This does
also incrementally change IR.
2026-02-03 17:57:51 +00:00
Justin Horvitz fb05ed2447 Avoid depending on the value of --stamp if stamp = 0 is passed (#6681)
This avoids reading the value of `--stamp` when it's not necessary,
which enables some additional google-internal build caching.
2026-02-02 23:57:15 +00:00
1761 changed files with 101006 additions and 69670 deletions
+83
View File
@@ -0,0 +1,83 @@
---
name: Bazel usage
description:
Instructions for using Bazel or Bazelisk to build, test, and debug in the
Carbon repository.
---
# Bazel usage
<!--
Part of the Carbon Language project, under the Apache License v2.0 with LLVM
Exceptions. See /LICENSE for license information.
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-->
This skill documents how best to use Bazel when building, testing, or
manipulating the Carbon repository's Bazel in any way.
## Bazel wrappers
Carbon uses Bazel for its build system. To ensure consistent versions, the
project uses Bazelisk.
> [!IMPORTANT] Always use `bazelisk` whenever you want to run Bazel. Never run
> `bazel` directly in the Carbon project. Anything you want to do with `bazel`
> can be done with the `bazelisk` command instead.
- **Bazelisk**: Try to use `bazelisk` in your existing `$PATH` if available.
- **`run_bazelisk.py`**: If `bazelisk` isn't available, use
`./scripts/run_bazelisk.py` to run bazelisk without it being installed.
## Essential commands
### Building
- **Build all**: `bazelisk build //...`
- **Build toolchain**: `bazelisk build //toolchain/...`
- **Build specific target**: `bazelisk build //toolchain:carbon`
### Testing
- **Test all**: `bazelisk test //...:all`
- **Test toolchain**: `bazelisk test //toolchain/...`
- **Test examples**: `bazelisk test //examples/...`
> [!TIP] Running all of the tests can be slow, so try to narrowly test the
> immediately relevant parts of the project first, and only expand coverage as
> necessary to be confident in the changes.
> [!TIP] For specialized instructions on testing and developing the Carbon
> toolchain, consult these skills:
>
> - [Toolchain tests](/.agents/skills/toolchain_tests/SKILL.md): For
> authoring, structuring, and running `file_test` tests.
> - [Toolchain development](/.agents/skills/toolchain_development/SKILL.md):
> For architecture, essential commands, and debugging the toolchain.
### Running binaries built by Bazel
> [!IMPORTANT] Always manually run binaries built by Bazel using the
> `bazelisk run` command. Never run the binary directly from `bazel-bin/`.
You can run the Carbon driver or command line directly via Bazel:
- `bazelisk run //toolchain -- compile --phase=parse toolchain/parse/testdata/basics/empty.carbon`
## Advanced configurations
### AddressSanitizer (ASan)
To enable ASan for local testing:
- Pass `--config=asan`: `bazelisk test --config=asan //...`
## Common pitfalls and troubleshooting
### `bazel clean`
Changes to packages installed on your system (like changing LLVM versions or
installing `libc++`) may not be noticed by Bazel.
- Run `bazelisk clean` to force cached state to be rebuilt when environment
changes occur.
+45
View File
@@ -0,0 +1,45 @@
---
name: Code style
description:
Instructions for code formatting and style guidelines in the Carbon
toolchain.
---
# Code style
<!--
Part of the Carbon Language project, under the Apache License v2.0 with LLVM
Exceptions. See /LICENSE for license information.
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-->
## License
- **Licenses**: All Carbon files outside of `third_party/` should have a
license following
[CONTRIBUTING license instructions](/CONTRIBUTING.md#license).
## Formatting
- **Bazel**: Use `pre-commit run buildifier --files <file.bzl>` to format
Bazel files.
- **C++**: Use `pre-commit run clang-format --files <file.cpp>` to format C++
files.
- **Carbon**: The toolchain's `format` command doesn't work well right now.
Instead, try to format Carbon code based on other Carbon files and the C++
style.
- **Markdown**: Use `pre-commit run prettier --files <file.md>` to format
markdown files.
- **Python**: Use `pre-commit run black --files <file.py>` to format Python
files.
## Style Guides
- **C++ style**: Follow the
[Carbon C++ Project Style Guide](/docs/project/cpp_style_guide.md).
- **Markdown style**: Follow the
[Google developer documentation style guide](https://developers.google.com/style).
- **Python style**: Follow the [PEP 8](https://peps.python.org/pep-0008/)
style guide.
- Wrap code and comments to 80 columns.
- Run `pre-commit run flake8 --files <file.py>` to check Python style.
+171
View File
@@ -0,0 +1,171 @@
---
name: GitHub CLI usage
description:
Instructions for using the `gh` command to query and inspect GitHub state
safely.
---
# GitHub CLI usage
<!--
Part of the Carbon Language project, under the Apache License v2.0 with LLVM
Exceptions. See /LICENSE for license information.
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-->
This skill provides instructions for using the GitHub CLI (`gh`) to query,
inspect, and search GitHub state (issues, pull requests, repositories) for the
Carbon project.
## Safety First: Read-Only Usage
> [!IMPORTANT] AI assistants MUST NOT use the `gh` tool to modify any GitHub
> project state. Do NOT run commands that create, edit, delete, label, comment
> on, or merge issues, pull requests, releases, or any other resources.
### Allowed Verbs
- `list`
- `view`
- `search`
- `status`
- `api` (Only with `GET` requests)
### Prohibited Verbs
- `create`
- `edit`
- `delete`
- `merge`
- `reopen`
- `close`
- `comment`
- `label`
## Repository Configuration
The `gh` tool interacts with a default repository when run within a local check
out. For this project, the default repository is expected to be
`carbon-language/carbon-lang`.
### Verifying Default Repository
To verify the current default repository configuration:
```bash
gh repo view
```
The output should indicate the repository is `carbon-language/carbon-lang`.
### Correcting Misconfigurations
If the default repository is misconfigured (for example, pointing to a personal
fork or a different repository), the human operator must correct it.
> [!IMPORTANT] AI Assistants MUST NOT attempt to mutate `gh` configuration or
> run commands that change the default repository (such as
> `gh repository set-default`).
Instruct the human operator to run the following command to select the correct
default repository:
```bash
gh repo set-default
```
The operator will be prompted to select the correct repository (e.g.,
`carbon-language/carbon-lang`) from the available remotes.
## Common Query Commands
### Issues
- **List issues**: `gh issue list`
- **View specific issue**: `gh issue view <number>`
- **Search issues**: `gh issue search "<query>"`
- Example: `gh issue search "crash" --state open`
### Pull Requests
- **List PRs**: `gh pr list`
- **View specific PR**: `gh pr view <number>`
- **View PR diff**: `gh pr diff <number>`
- **Check PR status**: `gh pr status`
### Search
- **Search code**: `gh search code "<query>"`
- **Search repositories**: `gh search repos "<query>"`
## Advanced Usage: GitHub API
For queries that are not supported by standard `gh` commands, you can use the
`gh api` command to query the GitHub REST or GraphQL APIs.
### REST API
Query the REST API using paths relative to the API root.
- **List contributors**:
```bash
gh api repos/carbon-language/carbon-lang/contributors
```
- **List issue comments**:
```bash
gh api repos/carbon-language/carbon-lang/issues/<issue_number>/comments
```
### GraphQL API
For complex queries, use GraphQL to fetch exactly the data needed.
- **Get repository information**:
```bash
gh api graphql -f query='
query {
repository(owner: "carbon-language", name: "carbon-lang") {
description
stargazerCount
}
}
'
```
### Pagination
Use the `--paginate` flag to automatically fetch all pages of results.
```bash
gh api --paginate repos/carbon-language/carbon-lang/issues
```
### Filtering and Formatting
Use `--json` to request JSON output, and `--jq` or `--template` to filter or
format the results.
- **List PR titles and authors**:
```bash
gh pr list --json title,author --jq '.[] | "\(.title) by \(.author.login)"'
```
- **Format with Go templates**:
```bash
gh issue list --template '{{range .}}{{.number}} - {{.title}}{{"\n"}}{{end}}'
```
## Documentation References
- **GitHub CLI Manual**:
[cli.github.com/manual](https://cli.github.com/manual/)
- **GitHub REST API Documentation**:
[docs.github.com/en/rest](https://docs.github.com/en/rest)
- **GitHub GraphQL API Documentation**:
[docs.github.com/en/graphql](https://docs.github.com/en/graphql)
+95
View File
@@ -0,0 +1,95 @@
---
name: Accessing GitHub issues
description:
Instructions for safely viewing and accessing GitHub issues by way of
command line.
---
# Accessing GitHub issues
<!--
Part of the Carbon Language project, under the Apache License v2.0 with LLVM
Exceptions. See /LICENSE for license information.
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-->
This skill provides instructions for AI assistants on how to access and view
GitHub issues. Agents should strongly prefer using the command line `gh` tool to
access and view the contents of issues rather than viewing their contents by way
of a web browser.
## Safety First
> [!IMPORTANT] AI assistants MUST NOT modify any GitHub issue state. Only use
> read-only access commands like `view` or `list`. Do NOT comment, edit, create,
> close, or delete issues.
## Accessing Issues
Agents must use this skill to access issues regardless of how they are mentioned
(for example, by URL or by issue number).
### Basic View
To view an issue in the current default repository (expected to be Carbon):
```bash
gh issue view <issue_number>
```
### Including Full Context (All Comments)
To ensure the view includes the entire context of the issue, always include the
`--comments` flag to dump all comments:
```bash
gh issue view <issue_number> --comments
```
> [!TIP] If the issue is extremely large and comments are truncated, or you need
> to process comments programmatically, use the JSON output with `jq`:
>
> ```bash
> gh issue view <issue_number> --json comments --jq '.comments[].body'
> ```
### Accessing Issues in Other Repositories
To view an issue in another repository (for example, LLVM), use the `-R` or
`--repo` flag to specify the repository:
```bash
gh issue view <issue_number> -R <owner>/<repo> --comments
```
Examples:
- **LLVM Issue**:
```bash
gh issue view 5678 -R llvm/llvm-project --comments
```
- **Carbon Issue (Explicit)**:
```bash
gh issue view 1234 -R carbon-language/carbon-lang --comments
```
## Mentions via URL
If an issue is mentioned via URL, parse the URL to extract the repository owner,
repository name, and issue number.
- **URL pattern**: `https://github.com/<owner>/<repo>/issues/<number>`
- **Extraction**:
- Host: `github.com`
- Owner: `<owner>`
- Repo: `<repo>`
- Number: `<number>`
Run the command specifying the repository:
```bash
gh issue view <number> -R <owner>/<repo> --comments
```
@@ -0,0 +1,203 @@
---
name: Summarize testdata changes
description:
Instructions for summarizing changes to Carbon testdata files
(`toolchain/*/testdata`).
---
# Summarize testdata changes
<!--
Part of the Carbon Language project, under the Apache License v2.0 with LLVM
Exceptions. See /LICENSE for license information.
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-->
This skill provides instructions for creating a comprehensive report summarizing
changes to Carbon testdata files (`toolchain/*/testdata`) and associating them
with related code changes.
## Goals
Produce a report that:
1. Summarizes code changes outside of testdata.
2. Groups similar testdata changes together, listing all affected files for
each group. **Every change to testdata must be represented by at least one
group. This includes changes to CHECK lines.**
3. Provides detailed breakdowns of test input changes and diagnostic output
changes in the corresponding group. **Every single change to inputs or to
STDERR checks must be explicitly mentioned in the group, with either an
inline diff or a link to the file.**
## Process
### 1. Identify Changes
Use your VCS (Git or Jujutsu) or query Github to identify changes. For large
changes, it is recommended to use the included helper script to extract test
input changes.
#### For Git Users:
- **Summarize code changes**: `git diff --stat -- ':!toolchain/*/testdata'`
- To see content of non-testdata changes:
`git diff -- ':!toolchain/*/testdata'`
- **Identify testdata changes**: `git diff --name-only 'toolchain/*/testdata'`
#### For Jujutsu (jj) Users:
- **Summarize code changes**:
`jj --no-pager diff --stat '~toolchain/*/testdata'`
- Note: Quoting the fileset `'~toolchain/*/testdata'` is critical if it
contains wildcards.
- To see content of non-testdata changes, use `--git` to get standard
unified diff format: `jj --no-pager diff --git '~toolchain/*/testdata'`
- **Identify testdata changes**:
`jj --no-pager diff --name-only 'toolchain/*/testdata'`
#### For Github Pull Requests:
- **Summarize code changes**: `gh pr diff`
- **Identify testdata changes**:
`gh pr diff --name-only | grep '^toolchain/.*/testdata'`
#### Handling Specific Revisions:
If you are summarizing changes in a specific revision (for example, `@-`) or
pull request (for example, #1234), add `-r <rev>` or `<pr_number>` to the
commands:
- `git diff <rev>^ <rev> ...` (or use `git show <rev>`)
- `jj --no-pager diff -r <rev> ...`
- `gh pr diff <pr_number>`
### 2. Extract Test Input Changes (Recommended)
To easily identify changes, use the included Python helper script to extract all
text additions and removals from the diff, categorized by Input, STDERR, and
STDOUT changes. This script reads a unified diff from stdin.
```bash
# For Git:
git diff -- 'toolchain/*/testdata' | python3 .agents/skills/summarize_testdata_changes/scripts/parse_diff.py
# For Jujutsu (jj):
jj diff --git 'toolchain/*/testdata' | python3 .agents/skills/summarize_testdata_changes/scripts/parse_diff.py
# For a specific revision with jj:
jj diff -r @- --git 'toolchain/*/testdata' | python3 .agents/skills/summarize_testdata_changes/scripts/parse_diff.py
# For a specific PR with Github:
gh pr diff 1234 | python3 .agents/skills/summarize_testdata_changes/scripts/parse_diff.py
```
### 3. Identify Patterns and Produce a List of Groups
- Read the diff and produce a list of groups of changes that share a common
theme or cause (for example, "Updated expected output for integer literals",
"Added tests for new keyword").
- **CRITICAL**: _Every single change_ in the testdata diff must be represented
by at least one group. Do not ignore changes to `CHECK` lines.
- If it's not clear what group a change belongs to, create a new group for
it.
- For each group:
- Provide a brief description of the group.
- (Optional) Briefly note if the group appears to be an intended or
unintended consequence of the code changes.
- Divide the groups into sections:
- Test Changes: Changes to test inputs (lines not prefixed with
`// CHECK`), along with diagnostic output changes where relevant
- Diagnostic Changes: Changes to diagnostic output (lines prefixed with
`// CHECK:STDERR`) with no corresponding changes to test inputs
- [Output Type] Changes: Changes to STDOUT (lines prefixed with `// CHECK:STDOUT`)
- Create one section for each relevant kind of test. For example,
parser tests should typically be in a "Parse Tree Changes" section,
check tests should typically be in a "SemIR Changes" section, and
lower tests should typically be in an "LLVM IR Changes" section.
### 4. Improve Grouping
- Read the list of groups and check to see if any of them should be combined
or split apart. If needed, do so.
### 5. Assign Changes to Groups
- Read the diff again, and then for _each_ change in the diff:
- Add the change to the appropriate group (or, rarely, groups).
- **CRITICAL**: _Every single change_ in the testdata diff must be
represented by at least one group. Do not ignore changes to `CHECK`
lines.
- If the change affects _test inputs_ (lines not prefixed with `// CHECK`)
or _diagnostic output_ (lines prefixed with `// CHECK:STDERR`):
- List the file within the group. Don't just give one or a few
examples. Include every file.
- Provide an inline diff if the change is small.
- Provide a link to the file if the change is large.
- Otherwise, if the change only affects _STDOUT_ (lines prefixed with
`// CHECK:STDOUT`):
- Ensure the group contains a representative example that matches the
current change.
- The representative example should be an inline diff of the change.
- **CRITICAL**: _Every single change_ to test inputs and diagnostic
outputs in the files being summarized must be explicitly listed in at
least one group. Do not skip changes, even if they are similar to
changes you've already seen, and do not just give examples.
### 6. Validation
As a final validation step:
- Read through the testdata diff again.
- Ensure that every change in the diff is reflected by at least one group in
the report.
## Report Template
Use the following template for the generated report:
```markdown
# `testdata` Change Summary
## Code Changes
[One paragraph summarizing changes outside of testdata.]
## Test Changes
### [Group Name]
[Description of the group.]
[Change 1: diff context OR link]
[Change 2: diff context OR link]
...
## Diagnostic Changes
### [Group Name]
[Description of the group.]
[Change 1: diff context OR link]
[Change 2: diff context OR link]
...
## [Output Type] Changes
### [File Path]
[Description of the group.]
[Example diff context]
Changes of this kind were found in [Number] files. Examples: [List of files]
...
```
Skip sections that would be empty.
@@ -0,0 +1,65 @@
__copyright__ = """
Part of the Carbon Language project, under the Apache License v2.0 with LLVM
Exceptions. See /LICENSE for license information.
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
"""
import sys
from collections import defaultdict
from typing import TextIO, Dict, List
def parse_diff(stream: TextIO) -> None:
current_file: str = ""
file_changes: Dict[str, Dict[str, List[str]]] = defaultdict(
lambda: {"input": [], "stderr": [], "stdout": []}
)
for line in stream:
if line.startswith("diff --git"):
parts = line.split()
if len(parts) >= 4:
current_file = (
parts[3][2:] if parts[3].startswith("b/") else parts[3]
)
elif line.startswith("+") or line.startswith("-"):
if not line.startswith("+++") and not line.startswith("---"):
stripped = line[1:].strip()
if stripped.startswith("// CHECK:STDERR"):
file_changes[current_file]["stderr"].append(
line.rstrip("\n")
)
elif stripped.startswith("// CHECK:STDOUT"):
file_changes[current_file]["stdout"].append(
line.rstrip("\n")
)
elif stripped.startswith("// CHECK"):
file_changes[current_file]["stdout"].append(
line.rstrip("\n")
)
else:
file_changes[current_file]["input"].append(
line.rstrip("\n")
)
for f, c in file_changes.items():
if not c["input"] and not c["stderr"] and not c["stdout"]:
continue
print(f"File: {f}")
if c["input"]:
print(" --- Input Changes ---")
for change in c["input"]:
print(f" {change}")
if c["stderr"]:
print(" --- STDERR Changes ---")
for change in c["stderr"]:
print(f" {change}")
if c["stdout"]:
print(" --- STDOUT Changes ---")
for change in c["stdout"]:
print(f" {change}")
print("-" * 40)
if __name__ == "__main__":
parse_diff(sys.stdin)
+34
View File
@@ -0,0 +1,34 @@
---
name: Tool usage
description:
Instructions for AI assistants on what tools to use in the carbon-lang
project.
---
# Tool usage
<!--
Part of the Carbon Language project, under the Apache License v2.0 with LLVM
Exceptions. See /LICENSE for license information.
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-->
## Bazelisk and Bazel
We use `bazelisk` for build and test.
**IMPORTANT**: AI assistants use `bazelisk` instead of `bazel`.
## Pre-commit
Running `pre-commit` is mandatory. To run it on all files:
```bash
pre-commit run -a
```
To validate a specific list of files:
```bash
pre-commit run --files <files>
```
@@ -0,0 +1,115 @@
---
name: Toolchain development
description:
Instructions for checking, building, debugging, and understanding the Carbon
toolchain.
---
# Toolchain development
<!--
Part of the Carbon Language project, under the Apache License v2.0 with LLVM
Exceptions. See /LICENSE for license information.
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-->
## Toolchain structure
- Under [`toolchain/`](/toolchain/):
- [`base/`](/toolchain/base/): Base infrastructure and common utilities.
- [`check/`](/toolchain/check/): Semantic analysis (SemIR generation).
- [`lex/`](/toolchain/lex/): Lexing (Source -> Tokens).
- [`lower/`](/toolchain/lower/): Lowering to LLVM IR.
- [`parse/`](/toolchain/parse/): Parsing (Token -> Parse Tree).
- [`sem_ir/`](/toolchain/sem_ir/): Semantic Intermediate Representation
(SemIR) definitions.
## Toolchain architecture
- **Documentation**: Refer to [`toolchain/docs`](/toolchain/docs) for detailed
architecture design and patterns.
- Refer to [Toolchain Idioms](/toolchain/docs/idioms.md) for a
comprehensive list of patterns (for example, `ValueStore`, formatting
`.def` files, struct reflection) used throughout the implementation.
- **Phases**: Lex -> Parse -> Check -> Lower.
- **Definitions**: Many kinds (tokens, parse nodes, SemIR instructions) are
defined in `.def` files and expanded by way of macros.
- **Handlers**:
- Parser: `Handle<StateName>` in `parse/handle_*.cpp`.
- Checker: `HandleParseNode` in `check/handle_*.cpp`.
- Lowering: `HandleInst` in `lower/handle_*.cpp`.
- **Iteration**: Prefer iterative algorithms over recursive ones to prevent
stack exhaustion on complex codebases.
### Essential commands
- **Test everything**: `bazelisk test //...`
- **Test specific target**: `bazelisk test //toolchain/testing:file_test`
- **Test specific file**:
`bazelisk test //toolchain/testing:file_test --test_arg=--file_tests=<path_to_carbon_file>`
- **Build toolchain**: `bazelisk build //toolchain/...`
### Updating test data
Carbon tests often use `file_test` (for example,
`//toolchain/testing/file_test`). For detailed guidelines on authoring tests,
including file splits, naming conventions (`fail_`, `todo_`), and generating
minimal output with SemIR dumps, please refer to the **Toolchain tests** skill.
If you change compiler behavior, you likely need to update expected test
outputs. **Do not manually edit thousands of lines of expected output.** Use the
script:
```bash
./toolchain/autoupdate_testdata.py
# Or for a specific file:
./toolchain/autoupdate_testdata.py toolchain/check/testdata/my_test.carbon
```
## Debugging and diagnostics
- **Printing to stderr**: Use `llvm::errs() << "debug info\n";`.
- Avoid `std::cout` (it may interfere with tool output).
- **SemIR Stringification**:
- SemIR objects often have a `Print` method or `operator<<`.
- `inst.Print(llvm::errs())`
- **Debugging Crashes**:
- Bazel sandboxing can hide artifacts. Use `--sandbox_debug` if needed,
but often running the binary directly from `bazel-bin/` is easier for
debugging.
## Error handling
- **No exceptions**: Do not use C++ exceptions.
- **`ErrorOr<T>`**: Return `ErrorOr<T>` for fallible operations.
- Check with `if (auto result = Function(); result) { Use(*result); }`
- **`llvm::Expected<T>`**: Similar to `ErrorOr`, used when interfacing with
LLVM.
### Casting (LLVM style)
- Use `llvm::cast<T>(obj)` (checked, asserts on failure).
- Use `llvm::dyn_cast<T>(obj)` (returns null on failure).
- Use `llvm::isa<T>(obj)` (boolean check).
- **Avoid** `dynamic_cast` and standard RTTI.
### Data structures
- Prefer APIs in `common/` and `toolchain/base/` over LLVM ADTs. For example,
use `Map` instead of `llvm::DenseMap`.
- If no Carbon API exists, prefer LLVM ADTs over standard library ones (for
example `llvm::SmallVector`, `llvm::StringRef`).
- `StringRef` is a view; be careful with lifetimes.
## Common pitfalls
1. **Legacy `explorer` references**: The `explorer` prototype has been moved.
Ignore references to it in proposals or old docs; focus on `toolchain`.
2. **Manually updating test files**: Always check if `autoupdate_testdata.py`
can do it for you.
3. **Using `std::string` unnecessarily**: Prefer `llvm::StringRef` for
arguments.
4. **Header includes**: Use specific include orders (often enforced by
`clang-format`).
5. **Parse node order**: Semantics processes parse nodes in post-order; ensure
your parser transitions support this.
+136
View File
@@ -0,0 +1,136 @@
---
name: Toolchain tests
description:
Instructions for authoring, structuring, and running toolchain tests using
the file_test infrastructure.
---
# Toolchain tests
<!--
Part of the Carbon Language project, under the Apache License v2.0 with LLVM
Exceptions. See /LICENSE for license information.
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-->
## Introduction
This skill provides guidelines and patterns for creating and updating tests for
the Carbon toolchain, especially file tests in `toolchain/*/testdata/` (for
example, `toolchain/check/testdata/`).
Toolchain tests evaluate Carbon source files through Lexing, Parsing, Checking,
and optionally Lowering. Output (for example SemIR dumps, Clang errors) is
captured and validated using inline CHECK records.
## Structure and Authoring
### File Layout and Headers
Test files must start with the standard Carbon license, followed by
configuration comments. Separate sections with blank comment lines (`//`).
```carbon
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
// INCLUDE-FILE: toolchain/testing/testdata/min_prelude/...
//
// AUTOUPDATE
```
- `// AUTOUPDATE` is mandatory for files using CHECK markers.
- `// TIP:` lines are automatically generated by the autoupdater. You do not
need to hand-write them. It is harmless to add them, but the script will
handle it.
### Minimized Preludes
When writing tests entirely unrelated to the Core package, specify a minimal
prelude file using `// INCLUDE-FILE`. Usually, include
`toolchain/testing/testdata/min_prelude/` scripts, such as `int.carbon` or
`primitives.carbon`. This significantly speeds up execution and minimizes STDOUT
noise.
### Split Tests and `[[@TEST_NAME]]`
A single physical file can test multiple scenarios using split constraints:
```carbon
// --- passing_case.carbon
library "[[@TEST_NAME]]";
// ...
// --- fail_bad_case.carbon
library "[[@TEST_NAME]]";
// ...
```
- Use `library "[[@TEST_NAME]]";` in each split when necessary to prevent name
conflicts or redefining the default library.
- Exactly `[[@TEST_NAME]]` (including the brackets) should be used. The test
infrastructure automatically replaces it with the split's filename minus
`todo_` and `fail_` prefixes.
- **Do not put code that is expected to pass and code that is expected to fail
into the same split.** Validation relies on non-failing splits producing
absolutely no errors and failing splits producing the correct compiler
errors independently.
### File Prefixing: `fail_` and `todo_`
Expected failures must be differentiated from unexpected failures (and from
bugs). Include prefixes to name individual split files or the main test:
- `fail_...`: The test should and does produce compiler errors.
- `todo_fail_...`: The test should produce errors but currently does not.
- `fail_todo_...`: The test does produce errors or crashes, but it shouldn't
(or produces the wrong errors or otherwise misbehaves with errors).
- `todo_...`: The test has some incorrect behavior, but doesn't produce errors
currently, and shouldn't.
**Main File Naming**: The main test file (and any split-files) must have a
`fail_` prefix if they have an associated error. **Exception**: The main file
may omit `fail_` if it contains a least one split that has a `fail_` prefix.
Both the `fail_` and `todo_` prefixes are stripped from filename properties like
`[[@TEST_NAME]]`.
### Test Code Comments
- **No agent thinking:** Do not include comments describing your reasoning or
"train of thought" (for example, "Wait, but...") inside the test files. Any
comments left in tests should be concise and describe what the test _itself_
is validating for human readers.
## SemIR Dumps and Minimizing Output
Limit STDOUT checks to the logic under test. Always use `//@dump-sem-ir-begin`
and `//@dump-sem-ir-end` around the specific declarations/blocks where SemIR
output is desired. Only use these markers and **not**
`--dump-sem-ir-ranges=if-present` or similar extra args—new tests use
`//@dump-sem-ir...` to naturally filter output to the highlighted segments based
on the default behavior.
```carbon
//@dump-sem-ir-begin
fn F(x:? form(ref i32));
//@dump-sem-ir-end
```
## Creating/Updating the Output
AI tools should **never** hand-write or manually touch `// CHECK:STDOUT:` or
`// CHECK:STDERR:` comments.
Write your Carbon test code, headers, and `// AUTOUPDATE` then run the test
updater:
```bash
./toolchain/autoupdate_testdata.py toolchain/PATH/TO/YOUR/TEST.carbon
```
Review the updated test outputs (for example, by way of `git diff`). Ensure
logic paths are correctly tested rather than producing massive boilerplate
blocks.
-3
View File
@@ -8,8 +8,5 @@ bazel-carbon-lang
# See github_tools/MODULE.bazel.
github_tools
# Used as part of repo patching.
third_party/boost_unordered
# Example Bazel project.
examples/bazel
+8 -5
View File
@@ -38,11 +38,9 @@ common:non-fatal-checks --per_file_copt=common/check_internal.cpp@-DCARBON_NON_F
# enable use of the target config here to make our build and tests more
# efficient, see the documentation in //bazel/carbon_rules/BUILD for details.
common --flag_alias=use_target_config_carbon_rules=//bazel/carbon_rules:use_target_config_carbon_rules
common --flag_alias=use_target_config_runtimes_builder=//toolchain/driver:use_target_config_runtimes_builder
# Bazel doesn't track what commands the flag_alias is valid for, so we can't use
# common here.
build --use_target_config_carbon_rules
build --use_target_config_runtimes_builder
# Default to using a disk cache to minimize re-building LLVM and Clang which we
# try to avoid updating too frequently to minimize rebuild cost. The location
@@ -87,12 +85,12 @@ common --define=absl=1
# Enable TCMalloc on Linux in optimized builds.
common --custom_malloc=//bazel/malloc:tcmalloc_if_linux_opt
# Configuration for enabling Address Sanitizer. Note that this is enabled by
# default for fastbuild. The config is provided to enable ASan even in
# optimized or other build configurations. Note that ASan and TCMalloc are
# Configuration for enabling Address Sanitizer. Note that ASan and TCMalloc are
# incompatible so this explicitly forces the system malloc.
common:asan --features=asan
common:asan --custom_malloc=@bazel_tools//tools/cpp:malloc
# Also double the test timeouts for ASan to improve their consistency.
test:asan --test_timeout=120,600,1800,-1
# Configuration for enabling LibFuzzer (along with ASan).
common:fuzzer --features=fuzzer
@@ -123,6 +121,11 @@ common:linux --define=pfm=1
# Disables `actions.declare_symlink`. Done for cross-environment support.
common --allow_unresolved_symlinks=false
# Removes the leading `/proc/self/cwd/` from file paths in the debug info. Some
# tools like VS Code don't understand `/proc/self/cwd` in places like terminal
# stack dumps, but do understand paths relative to the workspace root.
common --copt=-fdebug-prefix-map=/proc/self/cwd=
# Allow users to override any of the flags desired by importing a user-specific
# RC file here if present.
try-import %workspace%/user.bazelrc
+9
View File
@@ -11,6 +11,7 @@ DerivePointerAlignment: 'false'
ExperimentalAutoDetectBinPacking: 'false'
FixNamespaceComments: 'true'
InsertBraces: 'true'
InsertTrailingCommas: None
PointerAlignment: Left
# We abuse control macros for formatting other kinds of macros.
SpaceBeforeParens: ControlStatementsExceptControlMacros
@@ -23,3 +24,11 @@ IfMacros:
'CARBON_KIND_SWITCH',
]
StatementMacros: ['ABSTRACT']
QualifierAlignment: Custom
QualifierOrder:
[inline, static, friend, constexpr, const, volatile, restrict, type]
Macros:
# These macros can contain variable declarations, so clang-format needs to
# "see through" them in order to format them correctly.
- CARBON_ASSIGN_OR_RETURN(x)=x
- CARBON_KIND(x)=x
+9
View File
@@ -19,3 +19,12 @@ Diagnostics:
Suppress:
# The `#error` requiring a macro definition.
- pp_hash_error
---
# Suppress diagnostics for template source files.
If:
PathMatch: .*\.tpl\.h
Diagnostics:
Suppress:
- undeclared_var_use
@@ -12,12 +12,12 @@ runs:
using: composite
steps:
# Setup Python and related tools.
- uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
with:
# Match the min version listed in docs/project/contribution_tools.md
# or the oldest version available on the OS.
python-version:
${{ inputs.matrix_runner == 'macos-14' && '3.11' || '3.9' }}
${{ inputs.matrix_runner == 'macos-14' && '3.11' || '3.10' }}
- uses: ./.github/actions/build-setup-macos
if: startsWith(inputs.matrix_runner, 'macos')
@@ -70,6 +70,13 @@ runs:
build --remote_cache=https://storage.googleapis.com/carbon-builds-github-v${CACHE_VERSION}
build --remote_download_outputs=minimal
# Allow passing targets that are incompatible so that our explicit
# target lists work more like //... wild card patterns in CI. In CI,
# we're using explicit target lists to prune to a minimal set of
# dependencies, and so skipping incompatible targets is the expected
# behavior.
build --skip_incompatible_explicit_targets
# We import a special key into every action in order to key the Bazel
# remote cache in a way that avoids collisions between different
# runners. Anything that might change the system external to Bazel but
+1 -1
View File
@@ -28,7 +28,7 @@ runs:
# minimum supported LLVM version.
- name: Cache Homebrew
id: cache-homebrew-macos
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
with:
# Cover all the critical parts of Homebrew here. Homebrew on Arm macOS
# uses its own prefix making this easy to cover, but we need a few
@@ -27,7 +27,7 @@ runs:
# reliability.
- name: Cache LLVM and Clang installation
id: cache-llvm-ubuntu
uses: actions/cache@1bd1e32a3bdc45362d1e726936510720a7c30a57 # v4.2.0
uses: actions/cache@cdf6c1fa76f9f475f3d7449005a359c84ca0f306 # v5.0.3
with:
path: ~/llvm
key: LLVM-19.1.7-Cache-ubuntu-${{ runner.arch }}
+1
View File
@@ -18,6 +18,7 @@ the "Harden Runner" steps are
Most jobs only have a few endpoints, but due to tools which do downloads, a few
have significantly more. These are:
- clangd_tidy.yaml (Bazel)
- pre_commit.yaml (Bazel, pre-commit)
- nightly_release.yaml (Bazel)
- tests.yaml (Bazel)
+1 -1
View File
@@ -19,7 +19,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1
uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1
with:
disable-sudo: true
egress-policy: block
+33
View File
@@ -0,0 +1,33 @@
# Part of the Carbon Language project, under the Apache License v2.0 with LLVM
# Exceptions. See /LICENSE for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
name: Check Dependent Label
on:
pull_request_target:
types: [opened, synchronize, labeled, unlabeled]
# This workflow runs as `pull_request_target` so that the check can't be
# disabled or bypassed by a the PR, but it doesn't need any permissions.
permissions: {}
jobs:
check_label:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1
with:
disable-sudo: true
egress-policy: block
# prettier-ignore
allowed-endpoints: >
api.github.com:443
- name: Check for 'dependent' label
run: |
if [[ "${{ contains(github.event.pull_request.labels.*.name, 'dependent') }}" == "true" ]]; then
echo "PR has 'dependent' label. Blocking merge."
exit 1
fi
echo "PR does not have 'dependent' label."
+13 -8
View File
@@ -26,27 +26,36 @@ jobs:
steps:
- name: Harden Runner
uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1
uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1
with:
egress-policy: block
# When adding endpoints, see README.md.
# prettier-ignore
allowed-endpoints: >
*.dl.sourceforge.net:443
*.blob.storage.azure.net:443
*.githubapp.com:443
*.sourceforge.net:443
api.github.com:443
api.ipify.org:443
bcr.bazel.build:443
downloads.sourceforge.net:443
files.pythonhosted.org:443
github.com:443
go.dev:443
mirror.bazel.build:443
mirrors.kernel.org:443
nodejs.org:443
oauth2.googleapis.com:443
objects.githubusercontent.com:443
pypi.org:443
registry.npmjs.org:443
release-assets.githubusercontent.com:443
releases.bazel.build:443
sourceforge.net:443
storage.googleapis.com:443
uploads.github.com:443
www.googleapis.com:443
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- id: filter
uses: dorny/paths-filter@de90cc6fb38fc0963ad72b210f1f284cd68cea36 # v3.0.2
@@ -66,10 +75,6 @@ jobs:
if: steps.filter.outputs.has_cpp == 'true'
run: ./scripts/create_compdb.py
- name: Build deps for clangd-tidy
if: steps.filter.outputs.has_cpp == 'true'
run: ./scripts/run_bazel.py build //scripts:deps_for_clangd_tidy
- name: Install clangd-tidy
if: steps.filter.outputs.has_cpp == 'true'
run: pip install clangd-tidy==1.1.0.post2
+1 -1
View File
@@ -15,7 +15,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1
uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1
with:
egress-policy: audit
+3 -3
View File
@@ -22,16 +22,16 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1
uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1
with:
egress-policy: audit
- name: Checkout
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Prebuild actions
run: ./website/prebuild.py
- name: Setup Ruby
uses: ruby/setup-ruby@a6e6f86333f0a2523ece813039b8b4be04560854 # v1.190.0
uses: ruby/setup-ruby@6ca151fd1bfcfd6fe0c4eb6837eb0584d0134a0c # v1.290.0
with:
# Runs 'bundle install' and caches installed gems automatically.
bundler-cache: true
+5 -5
View File
@@ -29,18 +29,18 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1
uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1
with:
egress-policy: audit
- name: Checkout
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Prebuild actions
run: ./website/prebuild.py
- name: Setup Pages
uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5.0.0
- name: Setup Ruby
uses: ruby/setup-ruby@a6e6f86333f0a2523ece813039b8b4be04560854 # v1.190.0
uses: ruby/setup-ruby@6ca151fd1bfcfd6fe0c4eb6837eb0584d0134a0c # v1.290.0
with:
# Runs 'bundle install' and caches installed gems automatically.
bundler-cache: true
@@ -57,7 +57,7 @@ jobs:
- name: Upload artifact
# Automatically uploads an artifact from the './_site' directory by
# default.
uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3.0.1
uses: actions/upload-pages-artifact@7b1f4a764d45c48632c6b24a0339c27f5614fb0b # v4.0.0
deploy:
environment:
@@ -67,7 +67,7 @@ jobs:
needs: build
steps:
- name: Harden Runner
uses: step-security/harden-runner@5c7944e73c4c2a096b17a9cb74d65b6c2bbafbde # v2.9.1
uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1
with:
egress-policy: audit
+16 -5
View File
@@ -37,26 +37,37 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1
uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1
with:
egress-policy: block
# When adding endpoints, see README.md.
# prettier-ignore
allowed-endpoints: >
*.dl.sourceforge.net:443
*.blob.storage.azure.net:443
*.githubapp.com:443
*.sourceforge.net:443
api.github.com:443
api.ipify.org:443
bcr.bazel.build:443
downloads.sourceforge.net:443
files.pythonhosted.org:443
github.com:443
go.dev:443
mirror.bazel.build:443
mirrors.kernel.org:443
nodejs.org:443
oauth2.googleapis.com:443
objects.githubusercontent.com:443
pypi.org:443
registry.npmjs.org:443
release-assets.githubusercontent.com:443
releases.bazel.build:443
sourceforge.net:443
storage.googleapis.com:443
uploads.github.com:443
www.googleapis.com:443
- name: Checkout branch
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Set up remote cache access
env:
@@ -82,7 +93,7 @@ jobs:
test -c opt --stamp --remote_download_toplevel \
--pre_release=nightly --nightly_date=${{ env.nightly_date }} \
//toolchain \
//toolchain/install:carbon_toolchain_tar_gz_rule \
//toolchain/install:carbon_toolchain_tar_gz \
//toolchain/install:carbon_toolchain_tar_gz_test
- name: Extract the release version
+14 -7
View File
@@ -18,30 +18,37 @@ jobs:
runs-on: ubuntu-22.04
steps:
- name: Harden Runner
uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1
uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1
with:
disable-sudo-and-containers: true
egress-policy: block
# When adding endpoints, see README.md.
# prettier-ignore
allowed-endpoints: >
*.dl.sourceforge.net:443
*.blob.storage.azure.net:443
*.githubapp.com:443
*.sourceforge.net:443
api.github.com:443
api.ipify.org:443
bcr.bazel.build:443
downloads.sourceforge.net:443
files.pythonhosted.org:443
github.com:443
go.dev:443
mirror.bazel.build:443
mirrors.kernel.org:443
nodejs.org:443
oauth2.googleapis.com:443
objects.githubusercontent.com:443
pypi.org:443
registry.npmjs.org:443
release-assets.githubusercontent.com:443
releases.bazel.build:443
storage.googleapis.com:443
sourceforge.net:443
uploads.github.com:443
www.googleapis.com:443
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5.1.0
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6.2.0
# Ensure LLVM is set up consistently.
- uses: ./.github/actions/build-setup-common
@@ -63,7 +70,7 @@ jobs:
mkdir -p pre-commit-output
git diff > pre-commit-output/diff
cp $GITHUB_EVENT_PATH pre-commit-output/event
- uses: actions/upload-artifact@5d5d22a31266ced268874388b861e4b58bb5c2f3 # v4.3.1
- uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f # v7.0.0
if: failure()
with:
name: pre-commit output
@@ -28,12 +28,11 @@ jobs:
# Only generate suggestions if pre-commit for a PR failed.
if: |
github.event.workflow_run.conclusion == 'failure' &&
github.event.workflow_run.event == 'pull_request' &&
github.actor != 'jonmeow'
github.event.workflow_run.event == 'pull_request'
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1
uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1
with:
disable-sudo: true
egress-policy: block
@@ -48,10 +47,10 @@ jobs:
with:
reviewdog_version: latest
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- name: Download pre-commit output
uses: actions/download-artifact@c850b930e6ba138125429b7e5c93fc707a7f8427 # v4.1.4
uses: actions/download-artifact@70fc10c6e5e1ce46ad2ea6f2b72d43f7d47b13c3 # v8.0.0
with:
name: pre-commit output
github-token: ${{ secrets.GITHUB_TOKEN }}
+1 -1
View File
@@ -31,7 +31,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1
uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1
with:
disable-sudo: true
egress-policy: block
+1 -1
View File
@@ -23,7 +23,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1
uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1
with:
disable-sudo: true
egress-policy: block
+2 -2
View File
@@ -25,13 +25,13 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1
uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1
with:
egress-policy: audit
# Checkout our main repository.
- name: Checkout the main repository
uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
# Run the sync script.
- name: Sync to other repositories
+36 -9
View File
@@ -22,36 +22,62 @@ concurrency:
jobs:
test:
name:
Testing ${{ matrix.config.name != 'Default' && format('({0})',
matrix.config.name) || '' }} (${{ matrix.runner }})
strategy:
matrix:
# Test a recent version of each supported OS.
runner: ['ubuntu-22.04', 'macos-14']
build_mode: [fastbuild, opt]
# Create a synthetic matrix dimension with the event name for filtering.
event: ['${{ github.event_name }}']
config:
- name: 'Default'
flags: ''
- name: 'Opt'
flags: '-c opt'
- name: 'ASan'
flags: '--config=asan'
exclude:
- runner: 'macos-14'
config: { name: 'ASan', flags: '--config=asan' }
- event: 'pull_request'
config: { name: 'ASan', flags: '--config=asan' }
- event: 'merge_group'
config: { name: 'ASan', flags: '--config=asan' }
runs-on: ${{ matrix.runner }}
steps:
- name: Harden Runner
uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1
uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1
with:
egress-policy: block
# When adding endpoints, see README.md.
# prettier-ignore
allowed-endpoints: >
*.dl.sourceforge.net:443
*.blob.storage.azure.net:443
*.githubapp.com:443
*.sourceforge.net:443
api.github.com:443
api.ipify.org:443
bcr.bazel.build:443
downloads.sourceforge.net:443
files.pythonhosted.org:443
github.com:443
go.dev:443
mirror.bazel.build:443
mirrors.kernel.org:443
nodejs.org:443
oauth2.googleapis.com:443
objects.githubusercontent.com:443
pypi.org:443
registry.npmjs.org:443
release-assets.githubusercontent.com:443
releases.bazel.build:443
sourceforge.net:443
storage.googleapis.com:443
uploads.github.com:443
www.googleapis.com:443
- uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
- id: test-setup
uses: ./.github/actions/test-setup
@@ -65,7 +91,7 @@ jobs:
targets_file: ${{ runner.temp }}/targets
# Build and run just the tests impacted by the PR or merge group.
- name: Test (${{ matrix.build_mode }})
- name: Test (${{ matrix.config.name }})
if: steps.test-setup.outputs.has_code == 'true'
shell: bash
env:
@@ -76,10 +102,11 @@ jobs:
run: |
# Decrease the jobs sharply if we see repeated failures to try to
# work around transient network errors even if it makes things
# slower.
# slower. Note that we allow passing targets that are incompatible and
# skip thim as-if we were using `//...` style wild card patterns.
./scripts/run_bazel.py \
--attempts=5 --jobs-on-last-attempt=4 \
test -c ${{ matrix.build_mode }} \
test ${{ matrix.config.flags }} \
--target_pattern_file=$TARGETS_FILE
# See "Disk space before build" in `test-setup`.
+1 -1
View File
@@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Harden Runner
uses: step-security/harden-runner@17d0e2bd7d51742c71671bd19fa12bdc9d40a3d6 # v2.8.1
uses: step-security/harden-runner@58077d3c7e43986b6b15fba718e8ea69e387dfcc # v2.15.1
with:
disable-sudo: true
egress-policy: block
+1
View File
@@ -39,6 +39,7 @@
# vim temporary files
.*.sw[a-p]
.swp
# generated by utils/tree_sitter/helix.sh
/.helix/
+7 -2
View File
@@ -33,6 +33,11 @@ repos:
rev: efaea7c61c774c0b1a9805fd999e754a2d19dbd1 # frozen: v1.2.5
hooks:
- id: check-google-doc-style
exclude: |
(?x)^(
.*\.agents/.*|
.*AGENTS.md
)$
- id: markdown-toc
- repo: local
hooks:
@@ -45,7 +50,7 @@ repos:
# Formatters should be run late so that they can re-format any prior changes.
- repo: https://github.com/psf/black
rev: 8a737e727ac5ab2f1d4cf5876720ed276dc8dc4b # frozen: 25.1.0
rev: 35ea67920b7f6ac8e09be1c47278752b1e827f76 # frozen: 26.3.0
hooks:
- id: black
- repo: local
@@ -159,7 +164,7 @@ repos:
.*_test\.py
)$
- repo: https://github.com/codespell-project/codespell
rev: 63c8f8312b7559622c0d82815639671ae42132ac # frozen: v2.4.1
rev: 2ccb47ff45ad361a21071a7eedda4c37e6ae8c5a # frozen: v2.4.2
hooks:
- id: codespell
args: ['-I', '.codespell_ignore', '--uri-ignore-words-list', '*']
+58
View File
@@ -0,0 +1,58 @@
# Gemini & AI assistant guide for Carbon
<!--
Part of the Carbon Language project, under the Apache License v2.0 with LLVM
Exceptions. See /LICENSE for license information.
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
-->
This document provides high-density technical context for AI assistants (and
humans!) contributing to the Carbon Language project. If you are an AI
assistant, **read this first** to avoid common pitfalls.
## Table of contents
- [General instructions](#general-instructions)
- [Project structure](#project-structure)
- [Bazel usage](#bazel-usage)
- [Toolchain development](#toolchain-development)
## General instructions
- **Communication**: Be concise, professional, and technical. Use GitHub-style
markdown.
- **Verification**: Always run relevant tests.
- **Tool usage**: Use web search for any research outside the immediate
codebase or KIs.
## Project structure
- **[`common/`](common/)**: Common C++ utilities used across the project.
- **[`core/`](core/)**: The Carbon standard library (Core).
- **[`docs/`](docs/)**: Project documentation, design, and style guides.
- **[`examples/`](examples/)**: Example Carbon programs and code snippets.
- **[`proposals/`](proposals/)**: Evolution proposals.
- **[`testing/`](testing/)**: Testing utilities and infrastructure.
- **[`toolchain/`](toolchain/)**: The C++ implementation of the compiler
(Toolchain).
## Tool usage
See the "Tool usage" skill for instructions on what tools to use in the
carbon-lang project.
## Bazel usage
> [!IMPORTANT] Always use `bazelisk` instead of `bazel` for all commands in the
> Carbon project. Refer to the
> [Bazel usage skill](/.agents/skills/bazel/SKILL.md) for detailed instructions.
## Code style
See the "Code style" skill for instructions on formatting, style guides, and
code conventions to follow.
## Toolchain development
See the "Toolchain Development" skill for instructions on architecture,
building, testing, debugging, C++ patterns, and common pitfalls.
+43
View File
@@ -2,8 +2,51 @@
# Exceptions. See /LICENSE for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
load("@bazel_skylib//rules:common_settings.bzl", "bool_flag", "bool_setting", "int_flag")
filegroup(
name = "clang_tidy_config",
srcs = [".clang-tidy"],
visibility = ["//visibility:public"],
)
# `bazel run //:generate_compile_commands` to produce `compile_commands.json`.
alias(
name = "generate_compile_commands",
actual = "@wolfd_bazel_compile_commands//:generate_compile_commands",
)
bool_setting(
name = "runtimes_build",
build_setting_default = False,
visibility = ["//visibility:public"],
)
int_flag(
name = "bootstrap_stage",
build_setting_default = 0,
visibility = ["//visibility:public"],
)
# A setting that causes bootstrapping to occur using the `exec` config rather
# than the target config.
#
# The exec config is the more technically correct way of doing bootstrapping
# than the target config. For example it allows bootstrapping with a target that
# isn't compatible with the current execution host. However, in development
# builds, it is likely to force building the entire toolchain twice -- once in
# the target config for running test, and a second time in the exec config for
# the bootstrap. As a consequence, this is disabled by default.
#
# TODO: Add documentation for using the bootstrap flags once stabilized.
bool_flag(
name = "bootstrap_exec_config",
build_setting_default = False,
visibility = ["//visibility:public"],
)
config_setting(
name = "bootstrap_with_exec_config",
flag_values = {"//:bootstrap_exec_config": "True"},
visibility = ["//visibility:public"],
)
+14 -2
View File
@@ -33,6 +33,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- [Style](#style)
- [Google Docs and Markdown](#google-docs-and-markdown)
- [Other files](#other-files)
- [Testing](#testing)
- [License](#license)
- [Google Docs](#google-docs)
- [Markdown](#markdown)
@@ -98,7 +99,7 @@ early, before even writing a proposal, and the process explains how to do that.
Helping with
[pull requests](https://github.com/carbon-language/carbon-lang/pulls) review is
a good way to provide feedback, while getting a acquainted with the code base.
a good way to provide feedback, while getting acquainted with the code base.
#### Implement Carbon's design
@@ -231,6 +232,10 @@ as well as helpful tooling that will ease the contribution process. For example,
#### Using AI-based contribution tools
If you are using an AI assistant to help you contribute, or if you are an AI
assistant yourself, please consult [AGENTS.md](/AGENTS.md) for high-density
technical context and tips.
All submissions to Carbon need to follow our
[Contributor License Agreement (CLA)](#contributor-license-agreements-clas),
which covers any original work of authorship included in the submission. This
@@ -304,7 +309,6 @@ follow the Carbon documentation and coding styles.
request.
- For code:
- New features should have a documented design that has been approved
through the [evolution process](docs/project/evolution.md). This
includes modifications to preexisting designs.
@@ -423,6 +427,14 @@ Other style points to be aware of are:
If you're not sure what style to use, please ask on Discord or GitHub.
## Testing
Most development in the Carbon project is on the [toolchain](toolchain/). The
toolchain contains some unit tests, but the majority of testing is done through
`file_test` tests, which test the output of the different phases of the
toolchain. The toolchain docs include instructions for
[building and running tests](toolchain/docs/adding_features.md#tests-and-debugging).
## License
A license is required at the top of all documents and files.
+34 -61
View File
@@ -19,43 +19,33 @@ of:
- Running `bazel mod deps` provides a canonical update to
`MODULE.bazel.lock`; create a PR with those changes in order to include
the host platform.
For updates, run `scripts/query_module_versions.py` to list the latest package
versions.
"""
module(name = "carbon")
http_archive = use_repo_rule(
"@bazel_tools//tools/build_defs/repo:http.bzl",
"http_archive",
)
bazel_dep(name = "abseil-cpp", version = "20260107.0")
bazel_dep(name = "abseil-cpp", version = "20260107.1")
bazel_dep(name = "bazel_skylib", version = "1.9.0")
bazel_dep(name = "boost.unordered", version = "1.90.0.bcr.1")
bazel_dep(name = "google_benchmark", version = "1.9.5")
bazel_dep(name = "googletest", version = "1.17.0.bcr.2")
bazel_dep(name = "libpfm", version = "4.13.0")
bazel_dep(name = "re2", version = "2025-11-05.bcr.1")
bazel_dep(name = "rules_cc", version = "0.2.16")
bazel_dep(name = "rules_cc", version = "0.2.17")
bazel_dep(name = "rules_pkg", version = "1.2.0")
bazel_dep(name = "rules_shell", version = "0.6.1")
bazel_dep(name = "tcmalloc", version = "0.0.0-20250927-12f2552")
bazel_dep(name = "tree-sitter-bazel", version = "0.26.3.bcr.1")
bazel_dep(name = "tree-sitter-bazel", version = "0.26.5")
# The registry only has an old version. We use that here to avoid a miss but
# override it with a newer version.
bazel_dep(name = "libpfm", version = "4.11.0")
libpfm_version = "4.13.0"
# The official site is https://perfmon2.sourceforge.net/, but SourceForge makes
# it difficult to download from bazel. On GitHub action runners,
# https://git.code.sf.net/p/perfmon2/libpfm4 seems to be blocked. As a
# consequence, use a mirror.
archive_override(
module_name = "libpfm",
integrity = "sha256-sGBx1+UoQCplBCc+pwA1Tr/PS2L/4jnLZHH82wSuPz0=",
patch_strip = 1,
patches = ["@//bazel/libpfm:0001-Introduce-a-simple-native-Bazel-build.patch"],
strip_prefix = "libpfm4-{0}".format(libpfm_version),
urls = ["https://github.com/wcohen/libpfm4/archive/v{0}.tar.gz".format(libpfm_version)],
bazel_dep(name = "wolfd_bazel_compile_commands", version = "0.5.2", dev_dependency = True)
git_override(
module_name = "wolfd_bazel_compile_commands",
# This is https://github.com/wolfd/bazel-compile-commands/pull/3 which is
# needed to correctly select target configurations in our compile commands.
commit = "7c673ac868cd237f262bb37a7819b1a279566a66",
remote = "https://github.com/chandlerc/bazel-compile-commands.git",
)
bazel_dep(name = "bazel_clang_tidy", dev_dependency = True)
@@ -74,27 +64,11 @@ use_repo(bazel_cc_toolchain, "bazel_cc_toolchain")
register_toolchains("@bazel_cc_toolchain//:all")
bazel_dep(name = "hedron_compile_commands", dev_dependency = True)
git_override(
module_name = "hedron_compile_commands",
# HEAD as of 2026-01-28.
commit = "abb61a688167623088f8768cc9264798df6a9d10",
remote = "https://github.com/hedronvision/bazel-compile-commands-extractor.git",
)
boost_unordered_version = "1.88.0"
http_archive(
name = "boost_unordered",
build_file = "@//:third_party/boost_unordered/BUILD.bazel",
integrity = "sha256-a5ydXEQCspPhFmCD9vNa3JUIVeitbodEYaJhfOSO8no=",
strip_prefix = "boost_unordered-{0}".format(boost_unordered_version),
urls = ["https://github.com/MikePopoloski/boost_unordered/archive/v{0}.tar.gz".format(boost_unordered_version)],
)
register_toolchains("//toolchain/install:all")
# Required for llvm-project.
bazel_dep(name = "platforms", version = "1.0.0")
bazel_dep(name = "protobuf", version = "34.0-rc1", repo_name = "com_google_protobuf")
bazel_dep(name = "protobuf", version = "34.0.bcr.1", repo_name = "com_google_protobuf")
bazel_dep(name = "zlib-ng", version = "2.0.7", repo_name = "llvm_zlib")
bazel_dep(name = "zstd", version = "1.5.7.bcr.1", repo_name = "llvm_zstd")
@@ -102,26 +76,25 @@ bazel_dep(name = "zstd", version = "1.5.7.bcr.1", repo_name = "llvm_zstd")
# llvm-project
###############################################################################
# We pin to specific upstream commits and try to track top-of-tree reasonably
# closely rather than pinning to a specific release.
# HEAD as of 2026-01-08.
llvm_project_version = "21a1e6e6a70d70635c68b9aaa54f816ae36a6416"
# Load a repository for the raw llvm-project, pre-overlay.
http_archive(
name = "llvm-raw",
bazel_dep(name = "llvm-raw")
git_override(
module_name = "llvm-raw",
build_file_content = "# empty",
integrity = "sha256-ouWG2d4Cob9P6+dxCLZnV4RldSOqZp7mtwd6vd+ZK3Q=",
patch_args = ["-p1"],
# We pin to specific upstream commits and try to track top-of-tree
# reasonably closely rather than pinning to a specific release.
# HEAD as of 2026-04-01.
commit = "b71eacea7687f68c11299e3bda5654fbbaa1e20e",
patch_cmds = ["echo \"module(name='llvm-raw')\" > MODULE.bazel"],
patch_strip = 1,
patches = [
"@carbon//bazel/llvm_project:0001_Patch_for_mallinfo2_when_using_Bazel_build_system.patch",
"@carbon//bazel/llvm_project:0002_Added_Bazel_build_for_compiler_rt_fuzzer.patch",
"@carbon//bazel/llvm_project:0004_Introduce_basic_sources_exporting_for_libunwind.patch",
"@carbon//bazel/llvm_project:0005_Introduce_basic_sources_exporting_for_libcxx_and_libcxxabi.patch",
"@carbon//bazel/llvm_project:0008_Add_filegroups_for_installed_compiler-rt_headers.patch",
"//bazel/llvm_project:0001_Patch_for_mallinfo2_when_using_Bazel_build_system.patch",
"//bazel/llvm_project:0002_Added_Bazel_build_for_compiler_rt_fuzzer.patch",
"//bazel/llvm_project:0004_Introduce_basic_sources_exporting_for_libunwind.patch",
"//bazel/llvm_project:0005_Introduce_basic_sources_exporting_for_libcxx_and_libcxxabi.patch",
"//bazel/llvm_project:0009_Introduce_starlark_exporting_compiler-rt_build_information.patch",
],
strip_prefix = "llvm-project-{0}".format(llvm_project_version),
urls = ["https://github.com/llvm/llvm-project/archive/{0}.tar.gz".format(llvm_project_version)],
remote = "https://github.com/llvm/llvm-project.git",
)
# Apply the overlay to produce llvm-project.
@@ -135,7 +108,7 @@ use_repo(llvm_project, "llvm-project")
# Python
###############################################################################
bazel_dep(name = "rules_python", version = "1.8.3")
bazel_dep(name = "rules_python", version = "1.9.0")
python = use_extension("@rules_python//python/extensions:python.bzl", "python")
python.toolchain(
@@ -149,7 +122,7 @@ use_repo(python, "python_versions")
bazel_dep(
name = "rules_bazel_integration_test",
version = "0.36.0",
version = "0.37.1",
dev_dependency = True,
)
+57 -718
View File
@@ -11,12 +11,13 @@
"https://bcr.bazel.build/modules/abseil-cpp/20240116.0/MODULE.bazel": "98dc378d64c12a4e4741ad3362f87fb737ee6a0886b2d90c3cdbb4d93ea3e0bf",
"https://bcr.bazel.build/modules/abseil-cpp/20240116.1/MODULE.bazel": "37bcdb4440fbb61df6a1c296ae01b327f19e9bb521f9b8e26ec854b6f97309ed",
"https://bcr.bazel.build/modules/abseil-cpp/20240116.2/MODULE.bazel": "73939767a4686cd9a520d16af5ab440071ed75cec1a876bf2fcfaf1f71987a16",
"https://bcr.bazel.build/modules/abseil-cpp/20250127.0/MODULE.bazel": "d1086e248cda6576862b4b3fe9ad76a214e08c189af5b42557a6e1888812c5d5",
"https://bcr.bazel.build/modules/abseil-cpp/20250127.1/MODULE.bazel": "c4a89e7ceb9bf1e25cf84a9f830ff6b817b72874088bf5141b314726e46a57c1",
"https://bcr.bazel.build/modules/abseil-cpp/20250512.1/MODULE.bazel": "d209fdb6f36ffaf61c509fcc81b19e81b411a999a934a032e10cd009a0226215",
"https://bcr.bazel.build/modules/abseil-cpp/20250814.0/MODULE.bazel": "c43c16ca2c432566cdb78913964497259903ebe8fb7d9b57b38e9f1425b427b8",
"https://bcr.bazel.build/modules/abseil-cpp/20250814.1/MODULE.bazel": "51f2312901470cdab0dbdf3b88c40cd21c62a7ed58a3de45b365ddc5b11bcab2",
"https://bcr.bazel.build/modules/abseil-cpp/20260107.0/MODULE.bazel": "94bdc259eccc59d880d3ae55e35ff1f27a289618a023cb1ed87182e17887b7c3",
"https://bcr.bazel.build/modules/abseil-cpp/20260107.0/source.json": "cd3c69eebe331264c87283774631f39006cd25caf159f4e1dab74322ef5c4bb9",
"https://bcr.bazel.build/modules/abseil-cpp/20260107.1/MODULE.bazel": "e33b3801443f5fd64465262084534115db76363df13d2168a42bbfacc747be81",
"https://bcr.bazel.build/modules/abseil-cpp/20260107.1/source.json": "7a9a88969b1e79268cf613728ca8ff8fa4bc4b1a9abee9ec1fb5f113ca751971",
"https://bcr.bazel.build/modules/apple_support/1.11.1/MODULE.bazel": "1843d7cd8a58369a444fc6000e7304425fba600ff641592161d9f15b179fb896",
"https://bcr.bazel.build/modules/apple_support/1.15.1/MODULE.bazel": "a0556fefca0b1bb2de8567b8827518f94db6a6e7e7d632b4c48dc5f865bc7c85",
"https://bcr.bazel.build/modules/apple_support/1.22.1/MODULE.bazel": "90bd1a660590f3ceffbdf524e37483094b29352d85317060b2327fff8f3f4458",
@@ -65,8 +66,29 @@
"https://bcr.bazel.build/modules/bazel_skylib/1.8.2/MODULE.bazel": "69ad6927098316848b34a9142bcc975e018ba27f08c4ff403f50c1b6e646ca67",
"https://bcr.bazel.build/modules/bazel_skylib/1.9.0/MODULE.bazel": "72997b29dfd95c3fa0d0c48322d05590418edef451f8db8db5509c57875fb4b7",
"https://bcr.bazel.build/modules/bazel_skylib/1.9.0/source.json": "7ad77c1e8c1b84222d9b3f3cae016a76639435744c19330b0b37c0a3c9da7dc0",
"https://bcr.bazel.build/modules/boost.assert/1.90.0.bcr.1/MODULE.bazel": "82fa42de969959b0eb59b03b528b6ed6fdc130429766f980f0bda20a7efd09bb",
"https://bcr.bazel.build/modules/boost.assert/1.90.0.bcr.1/source.json": "276a47c8c07761df24435e276ec6ed0ac859839ae9d62259787d222e022d23e2",
"https://bcr.bazel.build/modules/boost.config/1.90.0.bcr.1/MODULE.bazel": "c14d7f8f9d6ba5d13383df5dabe296dcfef3925b398158b71c1c4080e2a14365",
"https://bcr.bazel.build/modules/boost.config/1.90.0.bcr.1/source.json": "44b2941a2e656fd2c3747576ddd1e44e4d55c5d3ef5a22f0231f35c8dded3051",
"https://bcr.bazel.build/modules/boost.container_hash/1.90.0.bcr.1/MODULE.bazel": "99905e56c4de3090bd802393e9a683fcf885f9ef9a7add79c05333de1c41ccf7",
"https://bcr.bazel.build/modules/boost.container_hash/1.90.0.bcr.1/source.json": "9403da9bcc0f1600e569d7921aede5505a4f8407541597b00dcfd116ffb30580",
"https://bcr.bazel.build/modules/boost.core/1.90.0.bcr.1/MODULE.bazel": "c94d17f2da1e7557046730a5647e06943e4e0fc10d6537e3656dbd23f8a0a573",
"https://bcr.bazel.build/modules/boost.core/1.90.0.bcr.1/source.json": "5b3b6b9c6ea8e38e63d3b1a92370902a9ba78a4efd6c23df3c538d719a200cbe",
"https://bcr.bazel.build/modules/boost.describe/1.90.0.bcr.1/MODULE.bazel": "ee5316a4d469c5a272e90b6a1c6f8185fb842a2a6401e970da159b08b4bdcc6a",
"https://bcr.bazel.build/modules/boost.describe/1.90.0.bcr.1/source.json": "5ca72db73619c8915d030d88f7bcff970211daee4d7fa49a99ac3a510b507355",
"https://bcr.bazel.build/modules/boost.mp11/1.90.0.bcr.1/MODULE.bazel": "9180b001b76e786d764f40b9cf9f3cffc92fd58b36fe7680b1f481e8e9991d2a",
"https://bcr.bazel.build/modules/boost.mp11/1.90.0.bcr.1/source.json": "5720af0062e685970e3adcc72e925445171ba2ff192cde0b68c53031d25fa7f4",
"https://bcr.bazel.build/modules/boost.predef/1.90.0.bcr.1/MODULE.bazel": "0c92fea5e1d63e301f7bb81763a5bfbb5f27204d6b6127e09ae23ae7d1bb3eaa",
"https://bcr.bazel.build/modules/boost.predef/1.90.0.bcr.1/source.json": "f32e27769816c6de69925c5995733adf8e176e5a281d23c079c64aafae532e2f",
"https://bcr.bazel.build/modules/boost.throw_exception/1.90.0.bcr.1/MODULE.bazel": "57242f92eecc485f09b07a8a1c8e2c7a6bf211808abb4599eec6fdbe875bb33f",
"https://bcr.bazel.build/modules/boost.throw_exception/1.90.0.bcr.1/source.json": "1889e091be52f80ebb436305663c64bc631527445edb153e622f6e22010e6c9e",
"https://bcr.bazel.build/modules/boost.unordered/1.90.0.bcr.1/MODULE.bazel": "4f7e455c70e9b3c57b840307aa77224011c10045082b45c0e46a1f96fce141ef",
"https://bcr.bazel.build/modules/boost.unordered/1.90.0.bcr.1/source.json": "61fb5bd89e2f70131f4afb459e61f14faa5f0b6d5cbbfc0a5cc1e0bee6e6fece",
"https://bcr.bazel.build/modules/boost/1.90.0.bcr.1/MODULE.bazel": "2f0a26d9a55a46017cf1f8a7895e49250f11306486419b002355f85ab595390f",
"https://bcr.bazel.build/modules/boost/1.90.0.bcr.1/source.json": "3ba95d0dcf35d52e907cc82d460a27024270cd684641912e550bfb4102da1a9e",
"https://bcr.bazel.build/modules/buildifier_prebuilt/7.3.1/MODULE.bazel": "537faf0ad9f5892910074b8e43b4c91c96f1d5d86b6ed04bdbe40cf68aa48b68",
"https://bcr.bazel.build/modules/buildifier_prebuilt/7.3.1/source.json": "55153a5e6ca9c8a7e266c4b46b951e8a010d25ec6062bc35d5d4f89925796bad",
"https://bcr.bazel.build/modules/buildifier_prebuilt/8.2.1.1/MODULE.bazel": "2e2e306add04b7c7cd21e73c9293dcbd7528a08a84338e919036f402eb6b1e2e",
"https://bcr.bazel.build/modules/buildifier_prebuilt/8.2.1.1/source.json": "4c86fd3a384a09613c2213fb1f71562d6d70471977e6e81173e6625fd6ce53bc",
"https://bcr.bazel.build/modules/buildozer/7.1.2/MODULE.bazel": "2e8dd40ede9c454042645fd8d8d0cd1527966aa5c919de86661e62953cd73d84",
"https://bcr.bazel.build/modules/buildozer/7.1.2/source.json": "c9028a501d2db85793a6996205c8de120944f50a0d570438fcae0457a5f9d1f8",
"https://bcr.bazel.build/modules/cgrindel_bazel_starlib/0.28.0/MODULE.bazel": "85c2dba5f968cbf8aa0fc735cab450f16cd36eed58b941ff7e3587ad442d5627",
@@ -94,8 +116,11 @@
"https://bcr.bazel.build/modules/jsoncpp/1.9.5/MODULE.bazel": "31271aedc59e815656f5736f282bb7509a97c7ecb43e927ac1a37966e0578075",
"https://bcr.bazel.build/modules/jsoncpp/1.9.6/MODULE.bazel": "2f8d20d3b7d54143213c4dfc3d98225c42de7d666011528dc8fe91591e2e17b0",
"https://bcr.bazel.build/modules/jsoncpp/1.9.6/source.json": "a04756d367a2126c3541682864ecec52f92cdee80a35735a3cb249ce015ca000",
"https://bcr.bazel.build/modules/libpfm/4.11.0.bcr.1/MODULE.bazel": "e5362dadc90aab6724c83a2cc1e67cbed9c89a05d97fb1f90053c8deb1e445c8",
"https://bcr.bazel.build/modules/libpfm/4.11.0/MODULE.bazel": "45061ff025b301940f1e30d2c16bea596c25b176c8b6b3087e92615adbd52902",
"https://bcr.bazel.build/modules/libpfm/4.13.0/MODULE.bazel": "6f2fcac49a2ebd660573aa8075654d84a4904d3a8a7d416f3bde3678573a7244",
"https://bcr.bazel.build/modules/libpfm/4.13.0/source.json": "d77a2fd45f92dcebdd864a3c2a05f28506a4f2f71ce15f85333d9ce5b9e29742",
"https://bcr.bazel.build/modules/nlohmann_json/3.6.1/MODULE.bazel": "6f7b417dcc794d9add9e556673ad25cb3ba835224290f4f848f8e2db1e1fca74",
"https://bcr.bazel.build/modules/nlohmann_json/3.6.1/source.json": "f448c6e8963fdfa7eb831457df83ad63d3d6355018f6574fb017e8169deb43a9",
"https://bcr.bazel.build/modules/package_metadata/0.0.2/MODULE.bazel": "fb8d25550742674d63d7b250063d4580ca530499f045d70748b1b142081ebb92",
"https://bcr.bazel.build/modules/package_metadata/0.0.2/source.json": "e53a759a72488d2c0576f57491ef2da0cf4aab05ac0997314012495935531b73",
"https://bcr.bazel.build/modules/platforms/0.0.10/MODULE.bazel": "8cb8efaf200bdeb2150d93e162c40f388529a25852b332cec879373771e48ed5",
@@ -121,9 +146,10 @@
"https://bcr.bazel.build/modules/protobuf/3.19.0/MODULE.bazel": "6b5fbb433f760a99a22b18b6850ed5784ef0e9928a72668b66e4d7ccd47db9b0",
"https://bcr.bazel.build/modules/protobuf/3.19.2/MODULE.bazel": "532ffe5f2186b69fdde039efe6df13ba726ff338c6bc82275ad433013fa10573",
"https://bcr.bazel.build/modules/protobuf/3.19.6/MODULE.bazel": "9233edc5e1f2ee276a60de3eaa47ac4132302ef9643238f23128fea53ea12858",
"https://bcr.bazel.build/modules/protobuf/31.0/MODULE.bazel": "cce0f305064713b382211c4c5af1d4fc1466e1fbc9059aa0941801970f6add5c",
"https://bcr.bazel.build/modules/protobuf/32.1/MODULE.bazel": "89cd2866a9cb07fee9ff74c41ceace11554f32e0d849de4e23ac55515cfada4d",
"https://bcr.bazel.build/modules/protobuf/34.0-rc1/MODULE.bazel": "3625d0d1e4032b624d093c1064cf4d7544caec48e66766f32b6407d4e15822f3",
"https://bcr.bazel.build/modules/protobuf/34.0-rc1/source.json": "aab642d6812f4aaf3f2f1097f23182702c465aff1a79c86a8e6f32db1600934a",
"https://bcr.bazel.build/modules/protobuf/34.0.bcr.1/MODULE.bazel": "74e541b0ba877813da786a11707d4e394433c157841d5111a36be0d44b907931",
"https://bcr.bazel.build/modules/protobuf/34.0.bcr.1/source.json": "fc174b3d6215aa14197d1bd779f98bb72d9fd666ee5ec0d6bba6ae986baa4535",
"https://bcr.bazel.build/modules/pybind11_bazel/2.11.1.bzl.1/MODULE.bazel": "1ef2994c097ee88f8f7ae8fbf991aaefb0603b2540fe575eca14943bc9f220a6",
"https://bcr.bazel.build/modules/pybind11_bazel/2.11.1/MODULE.bazel": "88af1c246226d87e65be78ed49ecd1e6f5e98648558c14ce99176da041dc378e",
"https://bcr.bazel.build/modules/pybind11_bazel/2.12.0/MODULE.bazel": "e6f4c20442eaa7c90d7190d8dc539d0ab422f95c65a57cc59562170c58ae3d34",
@@ -140,9 +166,8 @@
"https://bcr.bazel.build/modules/rules_android/0.1.1/MODULE.bazel": "48809ab0091b07ad0182defb787c4c5328bd3a278938415c00a7b69b50c4d3a8",
"https://bcr.bazel.build/modules/rules_android/0.1.1/source.json": "e6986b41626ee10bdc864937ffb6d6bf275bb5b9c65120e6137d56e6331f089e",
"https://bcr.bazel.build/modules/rules_apple/3.16.0/MODULE.bazel": "0d1caf0b8375942ce98ea944be754a18874041e4e0459401d925577624d3a54a",
"https://bcr.bazel.build/modules/rules_apple/3.16.0/source.json": "d8b5fe461272018cc07cfafce11fe369c7525330804c37eec5a82f84cd475366",
"https://bcr.bazel.build/modules/rules_bazel_integration_test/0.36.0/MODULE.bazel": "80e7595ab3a92ecd32f3cb00a60df6018e9eb1b2a2a3d5aa68d908514d0c6c69",
"https://bcr.bazel.build/modules/rules_bazel_integration_test/0.36.0/source.json": "928bead08b5cf296bc0abd11f86989b13758891cfb7925885dde9c006a0c5b2f",
"https://bcr.bazel.build/modules/rules_bazel_integration_test/0.37.1/MODULE.bazel": "f0ae81ced7a917eb59f865ebd2307af9e142763783990ac1207140ad6275505e",
"https://bcr.bazel.build/modules/rules_bazel_integration_test/0.37.1/source.json": "9123f56b53be8d7dbe6b90a753bb2443e286605e70e485cd4f649d8ab7fe2564",
"https://bcr.bazel.build/modules/rules_cc/0.0.1/MODULE.bazel": "cb2aa0747f84c6c3a78dad4e2049c154f08ab9d166b1273835a8174940365647",
"https://bcr.bazel.build/modules/rules_cc/0.0.10/MODULE.bazel": "ec1705118f7eaedd6e118508d3d26deba2a4e76476ada7e0e3965211be012002",
"https://bcr.bazel.build/modules/rules_cc/0.0.13/MODULE.bazel": "0e8529ed7b323dad0775ff924d2ae5af7640b23553dfcd4d34344c7e7a867191",
@@ -160,7 +185,8 @@
"https://bcr.bazel.build/modules/rules_cc/0.2.0/MODULE.bazel": "b5c17f90458caae90d2ccd114c81970062946f49f355610ed89bebf954f5783c",
"https://bcr.bazel.build/modules/rules_cc/0.2.14/MODULE.bazel": "353c99ed148887ee89c54a17d4100ae7e7e436593d104b668476019023b58df8",
"https://bcr.bazel.build/modules/rules_cc/0.2.16/MODULE.bazel": "9242fa89f950c6ef7702801ab53922e99c69b02310c39fb6e62b2bd30df2a1d4",
"https://bcr.bazel.build/modules/rules_cc/0.2.16/source.json": "d03d5cde49376d87e14ec14b666c56075e5e3926930327fd5d0484a1ff2ac1cc",
"https://bcr.bazel.build/modules/rules_cc/0.2.17/MODULE.bazel": "1849602c86cb60da8613d2de887f9566a6d354a6df6d7009f9d04a14402f9a84",
"https://bcr.bazel.build/modules/rules_cc/0.2.17/source.json": "3832f45d145354049137c0090df04629d9c2b5493dc5c2bf46f1834040133a07",
"https://bcr.bazel.build/modules/rules_cc/0.2.8/MODULE.bazel": "f1df20f0bf22c28192a794f29b501ee2018fa37a3862a1a2132ae2940a23a642",
"https://bcr.bazel.build/modules/rules_cc/0.2.9/MODULE.bazel": "34263f1dca62ea664265438cef714d7db124c03e1ed55ebb4f1dc860164308d1",
"https://bcr.bazel.build/modules/rules_foreign_cc/0.9.0/MODULE.bazel": "c9e8c682bf75b0e7c704166d79b599f93b72cfca5ad7477df596947891feeef6",
@@ -233,8 +259,8 @@
"https://bcr.bazel.build/modules/rules_python/1.5.1/MODULE.bazel": "acfe65880942d44a69129d4c5c3122d57baaf3edf58ae5a6bd4edea114906bf5",
"https://bcr.bazel.build/modules/rules_python/1.6.0/MODULE.bazel": "7e04ad8f8d5bea40451cf80b1bd8262552aa73f841415d20db96b7241bd027d8",
"https://bcr.bazel.build/modules/rules_python/1.6.3/MODULE.bazel": "a7b80c42cb3de5ee2a5fa1abc119684593704fcd2fec83165ebe615dec76574f",
"https://bcr.bazel.build/modules/rules_python/1.8.3/MODULE.bazel": "f343e159b59701334be3914416b9f1b72845801ba47920fcb288af4ce8c5cce3",
"https://bcr.bazel.build/modules/rules_python/1.8.3/source.json": "e5439f308e3c6f79f318a0f87108db46fc575be89370c3dfb3f7e0eaa571a3f8",
"https://bcr.bazel.build/modules/rules_python/1.9.0/MODULE.bazel": "afc3a05f29f09f2d3ee95ad99a145250dab41a2b2d8d6f82cc91936b3213282c",
"https://bcr.bazel.build/modules/rules_python/1.9.0/source.json": "3921ea0b65298d51aead5b9e4a82203d7be9b5918619b58b53f1c259f4e63169",
"https://bcr.bazel.build/modules/rules_shell/0.2.0/MODULE.bazel": "fda8a652ab3c7d8fee214de05e7a9916d8b28082234e8d2c0094505c5268ed3c",
"https://bcr.bazel.build/modules/rules_shell/0.3.0/MODULE.bazel": "de4402cd12f4cc8fda2354fce179fdb068c0b9ca1ec2d2b17b3e21b24c1a937b",
"https://bcr.bazel.build/modules/rules_shell/0.4.1/MODULE.bazel": "00e501db01bbf4e3e1dd1595959092c2fadf2087b2852d3f553b5370f5633592",
@@ -242,7 +268,6 @@
"https://bcr.bazel.build/modules/rules_shell/0.6.1/source.json": "20ec05cd5e592055e214b2da8ccb283c7f2a421ea0dc2acbf1aa792e11c03d0c",
"https://bcr.bazel.build/modules/rules_swift/1.16.0/MODULE.bazel": "4a09f199545a60d09895e8281362b1ff3bb08bbde69c6fc87aff5b92fcc916ca",
"https://bcr.bazel.build/modules/rules_swift/2.1.1/MODULE.bazel": "494900a80f944fc7aa61500c2073d9729dff0b764f0e89b824eb746959bc1046",
"https://bcr.bazel.build/modules/rules_swift/2.1.1/source.json": "40fc69dfaac64deddbb75bd99cdac55f4427d9ca0afbe408576a65428427a186",
"https://bcr.bazel.build/modules/stardoc/0.5.1/MODULE.bazel": "1a05d92974d0c122f5ccf09291442580317cdd859f07a8655f1db9a60374f9f8",
"https://bcr.bazel.build/modules/stardoc/0.5.3/MODULE.bazel": "c7f6948dae6999bf0db32c1858ae345f112cacf98f174c7a8bb707e41b974f1c",
"https://bcr.bazel.build/modules/stardoc/0.5.6/MODULE.bazel": "c43dabc564990eeab55e25ed61c07a1aadafe9ece96a4efabb3f8bf9063b71ef",
@@ -253,14 +278,13 @@
"https://bcr.bazel.build/modules/stardoc/0.8.0/MODULE.bazel": "bbad4298d7ba185684f5fcd71b049c95b0575d1248891fd80b8d7077d647c9d8",
"https://bcr.bazel.build/modules/stardoc/0.8.0/source.json": "7321db37080ee8a445dc60e8516a98ab3a27884d1457b892485d73759ccb7f4d",
"https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.1/MODULE.bazel": "5e463fbfba7b1701d957555ed45097d7f984211330106ccd1352c6e0af0dcf91",
"https://bcr.bazel.build/modules/swift_argument_parser/1.3.1.1/source.json": "32bd87e5f4d7acc57c5b2ff7c325ae3061d5e242c0c4c214ae87e0f1c13e54cb",
"https://bcr.bazel.build/modules/tar.bzl/0.2.1/MODULE.bazel": "52d1c00a80a8cc67acbd01649e83d8dd6a9dc426a6c0b754a04fe8c219c76468",
"https://bcr.bazel.build/modules/tar.bzl/0.5.1/MODULE.bazel": "7c2eb3dcfc53b0f3d6f9acdfd911ca803eaf92aadf54f8ca6e4c1f3aee288351",
"https://bcr.bazel.build/modules/tar.bzl/0.5.1/source.json": "deed3094f7cc779ed1d37a68403847b0e38d9dd9d931e03cb90825f3368b515f",
"https://bcr.bazel.build/modules/tcmalloc/0.0.0-20250927-12f2552/MODULE.bazel": "b702a6b6806b1041d84918c5098b765b204261647f8cb3e75e0f439106b65ddd",
"https://bcr.bazel.build/modules/tcmalloc/0.0.0-20250927-12f2552/source.json": "a6f5da61dd65e3f2f7380b4f52dd4b0f771a5b6ba9db7b46be7c28c52bc7af58",
"https://bcr.bazel.build/modules/tree-sitter-bazel/0.26.3.bcr.1/MODULE.bazel": "f1a345fed7a67d7638580bad407f34d06eee2ca61816e3e7e75c80a1c0a2e610",
"https://bcr.bazel.build/modules/tree-sitter-bazel/0.26.3.bcr.1/source.json": "4e468b20cd538648e5a9ac3581ff459e68509bd5b7ce467f6faf0382a469b0c1",
"https://bcr.bazel.build/modules/tree-sitter-bazel/0.26.5/MODULE.bazel": "89490910fa107d8ef22cc8c3be7acbce733c2352739c7a61297336454a539a65",
"https://bcr.bazel.build/modules/tree-sitter-bazel/0.26.5/source.json": "cd6d21ca1b159961230ac6c33e0c7f638d7c40daa6746b4097d896441fd89074",
"https://bcr.bazel.build/modules/upb/0.0.0-20220923-a547704/MODULE.bazel": "7298990c00040a0e2f121f6c32544bab27d4452f80d9ce51349b1a28f3005c43",
"https://bcr.bazel.build/modules/upb/0.0.0-20230516-61a97ef/MODULE.bazel": "c0df5e35ad55e264160417fd0875932ee3c9dda63d9fccace35ac62f45e1b6f9",
"https://bcr.bazel.build/modules/yq.bzl/0.1.1/MODULE.bazel": "9039681f9bcb8958ee2c87ffc74bdafba9f4369096a2b5634b88abc0eaefa072",
@@ -279,7 +303,7 @@
"moduleExtensions": {
"//bazel/cc_toolchains:clang_configuration.bzl%clang_toolchain_extension": {
"general": {
"bzlTransitiveDigest": "44/bjnoCpU6JrWf798MGhACH/QjSv0OkcCi/jF+EGg0=",
"bzlTransitiveDigest": "H3RsK0MbgutDMSlPWTwZq4Vk1U5sjDtgJ5MXQxg7GLU=",
"usagesDigest": "lTxkeAFhR0iBEa3dg5hWvtd2HFCr5zCJx/fl27A+IKA=",
"recordedFileInputs": {},
"recordedDirentsInputs": {},
@@ -302,7 +326,7 @@
"envVariables": {},
"generatedRepoSpecs": {
"llvm-project": {
"repoRuleId": "@@+_repo_rules+llvm-raw//utils/bazel:configure.bzl%llvm_configure",
"repoRuleId": "@@llvm-raw+//utils/bazel:configure.bzl%llvm_configure",
"attributes": {
"targets": [
"AArch64",
@@ -315,146 +339,7 @@
[
"",
"llvm-raw",
"+_repo_rules+llvm-raw"
]
]
}
},
"@@buildifier_prebuilt+//:defs.bzl%buildifier_prebuilt_deps_extension": {
"general": {
"bzlTransitiveDigest": "o1WPvgvSISMJsXVrFW1v+M17eIj9AJjkcTAucRVb3vI=",
"usagesDigest": "eWMDBEn8E8CrwAPXrlrjIap2pseSMhxDyDdrntHBOOE=",
"recordedFileInputs": {},
"recordedDirentsInputs": {},
"envVariables": {},
"generatedRepoSpecs": {
"buildifier_darwin_amd64": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file",
"attributes": {
"urls": [
"https://github.com/bazelbuild/buildtools/releases/download/v7.3.1/buildifier-darwin-amd64"
],
"downloaded_file_path": "buildifier",
"executable": true,
"sha256": "375f823103d01620aaec20a0c29c6cbca99f4fd0725ae30b93655c6704f44d71"
}
},
"buildifier_darwin_arm64": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file",
"attributes": {
"urls": [
"https://github.com/bazelbuild/buildtools/releases/download/v7.3.1/buildifier-darwin-arm64"
],
"downloaded_file_path": "buildifier",
"executable": true,
"sha256": "5a6afc6ac7a09f5455ba0b89bd99d5ae23b4174dc5dc9d6c0ed5ce8caac3f813"
}
},
"buildifier_linux_amd64": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file",
"attributes": {
"urls": [
"https://github.com/bazelbuild/buildtools/releases/download/v7.3.1/buildifier-linux-amd64"
],
"downloaded_file_path": "buildifier",
"executable": true,
"sha256": "5474cc5128a74e806783d54081f581662c4be8ae65022f557e9281ed5dc88009"
}
},
"buildifier_linux_arm64": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file",
"attributes": {
"urls": [
"https://github.com/bazelbuild/buildtools/releases/download/v7.3.1/buildifier-linux-arm64"
],
"downloaded_file_path": "buildifier",
"executable": true,
"sha256": "0bf86c4bfffaf4f08eed77bde5b2082e4ae5039a11e2e8b03984c173c34a561c"
}
},
"buildifier_windows_amd64": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file",
"attributes": {
"urls": [
"https://github.com/bazelbuild/buildtools/releases/download/v7.3.1/buildifier-windows-amd64.exe"
],
"downloaded_file_path": "buildifier.exe",
"executable": true,
"sha256": "370cd576075ad29930a82f5de132f1a1de4084c784a82514bd4da80c85acf4a8"
}
},
"buildozer_darwin_amd64": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file",
"attributes": {
"urls": [
"https://github.com/bazelbuild/buildtools/releases/download/v7.3.1/buildozer-darwin-amd64"
],
"downloaded_file_path": "buildozer",
"executable": true,
"sha256": "854c9583efc166602276802658cef3f224d60898cfaa60630b33d328db3b0de2"
}
},
"buildozer_darwin_arm64": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file",
"attributes": {
"urls": [
"https://github.com/bazelbuild/buildtools/releases/download/v7.3.1/buildozer-darwin-arm64"
],
"downloaded_file_path": "buildozer",
"executable": true,
"sha256": "31b1bfe20d7d5444be217af78f94c5c43799cdf847c6ce69794b7bf3319c5364"
}
},
"buildozer_linux_amd64": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file",
"attributes": {
"urls": [
"https://github.com/bazelbuild/buildtools/releases/download/v7.3.1/buildozer-linux-amd64"
],
"downloaded_file_path": "buildozer",
"executable": true,
"sha256": "3305e287b3fcc68b9a35fd8515ee617452cd4e018f9e6886b6c7cdbcba8710d4"
}
},
"buildozer_linux_arm64": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file",
"attributes": {
"urls": [
"https://github.com/bazelbuild/buildtools/releases/download/v7.3.1/buildozer-linux-arm64"
],
"downloaded_file_path": "buildozer",
"executable": true,
"sha256": "0b5a2a717ac4fc911e1fec8d92af71dbb4fe95b10e5213da0cc3d56cea64a328"
}
},
"buildozer_windows_amd64": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_file",
"attributes": {
"urls": [
"https://github.com/bazelbuild/buildtools/releases/download/v7.3.1/buildozer-windows-amd64.exe"
],
"downloaded_file_path": "buildozer.exe",
"executable": true,
"sha256": "58d41ce53257c5594c9bc86d769f580909269f68de114297f46284fbb9023dcf"
}
},
"buildifier_prebuilt_toolchains": {
"repoRuleId": "@@buildifier_prebuilt+//:defs.bzl%_buildifier_toolchain_setup",
"attributes": {
"assets_json": "[{\"arch\":\"amd64\",\"name\":\"buildifier\",\"platform\":\"darwin\",\"sha256\":\"375f823103d01620aaec20a0c29c6cbca99f4fd0725ae30b93655c6704f44d71\",\"version\":\"v7.3.1\"},{\"arch\":\"arm64\",\"name\":\"buildifier\",\"platform\":\"darwin\",\"sha256\":\"5a6afc6ac7a09f5455ba0b89bd99d5ae23b4174dc5dc9d6c0ed5ce8caac3f813\",\"version\":\"v7.3.1\"},{\"arch\":\"amd64\",\"name\":\"buildifier\",\"platform\":\"linux\",\"sha256\":\"5474cc5128a74e806783d54081f581662c4be8ae65022f557e9281ed5dc88009\",\"version\":\"v7.3.1\"},{\"arch\":\"arm64\",\"name\":\"buildifier\",\"platform\":\"linux\",\"sha256\":\"0bf86c4bfffaf4f08eed77bde5b2082e4ae5039a11e2e8b03984c173c34a561c\",\"version\":\"v7.3.1\"},{\"arch\":\"amd64\",\"name\":\"buildifier\",\"platform\":\"windows\",\"sha256\":\"370cd576075ad29930a82f5de132f1a1de4084c784a82514bd4da80c85acf4a8\",\"version\":\"v7.3.1\"},{\"arch\":\"amd64\",\"name\":\"buildozer\",\"platform\":\"darwin\",\"sha256\":\"854c9583efc166602276802658cef3f224d60898cfaa60630b33d328db3b0de2\",\"version\":\"v7.3.1\"},{\"arch\":\"arm64\",\"name\":\"buildozer\",\"platform\":\"darwin\",\"sha256\":\"31b1bfe20d7d5444be217af78f94c5c43799cdf847c6ce69794b7bf3319c5364\",\"version\":\"v7.3.1\"},{\"arch\":\"amd64\",\"name\":\"buildozer\",\"platform\":\"linux\",\"sha256\":\"3305e287b3fcc68b9a35fd8515ee617452cd4e018f9e6886b6c7cdbcba8710d4\",\"version\":\"v7.3.1\"},{\"arch\":\"arm64\",\"name\":\"buildozer\",\"platform\":\"linux\",\"sha256\":\"0b5a2a717ac4fc911e1fec8d92af71dbb4fe95b10e5213da0cc3d56cea64a328\",\"version\":\"v7.3.1\"},{\"arch\":\"amd64\",\"name\":\"buildozer\",\"platform\":\"windows\",\"sha256\":\"58d41ce53257c5594c9bc86d769f580909269f68de114297f46284fbb9023dcf\",\"version\":\"v7.3.1\"}]"
}
}
},
"recordedRepoMappingEntries": [
[
"buildifier_prebuilt+",
"bazel_skylib",
"bazel_skylib+"
],
[
"buildifier_prebuilt+",
"bazel_tools",
"bazel_tools"
"llvm-raw+"
]
]
}
@@ -475,174 +360,22 @@
"recordedRepoMappingEntries": []
}
},
"@@hedron_compile_commands+//:workspace_setup.bzl%hedron_compile_commands_extension": {
"@@protobuf+//python/dist:system_python.bzl%system_python_extension": {
"general": {
"bzlTransitiveDigest": "GTNjt7oW5GiUBfcBtXAq5etqAZ6ue6PRd5nPaxeMoYM=",
"usagesDigest": "CbJ2MjubH36j9xaONhhASfhodhpi5fzvuyg/IW2f7Ds=",
"recordedFileInputs": {},
"recordedDirentsInputs": {},
"envVariables": {},
"generatedRepoSpecs": {},
"recordedRepoMappingEntries": [
[
"hedron_compile_commands+",
"bazel_tools",
"bazel_tools"
]
]
}
},
"@@hedron_compile_commands+//:workspace_setup_transitive.bzl%hedron_compile_commands_extension": {
"general": {
"bzlTransitiveDigest": "IfDf0vEa2jjQ11RNpUM0u4xftPXIs+pyM8IMVkRqVMk=",
"usagesDigest": "yxZQbFglJyjpn7JZ9mhIc3EhLzZivlbs6wiHWOKJ/UA=",
"recordedFileInputs": {},
"recordedDirentsInputs": {},
"envVariables": {},
"generatedRepoSpecs": {},
"recordedRepoMappingEntries": []
}
},
"@@hedron_compile_commands+//:workspace_setup_transitive_transitive.bzl%hedron_compile_commands_extension": {
"general": {
"bzlTransitiveDigest": "1p58k3o2Jgjt/pBE7cb8WmmkplrSguIKma/h32x7X10=",
"usagesDigest": "GkOuy/k8wz0dbKMeEJFKEJB3CWkMZt3DYcPgj4lALkI=",
"recordedFileInputs": {},
"recordedDirentsInputs": {},
"envVariables": {},
"generatedRepoSpecs": {},
"recordedRepoMappingEntries": []
}
},
"@@hedron_compile_commands+//:workspace_setup_transitive_transitive_transitive.bzl%hedron_compile_commands_extension": {
"general": {
"bzlTransitiveDigest": "arNWX4EleUjJxqkM5nCRTj+ce05Zz1gSdGH1DCKOoLs=",
"usagesDigest": "WZExKK/BI4lqpUZfPpv4YARDE1Y7igQB+wYGKvNoCKs=",
"recordedFileInputs": {},
"recordedDirentsInputs": {},
"envVariables": {},
"generatedRepoSpecs": {},
"recordedRepoMappingEntries": []
}
},
"@@rules_apple+//apple:apple.bzl%provisioning_profile_repository_extension": {
"general": {
"bzlTransitiveDigest": "pdRt+Wm+XQmS427nAIg9z7qfm56CnZChO+HJ4zu3Xa8=",
"usagesDigest": "vsJl8Rw5NL+5Ag2wdUDoTeRF/5klkXO8545Iy7U1Q08=",
"bzlTransitiveDigest": "pmsA+awieucfllLc2n7k8xEoPp0i5LF9Hw6mGX0cqSQ=",
"usagesDigest": "A+RWmbKdBBwZcBbNGNvfPbqG2vYZRjVrFp6x1iRUrAk=",
"recordedFileInputs": {},
"recordedDirentsInputs": {},
"envVariables": {},
"generatedRepoSpecs": {
"local_provisioning_profiles": {
"repoRuleId": "@@rules_apple+//apple/internal:local_provisioning_profiles.bzl%provisioning_profile_repository",
"attributes": {}
}
},
"recordedRepoMappingEntries": [
[
"apple_support+",
"bazel_skylib",
"bazel_skylib+"
],
[
"bazel_tools",
"rules_cc",
"rules_cc+"
],
[
"rules_apple+",
"bazel_skylib",
"bazel_skylib+"
],
[
"rules_apple+",
"bazel_tools",
"bazel_tools"
],
[
"rules_apple+",
"build_bazel_apple_support",
"apple_support+"
],
[
"rules_apple+",
"build_bazel_rules_swift",
"rules_swift+"
],
[
"rules_cc+",
"bazel_tools",
"bazel_tools"
],
[
"rules_cc+",
"cc_compatibility_proxy",
"rules_cc++compatibility_proxy+cc_compatibility_proxy"
],
[
"rules_cc+",
"rules_cc",
"rules_cc+"
],
[
"rules_cc++compatibility_proxy+cc_compatibility_proxy",
"rules_cc",
"rules_cc+"
],
[
"rules_swift+",
"bazel_skylib",
"bazel_skylib+"
],
[
"rules_swift+",
"bazel_tools",
"bazel_tools"
],
[
"rules_swift+",
"build_bazel_apple_support",
"apple_support+"
],
[
"rules_swift+",
"build_bazel_rules_swift",
"rules_swift+"
],
[
"rules_swift+",
"build_bazel_rules_swift_local_config",
"rules_swift++non_module_deps+build_bazel_rules_swift_local_config"
]
]
}
},
"@@rules_apple+//apple:extensions.bzl%non_module_deps": {
"general": {
"bzlTransitiveDigest": "UsflLeiazyu2v5pvibcvOeIdDV95S25rT96h4XU1nhY=",
"usagesDigest": "M3VqFpeTCo4qmrNKGZw0dxBHvTYDrfV3cscGzlSAhQ4=",
"recordedFileInputs": {},
"recordedDirentsInputs": {},
"envVariables": {},
"generatedRepoSpecs": {
"xctestrunner": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"system_python": {
"repoRuleId": "@@protobuf+//python/dist:system_python.bzl%system_python",
"attributes": {
"urls": [
"https://github.com/google/xctestrunner/archive/b7698df3d435b6491b4b4c0f9fc7a63fbed5e3a6.tar.gz"
],
"strip_prefix": "xctestrunner-b7698df3d435b6491b4b4c0f9fc7a63fbed5e3a6",
"sha256": "ae3a063c985a8633cb7eb566db21656f8db8eb9a0edb8c182312c7f0db53730d"
"minimum_python_version": "3.9"
}
}
},
"recordedRepoMappingEntries": [
[
"rules_apple+",
"bazel_tools",
"bazel_tools"
]
]
"recordedRepoMappingEntries": []
}
},
"@@rules_bazel_integration_test+//:extensions.bzl%bazel_binaries": {
@@ -782,245 +515,10 @@
]
}
},
"@@rules_python+//python/extensions:config.bzl%config": {
"general": {
"bzlTransitiveDigest": "uo49IDITNsksO4x76pZ7eYlLKomkU77mK8VTrbCHXZM=",
"usagesDigest": "HZ99ezJBkgjKcxXQ3OBxGgesUIMF6eg7E0TUNOait2I=",
"recordedFileInputs": {},
"recordedDirentsInputs": {},
"envVariables": {},
"generatedRepoSpecs": {
"rules_python_internal": {
"repoRuleId": "@@rules_python+//python/private:internal_config_repo.bzl%internal_config_repo",
"attributes": {
"transition_setting_generators": {},
"transition_settings": []
}
},
"pypi__build": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"url": "https://files.pythonhosted.org/packages/e2/03/f3c8ba0a6b6e30d7d18c40faab90807c9bb5e9a1e3b2fe2008af624a9c97/build-1.2.1-py3-none-any.whl",
"sha256": "75e10f767a433d9a86e50d83f418e83efc18ede923ee5ff7df93b6cb0306c5d4",
"type": "zip",
"build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
}
},
"pypi__click": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"url": "https://files.pythonhosted.org/packages/00/2e/d53fa4befbf2cfa713304affc7ca780ce4fc1fd8710527771b58311a3229/click-8.1.7-py3-none-any.whl",
"sha256": "ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28",
"type": "zip",
"build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
}
},
"pypi__colorama": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"url": "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl",
"sha256": "4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6",
"type": "zip",
"build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
}
},
"pypi__importlib_metadata": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"url": "https://files.pythonhosted.org/packages/2d/0a/679461c511447ffaf176567d5c496d1de27cbe34a87df6677d7171b2fbd4/importlib_metadata-7.1.0-py3-none-any.whl",
"sha256": "30962b96c0c223483ed6cc7280e7f0199feb01a0e40cfae4d4450fc6fab1f570",
"type": "zip",
"build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
}
},
"pypi__installer": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"url": "https://files.pythonhosted.org/packages/e5/ca/1172b6638d52f2d6caa2dd262ec4c811ba59eee96d54a7701930726bce18/installer-0.7.0-py3-none-any.whl",
"sha256": "05d1933f0a5ba7d8d6296bb6d5018e7c94fa473ceb10cf198a92ccea19c27b53",
"type": "zip",
"build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
}
},
"pypi__more_itertools": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"url": "https://files.pythonhosted.org/packages/50/e2/8e10e465ee3987bb7c9ab69efb91d867d93959095f4807db102d07995d94/more_itertools-10.2.0-py3-none-any.whl",
"sha256": "686b06abe565edfab151cb8fd385a05651e1fdf8f0a14191e4439283421f8684",
"type": "zip",
"build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
}
},
"pypi__packaging": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"url": "https://files.pythonhosted.org/packages/49/df/1fceb2f8900f8639e278b056416d49134fb8d84c5942ffaa01ad34782422/packaging-24.0-py3-none-any.whl",
"sha256": "2ddfb553fdf02fb784c234c7ba6ccc288296ceabec964ad2eae3777778130bc5",
"type": "zip",
"build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
}
},
"pypi__pep517": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"url": "https://files.pythonhosted.org/packages/25/6e/ca4a5434eb0e502210f591b97537d322546e4833dcb4d470a48c375c5540/pep517-0.13.1-py3-none-any.whl",
"sha256": "31b206f67165b3536dd577c5c3f1518e8fbaf38cbc57efff8369a392feff1721",
"type": "zip",
"build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
}
},
"pypi__pip": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"url": "https://files.pythonhosted.org/packages/8a/6a/19e9fe04fca059ccf770861c7d5721ab4c2aebc539889e97c7977528a53b/pip-24.0-py3-none-any.whl",
"sha256": "ba0d021a166865d2265246961bec0152ff124de910c5cc39f1156ce3fa7c69dc",
"type": "zip",
"build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
}
},
"pypi__pip_tools": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"url": "https://files.pythonhosted.org/packages/0d/dc/38f4ce065e92c66f058ea7a368a9c5de4e702272b479c0992059f7693941/pip_tools-7.4.1-py3-none-any.whl",
"sha256": "4c690e5fbae2f21e87843e89c26191f0d9454f362d8acdbd695716493ec8b3a9",
"type": "zip",
"build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
}
},
"pypi__pyproject_hooks": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"url": "https://files.pythonhosted.org/packages/ae/f3/431b9d5fe7d14af7a32340792ef43b8a714e7726f1d7b69cc4e8e7a3f1d7/pyproject_hooks-1.1.0-py3-none-any.whl",
"sha256": "7ceeefe9aec63a1064c18d939bdc3adf2d8aa1988a510afec15151578b232aa2",
"type": "zip",
"build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
}
},
"pypi__setuptools": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"url": "https://files.pythonhosted.org/packages/90/99/158ad0609729111163fc1f674a5a42f2605371a4cf036d0441070e2f7455/setuptools-78.1.1-py3-none-any.whl",
"sha256": "c3a9c4211ff4c309edb8b8c4f1cbfa7ae324c4ba9f91ff254e3d305b9fd54561",
"type": "zip",
"build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
}
},
"pypi__tomli": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"url": "https://files.pythonhosted.org/packages/97/75/10a9ebee3fd790d20926a90a2547f0bf78f371b2f13aa822c759680ca7b9/tomli-2.0.1-py3-none-any.whl",
"sha256": "939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc",
"type": "zip",
"build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
}
},
"pypi__wheel": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"url": "https://files.pythonhosted.org/packages/7d/cd/d7460c9a869b16c3dd4e1e403cce337df165368c71d6af229a74699622ce/wheel-0.43.0-py3-none-any.whl",
"sha256": "55c570405f142630c6b9f72fe09d9b67cf1477fcf543ae5b8dcb1f5b7377da81",
"type": "zip",
"build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
}
},
"pypi__zipp": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"url": "https://files.pythonhosted.org/packages/da/55/a03fd7240714916507e1fcf7ae355bd9d9ed2e6db492595f1a67f61681be/zipp-3.18.2-py3-none-any.whl",
"sha256": "dce197b859eb796242b0622af1b8beb0a722d52aa2f57133ead08edd5bf5374e",
"type": "zip",
"build_file_content": "package(default_visibility = [\"//visibility:public\"])\n\nload(\"@rules_python//python:py_library.bzl\", \"py_library\")\n\npy_library(\n name = \"lib\",\n srcs = glob([\"**/*.py\"]),\n data = glob([\"**/*\"], exclude=[\n # These entries include those put into user-installed dependencies by\n # data_exclude to avoid non-determinism.\n \"**/*.py\",\n \"**/*.pyc\",\n \"**/*.pyc.*\", # During pyc creation, temp files named *.pyc.NNN are created\n \"**/*.dist-info/RECORD\",\n \"BUILD\",\n \"WORKSPACE\",\n ]),\n # This makes this directory a top-level in the python import\n # search path for anything that depends on this.\n imports = [\".\"],\n)\n"
}
}
},
"recordedRepoMappingEntries": [
[
"rules_python+",
"bazel_tools",
"bazel_tools"
],
[
"rules_python+",
"pypi__build",
"rules_python++config+pypi__build"
],
[
"rules_python+",
"pypi__click",
"rules_python++config+pypi__click"
],
[
"rules_python+",
"pypi__colorama",
"rules_python++config+pypi__colorama"
],
[
"rules_python+",
"pypi__importlib_metadata",
"rules_python++config+pypi__importlib_metadata"
],
[
"rules_python+",
"pypi__installer",
"rules_python++config+pypi__installer"
],
[
"rules_python+",
"pypi__more_itertools",
"rules_python++config+pypi__more_itertools"
],
[
"rules_python+",
"pypi__packaging",
"rules_python++config+pypi__packaging"
],
[
"rules_python+",
"pypi__pep517",
"rules_python++config+pypi__pep517"
],
[
"rules_python+",
"pypi__pip",
"rules_python++config+pypi__pip"
],
[
"rules_python+",
"pypi__pip_tools",
"rules_python++config+pypi__pip_tools"
],
[
"rules_python+",
"pypi__pyproject_hooks",
"rules_python++config+pypi__pyproject_hooks"
],
[
"rules_python+",
"pypi__setuptools",
"rules_python++config+pypi__setuptools"
],
[
"rules_python+",
"pypi__tomli",
"rules_python++config+pypi__tomli"
],
[
"rules_python+",
"pypi__wheel",
"rules_python++config+pypi__wheel"
],
[
"rules_python+",
"pypi__zipp",
"rules_python++config+pypi__zipp"
]
]
}
},
"@@rules_python+//python/uv:uv.bzl%uv": {
"general": {
"bzlTransitiveDigest": "zyNsrbgVKwpA0B3zI84imAfuC424VSzYNPgjr/HJy5M=",
"usagesDigest": "XRYYokHTb3p1WwpZj2sncZ1bh8zJfO4YrKJ2PkapnO8=",
"bzlTransitiveDigest": "xMgnVVV6SeyGCaYQT+4rYddx63q6+JXtyCrlLeA8OLM=",
"usagesDigest": "6MjoD3H+netDdhklgMWks3NARpHVXxy8kfsMe9XXPa8=",
"recordedFileInputs": {},
"recordedDirentsInputs": {},
"envVariables": {},
@@ -1058,165 +556,6 @@
]
}
},
"@@rules_swift+//swift:extensions.bzl%non_module_deps": {
"general": {
"bzlTransitiveDigest": "WQxCEBSXJEaQYe860JXZvAQug2B6+/VbBtRIDMF0pOc=",
"usagesDigest": "mhACFnrdMv9Wi0Mt67bxocJqviRkDSV+Ee5Mqdj5akA=",
"recordedFileInputs": {},
"recordedDirentsInputs": {},
"envVariables": {},
"generatedRepoSpecs": {
"com_github_apple_swift_protobuf": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"urls": [
"https://github.com/apple/swift-protobuf/archive/1.20.2.tar.gz"
],
"sha256": "3fb50bd4d293337f202d917b6ada22f9548a0a0aed9d9a4d791e6fbd8a246ebb",
"strip_prefix": "swift-protobuf-1.20.2/",
"build_file": "@@rules_swift+//third_party:com_github_apple_swift_protobuf/BUILD.overlay"
}
},
"com_github_grpc_grpc_swift": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"urls": [
"https://github.com/grpc/grpc-swift/archive/1.16.0.tar.gz"
],
"sha256": "58b60431d0064969f9679411264b82e40a217ae6bd34e17096d92cc4e47556a5",
"strip_prefix": "grpc-swift-1.16.0/",
"build_file": "@@rules_swift+//third_party:com_github_grpc_grpc_swift/BUILD.overlay"
}
},
"com_github_apple_swift_docc_symbolkit": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"urls": [
"https://github.com/apple/swift-docc-symbolkit/archive/refs/tags/swift-5.10-RELEASE.tar.gz"
],
"sha256": "de1d4b6940468ddb53b89df7aa1a81323b9712775b0e33e8254fa0f6f7469a97",
"strip_prefix": "swift-docc-symbolkit-swift-5.10-RELEASE",
"build_file": "@@rules_swift+//third_party:com_github_apple_swift_docc_symbolkit/BUILD.overlay"
}
},
"com_github_apple_swift_nio": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"urls": [
"https://github.com/apple/swift-nio/archive/2.42.0.tar.gz"
],
"sha256": "e3304bc3fb53aea74a3e54bd005ede11f6dc357117d9b1db642d03aea87194a0",
"strip_prefix": "swift-nio-2.42.0/",
"build_file": "@@rules_swift+//third_party:com_github_apple_swift_nio/BUILD.overlay"
}
},
"com_github_apple_swift_nio_http2": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"urls": [
"https://github.com/apple/swift-nio-http2/archive/1.26.0.tar.gz"
],
"sha256": "f0edfc9d6a7be1d587e5b403f2d04264bdfae59aac1d74f7d974a9022c6d2b25",
"strip_prefix": "swift-nio-http2-1.26.0/",
"build_file": "@@rules_swift+//third_party:com_github_apple_swift_nio_http2/BUILD.overlay"
}
},
"com_github_apple_swift_nio_transport_services": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"urls": [
"https://github.com/apple/swift-nio-transport-services/archive/1.15.0.tar.gz"
],
"sha256": "f3498dafa633751a52b9b7f741f7ac30c42bcbeb3b9edca6d447e0da8e693262",
"strip_prefix": "swift-nio-transport-services-1.15.0/",
"build_file": "@@rules_swift+//third_party:com_github_apple_swift_nio_transport_services/BUILD.overlay"
}
},
"com_github_apple_swift_nio_extras": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"urls": [
"https://github.com/apple/swift-nio-extras/archive/1.4.0.tar.gz"
],
"sha256": "4684b52951d9d9937bb3e8ccd6b5daedd777021ef2519ea2f18c4c922843b52b",
"strip_prefix": "swift-nio-extras-1.4.0/",
"build_file": "@@rules_swift+//third_party:com_github_apple_swift_nio_extras/BUILD.overlay"
}
},
"com_github_apple_swift_log": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"urls": [
"https://github.com/apple/swift-log/archive/1.4.4.tar.gz"
],
"sha256": "48fe66426c784c0c20031f15dc17faf9f4c9037c192bfac2f643f65cb2321ba0",
"strip_prefix": "swift-log-1.4.4/",
"build_file": "@@rules_swift+//third_party:com_github_apple_swift_log/BUILD.overlay"
}
},
"com_github_apple_swift_nio_ssl": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"urls": [
"https://github.com/apple/swift-nio-ssl/archive/2.23.0.tar.gz"
],
"sha256": "4787c63f61dd04d99e498adc3d1a628193387e41efddf8de19b8db04544d016d",
"strip_prefix": "swift-nio-ssl-2.23.0/",
"build_file": "@@rules_swift+//third_party:com_github_apple_swift_nio_ssl/BUILD.overlay"
}
},
"com_github_apple_swift_collections": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"urls": [
"https://github.com/apple/swift-collections/archive/1.0.4.tar.gz"
],
"sha256": "d9e4c8a91c60fb9c92a04caccbb10ded42f4cb47b26a212bc6b39cc390a4b096",
"strip_prefix": "swift-collections-1.0.4/",
"build_file": "@@rules_swift+//third_party:com_github_apple_swift_collections/BUILD.overlay"
}
},
"com_github_apple_swift_atomics": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"urls": [
"https://github.com/apple/swift-atomics/archive/1.1.0.tar.gz"
],
"sha256": "1bee7f469f7e8dc49f11cfa4da07182fbc79eab000ec2c17bfdce468c5d276fb",
"strip_prefix": "swift-atomics-1.1.0/",
"build_file": "@@rules_swift+//third_party:com_github_apple_swift_atomics/BUILD.overlay"
}
},
"build_bazel_rules_swift_index_import": {
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"build_file": "@@rules_swift+//third_party:build_bazel_rules_swift_index_import/BUILD.overlay",
"canonical_id": "index-import-5.8",
"urls": [
"https://github.com/MobileNativeFoundation/index-import/releases/download/5.8.0.1/index-import.tar.gz"
],
"sha256": "28c1ffa39d99e74ed70623899b207b41f79214c498c603915aef55972a851a15"
}
},
"build_bazel_rules_swift_local_config": {
"repoRuleId": "@@rules_swift+//swift/internal:swift_autoconfiguration.bzl%swift_autoconfiguration",
"attributes": {}
}
},
"recordedRepoMappingEntries": [
[
"rules_swift+",
"bazel_tools",
"bazel_tools"
],
[
"rules_swift+",
"build_bazel_rules_swift",
"rules_swift+"
]
]
}
},
"@@tar.bzl+//tar:extensions.bzl%toolchains": {
"general": {
"bzlTransitiveDigest": "/2afh6fPjq/rcyE/jztQDK3ierehmFFngfvmqyRv72M=",
@@ -1273,8 +612,8 @@
},
"@@tree-sitter-bazel+//:extensions.bzl%tree_sitter_source_code": {
"general": {
"bzlTransitiveDigest": "KYhQoHhKhCJWpa7kdOCSJHfvoRI6uarN4w0fyeq4iR4=",
"usagesDigest": "hkrVfsiyTLSTF7N2MmeQQHb6pousjxoec1z1ssf1ves=",
"bzlTransitiveDigest": "+u7gt12DDE2IggDr5YYMDsyBWdTH2+a+CzDt4N2GLEA=",
"usagesDigest": "SDugPL30QE62Ha2gZXbI9INYOeOxsPevizX6CCLFoto=",
"recordedFileInputs": {},
"recordedDirentsInputs": {},
"envVariables": {},
@@ -1283,11 +622,11 @@
"repoRuleId": "@@bazel_tools//tools/build_defs/repo:http.bzl%http_archive",
"attributes": {
"urls": [
"https://github.com/tree-sitter/tree-sitter/archive/refs/tags/v0.26.3.tar.gz"
"https://github.com/tree-sitter/tree-sitter/archive/refs/tags/v0.26.5.tar.gz"
],
"sha256": "",
"integrity": "sha384-hjXxOdrMwTow3ji5CeIL5UchJHXQYTIU/MOZ4cG+TPqS0kQaEF9HsGianilGFIY+",
"strip_prefix": "tree-sitter-0.26.3",
"integrity": "sha384-UFn59au2/IMpAb2LqYOhZsHOhoFOttBAnZ5wPPPL4woryAnZyW/c1xEiiBobALr/",
"strip_prefix": "tree-sitter-0.26.5",
"build_file_content": "exports_files(glob([\"lib/**\"]))"
}
}
+13
View File
@@ -365,6 +365,19 @@ Learn more about the Carbon project:
Carbon focused talks from the community:
### 2026
- Benchmarking and optimizing the Carbon compiler, NDC {Toronto} (May 5-8)
- Carbon: graduating from the experiment, NDC {Toronto} (May 5-8)
### 2025
- Carbon: from C++ to Memory Safety, REBASE - ICFP/SPLASH
([slides](https://chandlerc.blog/slides/2025-rebase-carbon))
- Memory safety everywhere with both Carbon and Rust, RustConf
([video](https://youtu.be/FYLuom6gg_s),
[slides](https://chandlerc.blog/slides/2025-rustconf-memory-safety-everywhere))
### 2024
- Generic implementation strategies in Carbon and Clang, LLVM Developers'
-1
View File
@@ -27,7 +27,6 @@ If you haven't received a response, a couple steps to take are (in order):
1. Contact individuals directly:
- [Chandler Carruth](mailto:chandlerc@gmail.com)
- [Richard Smith](mailto:richard@metafoo.co.uk)
- [Jon Ross-Perkins](mailto:jperkins@google.com)
2. Reach out on
[#infra](https://discord.com/channels/655572317891461132/707150492370862090)
on Discord ([invite](https://discord.gg/ZjVdShJDAs))
+45 -23
View File
@@ -4,20 +4,10 @@
"""Provides rules for building Carbon files using the toolchain."""
load("@rules_cc//cc:action_names.bzl", "ACTION_NAMES")
load("@rules_cc//cc/common:cc_common.bzl", "cc_common")
load("@rules_cc//cc/common:cc_info.bzl", "CcInfo")
def _runtimes_path(runtimes_target):
path = None
for f in runtimes_target:
if f.short_path.endswith("clang_resource_dir/lib"):
path = f.path
break
if not path:
fail("Could not find the `clang_resource_dir` in target {}".format(runtimes_target.label))
return path[:-len("/clang_resource_dir/lib")]
def _carbon_binary_impl(ctx):
toolchain_driver = ctx.executable.internal_exec_toolchain_driver
toolchain_data = ctx.files.internal_exec_toolchain_data
@@ -30,10 +20,12 @@ def _carbon_binary_impl(ctx):
toolchain_data = ctx.files.internal_target_toolchain_data
prebuilt_runtimes = ctx.files.internal_target_prebuilt_runtimes
# The extra link flags needed.
link_flags = []
# Pass any C++ flags from our dependencies onto Carbon.
dep_flags = []
dep_hdrs = []
dep_link_flags = []
dep_link_inputs = []
for dep in ctx.attr.deps:
if CcInfo in dep:
@@ -47,15 +39,16 @@ def _carbon_binary_impl(ctx):
dep_flags += ["--clang-arg=-isystem{0}".format(path) for path in cc_info.compilation_context.system_includes.to_list()]
dep_hdrs.append(cc_info.compilation_context.headers)
for link_input in cc_info.linking_context.linker_inputs.to_list():
# TODO: `carbon link` doesn't support linker flags yet.
# dep_link_flags += link_input.user_link_flags
link_flags += link_input.user_link_flags
dep_link_inputs += link_input.additional_inputs
for lib in link_input.libraries:
dep_link_inputs += [dep for dep in [lib.dynamic_library, lib.static_library] if dep]
dep_link_inputs += lib.objects
if DefaultInfo in dep:
dep_link_inputs += dep[DefaultInfo].files.to_list()
dep_link_flags += [dep.path for dep in dep_link_inputs]
# Add the dependencies' link flags and inputs to the link flags.
link_flags += [dep.path for dep in dep_link_inputs]
# Build object files for the prelude and for the binary itself.
# TODO: Eventually the prelude should be build as a separate `carbon_library`.
@@ -89,19 +82,47 @@ def _carbon_binary_impl(ctx):
inputs = depset(direct = srcs_reordered, transitive = dep_hdrs),
executable = toolchain_driver,
tools = depset(toolchain_data),
arguments = ["compile", "--output=" + out.path] +
arguments = ["compile", "--output=" + out.path, "--output-last-input-only"] +
[s.path for s in srcs_reordered] + extra_flags + ctx.attr.flags,
mnemonic = "CarbonCompile",
progress_message = "Compiling " + src.short_path,
)
# Add the Carbon object files to the link flags.
link_flags += [o.path for o in objs]
bin = ctx.actions.declare_file(ctx.label.name)
# Get all link options from the toolchain and dependencies using standard pattern.
cc_toolchain = ctx.attr._cc_toolchain[cc_common.CcToolchainInfo]
feature_configuration = cc_common.configure_features(
ctx = ctx,
cc_toolchain = cc_toolchain,
requested_features = ctx.features,
unsupported_features = ctx.disabled_features,
)
variables = cc_common.create_link_variables(
feature_configuration = feature_configuration,
cc_toolchain = cc_toolchain,
is_using_linker = True,
user_link_flags = link_flags + [
# TODO: Remove once the sanitizer runtimes are available.
"-fno-sanitize=all",
],
output_file = bin.path,
)
full_link_flags = cc_common.get_memory_inefficient_command_line(
feature_configuration = feature_configuration,
action_name = ACTION_NAMES.cpp_link_executable,
variables = variables,
)
ctx.actions.run(
outputs = [bin],
inputs = objs + dep_link_inputs,
executable = toolchain_driver,
tools = depset(toolchain_data + prebuilt_runtimes),
arguments = ["--prebuilt-runtimes=" + _runtimes_path(prebuilt_runtimes), "link", "--output=" + bin.path] + ["--"] + dep_link_flags + [o.path for o in objs],
arguments = full_link_flags,
mnemonic = "CarbonLink",
progress_message = "Linking " + bin.short_path,
)
@@ -148,9 +169,10 @@ _carbon_binary_internal = rule(
),
"prelude_srcs": attr.label_list(allow_files = [".carbon"]),
"srcs": attr.label_list(allow_files = [".carbon"]),
"_cc_toolchain": attr.label(default = "@bazel_tools//tools/cpp:current_cc_toolchain"),
"_cc_toolchain": attr.label(default = "//toolchain/install:carbon_stage1_cc_toolchain"),
},
executable = True,
fragments = ["cpp"],
)
def carbon_binary(name, srcs, deps = [], flags = [], tags = []):
@@ -177,7 +199,7 @@ def carbon_binary(name, srcs, deps = [], flags = [], tags = []):
# `select` which one we use.
internal_exec_toolchain_driver = select({
"//bazel/carbon_rules:use_target_config_carbon_rules_config": None,
"//conditions:default": "//toolchain/install:prefix/bin/carbon",
"//conditions:default": "//toolchain/install:carbon-busybox",
}),
internal_exec_toolchain_data = select({
"//bazel/carbon_rules:use_target_config_carbon_rules_config": None,
@@ -185,10 +207,10 @@ def carbon_binary(name, srcs, deps = [], flags = [], tags = []):
}),
internal_exec_prebuilt_runtimes = select({
"//bazel/carbon_rules:use_target_config_carbon_rules_config": None,
"//conditions:default": "//toolchain/driver:prebuilt_runtimes",
"//conditions:default": "//toolchain/install:built_runtimes",
}),
internal_target_toolchain_driver = select({
"//bazel/carbon_rules:use_target_config_carbon_rules_config": "//toolchain/install:prefix/bin/carbon",
"//bazel/carbon_rules:use_target_config_carbon_rules_config": "//toolchain/install:carbon-busybox",
"//conditions:default": None,
}),
internal_target_toolchain_data = select({
@@ -196,7 +218,7 @@ def carbon_binary(name, srcs, deps = [], flags = [], tags = []):
"//conditions:default": None,
}),
internal_target_prebuilt_runtimes = select({
"//bazel/carbon_rules:use_target_config_carbon_rules_config": "//toolchain/driver:prebuilt_runtimes",
"//bazel/carbon_rules:use_target_config_carbon_rules_config": "//toolchain/install:built_runtimes",
"//conditions:default": None,
}),
)
+30
View File
@@ -3,9 +3,13 @@
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
load("@bazel_skylib//lib:selects.bzl", "selects")
load("@rules_python//python:defs.bzl", "py_library", "py_test")
load(":carbon_cc_toolchain_config.bzl", "gen_cc_toolchain_paths_with_stage")
package(default_visibility = ["//visibility:public"])
exports_files(["carbon_cc_toolchain_config.bzl"])
# For use by defs.bzl.
# Matches when asan is enabled on a macOS platform.
selects.config_setting_group(
@@ -61,5 +65,31 @@ filegroup(
"cc_toolchain_optimization.bzl",
"cc_toolchain_sanitizer_features.bzl",
"cc_toolchain_tools.bzl",
# TODO: Remove this once we can remove the use of it from Carbon
# toolchain rules.
"cc_toolchain_carbon_project_features.bzl",
],
)
gen_cc_toolchain_paths_with_stage(
name = "gen_cc_tools_paths",
stage = 0,
)
# Test that the default toolchain's Make variables expand correctly.
py_test(
name = "cc_tools_test",
srcs = ["cc_tools_test.py"],
args = ["$(location :gen_cc_tools_paths)"],
data = [":gen_cc_tools_paths"],
deps = [":cc_tools_test_lib"],
)
# Library containing the test logic, used by tests in other packages.
py_library(
name = "cc_tools_test_lib",
srcs = ["cc_tools_test.py"],
visibility = ["//visibility:public"],
deps = ["@bazel_tools//tools/python/runfiles"],
)
@@ -0,0 +1,547 @@
# Part of the Carbon Language project, under the Apache License v2.0 with LLVM
# Exceptions. See /LICENSE for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
"""Starlark cc_toolchain configuration rules for using the Carbon toolchain"""
load("@bazel_tools//tools/cpp:toolchain_utils.bzl", "find_cpp_toolchain")
load("@rules_cc//cc:action_names.bzl", "ACTION_NAMES")
load(
"@rules_cc//cc:cc_toolchain_config_lib.bzl",
"action_config",
"flag_group",
"flag_set",
"tool",
)
load(
"@rules_cc//cc:defs.bzl",
"CcToolchainConfigInfo",
"cc_toolchain",
)
load("@rules_cc//cc/common:cc_common.bzl", "cc_common")
load("//toolchain/runtimes:carbon_runtimes.bzl", "carbon_runtimes_build")
load(
"carbon_clang_variables.bzl",
"clang_include_dirs",
"clang_resource_dir",
"clang_sysroot",
)
load(
"cc_toolchain_actions.bzl",
"all_c_compile_actions",
"all_cpp_compile_actions",
"all_link_actions",
)
load("cc_toolchain_carbon_project_features.bzl", "carbon_project_features")
load("cc_toolchain_features.bzl", "clang_cc_toolchain_features")
load(
":cc_toolchain_tools.bzl",
"llvm_tool_paths",
)
def _make_action_configs(tools, runtimes_path = None):
runtimes_flag = "--no-build-runtimes"
if runtimes_path:
runtimes_flag = "--prebuilt-runtimes={0}".format(runtimes_path)
return [
action_config(
action_name = name,
enabled = True,
tools = [tools.clang],
)
for name in all_c_compile_actions
] + [
action_config(
action_name = name,
enabled = True,
tools = [tools.clangpp],
)
for name in all_cpp_compile_actions
] + [
action_config(
action_name = name,
enabled = True,
tools = [tools.carbon_busybox],
flag_sets = [flag_set(flag_groups = [flag_group(flags = [
runtimes_flag,
"link",
# We want to allow Bazel to intermingle linked object files and
# Clang-spelled link flags. The first `--` starts the list of
# initial object files by ending flags to the `link` subcommand,
# and the second `--` switches to Clang-spelled flags.
"--",
"--",
])])],
)
for name in all_link_actions
] + [
action_config(
action_name = name,
enabled = True,
tools = [tools.llvm_ar],
)
for name in [ACTION_NAMES.cpp_link_static_library]
] + [
action_config(
action_name = name,
enabled = True,
tools = [tools.llvm_strip],
)
for name in [ACTION_NAMES.strip]
]
def _compute_clang_system_include_dirs():
system_include_dirs_start_index = None
for index, dir in enumerate(clang_include_dirs):
# Skip over the include search directories until we find the resource
# directory. The system include directories are everything after that.
if dir.startswith(clang_resource_dir):
system_include_dirs_start_index = index + 1
break
if not system_include_dirs_start_index:
fail("Could not find the resource directory in the clang include " +
"directories: {}".format(clang_include_dirs))
return clang_include_dirs[system_include_dirs_start_index:]
def _carbon_cc_toolchain_config_impl(ctx):
llvm_bindir = "llvm/bin"
clang_bindir = llvm_bindir
tools = struct(
carbon_busybox = tool(path = "carbon-busybox"),
clang = tool(path = clang_bindir + "/clang"),
clangpp = tool(path = clang_bindir + "/clang++"),
llvm_ar = tool(path = llvm_bindir + "/llvm-ar"),
llvm_strip = tool(path = llvm_bindir + "/llvm-strip"),
)
if ctx.attr.bins:
carbon_busybox = None
clang = None
clangpp = None
llvm_ar = None
llvm_strip = None
for f in ctx.files.bins:
if f.basename == "carbon-busybox":
carbon_busybox = f
elif f.basename == "clang":
clang = f
elif f.basename == "clang++":
clangpp = f
elif f.basename == "llvm-ar":
llvm_ar = f
elif f.basename == "llvm-strip":
llvm_strip = f
if not all([carbon_busybox, clang, clangpp, llvm_ar, llvm_strip]):
fail("Missing required tool in bins: {0}".format(ctx.attr.bins))
llvm_bindir = llvm_ar.dirname
clang_bindir = clang.dirname
tools = struct(
carbon_busybox = tool(tool = carbon_busybox),
clang = tool(tool = clang),
clangpp = tool(tool = clangpp),
llvm_ar = tool(tool = llvm_ar),
llvm_strip = tool(tool = llvm_strip),
)
# Only use a sysroot if a non-trivial one is set in Carbon's config.
builtin_sysroot = None
sysroot_include_search = []
if clang_sysroot != "None" and clang_sysroot != "/":
builtin_sysroot = clang_sysroot
sysroot_include_search = ["%sysroot%/usr/include"]
runtimes_path = None
if ctx.attr.runtimes:
for f in ctx.files.runtimes:
if f.basename == "runtimes_root":
runtimes_path = f.dirname
break
if not runtimes_path:
fail("Unable to compute the runtimes path for: {0}".format(
ctx.attr.runtimes,
))
identifier = "{0}_toolchain_{1}_{2}".format(
ctx.attr.identifier_prefix,
ctx.attr.target_cpu,
ctx.attr.target_os,
)
return cc_common.create_cc_toolchain_config_info(
ctx = ctx,
features = clang_cc_toolchain_features(
target_os = ctx.attr.target_os,
target_cpu = ctx.attr.target_cpu,
# TODO: This should be configured externally rather than here so
# that the install Carbon toolchain doesn't automatically include
# Carbon-project-specific flags. However, that is especially awkward
# to do until we fully migrate to a rules-based toolchain, and the
# project-specific flags are largely harmless at the moment. We also
# omit a meaningful cache key as when using the Carbon toolchain we
# don't need it as it is a hermetic part of Bazel.
project_features = carbon_project_features(cache_key = ""),
),
action_configs = _make_action_configs(tools, runtimes_path),
cxx_builtin_include_directories = [
"runtimes/libunwind/include",
"runtimes/libcxx/include",
"runtimes/libcxxabi/include",
"{}/include".format(clang_resource_dir),
"runtimes/clang_resource_dir/include",
] + _compute_clang_system_include_dirs() + sysroot_include_search,
builtin_sysroot = builtin_sysroot,
# This configuration only supports local non-cross builds so derive
# everything from the target CPU selected.
toolchain_identifier = identifier,
# This is used to expose a "flag" that `config_setting` rules can use to
# determine if the compiler is Clang.
compiler = "clang",
# Pass in our tool paths to expose Make variables like $(NM) and
# $(OBJCOPY).
tool_paths = llvm_tool_paths(llvm_bindir, clang_bindir),
)
carbon_cc_toolchain_config = rule(
implementation = _carbon_cc_toolchain_config_impl,
attrs = {
"bins": attr.label(mandatory = False),
"identifier_prefix": attr.string(mandatory = True),
"runtimes": attr.label(mandatory = False),
"target_cpu": attr.string(mandatory = True),
"target_os": attr.string(mandatory = True),
},
provides = [CcToolchainConfigInfo],
)
def _transition_with_stage_impl(_, attr):
return {
"//:bootstrap_stage": attr.stage,
"//:runtimes_build": attr.enable_runtimes_build,
}
_transition_with_stage = transition(
inputs = [],
outputs = [
"//:bootstrap_stage",
"//:runtimes_build",
],
implementation = _transition_with_stage_impl,
)
def _filegroup_with_stage_impl(ctx):
return [DefaultInfo(files = depset(ctx.files.srcs))]
filegroup_with_stage = rule(
implementation = _filegroup_with_stage_impl,
attrs = {
# Whether to enable runtimes building for the sources of this filegroup.
"enable_runtimes_build": attr.bool(default = False),
# Mark that our dependencies are built through a transition.
"srcs": attr.label_list(mandatory = True, cfg = _transition_with_stage),
# The bootstrap stage that the sources of this filegroup should be built
# with.
"stage": attr.int(mandatory = True),
# Enable transitions in this rule.
"_allowlist_function_transition": attr.label(
default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
),
},
doc = """
A filegroup whose sources are built using a specific toolchain stage, and
which provides an interface to build those sources with or without enabling
runtimes building.
""",
)
def _exec_filegroup_impl(ctx):
return [DefaultInfo(files = depset(ctx.files.srcs))]
_exec_filegroup = rule(
implementation = _exec_filegroup_impl,
attrs = {
"srcs": attr.label_list(cfg = "exec"),
},
)
def filegroup_with_stage_and_exec(name, srcs, stage, tags = []):
"""Wraps `filegroup_with_stage` with a conditional `exec` config transition.
When `//:bootstrap_exec_config` is disabled, this works exactly like
`filegroup_with_stage`. But when it is _enabled_, it also adds an `exec`
config transition. This allows bootstrapping for a target that is not exec
compatible with the host, and in general makes bootstrapping more robust at
the expense of a likely duplicate build of the entire toolchain.
"""
filegroup_with_stage(
name = name + "_stage_only",
srcs = srcs,
stage = stage,
tags = tags,
)
_exec_filegroup(
name = name + "_with_exec",
srcs = [":" + name + "_stage_only"],
tags = tags,
)
native.alias(
name = name,
actual = select({
"//:bootstrap_with_exec_config": ":" + name + "_with_exec",
"//conditions:default": ":" + name + "_stage_only",
}),
tags = tags,
)
def _gen_cc_toolchain_paths_impl(ctx):
cc_toolchain = find_cpp_toolchain(ctx)
expanded_vars = [
ctx.expand_make_variables("vars", v, {})
for v in ctx.attr.vars
]
out = ctx.actions.declare_file(ctx.attr.name + ".txt")
ctx.actions.write(out, "\n".join(expanded_vars) + "\n")
# Include all toolchain files in runfiles.
runfiles = ctx.runfiles(files = [out]).merge(
ctx.runfiles(transitive_files = cc_toolchain.all_files),
)
return [DefaultInfo(files = depset([out]), runfiles = runfiles)]
gen_cc_toolchain_paths_with_stage = rule(
implementation = _gen_cc_toolchain_paths_impl,
attrs = {
"enable_runtimes_build": attr.bool(default = False),
"stage": attr.int(mandatory = True),
"vars": attr.string_list(
default = ["$(CC)", "$(AR)", "$(NM)", "$(OBJCOPY)", "$(STRIP)"],
),
"_allowlist_function_transition": attr.label(
default = "@bazel_tools//tools/allowlists/function_transition_allowlist",
),
"_cc_toolchain": attr.label(
default = Label("@bazel_tools//tools/cpp:current_cc_toolchain"),
),
},
toolchains = ["@bazel_tools//tools/cpp:toolchain_type"],
cfg = _transition_with_stage,
)
def carbon_cc_toolchain_suite(
name,
all_hdrs,
base_files,
clang_hdrs,
platforms,
runtimes_cfg,
build_stage = 1,
base_stage = 0,
tags = []):
"""Create a Carbon `cc_toolchain` for the current target platform.
This provides the final toolchain for Carbon, but also all of the
infrastructure for supporting on-demand built runtimes in this toolchain.
There is also support for bootstrapping, where one `build_stage` toolchain
builds on top of another `base_stage`.
Args:
name:
The name of the toolchain suite to produce, used as the base of the
names of each component of the toolchain suite.
all_hdrs: A list of header files to include in the toolchain.
base_files: A list of files to include in the toolchain.
build_stage: The stage to use for the build files.
base_stage: The stage to use for the base files.
clang_hdrs: A list of header files to include in the toolchain.
platforms: An array of (os, cpu) pairs to support in the toolchain.
runtimes_cfg: The runtimes configuration to use in the toolchain.
tags: Tags to apply to the toolchain.
"""
# First, declare file groups that are explicitly built using the base stage,
# and not in the runtimes build. These allow us to form the inputs to both
# the runtimes toolchain and the main toolchain of this stage that are built
# entirely by the base stage toolchain.
filegroup_with_stage_and_exec(
name = "{}_clang_hdrs".format(name),
srcs = clang_hdrs,
stage = base_stage,
tags = tags,
)
filegroup_with_stage_and_exec(
name = "{}_base_files".format(name),
srcs = base_files,
stage = base_stage,
tags = tags,
)
filegroup_with_stage_and_exec(
name = "{}_runtimes_compile_files".format(name),
srcs = [
":{}_base_files".format(name),
":{}_clang_hdrs".format(name),
],
stage = base_stage,
tags = tags,
)
filegroup_with_stage_and_exec(
name = "{}_compile_files".format(name),
srcs = [":{}_base_files".format(name)] + all_hdrs,
stage = base_stage,
tags = tags,
)
# Now build a configuration and toolchain that is configured to work
# _without_ runtimes, and be used to _build_ the runtimes on-demand.
carbon_cc_toolchain_config(
name = "{}_runtimes_toolchain_config".format(name),
identifier_prefix = "{}_runtimes".format(name),
target_cpu = select({
# Note that we need to select on both OS and CPU so that we end up
# spelling the CPU in the correct OS-specific ways.
":is_{}_{}".format(os, cpu): cpu
for os, cpus in platforms.items()
for cpu in cpus
}),
target_os = select({
"@platforms//os:{}".format(os): os
for os in platforms.keys()
}),
bins = ":{}_base_files".format(name),
tags = tags,
)
cc_toolchain(
name = "{}_runtimes_cc_toolchain".format(name),
all_files = ":{}_runtimes_compile_files".format(name),
ar_files = ":{}_base_files".format(name),
as_files = ":{}_runtimes_compile_files".format(name),
compiler_files = ":{}_runtimes_compile_files".format(name),
dwp_files = ":{}_base_files".format(name),
linker_files = ":{}_base_files".format(name),
objcopy_files = ":{}_base_files".format(name),
strip_files = ":{}_base_files".format(name),
toolchain_config = ":{}_runtimes_toolchain_config".format(name),
toolchain_identifier = select({
":is_{}_{}".format(os, cpu): "{}_{}_{}_runtimes_toolchain".format(name, os, cpu)
for os, cpus in platforms.items()
for cpu in cpus
}),
tags = tags,
)
native.toolchain(
name = "{}_runtimes_toolchain".format(name),
target_settings = [
":is_bootstrap_stage_{}".format(build_stage),
":is_runtimes_build",
],
use_target_platform_constraints = True,
toolchain = ":{}_runtimes_cc_toolchain".format(name),
toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
tags = tags,
)
# Now that we have a toolchain for building runtimes, actually do the build
# here using the runtimes config provided to us. This is important to do
# here because we need each runtimes build for a particular bootstrapping
# stage of the toolchain to be distinct.
carbon_runtimes_build(
name = "{}_runtimes_build".format(name),
config = runtimes_cfg,
clang_hdrs = [":{}_clang_hdrs".format(name)],
tags = tags,
)
# Wrap the built runtimes for this stage in a filegroup that ensures they
# are built at this stage, but with the runtimes build enabled. This will
# select the runtimes build toolchain above that doesn't yet provide any
# runtimes, avoiding a cycle when the main toolchain below depends on these
# runtimes.
filegroup_with_stage(
name = "{}_runtimes".format(name),
enable_runtimes_build = True,
srcs = ["{}_runtimes_build".format(name)],
stage = build_stage,
tags = tags,
)
# Now we can build the main toolchain configuration, filegroups including
# the on-demand built runtimes, and the final tolochain itself.
carbon_cc_toolchain_config(
name = "{}_toolchain_config".format(name),
identifier_prefix = name,
target_cpu = select({
# Note that we need to select on both OS and CPU so that we end up
# spelling the CPU in the correct OS-specific ways.
":is_{}_{}".format(os, cpu): cpu
for os, cpus in platforms.items()
for cpu in cpus
}),
target_os = select({
"@platforms//os:{}".format(os): os
for os in platforms.keys()
}),
runtimes = ":{}_runtimes".format(name),
bins = ":{}_base_files".format(name),
tags = tags,
)
native.filegroup(
name = "{}_linker_files".format(name),
srcs = [
":{}_base_files".format(name),
":{}_runtimes".format(name),
],
tags = tags,
)
native.filegroup(
name = "{}_all_files".format(name),
srcs = [
":{}_compile_files".format(name),
":{}_linker_files".format(name),
],
tags = tags,
)
cc_toolchain(
name = "{}_cc_toolchain".format(name),
all_files = ":{}_all_files".format(name),
ar_files = ":" + name + "_base_files",
as_files = ":" + name + "_compile_files",
compiler_files = ":" + name + "_compile_files",
dwp_files = ":" + name + "_linker_files",
linker_files = ":" + name + "_linker_files",
objcopy_files = ":" + name + "_base_files",
strip_files = ":" + name + "_base_files",
toolchain_config = ":" + name + "_toolchain_config",
toolchain_identifier = select({
":is_{}_{}".format(os, cpu): "{}_{}_{}_toolchain".format(name, os, cpu)
for os, cpus in platforms.items()
for cpu in cpus
}),
tags = tags,
)
native.toolchain(
name = name + "_toolchain",
target_settings = [":is_bootstrap_stage_{}".format(build_stage), ":not_runtimes_build"],
use_target_platform_constraints = True,
toolchain = ":" + name + "_cc_toolchain",
toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
tags = tags,
)
@@ -0,0 +1,20 @@
# Part of the Carbon Language project, under the Apache License v2.0 with LLVM
# Exceptions. See /LICENSE for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
"""A Starlark file exporting detected Carbon toolchain configuration variables.
This file gets processed by a repository rule, substituting the `VARIABLE`s with
values, for example using an invocation of `carbon config`.
"""
load(
"@bazel_cc_toolchain//:clang_detected_variables.bzl",
_clang_include_dirs = "clang_include_dirs",
_clang_resource_dir = "clang_resource_dir",
_sysroot_dir = "sysroot_dir",
)
clang_include_dirs = _clang_include_dirs
clang_resource_dir = _clang_resource_dir
clang_sysroot = _sysroot_dir
@@ -4,6 +4,7 @@
"""Definitions used for the base features of a `cc_toolchain_config`."""
load("@rules_cc//cc:action_names.bzl", "ACTION_NAMES")
load(
"@rules_cc//cc:cc_toolchain_config_lib.bzl",
"feature",
@@ -92,12 +93,41 @@ output_flags_feature = feature(
],
)
strip_feature = feature(
name = "strip_flags",
enabled = True,
flag_sets = [flag_set(
actions = [ACTION_NAMES.strip],
flag_groups = [
flag_group(
flags = ["-S"],
),
flag_group(
flags = ["-p"],
),
flag_group(
expand_if_available = "output_file",
flags = ["-o", "%{output_file}"],
),
flag_group(
iterate_over = "stripopts",
flags = ["%{stripopts}"],
),
flag_group(
expand_if_available = "input_file",
flags = ["%{input_file}"],
),
],
)],
)
base_features = [
dbg_feature,
fastbuild_feature,
host_feature,
no_legacy_features_feature,
opt_feature,
strip_feature,
supports_pic_feature,
supports_dynamic_linker_feature,
supports_start_end_lib_feature,
@@ -27,10 +27,9 @@ carbon_project_fastbuild_feature = feature(
enabled = True,
requires = [feature_set(["fastbuild"])],
implies = [
"asan",
"asan_min_size",
"minimal_optimization_flags",
"minimal_debug_info_flags",
"preserve_call_stacks",
],
)
@@ -26,7 +26,7 @@ minimal_optimization_flags = feature(
name = "minimal_optimization_flags",
flag_sets = [flag_set(
actions = codegen_compile_actions,
flag_groups = [flag_group(flags = ["-O1"])],
flag_groups = [flag_group(flags = ["-Og"])],
)],
)
default_optimization_flags = feature(
+59
View File
@@ -0,0 +1,59 @@
"""Tests that the C++ toolchain tools can be executed.
This script reads a file containing paths to C++ tools (like clang++, llvm-ar)
and attempts to run each with `--version` to verify they are functional.
"""
__copyright__ = """
Part of the Carbon Language project, under the Apache License v2.0 with LLVM
Exceptions. See /LICENSE for license information.
SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
"""
import os
import subprocess
import sys
from bazel_tools.tools.python.runfiles import runfiles
def test_tools() -> None:
"""Reads paths from file and runs each tool with --version."""
if len(sys.argv) < 2:
print("Usage: cc_tools_test.py <paths_file>")
sys.exit(1)
paths_file = sys.argv[1]
print(f"Reading tools from: {paths_file}")
with open(paths_file, "r") as f:
tools = [line.strip() for line in f if line.strip()]
print(f"Testing tools: {tools}")
r = runfiles.Create()
repo_name = os.environ.get("TEST_WORKSPACE") or "_main"
for tool in tools:
if "bazel-out/" in tool:
_, _, rest = tool.partition("bazel-out/")
_, sep, after = rest.partition("bin/")
if sep:
tool = after
rlocation_path = os.path.join(repo_name, tool)
tool = r.Rlocation(rlocation_path)
print(f"Running {tool} --version")
try:
res = subprocess.run(
[tool, "--version"],
capture_output=True,
text=True,
check=True,
)
print(res.stdout)
except Exception as e:
print(f"Failed to run {tool}: {e}")
sys.exit(1)
if __name__ == "__main__":
test_tools()
@@ -17,7 +17,7 @@ load(
load(
":clang_detected_variables.bzl",
"clang_bindir",
"clang_include_dirs_list",
"clang_include_dirs",
"clang_resource_dir",
"clang_version_for_cache",
"llvm_bindir",
@@ -40,7 +40,7 @@ def _impl(ctx):
extra_cpp_features = [libcxx_feature(llvm_bindir, clang_bindir)],
),
action_configs = llvm_action_configs(llvm_bindir, clang_bindir),
cxx_builtin_include_directories = clang_include_dirs_list + [
cxx_builtin_include_directories = clang_include_dirs + [
# Add Clang's resource directory to the end of the builtin include
# directories to cover the use of sanitizer resource files by the
# driver.
@@ -92,7 +92,7 @@ def cc_local_toolchain_suite(name, configs):
target_cpu = cpu,
)
cc_toolchain(
name = config_name + "_tools",
name = config_name + "_toolchain",
all_files = ":" + name + "_empty",
ar_files = ":" + name + "_empty",
as_files = ":" + name + "_empty",
@@ -109,7 +109,11 @@ def cc_local_toolchain_suite(name, configs):
native.toolchain(
name = config_name,
exec_compatible_with = compatible_with,
target_settings = [
"@carbon//toolchain/install:is_bootstrap_stage_0",
"@carbon//toolchain/install:not_runtimes_build",
],
target_compatible_with = compatible_with,
toolchain = config_name + "_tools",
toolchain = config_name + "_toolchain",
toolchain_type = "@bazel_tools//tools/cpp:toolchain_type",
)
+1 -1
View File
@@ -226,7 +226,7 @@ def _configure_clang_toolchain_impl(repository_ctx):
repository_ctx.attr._clang_detected_variables_template,
substitutions = {
"{CLANG_BINDIR}": str(clang.dirname),
"{CLANG_INCLUDE_DIRS_LIST}": str(
"{CLANG_INCLUDE_DIRS}": str(
[str(path) for path in include_dirs],
),
"{CLANG_RESOURCE_DIR}": resource_dir,
@@ -14,5 +14,5 @@ clang_bindir = "{CLANG_BINDIR}"
clang_version = {CLANG_VERSION}
clang_version_for_cache = "{CLANG_VERSION_FOR_CACHE}"
clang_resource_dir = "{CLANG_RESOURCE_DIR}"
clang_include_dirs_list = {CLANG_INCLUDE_DIRS_LIST}
clang_include_dirs = {CLANG_INCLUDE_DIRS}
sysroot_dir = "{SYSROOT}"
+2 -2
View File
@@ -13,8 +13,8 @@ load("@rules_python//python:defs.bzl", "py_test")
filegroup(
name = "non_test_cc_rules",
data = [
"//toolchain/install:carbon_toolchain_tar_gz_rule",
"//toolchain/install:carbon_toolchain_tar_rule",
"//toolchain/install:carbon_toolchain_tar",
"//toolchain/install:carbon_toolchain_tar_gz",
],
tags = ["manual"],
)
@@ -1,133 +0,0 @@
From 04fb28b5673d29a8c38519845c87f4c00c76e9cf Mon Sep 17 00:00:00 2001
From: Chandler Carruth <chandlerc@gmail.com>
Date: Sat, 13 Jan 2024 02:15:19 -0800
Subject: [PATCH] Introduce a simple native Bazel build.
---
BUILD.bazel | 84 +++++++++++++++++++++++++++++++++++++++++++++++++
MODULE.bazel | 10 ++++++
WORKSPACE.bazel | 5 +++
3 files changed, 99 insertions(+)
create mode 100644 BUILD.bazel
create mode 100644 MODULE.bazel
create mode 100644 WORKSPACE.bazel
diff --git a/BUILD.bazel b/BUILD.bazel
new file mode 100644
index 0000000..427c854
--- /dev/null
+++ b/BUILD.bazel
@@ -0,0 +1,84 @@
+# Part of the Carbon Language project, under the Apache License v2.0 with LLVM
+# Exceptions. See /LICENSE for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+load("@rules_cc//cc:defs.bzl", "cc_library")
+
+package(default_visibility = ["//visibility:public"])
+
+aarch64_srcs = [
+ "lib/pfmlib_arm_perf_event.c",
+ "lib/pfmlib_arm.c",
+ "lib/pfmlib_arm_armv8.c",
+ "lib/pfmlib_arm_armv9.c",
+ "lib/pfmlib_tx2_unc_perf_event.c",
+ "lib/pfmlib_kunpeng_unc_perf_event.c",
+ "lib/pfmlib_arm_priv.h",
+ "lib/events/arm_cortex_a57_events.h",
+ "lib/events/arm_cortex_a53_events.h",
+ "lib/events/arm_xgene_events.h",
+ "lib/events/arm_cavium_tx2_events.h",
+ "lib/events/arm_marvell_tx2_unc_events.h",
+ "lib/events/arm_fujitsu_a64fx_events.h",
+ "lib/events/arm_neoverse_n1_events.h",
+ "lib/events/arm_neoverse_n2_events.h",
+ "lib/events/arm_neoverse_v1_events.h",
+ "lib/events/arm_neoverse_v2_events.h",
+ "lib/events/arm_hisilicon_kunpeng_events.h",
+ "lib/events/arm_hisilicon_kunpeng_unc_events.h",
+]
+
+x86_64_srcs = [
+ "lib/pfmlib_amd64_priv.h",
+] + glob(
+ [
+ "lib/pfmlib_amd64*.c",
+ "lib/pfmlib_intel*.c",
+ "lib/pfmlib_intel*_priv.h",
+ "lib/events/amd64_events_*.h",
+ "lib/events/intel_*_events.h",
+ ],
+ exclude = [
+ # 32-bit CPUs
+ "lib/pfmlib_intel_coreduo.c",
+ "lib/pfmlib_intel_p6.c",
+ ],
+)
+
+cc_library(
+ name = "libpfm",
+ srcs = [
+ "lib/events/perf_events.h",
+ "lib/pfmlib_common.c",
+ "lib/pfmlib_perf_event.c",
+ "lib/pfmlib_perf_event_pmu.c",
+ "lib/pfmlib_perf_event_priv.h",
+ "lib/pfmlib_perf_event_raw.c",
+ "lib/pfmlib_priv.h",
+ ] + select({
+ "@platforms//cpu:aarch64": aarch64_srcs,
+ "@platforms//cpu:x86_64": x86_64_srcs,
+ }),
+ hdrs = glob(["include/perfmon/*.h"]),
+ copts = [
+ "-DHAS_OPENAT",
+ "-D_REENTRANT",
+ "-I.",
+ "-fvisibility=hidden",
+ ] + select({
+ "@platforms//cpu:x86_64": [
+ "-DCONFIG_PFMLIB_ARCH_X86",
+ "-DCONFIG_PFMLIB_ARCH_X86_64",
+ ],
+ "//conditions:default": [],
+ }),
+ strip_include_prefix = "include",
+ target_compatible_with = select({
+ # This library only makes sense on Linux, and we only include support
+ # for building on AArch64 and x86-64. Other CPUs can be added to this
+ # list if build support is added for them.
+ "@platforms//cpu:aarch64": ["@platforms//os:linux"],
+ "@platforms//cpu:x86_64": ["@platforms//os:linux"],
+ "//conditions:default": ["@platforms//:incompatible"],
+ }),
+)
diff --git a/MODULE.bazel b/MODULE.bazel
new file mode 100644
index 0000000..c901cbe
--- /dev/null
+++ b/MODULE.bazel
@@ -0,0 +1,10 @@
+# Part of the Carbon Language project, under the Apache License v2.0 with LLVM
+# Exceptions. See /LICENSE for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+"""Bazel modules."""
+
+module(name = "libpfm")
+
+bazel_dep(name = "rules_cc", version = "0.0.9")
+bazel_dep(name = "platforms", version = "0.0.8")
diff --git a/WORKSPACE.bazel b/WORKSPACE.bazel
new file mode 100644
index 0000000..9aad57c
--- /dev/null
+++ b/WORKSPACE.bazel
@@ -0,0 +1,5 @@
+# Part of the Carbon Language project, under the Apache License v2.0 with LLVM
+# Exceptions. See /LICENSE for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+# See `MODULE.bazel` for details.
--
2.43.0
-9
View File
@@ -1,9 +0,0 @@
# Part of the Carbon Language project, under the Apache License v2.0 with LLVM
# Exceptions. See /LICENSE for license information.
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
package(default_visibility = ["//visibility:public"])
exports_files(glob([
"*.patch",
]))
@@ -1,7 +1,7 @@
Commit ID: a79f1facf56cc5772557cdb09d811aa11a22e43b
Commit ID: 354e38c89f28e2cc284e655a9cde707f457dc02c
Change ID: sxspxmonsuvqzuvxvrvorlumwpwromsv
Author : Chandler Carruth <chandlerc@gmail.com> (2025-09-25 22:55:26)
Committer: Chandler Carruth <chandlerc@gmail.com> (2025-11-17 09:59:25)
Committer: Chandler Carruth <chandlerc@gmail.com> (2026-02-14 03:46:06)
Introduce basic sources exporting for libunwind
@@ -32,3 +32,33 @@ index c9fdc819c0..7d734c5a06 100644
+ "src/*.S",
+ ]),
+)
diff --git a/utils/bazel/llvm-project-overlay/libunwind/libunwind_library.bzl b/utils/bazel/llvm-project-overlay/libunwind/libunwind_library.bzl
new file mode 100644
index 0000000000..25675d3070
--- /dev/null
+++ b/utils/bazel/llvm-project-overlay/libunwind/libunwind_library.bzl
@@ -0,0 +1,24 @@
+# This file is licensed under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+"""Starlark variables and macros for building libunwind.
+
+Variables provide base line information for how to build libunwind source files.
+These can be used to generate non-Bazel builds of the library.
+
+Macros provide a convenient way to construct Bazel `cc_library` rules for
+libunwind.
+"""
+
+# TODO: Should libunwind use `-fvisibility-inlines-hidden` and
+# `-fvisibility=hidden`, similar to libc++?
+libunwind_copts = [
+ "-D_LIBUNWIND_IS_NATIVE_ONLY",
+ "-O3",
+ "-fPIC",
+ "-fno-exceptions",
+ "-fno-rtti",
+ "-funwind-tables",
+ "-nostdinc++",
+]
@@ -1,20 +1,21 @@
Commit ID: e4ff7299fe7e35e70ba79f5d8e2c58658cfba678
Commit ID: 1fd710ed69a0f47f454c386d39302ddb756a88b3
Change ID: mstnwoqruyypnoouksnyqssllrsozpos
Bookmarks: bz-libcxx bz-libcxx@git bz-libcxx@origin
Bookmarks: bz-libcxx* bz-libcxx@git
Author : Chandler Carruth <chandlerc@gmail.com> (2025-09-25 22:55:26)
Committer: Chandler Carruth <chandlerc@gmail.com> (2025-11-22 09:23:52)
Committer: Chandler Carruth <chandlerc@gmail.com> (2026-03-08 07:41:54)
Introduce basic sources exporting for libcxx and libcxxabi
This exports the source files directly so that they can be used to build
a libcxx runtime library on demand.
a libcxx runtime library on demand. It also differentiates between
normal sources and textual sources.
diff --git a/utils/bazel/llvm-project-overlay/libcxx/BUILD.bazel b/utils/bazel/llvm-project-overlay/libcxx/BUILD.bazel
new file mode 100644
index 0000000000..a81a64c649
index 0000000000..c8b517ab56
--- /dev/null
+++ b/utils/bazel/llvm-project-overlay/libcxx/BUILD.bazel
@@ -0,0 +1,49 @@
@@ -0,0 +1,139 @@
+# This file is licensed under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
@@ -25,9 +26,11 @@ index 0000000000..a81a64c649
+ default_visibility = ["//visibility:public"],
+)
+
+exports_files(["include/__config_site.in"])
+
+exports_files(["vendor/llvm/default_assertion_handler.in"])
+exports_files([
+ "include/__config_site.in",
+ "include/module.modulemap.in",
+ "vendor/llvm/default_assertion_handler.in",
+])
+
+filegroup(
+ name = "libcxx_hdrs",
@@ -54,22 +57,153 @@ index 0000000000..a81a64c649
+ ),
+)
+
+LIBCXX_SRCS_PSTL_LIBDISPATCH = [
+ "src/pstl/libdispatch.cpp",
+]
+
+filegroup(
+ name = "libcxx_srcs",
+ name = "libcxx_srcs_pstl_libdispatch",
+ srcs = LIBCXX_SRCS_PSTL_LIBDISPATCH,
+)
+
+LIBCXX_SRCS_SUPPORT_IBM_PATTERNS = [
+ "src/support/ibm/**/*.cpp",
+]
+
+filegroup(
+ name = "libcxx_srcs_support_ibm",
+ srcs = glob(LIBCXX_SRCS_SUPPORT_IBM_PATTERNS),
+)
+
+LIBCXX_SRCS_SUPPORT_WIN32_PATTERNS = [
+ "src/support/win32/**/*.cpp",
+]
+
+filegroup(
+ name = "libcxx_srcs_support_win32",
+ srcs = glob(LIBCXX_SRCS_SUPPORT_WIN32_PATTERNS),
+)
+
+LIBCXX_SRCS_TZDB = [
+ "src/experimental/chrono_exception.cpp",
+ "src/experimental/time_zone.cpp",
+ "src/experimental/tzdb.cpp",
+ "src/experimental/tzdb_list.cpp",
+]
+
+filegroup(
+ name = "libcxx_srcs_tzdb",
+ srcs = LIBCXX_SRCS_TZDB,
+)
+
+# Exclude platform-dependent patterns that are provided by per-target filegroups
+# above.
+LIBCXX_SRCS_TARGET_EXCLUDES = (
+ LIBCXX_SRCS_PSTL_LIBDISPATCH +
+ LIBCXX_SRCS_SUPPORT_IBM_PATTERNS +
+ LIBCXX_SRCS_SUPPORT_WIN32_PATTERNS +
+ LIBCXX_SRCS_TZDB
+)
+
+filegroup(
+ name = "libcxx_srcs_generic",
+ srcs = glob(
+ [
+ "src/**/*.cpp",
+ "src/**/*.h",
+ "src/**/*.ipp",
+ ],
+ exclude = [
+ # Build is for use with libc++abi and so don't need 'new.cpp'.
+ "src/new.cpp",
+
+ # Build is for compiler-rt platforms so we have its int128 support.
+ "src/filesystem/int128_builtins.cpp",
+ ] + LIBCXX_SRCS_TARGET_EXCLUDES,
+ ),
+)
+
+filegroup(
+ name = "libcxx_linux_srcs",
+ srcs = [
+ ":libcxx_srcs_generic",
+ ":libcxx_srcs_tzdb",
+ ],
+)
+
+filegroup(
+ name = "libcxx_macos_srcs",
+ srcs = [
+ ":libcxx_srcs_generic",
+ # TODO: Include libdispatch sources here to enable that pstl backend.
+ ],
+)
+
+filegroup(
+ name = "libcxx_win32_srcs",
+ srcs = [
+ ":libcxx_srcs_generic",
+ ":libcxx_srcs_support_win32",
+ ],
+)
+
+filegroup(
+ name = "libcxx_all_srcs",
+ srcs = [
+ ":libcxx_linux_srcs",
+ ":libcxx_macos_srcs",
+ ":libcxx_win32_srcs",
+ ],
+)
diff --git a/utils/bazel/llvm-project-overlay/libcxx/libcxx_library.bzl b/utils/bazel/llvm-project-overlay/libcxx/libcxx_library.bzl
new file mode 100644
index 0000000000..66f64f3610
--- /dev/null
+++ b/utils/bazel/llvm-project-overlay/libcxx/libcxx_library.bzl
@@ -0,0 +1,37 @@
+# This file is licensed under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+"""Starlark variables and macros for building libc++ and libc++abi.
+
+Variables provide base line information for how to build libc++ and libc++abi
+source files. These can be used to generate non-Bazel builds of the library.
+
+TODO: Add macros that provide a convenient way to construct Bazel `cc_library`
+rules for libc++ and libc++abi.
+
+TODO: Add either sufficient usage in the macros, or add a how-to example here in
+the documentation so the use of these variables is more clear.
+"""
+
+_libcxx_base_copts = [
+ "-std=c++26",
+ "-O3",
+ "-fPIC",
+ "-fvisibility-inlines-hidden",
+ "-fvisibility=hidden",
+ "-nostdinc++",
+]
+
+_libcxx_defines = [
+ "-D_LIBCPP_BUILDING_LIBRARY",
+ "-D_LIBCPP_REMOVE_TRANSITIVE_INCLUDES",
+]
+
+_libcxxabi_defines = [
+ "-DLIBCXX_BUILDING_LIBCXXABI",
+]
+
+libcxx_copts = _libcxx_base_copts + _libcxx_defines
+libcxxabi_copts = _libcxx_base_copts + _libcxxabi_defines
+libcxx_and_abi_copts = _libcxx_base_copts + _libcxx_defines + _libcxxabi_defines
diff --git a/utils/bazel/llvm-project-overlay/libcxxabi/BUILD.bazel b/utils/bazel/llvm-project-overlay/libcxxabi/BUILD.bazel
new file mode 100644
index 0000000000..cf491e4e46
index 0000000000..2db70b54e2
--- /dev/null
+++ b/utils/bazel/llvm-project-overlay/libcxxabi/BUILD.bazel
@@ -0,0 +1,24 @@
@@ -0,0 +1,30 @@
+# This file is licensed under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
@@ -89,8 +223,14 @@ index 0000000000..cf491e4e46
+ name = "libcxxabi_srcs",
+ srcs = glob([
+ "src/**/*.cpp",
+ "src/**/*.def",
+ "src/**/*.inc",
+ "src/**/*.h",
+ ]),
+)
+
+filegroup(
+ name = "libcxxabi_textual_srcs",
+ srcs = glob([
+ "src/**/*.def",
+ "src/**/*.inc",
+ ]),
+)
@@ -1,35 +0,0 @@
Commit ID: e92461dc72d53b737ac14fe2c4c9c539946a4318
Change ID: xyswklonuwpozzpkzwowszwnrzvkonxu
Author : Chandler Carruth <chandlerc@gmail.com> (2025-12-30 10:19:01)
Committer: Chandler Carruth <chandlerc@gmail.com> (2025-12-30 21:28:56)
Add filegroups for installed compiler-rt headers
These are installed along-side the builtin Clang headers.
diff --git a/utils/bazel/llvm-project-overlay/compiler-rt/BUILD.bazel b/utils/bazel/llvm-project-overlay/compiler-rt/BUILD.bazel
index 115da4cb77..ebe376fcaa 100644
--- a/utils/bazel/llvm-project-overlay/compiler-rt/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/compiler-rt/BUILD.bazel
@@ -131,6 +131,21 @@
],
)
+filegroup(
+ name = "fuzzer_installed_hdrs",
+ srcs = glob(["include/fuzzer/*.h"]),
+)
+
+filegroup(
+ name = "profile_installed_hdrs",
+ srcs = glob(["include/profile/*.h"]),
+)
+
+filegroup(
+ name = "sanitizer_installed_hdrs",
+ srcs = glob(["include/sanitizer/*.h"]),
+)
+
BUILTINS_CRTBEGIN_SRCS = ["lib/builtins/crtbegin.c"]
filegroup(
@@ -0,0 +1,521 @@
Commit ID: d3b82534c2546a892a27856672ed95a7db97dba3
Change ID: zyxuvzwmzsnorloyuupuurxkppkoplnw
Author : Chandler Carruth <chandlerc@gmail.com> (2026-02-16 23:17:06)
Committer: Chandler Carruth <chandlerc@gmail.com> (2026-03-11 07:54:02)
Improve compiler-rt build structure and export compilation info
This first improves the structure of the compiler-rt BUILD.bazel, fixing
bugs and exposing more carefully arranged source files.
It also exposes compilation info for builtins and CRT files for use in
compiling these source files.
diff --git a/utils/bazel/llvm-project-overlay/compiler-rt/BUILD.bazel b/utils/bazel/llvm-project-overlay/compiler-rt/BUILD.bazel
index 4ded226174..3b5b8fc787 100644
--- a/utils/bazel/llvm-project-overlay/compiler-rt/BUILD.bazel
+++ b/utils/bazel/llvm-project-overlay/compiler-rt/BUILD.bazel
@@ -3,6 +3,7 @@
# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
load("@rules_cc//cc:defs.bzl", "cc_library")
+load("compiler-rt.bzl", "make_filtered_builtins_srcs_groups")
package(
default_visibility = ["//visibility:public"],
@@ -160,9 +161,15 @@
srcs = BUILTINS_CRTEND_SRCS,
)
+BUILTINS_EMUTLS_SRCS = ["lib/builtins/emutls.c"]
+
+filegroup(
+ name = "builtins_emutls_srcs",
+ srcs = BUILTINS_EMUTLS_SRCS,
+)
+
BUILTINS_HOSTED_SRCS = [
"lib/builtins/clear_cache.c",
- "lib/builtins/emutls.c",
"lib/builtins/enable_execute_stack.c",
"lib/builtins/eprintf.c",
]
@@ -224,11 +231,11 @@
),
)
-BUILTNS_ATOMICS_SRCS = ["lib/builtins/atomic.c"]
+BUILTINS_ATOMICS_SRCS = ["lib/builtins/atomic.c"]
filegroup(
name = "builtins_atomics_srcs",
- srcs = BUILTNS_ATOMICS_SRCS + ["lib/builtins/assembly.h"],
+ srcs = BUILTINS_ATOMICS_SRCS + ["lib/builtins/assembly.h"],
)
BUILTINS_MACOS_ATOMIC_SRCS_PATTERNS = [
@@ -241,6 +248,28 @@
srcs = glob(BUILTINS_MACOS_ATOMIC_SRCS_PATTERNS),
)
+# Source files for portable components of the compiler builtins library.
+filegroup(
+ name = "builtins_generic_srcs",
+ srcs = ["lib/builtins/cpu_model/cpu_model.h"] + glob(
+ [
+ "lib/builtins/*.c",
+ "lib/builtins/*.cpp",
+ "lib/builtins/*.h",
+ "lib/builtins/*.inc",
+ ],
+ allow_empty = True,
+ exclude = (
+ BUILTINS_CRTBEGIN_SRCS +
+ BUILTINS_CRTEND_SRCS +
+ BUILTINS_TF_EXCLUDES +
+ BUILTINS_TF_SRCS_PATTERNS +
+ BUILTINS_ATOMICS_SRCS +
+ BUILTINS_MACOS_ATOMIC_SRCS_PATTERNS
+ ),
+ ),
+)
+
# Apple-platform specific SME source file.
filegroup(
name = "builtins_aarch64_apple_sme_srcs",
@@ -305,10 +334,13 @@
# Source files for the AArch64 architecture-specific builtins.
filegroup(
- name = "builtins_aarch64_srcs",
+ name = "builtins_unfiltered_aarch64_srcs",
srcs = [
"lib/builtins/cpu_model/aarch64.c",
"lib/builtins/cpu_model/aarch64.h",
+ ":builtins_bf16_srcs",
+ ":builtins_generic_srcs",
+ ":builtins_tf_srcs",
] + [
AARCH64_OUTLINE_ATOMICS_FMT.format(pat, size, model)
for (pat, size, model) in AARCH64_OUTLINE_ATOMICS
@@ -328,10 +360,20 @@
"lib/builtins/aarch64/lse.S",
# These files are provided by SME-specific file groups above.
"lib/builtins/aarch64/*sme*",
+ # This is only used with MinGW.
+ "lib/builtins/aarch64/chkstk.S",
+ # TODO: Remove this once we have a way of accessing `SipHash.h`.
+ "lib/builtins/aarch64/emupac.cpp",
],
),
)
+make_filtered_builtins_srcs_groups(
+ name = "builtins_aarch64_srcs",
+ srcs = [":builtins_unfiltered_aarch64_srcs"],
+ textual_name = "builtins_aarch64_textual_srcs",
+)
+
BUILTINS_ARM_VFP_SRCS_PATTERNS = [
"lib/builtins/arm/*vfp*.S",
"lib/builtins/arm/*vfp*.c",
@@ -348,9 +390,19 @@
),
)
+BUILTINS_ARM_IMPLICIT_IT_SRCS = [
+ "lib/builtins/arm/mulsf3.S",
+ "lib/builtins/arm/divsf3.S",
+]
+
+filegroup(
+ name = "builtins_arm_implicit_it_srcs",
+ srcs = BUILTINS_ARM_IMPLICIT_IT_SRCS,
+)
+
# Source files for the ARM architecture-specific builtins.
filegroup(
- name = "builtins_arm_srcs",
+ name = "builtins_arm_arch_srcs",
srcs = glob(
[
"lib/builtins/arm/*.S",
@@ -359,14 +411,52 @@
"lib/builtins/arm/*.h",
],
allow_empty = True,
- exclude = BUILTINS_ARM_VFP_SRCS_PATTERNS,
+ exclude = (BUILTINS_ARM_VFP_SRCS_PATTERNS +
+ BUILTINS_ARM_IMPLICIT_IT_SRCS) + [
+ # This is only used with MinGW.
+ "lib/builtins/arm/chkstk.S",
+ ],
),
)
-# Source files for the PPC architecture-specific builtins.
-filegroup(
- name = "builtins_ppc_srcs",
- srcs = glob(
+filegroup(
+ name = "builtins_unfiltered_armv7_srcs",
+ srcs = [
+ ":builtins_arm_arch_srcs",
+ ":builtins_arm_vfp_srcs",
+ ":builtins_bf16_srcs",
+ ":builtins_generic_srcs",
+ ],
+)
+
+make_filtered_builtins_srcs_groups(
+ name = "builtins_armv7_srcs",
+ srcs = [":builtins_unfiltered_armv7_srcs"],
+ textual_name = "builtins_armv7_textual_srcs",
+)
+
+filegroup(
+ name = "builtins_unfiltered_aarch32_srcs",
+ srcs = [
+ ":builtins_arm_arch_srcs",
+ ":builtins_arm_vfp_srcs",
+ ":builtins_bf16_srcs",
+ ":builtins_generic_srcs",
+ ],
+)
+
+make_filtered_builtins_srcs_groups(
+ name = "builtins_aarch32_srcs",
+ srcs = [":builtins_unfiltered_aarch32_srcs"],
+ textual_name = "builtins_aarch32_textual_srcs",
+)
+
+filegroup(
+ name = "builtins_unfiltered_ppc64_srcs",
+ srcs = [
+ ":builtins_generic_srcs",
+ ":builtins_tf_srcs",
+ ] + glob(
[
"lib/builtins/ppc/*.S",
"lib/builtins/ppc/*.c",
@@ -377,17 +467,64 @@
),
)
-# Source files for the RISC-V architecture-specific builtins.
-filegroup(
- name = "builtins_riscv_srcs",
- srcs = glob(
- [
- "lib/builtins/riscv/*.S",
- "lib/builtins/riscv/*.c",
- "lib/builtins/riscv/*.cpp",
- ],
- allow_empty = True,
- ),
+make_filtered_builtins_srcs_groups(
+ name = "builtins_ppc64_srcs",
+ srcs = [":builtins_unfiltered_ppc64_srcs"],
+ textual_name = "builtins_ppc64_textual_srcs",
+)
+
+filegroup(
+ name = "builtins_unfiltered_ppc32_srcs",
+ srcs = [":builtins_generic_srcs"],
+)
+
+make_filtered_builtins_srcs_groups(
+ name = "builtins_ppc32_srcs",
+ srcs = [":builtins_unfiltered_ppc32_srcs"],
+ textual_name = "builtins_ppc32_textual_srcs",
+)
+
+filegroup(
+ name = "builtins_unfiltered_riscv64_srcs",
+ srcs = [
+ ":builtins_generic_srcs",
+ ":builtins_tf_srcs",
+ ] + glob(
+ [
+ "lib/builtins/riscv/*.S",
+ "lib/builtins/riscv/*.c",
+ "lib/builtins/riscv/*.cpp",
+ "lib/builtins/riscv/*.h",
+ ],
+ allow_empty = True,
+ ),
+)
+
+make_filtered_builtins_srcs_groups(
+ name = "builtins_riscv64_srcs",
+ srcs = [":builtins_unfiltered_riscv64_srcs"],
+ textual_name = "builtins_riscv64_textual_srcs",
+)
+
+filegroup(
+ name = "builtins_unfiltered_riscv32_srcs",
+ srcs = [
+ ":builtins_generic_srcs",
+ ] + glob(
+ [
+ "lib/builtins/riscv/*.S",
+ "lib/builtins/riscv/*.c",
+ "lib/builtins/riscv/*.cpp",
+ "lib/builtins/riscv/*.h",
+ ],
+ allow_empty = True,
+ ),
+)
+
+make_filtered_builtins_srcs_groups(
+ name = "builtins_riscv32_srcs",
+ srcs = [":builtins_unfiltered_riscv32_srcs"],
+ textual_name = "builtins_riscv32_textual_srcs",
)
# Source files for the x86 architecture specific builtins (both 32-bit and
@@ -402,8 +539,14 @@
# Source files for the x86-64 architecture specific builtins.
filegroup(
- name = "builtins_x86_64_srcs",
- srcs = glob(
+ name = "builtins_unfiltered_x86_64_srcs",
+ srcs = [
+ ":builtins_bf16_srcs",
+ ":builtins_generic_srcs",
+ ":builtins_tf_srcs",
+ ":builtins_x86_arch_srcs",
+ ":builtins_x86_fp80_srcs",
+ ] + glob(
[
"lib/builtins/x86_64/*.S",
"lib/builtins/x86_64/*.c",
@@ -411,13 +554,29 @@
"lib/builtins/x86_64/*.h",
],
allow_empty = True,
+ exclude = [
+ # This is a Windows-specific routine.
+ # TODO: We should expose this as a Windows source at some point.
+ "lib/builtins/x86_64/chkstk.S",
+ ],
),
)
+make_filtered_builtins_srcs_groups(
+ name = "builtins_x86_64_srcs",
+ srcs = [":builtins_unfiltered_x86_64_srcs"],
+ textual_name = "builtins_x86_64_textual_srcs",
+)
+
# Source files for the 32-bit-specific x86 architecture specific builtins.
filegroup(
- name = "builtins_i386_srcs",
- srcs = glob(
+ name = "builtins_unfiltered_i386_srcs",
+ srcs = [
+ ":builtins_bf16_srcs",
+ ":builtins_generic_srcs",
+ ":builtins_x86_arch_srcs",
+ ":builtins_x86_fp80_srcs",
+ ] + glob(
[
"lib/builtins/i386/*.S",
"lib/builtins/i386/*.c",
@@ -429,28 +588,16 @@
# This file is used for both i386 and x86_64 and so included in the
# broader x86 sources.
"lib/builtins/i386/fp_mode.c",
+ # These are Windows-specific routines.
+ # TODO: We should expose these as Windows source at some point.
+ "lib/builtins/i386/chkstk.S",
+ "lib/builtins/i386/chkstk2.S",
],
),
)
-# Source files for portable components of the compiler builtins library.
-filegroup(
- name = "builtins_generic_srcs",
- srcs = ["lib/builtins/cpu_model/cpu_model.h"] + glob(
- [
- "lib/builtins/*.c",
- "lib/builtins/*.cpp",
- "lib/builtins/*.h",
- "lib/builtins/*.inc",
- ],
- allow_empty = True,
- exclude = (
- BUILTINS_CRTBEGIN_SRCS +
- BUILTINS_CRTEND_SRCS +
- BUILTINS_TF_EXCLUDES +
- BUILTINS_TF_SRCS_PATTERNS +
- BUILTNS_ATOMICS_SRCS +
- BUILTINS_MACOS_ATOMIC_SRCS_PATTERNS
- ),
- ),
+make_filtered_builtins_srcs_groups(
+ name = "builtins_i386_srcs",
+ srcs = [":builtins_unfiltered_i386_srcs"],
+ textual_name = "builtins_i386_textual_srcs",
)
diff --git a/utils/bazel/llvm-project-overlay/compiler-rt/compiler-rt.bzl b/utils/bazel/llvm-project-overlay/compiler-rt/compiler-rt.bzl
new file mode 100644
index 0000000000..e33ceb6a89
--- /dev/null
+++ b/utils/bazel/llvm-project-overlay/compiler-rt/compiler-rt.bzl
@@ -0,0 +1,153 @@
+# This file is licensed under the Apache License v2.0 with LLVM Exceptions.
+# See https://llvm.org/LICENSE.txt for license information.
+# SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+
+"""Starlark for building parts of compiler-rt.
+
+Variables provide baseline information for how to build various parts of
+compiler-rt. These can be used to generate non-Bazel builds of the library.
+
+Rules and macros support building the relevant filegroups of source files.
+
+TODO: Add macros that provide a convenient way to construct a Bazel target for
+the Clang resource directory with builtins and crt files.
+"""
+
+_common_copts = [
+ "-O3",
+ "-fPIC",
+ "-ffreestanding",
+ "-std=c11",
+]
+
+crt_copts = _common_copts + [
+ "-DCRT_HAS_INITFINI_ARRAY",
+ "-DEH_USE_FRAME_REGISTRY",
+ "-fno-lto",
+]
+
+builtins_copts = _common_copts + [
+ "-fno-builtin",
+ "-fomit-frame-pointer",
+ "-fvisibility=hidden",
+ "-Wno-missing-prototypes",
+ "-Wno-unused-parameter",
+]
+
+def _get_rel_path(path_str):
+ rel_path = path_str.rpartition("/lib/builtins/")[2]
+ if rel_path == path_str:
+ fail("Expected '/lib/builtins/' in path " + path_str)
+ return rel_path
+
+def _filtered_builtins_srcs_impl(ctx):
+ """Implementation of filter_builtins_srcs rule."""
+
+ # Build a map from generic file basename to list of overriding files.
+ overrides = {}
+ for f in ctx.files.srcs:
+ rel_path = _get_rel_path(f.short_path)
+ if "/" in rel_path:
+ base_file = rel_path.rpartition("/")[2]
+ if base_file.endswith(".S"):
+ base_file = base_file.removesuffix(".S") + ".c"
+ overrides[base_file] = True
+
+ filtered_files = []
+ for f in ctx.files.srcs:
+ rel_path = _get_rel_path(f.short_path)
+ if "/" not in rel_path:
+ # This is a generic file. Check if it's overridden.
+ if rel_path not in overrides:
+ filtered_files.append(f)
+ else:
+ # This is an arch-specific file, include it.
+ filtered_files.append(f)
+
+ # Remove any textual sources from this list.
+ filtered_files = [
+ f
+ for f in filtered_files
+ if f.extension not in ["inc", "def"]
+ ]
+
+ return [DefaultInfo(files = depset(filtered_files))]
+
+filtered_builtins_srcs = rule(
+ implementation = _filtered_builtins_srcs_impl,
+ attrs = {
+ "srcs": attr.label_list(
+ mandatory = True,
+ allow_files = True,
+ doc = "Input files.",
+ ),
+ },
+ doc = """Build a filtered filegroup of non-textual srcs for builtins.
+
+ Accepts a filegroup whose files are in lib/builtins/, and produces a target
+ behaving like a filegroup containing filtered files.
+
+ This removes any textual source files (`.inc` or `.def`) from the input.
+
+ It also replaces generic srcs that are overridden by architecture-specific
+ sources. For example, given a list of sources from filegroup of the form:
+
+ - `.../lib/builtins/file_0.c`
+ - `.../lib/builtins/file_1.c`
+ - `.../lib/builtins/file_2.c`
+ - `.../lib/builtins/arch/file_0.c`
+ - `.../lib/builtins/arch/file_1.S`
+
+ It removes any source-file at the top level of lib/builtins/ (e.g.
+ lib/builtins/file_0.c) that has a corresponding source-file in an arch
+ directory (e.g. lib/builtins/arch/file_0.c or lib/builtins/arch/file_1.S),
+ producing a list like:
+
+ - `.../lib/builtins/file_2.c`
+ - `.../lib/builtins/arch/file_0.c`
+ - `.../lib/builtins/arch/file_1.S`
+
+ This allows a target architecture to simply add a specialized file to the
+ list of sources with the architecture prefix and have the specialized
+ version override the generic version.
+ """,
+)
+
+def _filtered_builtins_textual_srcs_impl(ctx):
+ """Implementation of filter_builtins_textual_srcs rule."""
+
+ filtered_files = [
+ f
+ for f in ctx.files.srcs
+ if f.extension in ["inc", "def"]
+ ]
+
+ return [DefaultInfo(files = depset(filtered_files))]
+
+filtered_builtins_textual_srcs = rule(
+ implementation = _filtered_builtins_textual_srcs_impl,
+ attrs = {
+ "srcs": attr.label_list(
+ mandatory = True,
+ allow_files = True,
+ doc = "Input files.",
+ ),
+ },
+ doc = """Build a filegroup of the textual srcs for builtins.
+
+ Textual sources are those that can't be compiled directly and aren't
+ recognized as header files by Bazel. The extensions recognized here are
+ `.inc` and `.def`.
+ """,
+)
+
+def make_filtered_builtins_srcs_groups(name, textual_name, srcs):
+ """Macro to expand both the non-textual and textual filtered srcs groups."""
+ filtered_builtins_srcs(
+ name = name,
+ srcs = srcs,
+ )
+ filtered_builtins_textual_srcs(
+ name = textual_name,
+ srcs = srcs,
+ )
-4
View File
@@ -8,10 +8,6 @@ def _get_files(ctx):
files = []
for src in ctx.attr.srcs:
files.extend([f.path for f in src[DefaultInfo].files.to_list()])
files.extend([
f.path
for f in src[DefaultInfo].default_runfiles.files.to_list()
])
if ctx.attr.strip_package_dir:
# Files may or may not be prefixed with the bin directory, and then
+1 -1
View File
@@ -88,7 +88,7 @@ def main() -> None:
# Remove line endings.
line = line.rstrip("\r\n")
# Exactly matches our pattern
(key, value) = line.split(" ", 1)
key, value = line.split(" ", 1)
key = key.removeprefix("STABLE_")
if key in substitutions:
if args.verbose:
+1 -1
View File
@@ -134,7 +134,7 @@ expand_version_build_info_internal = rule(
def expand_version_build_info(name, **kwargs):
expand_version_build_info_internal(
name = name,
internal_stamp_flag_detect = select({
internal_stamp_flag_detect = False if kwargs.get("stamp") == 0 else select({
"//bazel/version:internal_stamp_flag_detect": True,
"//conditions:default": False,
}),
+2 -2
View File
@@ -473,7 +473,7 @@ cc_binary(
"//testing/base:benchmark_main",
"@abseil-cpp//absl/container:flat_hash_map",
"@abseil-cpp//absl/random",
"@boost_unordered",
"@boost.unordered",
"@google_benchmark//:benchmark",
"@llvm-project//llvm:Support",
],
@@ -577,7 +577,7 @@ cc_library(
"@abseil-cpp//absl/base:no_destructor",
"@abseil-cpp//absl/hash",
"@abseil-cpp//absl/random",
"@boost_unordered",
"@boost.unordered",
"@google_benchmark//:benchmark",
"@llvm-project//llvm:Support",
],
+1 -1
View File
@@ -643,7 +643,7 @@ auto DirRef::ReadlinkSlow(const std::filesystem::path& path)
if (buffer_size == 0) {
buffer_size = MinBufferSize;
}
large_buffer.resize(status.size());
large_buffer.resize(buffer_size);
ssize_t result =
readlinkat(dfd_, path.c_str(), large_buffer.data(), large_buffer.size());
if (result == -1) {
+37 -7
View File
@@ -18,17 +18,18 @@ namespace Carbon {
//
// This provides a hashtable-specific extension point to implement equality
// comparison within a hashtable key context. By default, it will use
// `operator==` on the LHS and RHS operands. However, types can provide a
// dedicated customization point by implementing a free function that can be
// found by ADL for your type called `CarbonHashtableEq` with the following
// signature:
// `operator==` on the LHS and RHS operands if they are of the identical type.
// However, types can provide a dedicated customization point by implementing a
// free function that can be found by ADL for your type called
// `CarbonHashtableEq` with the following signature:
//
// ```cpp
// auto CarbonHashtableEq(const YourType& lhs, const YourType& rhs) -> bool;
// ```
//
// Any such overload will be able to override the default we provide for types
// that can compare with `==`.
// that can compare with `==`. This overload may only compare two objects equal
// if the hash of those two objects are identical.
//
// This library also provides any customization points for LLVM or standard
// library types either lacking `operator==` or where that operator is not
@@ -161,8 +162,37 @@ inline auto CarbonHashtableEq(const llvm::APFloat& lhs,
return lhs.bitwiseIsEqual(rhs);
}
template <typename LeftT, typename RightT>
inline auto CarbonHashtableEq(const LeftT& lhs, const RightT& rhs) -> bool
inline auto CarbonHashtableEq(llvm::StringRef lhs, const std::string& rhs)
-> bool {
return lhs == rhs;
}
template <typename T>
inline auto CarbonHashtableEq(llvm::MutableArrayRef<T> lhs,
llvm::ArrayRef<T> rhs) -> bool {
return lhs == rhs;
}
template <typename LHS, typename RHS>
inline auto CarbonHashtableEq(const LHS& lhs, const RHS& rhs) -> bool
requires(requires {
{ CarbonHashtableEq(rhs, lhs) } -> std::convertible_to<bool>;
})
{
return CarbonHashtableEq(rhs, lhs);
}
// Provides symmetric equality so the `CarbonHashtableEq` operands aren't
// ordered.
//
// If this template proves problematic in any way, we can revisit it - the
// `CarbonHashtableEq` functions don't really need to be symmetric, since they
// generally represent an implicit conversion which is often only one-way (eg:
// MutableArrayRef converts to ArrayRef, but not the other way around) - but
// documenting/describing that asymmetry felt a little awkward too - so maybe
// this template is an OK solution for now.
template <typename T>
inline auto CarbonHashtableEq(const T& lhs, const T& rhs) -> bool
requires(requires {
{ lhs == rhs } -> std::convertible_to<bool>;
})
+8
View File
@@ -45,6 +45,10 @@ struct TestData : Printable<TestData> {
static_assert(std::is_copy_constructible_v<TestData>);
inline auto CarbonHashtableEq(int lhs, TestData rhs) -> bool {
return lhs == rhs;
}
// Non-trivial type for testing.
struct MoveOnlyTestData : Printable<TestData> {
int value;
@@ -85,6 +89,10 @@ struct MoveOnlyTestData : Printable<TestData> {
static_assert(!std::is_copy_constructible_v<MoveOnlyTestData>);
static_assert(std::is_move_constructible_v<MoveOnlyTestData>);
inline auto CarbonHashtableEq(int lhs, const MoveOnlyTestData& rhs) -> bool {
return lhs == rhs;
}
// Test stateless key context that produces different hashes from normal.
// Changing the hash values should result in test failures if the context ever
// fails to be used.
+1
View File
@@ -7,6 +7,7 @@
package Core library "prelude";
export import library "prelude/copy";
export import library "prelude/default";
export import library "prelude/destroy";
export import library "prelude/iterate";
export import library "prelude/operators";
+54
View File
@@ -0,0 +1,54 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
package Core library "prelude/default";
import library "prelude/types/bool";
import library "prelude/types/int_literal";
// Provides the default value of an object. If implemented for a type `T`, this
// is used to initialize declarations without an explicit initializer, such as
// `var x: T;`, and leaves them in a fully-formed state.
interface Default { fn Op() -> Self; }
// Indicates that a type permits unformed initialization, which leaves the
// object in a state where calling the destructor is valid but optional, and no
// other operations on the object except for reinitialization are permitted.
interface UnformedInit {
// TODO: This should probably be:
// let StructT:! type;
// fn Op() -> StructT;
// and should be able to initialize a subset of the fields. For now we always
// leave the object uninitialized when it is in an unformed state.
// See https://github.com/carbon-language/carbon-lang/pull/5913
}
// Implementations for some builtin types. These need to be here to satisfy the
// orphan rule because these builtin types have no associated library of their
// own.
impl bool as UnformedInit {}
impl forall [T:! type] T* as UnformedInit {}
impl forall [T:! UnformedInit, N:! IntLiteral()] array(T, N) as UnformedInit {}
// TODO: Generalize these to apply to tuples and structs containing only
// `UnformedInit` types.
impl () as UnformedInit {}
impl {} as UnformedInit {}
// Provides a default, possibly unformed, value of an object. This should not be
// implemented directly. Instead, implement `Default` to provide a fully-formed
// state or (eventually) `UnformedInit` to provide an unformed state.
interface DefaultOrUnformed {
// TODO: This should return `MaybeUnformed(Self)` once that is supported.
fn Op() -> Self;
}
final impl forall [T:! Default] T as DefaultOrUnformed {
fn Op() -> Self {
return T.(Default.Op)();
}
}
impl forall [T:! UnformedInit] T as DefaultOrUnformed {
fn Op() -> Self = "make_uninitialized";
}
+1 -1
View File
@@ -20,7 +20,7 @@ interface Iterate {
impl forall [T:! Copy & Destroy, N:! IntLiteral()]
array(T, N) as Iterate
where .ElementType = T and .CursorType = i32 {
fn NewCursor[self: Self]() -> i32 { return 0; }
fn NewCursor[unused self: Self]() -> i32 { return 0; }
fn Next[self: Self](cursor: i32*) -> Optional(T) {
if (*cursor < N) {
++*cursor;
+1
View File
@@ -9,3 +9,4 @@ export import library "prelude/operators/as";
export import library "prelude/operators/bitwise";
export import library "prelude/operators/comparison";
export import library "prelude/operators/index";
export import library "prelude/operators/deref";
+13
View File
@@ -44,8 +44,21 @@ impl forall [T:! type, U:! ImplicitAs(T)] const U as ImplicitAs(T) {
fn Convert[self: const U]() -> T { return (self as U).Convert(); }
}
// `const` can be added to a pointer.
// TODO: This is also provided as a builtin conversion. We provide it here so
// that Optional(T*) can implicitly convert to Optional(const T*). See #5750.
impl forall [T:! type] T* as ImplicitAs(const T*) {
fn Convert[self: T*]() -> const T* = "pointer.unsafe_convert";
}
impl forall [T:! type] T* as As(const T*) {
fn Convert[self: T*]() -> const T* = "pointer.unsafe_convert";
}
// Pointer types can be unsafely cast to other pointer types.
// TODO: Should `unsafe as` be able to remove `const`?
impl forall [T:! type, U:! type] T* as UnsafeAs(U*) {
fn Convert[self: T*]() -> U* = "pointer.unsafe_convert";
}
interface IntFitsIn(Dest:! type) {}
+11
View File
@@ -0,0 +1,11 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
package Core library "prelude/operators/deref";
// TODO: Align with https://docs.carbon-lang.dev/docs/design/values.html#dereferencing-customization.
interface CppUnsafeDeref {
let Result:! type;
fn Op[ref self: Self]() -> ref Result;
}
+3
View File
@@ -5,6 +5,7 @@
package Core library "prelude/types/char";
import library "prelude/copy";
import library "prelude/default";
import library "prelude/destroy";
import library "prelude/operators";
import library "prelude/types/uint";
@@ -17,6 +18,8 @@ class Char {
adapt u8;
}
impl Char as UnformedInit {}
impl Char as Copy {
fn Op[self: Self]() -> Self = "primitive_copy";
}
+12 -6
View File
@@ -5,6 +5,7 @@
package Core library "prelude/types/cpp/int";
import library "prelude/copy";
import library "prelude/default";
import library "prelude/operators";
import library "prelude/types/int";
import library "prelude/types/int_literal";
@@ -28,6 +29,11 @@ class CppCompat.ULongLong64 {
adapt u64;
}
impl CppCompat.Long32 as UnformedInit {}
impl CppCompat.ULong32 as UnformedInit {}
impl CppCompat.LongLong64 as UnformedInit {}
impl CppCompat.ULongLong64 as UnformedInit {}
// Copy
impl CppCompat.Long32 as Copy {
@@ -93,12 +99,12 @@ final impl CppCompat.ULong32 as ImplicitAs(IntLiteral()) {
// TODO: ImplicitAs from UInt(N) to ULong32 if N < 32.
impl u32 as ImplicitAs(CppCompat.ULong32) {
fn Convert[self: Self]() -> CppCompat.ULong32 = "int.convert_checked";
fn Convert[self: Self]() -> CppCompat.ULong32 = "int.convert";
}
// TODO: ImplicitAs from ULong32 to UInt(N) if N > 32.
final impl CppCompat.ULong32 as ImplicitAs(u32) {
fn Convert[self: Self]() -> u32 = "int.convert";
final impl CppCompat.ULong32 as ImplicitAs(u64) {
fn Convert[self: Self]() -> u64 = "int.convert";
}
impl IntLiteral() as ImplicitAs(CppCompat.LongLong64) {
@@ -142,12 +148,12 @@ final impl CppCompat.ULongLong64 as ImplicitAs(IntLiteral()) {
// TODO: ImplicitAs from UInt(N) to ULongLong64 if N < 64.
impl u64 as ImplicitAs(CppCompat.ULongLong64) {
fn Convert[self: Self]() -> CppCompat.ULongLong64 = "int.convert_checked";
fn Convert[self: Self]() -> CppCompat.ULongLong64 = "int.convert";
}
// TODO: ImplicitAs from ULongLong64 to UInt(N) if N > 64.
final impl CppCompat.ULongLong64 as ImplicitAs(u64) {
fn Convert[self: Self]() -> u64 = "int.convert";
final impl CppCompat.ULongLong64 as ImplicitAs(u128) {
fn Convert[self: Self]() -> u128 = "int.convert";
}
// TODO: As from Long32 to Int(N) if N < 32.
+11 -4
View File
@@ -5,6 +5,7 @@
package Core library "prelude/types/cpp/nullptr";
import library "prelude/copy";
import library "prelude/default";
import library "prelude/destroy";
import library "prelude/operators/as";
import library "prelude/types/cpp/void";
@@ -29,13 +30,17 @@ class CppCompat.NullptrT {
// TODO: Give this type a custom empty value representation.
adapt MaybeUnformed(VoidBase*);
// TODO: This should be just
// fn Make() -> Self = "make_uninitialized";
// but we don't yet delay processing builtin function definitions until the
// end of the enclosing class.
fn Make() -> Self {
returned var s: Self;
return var;
fn MakeImpl() -> Self = "make_uninitialized";
return MakeImpl();
}
impl as Copy {
fn Op[self: Self]() -> Self {
fn Op[unused self: Self]() -> Self {
return Make();
}
}
@@ -43,8 +48,10 @@ class CppCompat.NullptrT {
// TODO: impl as EqWith(Self)
impl forall [T:! type] as ImplicitAs(Optional(T*)) {
fn Convert[self: Self]() -> Optional(T*) {
fn Convert[unused self: Self]() -> Optional(T*) {
return Optional(T*).None();
}
}
}
impl CppCompat.NullptrT as UnformedInit {}
+3
View File
@@ -5,6 +5,7 @@
package Core library "prelude/types/float";
import library "prelude/copy";
import library "prelude/default";
import library "prelude/destroy";
import library "prelude/operators";
import library "prelude/types/float_literal";
@@ -16,6 +17,8 @@ class Float(N:! IntLiteral()) {
adapt MakeFloat(N);
}
impl forall [N:! IntLiteral()] Float(N) as UnformedInit {}
// Copy.
impl forall [N:! IntLiteral()] Float(N) as Copy {
+8
View File
@@ -0,0 +1,8 @@
// Part of the Carbon Language project, under the Apache License v2.0 with LLVM
// Exceptions. See /LICENSE for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
package Core library "prelude/types/form";
// TODO: this should be a concrete constant, not a function.
fn Form() -> type = "form.make_type";
+23 -1
View File
@@ -5,6 +5,7 @@
package Core library "prelude/types/int";
import library "prelude/copy";
import library "prelude/default";
import library "prelude/destroy";
import library "prelude/operators";
import library "prelude/types/int_literal";
@@ -15,6 +16,8 @@ class Int(N:! IntLiteral()) {
adapt MakeInt(N);
}
impl forall [N:! IntLiteral()] Int(N) as UnformedInit {}
// Copy.
impl forall [N:! IntLiteral()] Int(N) as Copy {
@@ -42,7 +45,26 @@ final impl forall [From:! IntLiteral()] Int(From) as As(IntLiteral()) {
fn Convert[self: Self]() -> IntLiteral() = "int.convert_checked";
}
// TODO: Allow as an implicit conversion if N > M.
// Work around the inability to put a `where` clause on a generic parameter of
// type `IntLiteral`.
// TODO: Remove this once possible.
private interface AnyInt {
let Width:! IntLiteral();
fn AsInt[self: Self]() -> Int(Width);
}
impl forall [N:! IntLiteral()] Int(N) as AnyInt where .Width = N {
fn AsInt[self: Self]() -> Self { return self; }
}
impl forall [To:! IntLiteral(), From:! AnyInt & IntFitsIn(Int(To))]
From as ImplicitAs(Int(To)) {
fn Convert[self: Self]() -> Int(To) {
fn Impl(src: Int(From.Width)) -> Int(To) = "int.convert";
return Impl(self.AsInt());
}
}
final impl forall [From:! IntLiteral(), To:! IntLiteral()] Int(From) as As(Int(To)) {
fn Convert[self: Self]() -> Int(To) = "int.convert";
}
+3
View File
@@ -4,6 +4,7 @@
package Core library "prelude/types/maybe_unformed";
import library "prelude/default";
import library "prelude/destroy";
private fn MakeMaybeUnformed(t: type) -> type = "maybe_unformed.make_type";
@@ -12,3 +13,5 @@ private fn MakeMaybeUnformed(t: type) -> type = "maybe_unformed.make_type";
class MaybeUnformed(T:! Destroy) {
adapt MakeMaybeUnformed(T);
}
impl forall [T:! Destroy] MaybeUnformed(T) as UnformedInit {}
+18 -5
View File
@@ -5,6 +5,7 @@
package Core library "prelude/types/optional";
import library "prelude/copy";
import library "prelude/default";
import library "prelude/destroy";
import library "prelude/operators/as";
import library "prelude/operators/bitwise";
@@ -40,6 +41,8 @@ class Optional(T:! OptionalStorage) {
adapt T.Type;
}
impl forall [T:! OptionalStorage & UnformedInit] Optional(T) as UnformedInit {}
// Support for converting a `T` to an `Optional(U)` if `T` converts to `U`.
// Once we have match_first, this can be rewritten more simply as:
//
@@ -105,17 +108,23 @@ private class DefaultOptionalStorage(T:! Copy & Destroy) {
var has_value: bool;
}
private fn MakeUninitializedOptionalStorage(T:! Copy & Destroy)
-> DefaultOptionalStorage(T) = "make_uninitialized";
impl forall [T:! Copy & Destroy] T as OptionalStorage
where .Type = DefaultOptionalStorage(T) {
fn None() -> DefaultOptionalStorage(T) {
returned var me: DefaultOptionalStorage(T);
returned var me: DefaultOptionalStorage(T) =
MakeUninitializedOptionalStorage(T);
me.has_value = false;
return var;
}
fn Some[self: Self]() -> DefaultOptionalStorage(T) {
returned var me: DefaultOptionalStorage(T);
// TODO: Should be:
// me.value = self as MaybeUnformed(T);
// TODO: This whole function should be just
// return {.value = self, .has_value = true};
// but that requires that `T` implements `ImplicitAs(MaybeUnformed(T))`.
returned var me: DefaultOptionalStorage(T) =
MakeUninitializedOptionalStorage(T);
me.value unsafe as T = self;
me.has_value = true;
return var;
@@ -130,13 +139,17 @@ impl forall [T:! Copy & Destroy] T as OptionalStorage
private fn PointerIsNull[T:! type](value: MaybeUnformed(T*)) -> bool = "pointer.is_null";
private fn MakeUninitializedOptionalPointer(T:! type)
-> MaybeUnformed(T*) = "make_uninitialized";
// For pointers, we use a null pointer value as the "None" value. This allows
// `Optional(T*)` to be ABI-compatible with a C++ nullable pointer.
final impl forall [T:! type] T* as OptionalStorage
where .Type = MaybeUnformed(T*) {
fn None() -> MaybeUnformed(T*) = "pointer.make_null";
fn Some[self: Self]() -> MaybeUnformed(T*) {
returned var result: MaybeUnformed(T*);
returned var result: MaybeUnformed(T*) =
MakeUninitializedOptionalPointer(T);
result unsafe as T* = self;
return var;
}
+3
View File
@@ -5,6 +5,7 @@
package Core library "prelude/types/string";
import library "prelude/copy";
import library "prelude/default";
import library "prelude/destroy";
import library "prelude/types/char";
import library "prelude/types/uint";
@@ -24,6 +25,8 @@ class String {
private var size: u64;
}
impl String as UnformedInit {}
impl forall [T:! ImplicitAs(i64)] String as IndexWith(T) where .ElementType = Char {
fn At[self: Self](subscript: T) -> Char = "string.at";
}
+45 -2
View File
@@ -5,6 +5,7 @@
package Core library "prelude/types/uint";
import library "prelude/copy";
import library "prelude/default";
import library "prelude/destroy";
import library "prelude/operators";
import library "prelude/types/int";
@@ -16,6 +17,8 @@ class UInt(N:! IntLiteral()) {
adapt MakeUInt(N);
}
impl forall [N:! IntLiteral()] UInt(N) as UnformedInit {}
// Copy.
impl forall [N:! IntLiteral()] UInt(N) as Copy {
@@ -43,12 +46,52 @@ final impl forall [From:! IntLiteral()] UInt(From) as As(IntLiteral()) {
fn Convert[self: Self]() -> IntLiteral() = "int.convert_checked";
}
// TODO: Allow as an implicit conversion if To > From.
// Work around the inability to put a `where` clause on a generic parameter of
// type `IntLiteral`.
// TODO: Remove this once possible.
private interface AnyUInt {
let Width:! IntLiteral();
fn AsUInt[self: Self]() -> UInt(Width);
}
impl forall [N:! IntLiteral()] UInt(N) as AnyUInt where .Width = N {
fn AsUInt[self: Self]() -> Self { return self; }
}
// Work around the inability to constrain types other than `.Self` by reversing
// the Self and argument type of `ImplicitAs`.
// TODO: Remove this once possible.
private interface FromUInt(From:! type) {
fn Convert(from: From) -> Self;
}
impl forall [To:! IntLiteral(), From:! AnyUInt & IntFitsIn(UInt(To))]
UInt(To) as FromUInt(From) {
fn Convert(from: From) -> Self {
fn Impl(src: UInt(From.Width)) -> Self = "int.convert";
return Impl(from.AsUInt());
}
}
impl forall [To:! IntLiteral(), From:! AnyUInt & IntFitsIn(Int(To))]
Int(To) as FromUInt(From) {
fn Convert(from: From) -> Self {
fn Impl(src: UInt(From.Width)) -> Self = "int.convert";
return Impl(from.AsUInt());
}
}
impl forall [From:! IntLiteral(), To:! FromUInt(UInt(From))]
UInt(From) as ImplicitAs(To) {
fn Convert[self: Self]() -> To {
return To.Convert(self);
}
}
final impl forall [From:! IntLiteral(), To:! IntLiteral()] UInt(From) as As(UInt(To)) {
fn Convert[self: Self]() -> UInt(To) = "int.convert";
}
// TODO: Allow as an implicit conversion if To > From.
final impl forall [From:! IntLiteral(), To:! IntLiteral()] UInt(From) as As(Int(To)) {
fn Convert[self: Self]() -> Int(To) = "int.convert";
}
+4 -3
View File
@@ -515,15 +515,16 @@ may be limited to integers of at most 128 bits due to LLVM limitations.
#### Integer literals
Integers may be written in decimal, hexadecimal, or binary:
Integers may be written in decimal, hexadecimal, octal, or binary:
- `12345` (decimal)
- `0x1FE` (hexadecimal)
- `0o755` (octal)
- `0b1010` (binary)
Underscores (`_`) may be used as digit separators. Numeric literals are
case-sensitive: `0x`, `0b` must be lowercase, whereas hexadecimal digits must be
uppercase. Integer literals never contain a `.`.
case-sensitive: `0x`, `0o`, `0b` must be lowercase, whereas hexadecimal digits
must be uppercase. Integer literals never contain a `.`.
Unlike in C++, literals do not have a suffix to indicate their type. Instead,
numeric literals have a type derived from their value, and can be
+13 -11
View File
@@ -601,19 +601,21 @@ Assert(different_order.y == 2);
```
Initialization and assignment occur field-by-field. The order of fields is
determined from the target on the left side of the `=`. This rule matches what
we expect for classes with encapsulation more generally.
determined by the source on the right side of the `=`, and individual operations
are generally interleaved field-by-field. See [here](values.md#type-conversions)
for details about the semantics, and
[here](pattern_matching.md#evaluation-order) for details about the order of
operations.
**Open question:** What operations and in what order happen for assignment and
initialization?
> **Open question:** Do we need a way for a class to require the source order to
> match? Should that be the default, with an opt out?
- Is assignment just destruction followed by initialization? Is that
destruction completed for the whole object before initializing, or is it
interleaved field-by-field?
- When initializing to a literal value, is a temporary containing the literal
value constructed first or are the fields initialized directly? The latter
approach supports types that can't be moved or copied, such as mutex.
- Perhaps some operations are _not_ ordered with respect to each other?
> **Open question:** What operations and in what order happen for assignment?
>
> - Is assignment just destruction followed by initialization? Is that
> destruction completed for the whole object before initializing, or is it
> interleaved field-by-field?
> - Perhaps some operations are _not_ ordered with respect to each other?
### Operations performed field-wise
@@ -20,6 +20,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- [Same type](#same-type)
- [Pointer conversions](#pointer-conversions)
- [Facet types](#facet-types)
- [Struct, tuple, and array types](#struct-tuple-and-array-types)
- [Consistency with `as`](#consistency-with-as)
- [Extensibility](#extensibility)
- [Alternatives considered](#alternatives-considered)
@@ -189,6 +190,10 @@ implicitly converted to the facet type `TT2` if `T`
[satisfies the requirements](../generics/details.md#subtyping-between-facet-types)
of `TT2`.
### Struct, tuple, and array types
See [here](/docs/design/values.md#type-conversions).
## Consistency with `as`
An implicit conversion of an expression `E` of type `T` to type `U`, when
+31 -16
View File
@@ -13,7 +13,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- [Overview](#overview)
- [Member resolution](#member-resolution)
- [Package and namespace members](#package-and-namespace-members)
- [Types and facets](#types-and-facets)
- [Types, forms, and facets](#types-forms-and-facets)
- [Tuple indexing](#tuple-indexing)
- [Values](#values)
- [Facet binding](#facet-binding)
@@ -127,13 +127,18 @@ A member access expression is processed using the following steps:
The process of _member resolution_ determines which member `M` a member access
expression is referring to.
For a simple member access, if the first operand is a type, facet, package, or
namespace, a search for the member name is performed in the first operand.
Otherwise, a search for the member name is performed in the type of the first
operand. In either case, the search must succeed. In the latter case, if the
result is an instance member, then [instance binding](#instance-binding) is
For a simple member access, if the first operand is a type, form, facet,
package, or namespace, a search for the member name is performed in the first
operand. Otherwise, a search for the member name is performed in the type of the
first operand. In either case, the search must succeed. In the latter case, if
the result is an instance member, then [instance binding](#instance-binding) is
performed on the first operand.
A search for a name within a form searches for the name in its
[type component](/docs/design/values.md#expression-forms). Note that this means
that the form of an expression never affects simple member access into that
expression, except through its type component.
For a compound member access, the second operand is evaluated as a compile-time
constant to determine the member being accessed. The evaluation is required to
succeed and to result in a member of a type, interface, or non-type facet, or a
@@ -189,11 +194,12 @@ class Bar {
}
```
### Types and facets
### Types, forms, and facets
If the first operand is a type or facet, it must be a compile-time constant.
This disallows member access into a type except during compile-time, see leads
issue [#1293](https://github.com/carbon-language/carbon-lang/issues/1293).
If the first operand is a type, form, or facet, it must be a compile-time
constant. This disallows member access into a type except during compile-time,
see leads issue
[#1293](https://github.com/carbon-language/carbon-lang/issues/1293).
Like the previous case, types (including
[facet types](/docs/design/generics/terminology.md#facet-type)) have member
@@ -228,6 +234,9 @@ class Avatar {
Simple member access `(Avatar as Cowboy).Draw` finds the `Cowboy.Draw`
implementation for `Avatar`, ignoring `Renderable.Draw`.
Similarly, a form has members, specifically the members of the form's type
component.
### Tuple indexing
Tuple types have member names that are *integer-literal*s, not *word*s.
@@ -273,9 +282,9 @@ let n: i32 = p->(e);
### Values
If the first operand is not a type, package, namespace, or facet, it does not
have member names, and a search is performed into the type of the first operand
instead.
If the first operand is not a type, form, package, namespace, or facet, it does
not have member names, and a search is performed into the type of the first
operand instead.
```carbon
interface Printable {
@@ -723,16 +732,22 @@ fn SumIntegers(v: Vector(Integer)) -> Integer {
## Instance binding
Next, _instance binding_ may be performed. This associates an expression with a
particular object instance. For example, this is the value bound to `self` when
calling a method.
particular object or value instance. For example, this is the value bound to
`self` when calling a method.
For the simple member access syntax `x.y`, if `x` is an entity that has member
names, such as a namespace or a type, then `y` is looked up within `x`, and
instance binding is not performed. Otherwise, `y` is looked up within the type
of `x` and instance binding is performed if an instance member is found.
If instance binding is performed:
If instance binding is to be performed, the result of instance binding depends
on what instance member `M` was found:
- For a field member of a struct type or tuple type, `x` is converted to a
struct or tuple form by
[form decomposition](/docs/design/values.md#category-conversions), and the
`.f` element of the result of that conversion becomes the result of `x.f`.
All other elements are [discarded](/docs/design/values.md#form-conversions).
- For a field member in class `C`, `x` is required to be of type `C` or of a
type derived from `C`. The result is the corresponding subobject within `x`.
If `x` is an
+6
View File
@@ -97,6 +97,9 @@ possible syntaxes:
`fn Sleep(seconds: i64) -> ();`.
- `()` is similar to a `void` return type in C++.
> **TODO:** Update this section to cover return forms, as discussed
> [here](values.md#function-calls-and-returns).
### `return` statements
The [`return` statement](control_flow/return.md) is essential to function
@@ -111,6 +114,9 @@ When the return clause is provided, including when it is `-> ()`, the `return`
statement must have an expression that is convertible to the return type, and a
`return` statement must be used to end control flow of the function.
> **TODO:** Update this section to cover the requirements on the form of the
> expression.
## Function declarations
Functions may be declared separate from the definition by providing only a
+94 -5
View File
@@ -27,6 +27,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- [Return type](#return-type)
- [Interfaces recap](#interfaces-recap)
- [Facet types](#facet-types)
- [Identified facet types](#identified-facet-types)
- [Named constraints](#named-constraints)
- [Subtyping between facet types](#subtyping-between-facet-types)
- [Combining interfaces by anding facet types](#combining-interfaces-by-anding-facet-types)
@@ -894,6 +895,25 @@ names of the facet type.
This general structure of facet types holds not just for interfaces, but others
described in the rest of this document.
### Identified facet types
A facet type is _identified_ if all the interfaces it references are declared
and all of its named constraints are complete. An identified facet type is
associated with a known set of interfaces.
A facet type is _partially identified_ if any of its named constraints are in
the process of being defined. The interfaces associated with a partially
identified facet type change as the named constraint is fully defined.
Types can implicitly convert to facet types when the requirements of the facet
type are satisfied, but only if the facet type is identified. Attempting to
convert to a facet type that is not identified is an error, since the
requirements of the target facet type are not yet fully determined.
A facet with an unidentified or partially identified facet type may be converted
_to_ other facet types. While its set of requirements are not fully determined,
the requirements that are known at that time may be used.
## Named constraints
If the interfaces discussed above are the building blocks for facet types,
@@ -933,6 +953,54 @@ constraint DrawVectorLegoFish {
}
```
However a named constraint may not refer to itself as a requirement, as that
produces a cycle. In general, any use of named constraint inside its own
definition is disallowed, except through the use of `Self`.
```carbon
constraint SelfReferential {
// ❌ Error: Can not refer to `SelfReferential` inside its own definition.
require impls SelfReferential;
}
```
The facet type of `Self` is partially identified inside the definition of a
named constraint. This allows `Self` to be converted to other facet types based
on the known requirements of the partially identified facet type. Those
requirements include any `require` ... `impls` statements written before the use
of `Self`.
```carbon
interface Z {}
class UsesZ(T:! Z) {}
interface Y(T:! type) {}
interface X {}
constraint Constraint {
// The partially identified facet type of `Self` includes `Z` after this
// statement.
require impls Z;
// OK, the partially identified facet type of `Self` can convert to facet
// type `Z` to match the parameter of `UsesZ`.
require impls Y(UsesZ(Self));
// Also OK, as `Self` converts to `Z` again.
require UsesZ(Self) impls X;
}
constraint UseOfFutureRequirement {
// ❌ Error: The partially identified facet type of `Self` does not yet
// include `Z` since the requirement for `Z` comes later in the definition.
require impls Y(UsesZ(Self));
// The partially identified facet type of `Self` includes `Z` after this
// statement.
require impls Z;
}
```
In general, Carbon makes no syntactic distinction between the uses of named
constraints and interfaces, so one may be replaced with the other without
affecting users. To accomplish this, Carbon allows a named constraint to be used
@@ -1229,6 +1297,27 @@ var x: Iota;
DoAdvanceAndEquals(x);
```
The facet type at the end of a `require` ... `impls` statement must be
identified.
```carbon
constraint N;
interface I {
// ❌ Error: Facet type `N` is not identified since the constraint `N` is not
// complete.
require impls N;
}
interface J;
interface K {
// OK, the facet type `J` is identified because the interface `J` is
// declared.
require impls J;
}
```
Like with named constraints, an interface implementation requirement doesn't by
itself add any names to the interface, but again those can be added with `alias`
declarations:
@@ -3189,7 +3278,7 @@ fn G[T:! Transitive](t: T) {
// ❌ Illegal: only the current type is
// searched for interface implementations.
a.(Q.InQ());
a.(Q.InQ)();
// ✅ Allowed: values of type `T.A` may be cast
// to `T.B`, which extends and implements `Q`.
@@ -3197,7 +3286,7 @@ fn G[T:! Transitive](t: T) {
// ✅ Allowed: `T.A` == `T.B` that implements `Q`.
observe T.A == T.B impls Q;
a.(Q.InQ());
a.(Q.InQ)();
// ❌ Illegal: `T.A` still does not extend `Q`.
a.InQ();
@@ -5913,10 +6002,10 @@ impl forall [T:! A] T as B { }
impl forall [T:! B] T as C { }
impl forall [T:! C] T as D { }
fn RequiresD(T:! D)(x: T);
fn RequiresB(T:! B)(x: T);
fn RequiresD[T:! D](x: T);
fn RequiresB[T:! B](x: T);
fn RequiresA(T:! A)(x: T) {
fn RequiresA[T:! A](x: T) {
// ✅ Allowed: There is a blanket implementation
// of `B` for types implementing `A`.
RequiresB(x);
+184 -1
View File
@@ -12,6 +12,26 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- [Philosophy and goals](#philosophy-and-goals)
- [Overview](#overview)
- [C++ interoperability model: introduction and principles](#c-interoperability-model-introduction-and-principles)
- [The successor language mandate](#the-successor-language-mandate)
- [The C++ interop type](#the-c-interop-type)
- [Importing C++ APIs into Carbon](#importing-c-apis-into-carbon)
- [Importing C++ libraries (header-based)](#importing-c-libraries-header-based)
- [TODO: Importing C++ code (inline)](#todo-importing-c-code-inline)
- [Accessing built-in C++ entities (file-less)](#accessing-built-in-c-entities-file-less)
- [The `Cpp` package](#the-cpp-package)
- [TODO: Importing C++ macros](#todo-importing-c-macros)
- [Calling C++ code from Carbon](#calling-c-code-from-carbon)
- [Function call syntax and semantics](#function-call-syntax-and-semantics)
- [TODO: Overload resolution](#todo-overload-resolution)
- [TODO: Constructors](#todo-constructors)
- [TODO: Struct literals](#todo-struct-literals)
- [TODO: Accessing C++ classes, structs, and members](#todo-accessing-c-classes-structs-and-members)
- [TODO: Accessing global variables](#todo-accessing-global-variables)
- [TODO: Bi-directional type mapping: primitives and core types](#todo-bi-directional-type-mapping-primitives-and-core-types)
- [TODO: Advanced type mapping: pointers, references, and `const`](#todo-advanced-type-mapping-pointers-references-and-const)
- [TODO: Bi-directional type mapping: standard library types](#todo-bi-directional-type-mapping-standard-library-types)
- [TODO: The operator interoperability model](#todo-the-operator-interoperability-model)
<!-- tocstop -->
@@ -29,4 +49,167 @@ more detail.
## Overview
TODO
Carbon's bidirectional interoperability with C++ is
[a cornerstone of its design](/docs/project/goals.md#interoperability-with-and-migration-from-existing-c-code),
enabling a gradual transition from existing C++ codebases. The goal is not just
a foreign function interface (FFI), but a seamless, high-fidelity integration
that supports advanced C++ features, from templates to class hierarchies.
C++ APIs are imported into Carbon using an `import Cpp` directive, which makes
C++ declarations available within a dedicated `Cpp` package in Carbon. This
prevents name collisions and makes the origin of symbols explicit. Carbon code
can then call C++ functions, instantiate C++ classes, and use C++ types, while
respecting C++'s semantics, including its complex overload resolution rules and
preserving the nominal distinctions between C++ types like `long` and
`long long`, or `T*` and `T&`, which is critical for correct overload resolution
and template instantiation.
Similarly, Carbon APIs can be designed to be callable from C++. The
interoperability layer is designed to be zero-cost, avoiding unnecessary
allocations or copies when calling between the two languages.
## C++ interoperability model: introduction and principles
### The successor language mandate
The design of Carbon's C++ interoperability is governed by its foundational
goal: [to be a successor language](/README.md), not merely a language with a
foreign function interface (FFI). This mandate dictates a design that moves
beyond the C-style FFI adopted by most modern languages and instead provides
seamless, bidirectional interoperability. The objective is to support deep
integration with existing C++ code, encompassing its most complex features, from
inheritance to templates.
This goal has profound implications for the Carbon compiler and language
semantics. It requires that C++ is not treated as a foreign entity. Instead,
Carbon's semantic model must be _co-designed_ to understand, map, and interact
with C++'s semantic constructs—including templates, class hierarchies, and
complex overload resolution—with high fidelity. The interoperability layer must,
therefore, operate at the semantic analysis level, not just at the linking (ABI)
level. This document specifies the design of this semantic contract.
### The C++ interop type
A core mechanism in this design is the C++ interop type. This concept defines
the "trigger" that activates C++-specific semantic rules within the Carbon
compiler. Any operation involving a type that is designated as a C++ interop
type could invoke the specialized interoperability logic, such as C++ overload
resolution or operator overload resolution that involves both Carbon and C++
operator overloads.
A type is considered a C++ interop type if its definition involves an imported
C++ type in any of the following ways:
1. A C++ imported type (for example, `Cpp.Widget`).
2. A pointer to a C++ interop type (for example, `Cpp.Widget*`).
3. A Carbon generic type parameterized with a C++ interop type (for example,
`MyCarbonVector(Cpp.Widget)`).
More generally, a C++ interop type is any type for which Carbon's
[orphan rule](https://docs.carbon-lang.dev/docs/design/generics/details.html#orphan-rule)
would allow an impl to be provided by a library in `package Cpp`.
This "pervasive" model of C++-awareness is a fundamental design choice. The C++
semantics are not confined to a specific `unsafe` or `extern "C++"` block; they
affect any Carbon type that composes them. For example, when the Carbon compiler
instantiates a _Carbon_ generic type like `MyCarbonVector(Cpp.Widget)`, its type
system must be aware that the `Cpp.Widget` parameter carries C++-specific rules.
This mandates that Carbon's own generic system, struct layout logic, overload
resolution and operator lookup must query the type system for the presence of a
C++ interop type. If present, Carbon must consider C++ rules when operating over
C++ interop types. This design prioritizes the goal of a seamless and intuitive
user experience.
## Importing C++ APIs into Carbon
### Importing C++ libraries (header-based)
The primary mechanism for importing existing, user-defined C++ code is through
header file inclusion. Carbon must be able to parse and analyze C++ header files
to make their declarations available within Carbon.
**Syntax:** The syntax for this operation is `import Cpp library "header_name"`.
This syntax is used for both standard library headers and user-defined headers:
- **Standard Library:**
```carbon
import Cpp library "<cstdio>";
```
This import makes entities like `putchar` available.
- **C++ User-Defined Header:**
```carbon
import Cpp library "circle.h";
```
This import makes user-defined declarations and definitions available.
### TODO: Importing C++ code (inline)
### Accessing built-in C++ entities (file-less)
Some C++ entities, particularly built-in primitive types, are not defined in any
header file. They are "intrinsic" to the C++ language. These entities are
available in Carbon without an explicit `import` declaration.
### The `Cpp` package
A critical design choice for managing C++ imports is the mandatory use of a
containing package, `Cpp`. All imported C++ named entities (functions, types,
namespaces) are contained in the `Cpp` package.
- **Functions:** `Cpp.putchar(...)`
- **Classes/Types:** `Cpp.Circle`, `Cpp.Point`
- **Constructors:** `Cpp.Circle.Circle()`
The `Cpp.` prefix makes the _origin_ of every symbol explicit and unambiguous.
It ensures that C++ entities cannot collide with Carbon code.
### TODO: Importing C++ macros
## Calling C++ code from Carbon
### Function call syntax and semantics
Once imported, C++ functions are invoked using standard Carbon function call
syntax, prefixed with the `Cpp` name. The Carbon compiler is responsible for
mapping the Carbon arguments to the types expected by the C++ function's
signature.
This often requires explicit casting on the Carbon side, using the `as` keyword,
to satisfy the C++ function's parameter types.
**Example:** The following example imports `cstdio` and calls the C function
`putchar`. The Carbon `Core.Char` variable `n` must be cast first to `u8` and
then to `i32` to match the `int` parameter expected by `putchar`.
```carbon
import Cpp library "<cstdio>";
fn Run() {
let hello: array(Core.Char, 6) = ('H', 'e', 'l', 'l', 'o', '!');
for (n: Core.Char in hello) {
// Carbon 'as' casting is used to match the C++ signature
Cpp.putchar((n as u8) as i32);
}
}
```
### TODO: Overload resolution
### TODO: Constructors
### TODO: Struct literals
## TODO: Accessing C++ classes, structs, and members
## TODO: Accessing global variables
## TODO: Bi-directional type mapping: primitives and core types
## TODO: Advanced type mapping: pointers, references, and `const`
## TODO: Bi-directional type mapping: standard library types
## TODO: The operator interoperability model
@@ -28,6 +28,7 @@ The following syntaxes are supported:
- [Integer literals](#integer-literals)
- `12345` (decimal)
- `0x1FE` (hexadecimal)
- `0o755` (octal)
- `0b1010` (binary)
- [Real-number literals](#real-number-literals)
- `123.456` (digits on both sides of the `.`)
@@ -55,15 +56,16 @@ base. The available base specifiers and corresponding bases are:
| Base specifier | Base | Digits |
| -------------- | ---- | ------------------------ |
| `b` | 2 | `0` and `1` |
| `o` | 8 | `0` ... `7` |
| `x` | 16 | `0` ... `9`, `A` ... `F` |
The above table is case-sensitive. For example, `0b1` and `0x1A` are valid, and
`0B1`, `0X1A`, and `0x1a` are invalid.
The above table is case-sensitive. For example, `0b1`, `0o7`, and `0x1A` are
valid, and `0B1`, `0O7`, `0X1A`, and `0x1a` are invalid.
A zero at the start of a literal can never be followed by another digit: either
the literal is `0`, the `0` begins a base specifier, or the next character is a
decimal point (see below). No support is provided for octal literals, and any C
or C++ octal literal (other than `0`) is invalid in Carbon.
decimal point (see below). The `0o` prefix is used for octal literals; a C-style
`0755` octal is invalid in Carbon.
### Real-number literals
@@ -111,8 +113,9 @@ example:
- Decimal integers: `1_23_456_7890`
- Hexadecimal integers: `0x7_F_FF_FFFF`
- Real-number literals: `2_147.48_3648e12_345` or `0x1_00CA.FE_F00Dp+2_4`
- Octal literals: `0o7_55`
- Binary literals: `0b1_000_101_11`
- Real-number literals: `2_147.48_3648e12_345` or `0x1_00CA.FE_F00Dp+2_4`
## Divergence from other languages
@@ -129,7 +132,7 @@ provides benefits directly in line with the goal that Carbon code should be
That said, it still provides sufficient variations to address important use
cases for the goal of not leaving room for a lower level language:
- Hexadecimal and binary integer literals.
- Hexadecimal, octal, and binary integer literals.
- Scientific notation floating point literals.
- Hexadecimal (scientific) floating point literals.
@@ -145,6 +148,7 @@ cases for the goal of not leaving room for a lower level language:
- [3-digit decimal groupings](/proposals/p1983.md#3-digit-decimal-groupings)
- [2-digit or 4-digit hexadecimal digit groupings](/proposals/p1983.md#2-digit-or-4-digit-hexadecimal-digit-groupings)
- [Disallow digit separators in fractions](/proposals/p1983.md#disallow-digit-separators-in-fractions)
- [No octal literals](/proposals/p6910.md#no-octal-literals)
## References
@@ -154,3 +158,5 @@ cases for the goal of not leaving room for a lower level language:
[#866: Allow ties in floating literals](https://github.com/carbon-language/carbon-lang/pull/866)
- Proposal
[#1983: Weaken digit separator placement rules](https://github.com/carbon-language/carbon-lang/pull/1983)
- Proposal
[#6910: Support octal literals](https://github.com/carbon-language/carbon-lang/pull/6910)
+258 -143
View File
@@ -18,7 +18,6 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- [Name binding patterns](#name-binding-patterns)
- [Anonymous bindings](#anonymous-bindings)
- [Alternatives considered](#alternatives-considered-1)
- [Compile-time bindings](#compile-time-bindings)
- [`auto` and type deduction](#auto-and-type-deduction)
- [Alternatives considered](#alternatives-considered-2)
- [`var`](#var)
@@ -36,10 +35,12 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- [Alternatives considered](#alternatives-considered-6)
- [Guards](#guards)
- [Pattern matching in local variables](#pattern-matching-in-local-variables)
- [Evaluation order](#evaluation-order)
- [Alternatives considered](#alternatives-considered-7)
- [Open questions](#open-questions)
- [Slice or array nested value pattern matching](#slice-or-array-nested-value-pattern-matching)
- [Pattern matching as function overload resolution](#pattern-matching-as-function-overload-resolution)
- [Alternatives considered](#alternatives-considered-7)
- [Alternatives considered](#alternatives-considered-8)
- [References](#references)
<!-- tocstop -->
@@ -60,14 +61,13 @@ of the full pattern as well.
## Pattern Syntax and Semantics
Expressions are patterns, as described below. A pattern that is not an
All expressions are patterns, but they may be either tuple patterns, struct
patterns, or expression patterns, as described below. A pattern that is not an
expression, because it contains pattern-specific syntax such as a binding
pattern, is a _proper pattern_. Many expression forms, such as arbitrary
function calls, are not permitted as proper patterns, so cannot contain binding
patterns.
- _pattern_ ::= _proper-pattern_
```carbon
fn F(n: i32) -> i32 { return n; }
@@ -81,10 +81,11 @@ match (F(42)) {
An expression is a pattern.
- _pattern_ ::= _expression_
- _expression-pattern_ ::= _expression_
- _pattern_ ::= _expression-pattern_
The pattern is compared with the expression using the `==` operator: _pattern_
`==` _scrutinee_.
The scrutinee is compared with the expression using the `==` operator:
_expression_ `==` _scrutinee_.
```carbon
fn F(n: i32) {
@@ -96,31 +97,30 @@ fn F(n: i32) {
}
```
Any `==` operations performed by a pattern match occur in lexical order, but for
repeated matches against the same _pattern_, later comparisons may be skipped by
reusing the result from an earlier comparison:
As depicted here, _expression-pattern_ is ambiguous with _tuple-pattern_,
_struct-pattern_, and _alternative-pattern_. In the case of _tuple-pattern_ and
_struct-pattern_, the ambiguity is resolved in their favor, meaning that a tuple
or struct literal in a pattern context is not interpreted as an expression
pattern, but as a tuple or struct pattern whose elements are expression
patterns. For example:
```carbon
class ChattyIntMatcher {
impl as EqWith(i32) {
fn Eq[self: ChattyIntMatcher](other: i32) {
Print("Matching {0}", other);
return other == 1;
}
}
}
fn F() {
// Prints `Matching 1` then `Matching 2`,
// may or may not then print `Matching 1` again.
match ((1, 2)) {
case ({} as ChattyIntMatcher, 0) => {}
case (1, {} as ChattyIntMatcher) => {}
case ({} as ChattyIntMatcher, 2) => {}
}
match (0, 1, 2) {
case (F(), 0, G()) => ...
}
```
Here `(F(), 0, G())` is not an expression, but three separate expressions in a
tuple pattern. As a result, this code will call `F()` but not `G()`, because the
mismatch between the middle tuple elements will cause pattern matching to fail
before reaching `G()`. Other than this short-circuiting behavior, a tuple
pattern of expression patterns behaves the same as if it were a single
expression pattern.
The resolution of the _alternative-pattern_ ambiguity is not specified, because
_alternative-pattern_ is specified to behave the same way an expression pattern
would, in the cases where they overlap.
#### Alternatives considered
- [Introducer syntax for expression patterns](/proposals/p2188.md#introducer-syntax-for-expression-patterns)
@@ -131,14 +131,16 @@ fn F() {
A name binding pattern is a pattern.
- _binding-pattern_ ::= _identifier_ `:` _expression_
- _proper-pattern_ ::= _binding-pattern_
- _binding-pattern_ ::= `ref`? (_identifier_ | `self`) `:` _expression_
- _binding-pattern_ ::= `template`? _identifier_ `:!` _expression_
- _pattern_ ::= _binding-pattern_
A name binding pattern declares a _binding_ with a name specified by the
_identifier_, which can be used as an expression. If the binding pattern is
enclosed by a `var` pattern, it is a _reference binding pattern_, and the
binding is a durable reference expression. Otherwise, it is a _value binding
pattern_, and the binding is a value expression.
prefixed with `ref` or enclosed by a `var` pattern, it is a _reference binding
pattern_, and otherwise it is a _value binding pattern_. A binding pattern
enclosed by a `var` pattern cannot have a `ref` prefix, because it would be
redundant.
A _variable binding pattern_ is a special kind of reference binding pattern,
which is the immediate subpattern of its enclosing `var` pattern.
@@ -147,15 +149,36 @@ which is the immediate subpattern of its enclosing `var` pattern.
> expected to be the only difference between variable binding patterns and other
> reference binding patterns.
The type of the binding is specified by the _expression_. If the pattern is a
value binding pattern, the scrutinee is implicitly converted to a value
expression of that type if necessary, and the binding is _bound_ to the
converted value. If the pattern is a reference binding pattern, the enclosing
`var` pattern will ensure that the scrutinee is already a durable reference
expression with the specified type, and the binding is bound directly to it.
If the pattern syntax uses `:` it is a _runtime binding pattern_. If it uses
`:!`, it is a _compile-time binding pattern_, and it cannot appear inside a
`var` pattern. A compile-time binding pattern is either a _symbolic binding
pattern_ or a _template binding pattern_, depending on whether it is prefixed
with `template`.
A use of a value binding is a value expression of the declared type, and a use
of a reference binding is a durable reference expression of the declared type.
The binding declared by a binding pattern has a
[primitive form](values.md#expression-forms) with the following components:
- The type is _expression_.
- The category is "value" if the pattern is a value binding pattern, "durable
entire reference" if it's a variable binding pattern, or "durable non-entire
reference" if it's a non-variable reference binding pattern.
- The phase is "runtime", "symbolic", or "template" depending on whether the
pattern is a runtime, symbolic, or template binding pattern.
During pattern matching, the scrutinee is implicitly converted as needed to have
the same form, and the binding is _bound_ to (and consumes) the result of these
conversions. This makes a runtime or template binding a kind of reusable alias
for the converted scrutinee expression, with the same form and value. Symbolic
bindings are more complex: the binding will have the same type, category, and
phase as the converted scrutinee expression, but its constant value is an opaque
symbol introduced by the binding, which the type system knows to be equal to the
converted scrutinee expression.
Note that there is no way to implicitly convert to a durable reference
expression from any other category, so the scrutinee of a reference binding
pattern must already be a durable reference. `var` pattern matching ensures that
this is the case for the bindings nested inside it, but for `ref` binding
patterns the user-provided scrutinee must meet this requirement itself.
```carbon
fn F() -> i32 {
@@ -170,41 +193,23 @@ fn F() -> i32 {
}
```
When a new object needs to be created for the binding, the lifetime of the bound
value matches the scope of the binding.
```carbon
class NoisyDestructor {
fn Make() -> Self { return {}; }
impl i32 as ImplicitAs(NoisyDestructor) {
fn Convert[self: i32]() -> Self { return Make(); }
}
destructor {
Print("Destroyed!");
}
}
fn G() {
// Does not print "Destroyed!".
let n: NoisyDestructor = NoisyDestructor.Make();
Print("Body of G");
// Prints "Destroyed!" here.
}
fn H(n: i32) {
// Does not print "Destroyed!".
let (v: NoisyDestructor, w: i32) = (n, n);
Print("Body of H");
// Prints "Destroyed!" here.
}
```
When `self` is used instead of an identifier, the pattern must appear in the
implicit parameter list of a method (as discussed [here](classes.md#methods)).
During pattern matching in a method call, the parameter pattern containing
`self` is matched with the object that the method was invoked on. In all other
respects, the `self` pattern behaves just like an ordinary binding pattern,
introducing a binding named `self` into scope, just as if `self` were an
identifier rather than a keyword.
#### Anonymous bindings
A syntax like a binding but with `_` in place of an identifier can be used to
ignore part of a value.
A syntax like a binding but with `_` in place of an identifier is an anonymous
binding. It does not participate in name lookup (so there can be multiple such
patterns in the same scope), and in all other respects it behaves as if it were
wrapped in an [`unused` pattern](#unused).
- _binding-pattern_ ::= `_` `:` _expression_
- _binding-pattern_ ::= `template`? `_` `:!` _expression_
```carbon
fn F(n: i32) {
@@ -239,27 +244,6 @@ fn H(m: i32) {}
- [Anonymous, named identifiers](/proposals/p2022.md#anonymous-named-identifiers)
- [Attributes](/proposals/p2022.md#attributes)
#### Compile-time bindings
A `:!` can be used in place of `:` for a binding that is usable at compile time.
- _compile-time-pattern_ ::= `template`? _identifier_ `:!` _expression_
- _compile-time-pattern_ ::= `template`? `_` `:!` _expression_
- _compile-time-pattern_ ::= `unused` `template`? _identifier_ `:!`
_expression_
- _proper-pattern_ ::= _compile-time-pattern_
```carbon
// ✅ `F` takes a symbolic facet parameter `T` and a parameter `x` of type `T`.
fn F(T:! type, x: T) {
var v: T = x;
}
```
The `template` keyword indicates the binding pattern is introducing a template
binding, so name lookups into the binding will not be fully resolved until its
value is known.
#### `auto` and type deduction
The `auto` keyword is a placeholder for a unique deduced type.
@@ -310,12 +294,18 @@ specified.
A `var` prefix indicates that a pattern provides mutable storage for the
scrutinee.
- _proper-pattern_ ::= `var` _proper-pattern_
- _pattern_ ::= `var` _pattern_
A `var` pattern matches when its nested pattern matches. The type of the storage
is the resolved type of the nested _pattern_. Any binding patterns within the
nested pattern are reference binding patterns, and their bindings refer to
portions of the corresponding storage rather than to the scrutinee.
The scrutinee is expected to have the same type as the resolved type of the
nested _pattern_, and it is expected to be a runtime-phase ephemeral entire
reference expression, which therefore refers to a newly-allocated temporary
object. The scrutinee expression is converted as needed to satisfy those
expectations, and the `var` pattern takes ownership of the referenced object,
promotes it to a _durable_ entire reference expression, and matches the nested
_pattern_ with it.
The lifetime of the allocated object extends to the end of scope of the `var`
pattern (that is the scope that any bindings declared within it would have).
```carbon
fn F(p: i32*);
@@ -382,56 +372,48 @@ fn G() {
A tuple of patterns can be used as a pattern.
- _tuple-pattern_ ::= `(` [_expression_ `,`]\* _proper-pattern_ [`,`
_pattern_]\*
`,`? `)`
- _proper-pattern_ ::= _tuple-pattern_
- _tuple-pattern_ ::= `(` [_pattern_ `,` [_pattern_ [`,` _pattern_]\* `,`? ] ]
`)`
- _pattern_ ::= _tuple-pattern_
A _tuple-pattern_ containing no commas is treated as grouping parens: the
contained _proper-pattern_ is matched directly against the scrutinee. Otherwise,
the behavior is as follows.
A tuple pattern is matched left-to-right. The scrutinee is required to be of
tuple type.
Note that a tuple pattern must contain at least one _proper-pattern_. Otherwise,
it is a tuple-valued expression. However, a tuple pattern and a corresponding
tuple-valued expression are matched in the same way because `==` for a tuple
compares fields left-to-right.
The scrutinee is required to be of tuple type, with the same arity as the number
of nested _patterns_. It is converted to a tuple form by
[form decomposition](values.md#form-conversions), and then each nested _pattern_
is matched against the corresponding element of the converted scrutinee's
[result](values.md#expression-forms). The tuple pattern matches if all of these
sub-matches succeed.
### Struct patterns
A struct can be matched with a struct pattern.
- _proper-pattern_ ::= `{` [_field-init_ `,`]\* _proper-field-pattern_ [`,`
_field-pattern_]\*
`}`
- _proper-pattern_ ::= `{` [_field-pattern_ `,`]+ `_` `}`
- _field-init_ ::= _designator_ `=` _expression_
- _proper-field-pattern_ ::= _designator_ `=` _proper-pattern_
- _proper-field-pattern_ ::= _binding-pattern_
- _field-pattern_ ::= _field-init_
- _field-pattern_ ::= _proper-field-pattern_
- _struct-pattern_ ::= `{` [_field-pattern_ [`,` _field-pattern_ ]\* ] `}`
- _struct-pattern_ ::= `{` [_field-pattern_ `,`]+ `_` `}`
- _field-pattern_ ::= _designator_ `=` _pattern_
- _field-pattern_ ::= _binding-pattern_
- _pattern_ ::= _struct-pattern_
A struct pattern resembles a struct literal, with at least one field initialized
with a proper pattern:
A struct pattern resembles a struct literal, except that the initializers can be
patterns.
```carbon
match ({.a = 1, .b = 2}) {
// Struct literal as an expression pattern.
// Struct literal as a pattern.
case {.b = 2, .a = 1} => {}
// Struct pattern.
// Proper struct pattern.
case {.b = n: i32, .a = m: i32} => {}
}
```
The scrutinee is required to be of struct type, and to have the same set of
field names as the pattern. The pattern is matched left-to-right, meaning that
matching is performed in the field order specified in the pattern, not in the
field order of the scrutinee. This is consistent with the behavior of matching
against a struct-valued expression, where the expression pattern becomes the
left operand of the `==` and so determines the order in which `==` comparisons
for fields are performed.
The scrutinee is required to be of struct type, and every field name in the
pattern must be a field name in the scrutinee. It is converted to a struct form
by [form decomposition](values.md#form-conversions) and then each
_field-pattern_ is matched with the same-named element of the converted
scrutinee's [result](values.md#expression-forms). If the scrutinee result has
any field names not present in the pattern, those sub-results are
[discarded](values.md#form-conversions) in lexical order if the pattern has a
trailing `_` (as in `{.a = 1, _}`), or diagnosed as an error if it does not. The
struct pattern matches if all of these sub-matches succeed.
In the case where a field will be bound to an identifier with the same name, a
shorthand syntax is available: `a: T` is synonymous with `.a = a: T`.
@@ -442,6 +424,9 @@ match ({.a = 1, .b = 2}) {
}
```
Likewise, `ref a: T` is synonymous with `.a = ref a: T`, and `var a: T` is
synonymous with `.a = var a: T`.
If some fields should be ignored when matching, a trailing `, _` can be added to
specify this:
@@ -462,19 +447,22 @@ This is valid even if all fields are actually named in the pattern.
An alternative pattern is used to match one alternative of a choice type.
- _proper-pattern_ ::= _callee-expression_ _tuple-pattern_
- _proper-pattern_ ::= _designator_ _tuple-pattern_?
- _alternative-pattern_ ::= _callee-expression_ _tuple-pattern_?
- _alternative-pattern_ ::= _designator_ _tuple-pattern_? \_ _pattern_ ::=
_alternative-pattern_
Here, _callee-expression_ is syntactically an expression that is valid as the
callee in a function call expression, and an alternative pattern is
syntactically a function call expression whose argument list contains at least
one _proper-pattern_.
syntactically a function call expression whose argument list may contain proper
patterns.
If a _callee-expression_ is provided, it is required to name a choice type
alternative that has a parameter list, and the scrutinee is implicitly converted
to that choice type. Otherwise, the scrutinee is required to be of some choice
type, and the designator is looked up in that type and is required to name an
alternative with a parameter list if and only if a _tuple-pattern_ is specified.
Semantically, if the argument list contains no proper patterns, it behaves like
an expression pattern. Otherwise, if a _callee-expression_ is provided, it is
required to name a choice type alternative that has a parameter list, and the
scrutinee is implicitly converted to that choice type. Otherwise, the scrutinee
is required to be of some choice type, and the designator is looked up in that
type and is required to name an alternative with a parameter list if and only if
a _tuple-pattern_ is specified.
The pattern matches if the active alternative in the scrutinee is the specified
alternative, and the arguments of the alternative match the given tuple pattern
@@ -750,8 +738,10 @@ In order to match a value, whatever is specified in the pattern must match.
Using `auto` for a type will always match, making `_: auto` the wildcard
pattern.
Any initializing expressions in the scrutinee of a `match` statement are
[materialized](values.md#temporary-materialization) before pattern matching
If the scrutinee expression's [form](values.md#expression-forms) contains any
primitive forms with category "initializing", they are converted to ephemeral
non-entire reference expressions by
[materialization](values.md#temporary-materialization) before pattern matching
begins, so that the result can be reused by multiple `case`s. However, the
objects created by `var` patterns are not reused by multiple `case`s:
@@ -813,6 +803,131 @@ fn Foo() -> i32 {
This extracts the first value from the result of calling `Bar()` and binds it to
a local variable named `p` which is then returned.
## Evaluation order
A pattern matching operation's potentially-observable side effects are a series
of calls to functions that might be user-defined. This includes function calls
and operators in the scrutinee and in expression patterns, and also type
conversions and category conversions. Note that category conversions on tuple
and struct types, and type conversions between tuple and struct types, are not
modeled as function calls, but are broken down into function calls on their
elements. Note also that for function and operator calls in expressions, we are
only considering top-level calls, that is calls that aren't inputs to other
calls within the expression, because the entire sub-expression of a top-level
call acts as a single unit for purposes of evaluation ordering.
For example, suppose `A` is implicitly convertible to a `C` and `B` is
implicitly convertible to `D`, but both conversions are value expressions
(rather than initializing expressions), and consider the following code:
```
fn MakeA() -> A;
fn MakeB() -> B;
var cd: (C, D) = (MakeA(), MakeB());
```
Evaluation of the last line involves 6 function calls:
1. Call `MakeA`.
2. Call `A.(Core.ImplicitAsPrimitive(C)).Convert`, to convert the `A` object to
a `C` value, as part of type conversion.
3. Call `A.(Core.Copy).Op` to copy the `C` value into the storage for `cd.0`, as
part of category conversion.
4. Call `MakeB`.
5. Call `B.(Core.ImplicitAsPrimitive(D)).Convert`.
6. Call `B.(Core.Copy).Op`.
> **Note:** These `Core` interfaces haven't been specified yet, and their
> details may change.
To define the evaluation order of these calls, we have to consider the
dependencies between them, which we'll model as a DAG, with function calls as
nodes, and edges representing data dependencies. It will also be useful to
include leaf patterns (that is, patterns that have no subpatterns) as nodes in
the graph; they don't have side effects as such, so they aren't part of the
evaluation order, but they do constrain the evaluation order.
```mermaid
%%{init: {'themeVariables': {'fontFamily': 'monospace'}}}%%
flowchart BT
2["A.(Core.ImplicitAsPrimitive(C))"]-->1[/"MakeA"\]
3["A.(Core.Copy)"]-->2
5["B.(Core.ImplicitAsPrimitive(D))"]-->4[/"MakeB"\]
6["B.(Core.Copy)"]-->5
7[\"cd: (C, D)"/]-->3
7-->6
```
This DAG will always have a few key properties:
- The sources are the primitive patterns. Only the sources can have multiple
out-edges.
- The sinks are function calls in the scrutinee expression, and in expression
patterns. Only scrutinee expression sinks can have multiple in-edges.
- The interior nodes always have one edge in and one edge out, forming a set
of paths that connect a source to a sink.
- The paths to calls in expression patterns are trivial: they consist of a
single edge from an expression pattern source to a function call sink.
Furthermore, a given source or sink has at most one such edge.
- Each path to the scrutinee connects a type in the pattern to a type in the
scrutinee, and together the paths uniquely cover the entire pattern and
scrutinee types. Furthermore, they are minimal, in the sense that unless the
path is a single edge, its source and sink types won't both be tuple or
struct types.
> **Future work:** this design needs to be reconciled with the design for
> [user-defined sum types](sum_types.md#user-defined-sum-types), because
> `Match.Op` can violate this topology. This should probably be folded into a
> broader redesign of sum type customization, which we expect to be necessary
> for other reasons.
The order of evaluation is determined by a depth-first postorder traversal of
the this DAG: while visiting a node, we recursively visit all its children, and
a call occurs when we finish visiting the corresponding node (revisiting a node
is a no-op). By eagerly consuming the result of each function call as soon as
possible, this minimizes the number of simultaneously-live temporaries, which
enables more efficient code generation.
When visiting a pattern, we visit its out-paths in the scrutinee type's
left-to-right source code order (recall that each path is associated with a
unique part of the scrutinee type). An edge to an expression pattern call, if
any, is visited last. The patterns themselves are visited in their own
left-to-right source code order. So, returning to our earlier example, the 6
function calls will be evaluated in the order we listed them.
In some cases, visiting the patterns in their own order may lead to visiting the
types within a scrutinee call out of order, but if it would lead to visiting the
scrutinee calls themselves out of order, the program is ill-formed. For example:
```carbon
// ❌ Error: visiting `.c: C` first leads to evaluating `MakeA()` before
// `MakeB()`
var {c: C, d: D} = {.d = MakeB(), .c = MakeA()};
// ✅ OK: only one pattern, and we use scrutinee order to visit its children.
var cd: {.c: C, .d: D} = {.d = MakeB(), .c = MakeA()};
// ✅ OK: only one scrutinee call, so it can't be out of order.
fn MakeAB() -> {.d: B, .c: A};
var {c: C, d: D} = MakeAB();
```
As a result, the overall evaluation order is always consistent with the written
order of the patterns, and with the written order of the scrutinee expressions.
Within those constraints, the order of the scrutinee types acts as a
tie-breaker. Note in particular that this means the fields of a struct-type
binding are not necessarily initialized in declaration order.
Note that generally speaking, pattern-match evaluation stops as soon as it's
known that the match will fail, in which case only a prefix of the full
evaluation order will be evaluated.
### Alternatives considered
- [Breadth-first evaluation order](/proposals/p5545.md#breadth-first-evaluation-order)
- [Depth-first evaluation with a different "horizontal" order](/proposals/p5545.md#depth-first-evaluation-with-a-different-horizontal-order)
## Open questions
### Slice or array nested value pattern matching
+9
View File
@@ -12,6 +12,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- [Overview](#overview)
- [Element access](#element-access)
- [Conversion](#conversion)
- [Empty tuples](#empty-tuples)
- [Trailing commas and single-element tuples](#trailing-commas-and-single-element-tuples)
- [Tuple of types and tuple types](#tuple-of-types-and-tuple-types)
@@ -64,6 +65,14 @@ fn Choose(template N:! i32) -> i32 {
}
```
## Conversion
A tuple type `Source` can be converted to a tuple type `Dest` if they have the
same number of elements, and each element type of `Source` is convertible to the
corresponding element type of `Dest`, and the conversion is implicit if all of
the element type conversions are implicit. See
[here](values.md#type-conversions) for full details.
### Empty tuples
`()` is the empty tuple. This is used in other parts of the design, such as
+541 -79
View File
@@ -20,6 +20,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- [Local variables](#local-variables)
- [Consuming function parameters](#consuming-function-parameters)
- [Reference expressions](#reference-expressions)
- [Entire reference expressions](#entire-reference-expressions)
- [Durable reference expressions](#durable-reference-expressions)
- [Ephemeral reference expressions](#ephemeral-reference-expressions)
- [Value expressions](#value-expressions)
@@ -31,6 +32,11 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- [Function calls and returns](#function-calls-and-returns)
- [Deferred initialization from values and references](#deferred-initialization-from-values-and-references)
- [Declared `returned` variable](#declared-returned-variable)
- [Expression forms](#expression-forms)
- [Initializing results](#initializing-results)
- [Form conversions](#form-conversions)
- [Type conversions](#type-conversions)
- [Category conversions](#category-conversions)
- [Pointers](#pointers)
- [Reference types](#reference-types)
- [Pointer syntax](#pointer-syntax)
@@ -64,21 +70,21 @@ itself.
### Expression categories
There are three expression categories in Carbon:
There are three primary expression categories in Carbon:
- [_Value expressions_](#value-expressions) produce abstract, read-only
_values_ that cannot be modified or have their address taken.
- [_Reference expressions_](#reference-expressions) refer to _objects_ with
_storage_ where a value may be read or written and the object's address can
be taken.
- [_Initializing expressions_](#initializing-expressions) require storage to
be provided implicitly when evaluating the expression. The expression then
initializes an object in that storage. These are used to model function
returns, which can construct the returned value directly in the caller's
storage.
- [_Initializing expressions_](#initializing-expressions) require a result
location to be provided implicitly when evaluating the expression. The
expression then initializes an object in that location. These are used to
model function returns, which can construct the returned value directly in
the caller's storage.
Expressions in one category can be converted to any other category when needed.
The primitive conversion steps used are:
Expressions in one category can be implicitly converted to any other primary
category when needed. The primitive conversion steps used are:
- [_Value acquisition_](#value-acquisition) forms a value expression from the
current value of the object referenced by a reference expression.
@@ -97,13 +103,36 @@ These conversion steps combine to provide the transitive conversion table:
| to **reference** | direct init + materialize | == | materialize |
| to **initializing** | direct init | copy init | == |
Reference expressions formed through temporary materialization are called
[_ephemeral reference expressions_](#ephemeral-reference-expressions) and have
restrictions on how they are used. In contrast, reference expressions that refer
to declared storage are called
[_durable reference expressions_](#durable-reference-expressions). Beyond the
restrictions on what is valid, there is no distinction in their behavior or
semantics.
Reference expressions are divided into 2x2 sub-categories: they can be either
[_ephemeral_](#ephemeral-reference-expressions) or
[_durable_](#durable-reference-expressions), and either _entire_ or
_non-entire_.
Ephemeral reference expressions are formed through temporary materialization,
and have restrictions on how they are used. In contrast, durable reference
expressions refer to storage that outlives the expression, and typically has a
declared name. Entire reference expressions can only refer to complete objects,
whereas non-entire reference expressions can refer to both complete objects and
sub-objects (such as class fields and base class sub-objects). As a consequence,
only entire reference expressions can be destructively moved.
> **Future work:** This means that pointer-dereference expressions are
> non-entire, but we will presumably want to be able to destructively move from
> them. We need to figure out how to support that without violating the
> invariant that a live object has live fields.
Value acquisition and copy initialization can be applied to any reference
expression, but materialization only produces ephemeral entire reference
expressions. An entire reference expression can be implicitly converted to
non-entire; this has no run-time effect because it merely discards static
object-completeness information. Non-entire reference expressions can only be
converted to entire reference expressions by round-tripping through
copy-initialization and materialization. Non-durable-reference expressions
cannot be implicitly converted to durable reference expressions at all.
> **TODO:** Determine how these reference sub-categories relate to memory-safety
> properties like uniqueness, and make sure their names are aligned with
> memory-safety terminology.
#### Value acquisition
@@ -157,9 +186,20 @@ fn Sum(x: i32, y: i32) -> i32 {
Value bindings require the matched expression to be a _value expression_,
converting it into one as necessary.
A _variable pattern_ is introduced with the `var` keyword. It declares storage
for a new object, and initializes it from the matched expression, which must be
an initializing expression.
A _variable pattern_ is introduced with the `var` keyword. The matched
expression must be an ephemeral entire reference expression (which typically
requires the matched expression to be materialized); the `var` pattern takes
ownership of the newly-allocated temporary storage it refers to, which extends
its lifetime to the end of the enclosing scope. The subpattern is then matched
against a _durable_ entire reference expression to the object in that storage.
> **Open question:** This implies that `var field: T = F().field;` doesn't
> perform any copies or moves on `T`. This, in turn, implies that the storage
> for `field` must be laid out as part of a complete `typeof(F())` object
> layout, which is initialized by the call to `F()`. All other members of that
> layout are immediately destroyed, and their storage is theoretically reusable
> after that point, but it's unclear if this is the right default, or how to
> enable user code to override that default when it's the wrong tradeoff.
A _reference binding pattern_ is a binding pattern that is nested under a `var`
pattern. It introduces a name called a _reference binding_ that is a
@@ -174,8 +214,10 @@ fn Example() {
let x: i64 = 1;
// `2` also starts as a value expression, but the variable pattern requires it
// to be converted to an initializing expression by using the value `2` to
// initialize the provided variable storage that `y` will refer to.
// to be converted to an ephemeral entire reference expression by using the
// value `2` to initialize temporary storage, which the variable pattern
// takes ownership of. The reference binding pattern is then bound to a
// durable reference to the newly-initialized object.
var y: i64 = 2;
// Allowed to take the address and mutate `y` as it is a durable reference
@@ -214,8 +256,10 @@ inner `var` pattern here:
fn DestructuringExample() {
// Both `1` and `2` start as value expressions. The `x` binding directly
// matches `1`. For `2`, the variable pattern requires it to be converted to
// an initializing expression by using the value `2` to initialize the
// provided variable storage that `y` will refer to.
// an ephemeral entire reference expression by using the value `2` to
// initialize temporary storage, which the variable pattern takes ownership
// of. The reference binding `y` is then bound to a durable reference to the
// newly-initialized object.
let (x: i64, var y: i64) = (1, 2);
// Just like above, we can take the address and mutate `y`:
@@ -250,9 +294,9 @@ This allows us to model an important special case of function inputs -- those
that are _consumed_ by the function, either through local processing or being
moved into some persistent storage. Marking these in the pattern and thus
signature of the function changes the expression category required for arguments
in the caller. These arguments are required to be _initializing expressions_,
potentially being converted into such an expression if necessary, that directly
initialize storage dedicated-to and owned-by the function parameter.
in the caller. These arguments are required to be _ephemeral entire reference
expressions_, potentially being converted into such an expression if necessary,
whose storage will be dedicated-to and owned-by the function parameter.
This pattern serves the same purpose as C++'s pass-by-value when used with types
that have non-trivial resources attached to pass ownership into the function and
@@ -264,9 +308,60 @@ makes this a use case that requires a special marking on the declaration.
_Reference expressions_ refer to _objects_ with _storage_ where a value may be
read or written and the object's address can be taken.
There are two sub-categories of reference expressions: _durable_ and
_ephemeral_. These refine the _lifetime_ of the underlying storage and provide
safety restrictions reflecting that lifetime.
Reference expressions can be either _durable_ or _ephemeral_. These refine the
_lifetime_ of the underlying storage and provide safety restrictions reflecting
that lifetime. Reference expressions can also be either _entire_ or
_non-entire_, depending on whether the referenced object is known to be complete
(rather than a sub-object of another object).
### Entire reference expressions
An _entire reference expression_ is one that is statically known to refer to a
complete object. Other references are _non-entire_. Durable and ephemeral
reference expressions can both be either entire or non-entire (although
non-entire ephemeral references are rare). Unless otherwise specified, an
expression or operation that produces a reference produces a non-entire
reference.
Note that a non-entire reference expression still _might_ refer to a complete
object; the language rules just don't _guarantee_ that is does. As a result, an
entire reference can be implicitly converted to a non-entire reference (with the
same durability), because this merely discards the knowledge that the object is
complete. By the same token, there is no context that requires a non-entire
reference; only contexts that accept both, that accept only entire references,
or that don't accept references at all.
Currently, the only context that requires an entire reference is the scrutinee
of a `var` pattern, which is required to be an entire ephemeral reference (and
is [converted](#category-conversions) to that category if necessary).
> **Note:** This extends the lifetime of the reference, so it must be possible
> to determine _which_ temporary an ephemeral entire reference refers to, so
> that the implementation knows which lifetime to extend. Under the current
> language rules, this can be done statically.
> **Open question:** Should we extend the language in ways that would force that
> determination to be dynamic? For example, should we allow
> `if c then r1 else r2` to be an entire ephemeral reference expression if `r1`
> and `r2` are? As a more extreme example, should we support functions that take
> and return entire ephemeral references?
There are several kinds of expressions that produce entire references. For
example:
- The name of an object introduced with a
[variable binding pattern](pattern_matching.md#name-binding-patterns) (in
other words, a name that was declared with `var <name> : <type>`) is a
durable entire reference.
- a member access expression `x.member` or `x.(member)` is an entire reference
if `x` is an initializing or entire ephemeral reference expression with a
struct or tuple type.
- The result of materialization is an entire ephemeral reference.
- When a [tuple pattern](pattern_matching.md#tuple-patterns) or
[struct pattern](pattern_matching.md#struct-patterns) is matched with an
ephemeral entire reference scrutinee, that scrutinee is destructured into
ephemeral entire references to its elements, which are then matched with the
corresponding subpatterns.
### Durable reference expressions
@@ -274,7 +369,8 @@ _Durable reference expressions_ are those where the object's storage outlives
the full expression and the address could be meaningfully propagated out of it
as well.
There are two contexts that require a durable reference expression in Carbon:
There are several contexts where durable reference expressions are required. For
example:
- [Assignment statements](/docs/design/assignment.md) require the
left-hand-side of the `=` to be a durable reference. This stronger
@@ -282,9 +378,14 @@ There are two contexts that require a durable reference expression in Carbon:
the `Carbon.Assign.Op` interface method.
- [Address-of expressions](#pointer-syntax) require their operand to be a
durable reference and compute the address of the referenced object.
- [`ref` binding patterns](pattern_matching.md#name-binding-patterns) require
their scrutinee to be a durable reference.
- If a function's [return form](#function-calls-and-returns) contains `ref`
tags, `return` statements require the corresponding parts of the operand to
be durable reference expressions.
There are several kinds of expressions that produce durable references in
Carbon:
There are also several kinds of expressions that produce durable references. For
example:
- Names of objects introduced with a
[reference binding](#binding-patterns-and-local-variables-with-let-and-var):
@@ -295,6 +396,8 @@ Carbon:
- [Indexing](/docs/design/expressions/indexing.md) into a type similar to
C++'s `std::span` that implements `IndirectIndexWith`, or indexing into any
type with a durable reference expression such as `local_array[i]`.
- Calls to functions whose [return forms](#function-calls-and-returns) contain
`ref`.
Durable reference expressions can only be produced _directly_ by one of these
expressions. They are never produced by converting one of the other expression
@@ -305,22 +408,34 @@ categories into a reference expression.
We call the reference expressions formed through
[temporary materialization](#temporary-materialization) _ephemeral reference
expressions_. They still refer to an object with storage, but it may be storage
that will not outlive the full expression. Because the storage is only
temporary, we impose restrictions on where these reference expressions can be
used: their address can only be taken implicitly as part of a method call whose
`self` parameter is marked with the `ref` specifier.
that will not outlive the full expression, and so it can't be used where a
durable reference is expected.
**Future work:** The current design allows directly requiring an ephemeral
reference for `ref`-methods because this replicates the flexibility in C++ --
very few C++ methods are L-value-ref-qualified which would have a similar effect
to `ref`-methods requiring a durable reference expression. This is leveraged
frequently in C++ for builder APIs and other patterns. However, Carbon provides
more tools in this space than C++ already, and so it may be worth evaluating
whether we can switch `ref`-methods to the same restrictions as assignment and
`&`. Temporaries would never have their address escaped (in a safe way) in that
world and there would be fewer different kinds of entities. But this is reserved
for future work as we should be very careful about the expressivity hit being
tolerable both for native-Carbon API design and for migrated C++ code.
> **Future work:** The current design does not support mutating ephemeral
> references (or initializing expressions): assigning to an ephemeral reference
> is disallowed directly, and invoking mutating methods is disallowed because
> the `ref self` parameter can only bind to a durable reference. In C++ it's
> unusual but not rare to intentionally mutate a temporary, such as in a
> builder-style method chain (for example `MakeFoo().SetBar().AddBaz()`), so
> Carbon will need to provide some interop and migration target for that kind of
> code.
There is one context that requires an ephemeral reference expression in Carbon:
the scrutinee of a
[`var` pattern](#binding-patterns-and-local-variables-with-let-and-var) (which
also requires the reference to be entire).
There are only a few ways to produce an ephemeral reference expression. Most
notably:
- The result of materialization is an entire ephemeral reference.
- A member access expression `x.member` or `x.(member)` is an ephemeral
reference if `x` is an initializing or ephemeral reference.
- When a [tuple pattern](pattern_matching.md#tuple-patterns) or
[struct pattern](pattern_matching.md#struct-patterns) is matched with an
initializing or ephemeral reference scrutinee, that scrutinee is
destructured into ephemeral references to its elements, which are then
matched with the corresponding subpatterns.
## Value expressions
@@ -487,8 +602,9 @@ The specific tradeoff here is covered in a proposal
## Initializing expressions
Storage in Carbon is initialized using _initializing expressions_. Their
evaluation produces an initialized object in the storage, although that object
may still be _unformed_.
evaluation takes a _result location_ as an implicit input, and produces an
initialized object at that location, although that object may still be
_unformed_.
**Future work:** More details on initialization and unformed objects should be
added to the design from the proposal
@@ -506,29 +622,37 @@ the provided storage.
**Future work:** The design should be expanded to fully cover how copying is
managed and linked to from here.
The first place where an initializing expression is _required_ is to satisfy
[_variable patterns_](#binding-patterns-and-local-variables-with-let-and-var).
These require the expression they match to be an initializing expression for the
storage they create. The simplest example is the expression after the `=` in a
local `var` declaration.
There are no syntactic contexts in Carbon that always require an initializing
expression, and no expression syntax that always produces an initializing
expression. By default, function call expressions are initializing expressions,
and correspondingly the operand of `return` is required to be an initializing
expression, but this default can be overridden by the
[function signature](#function-calls-and-returns).
The next place where a Carbon expression requires an initializing expression is
the expression operand to `return` statements. We expand more completely on how
return statements interact with expressions, values, objects, and storage
[below](#function-calls-and-returns).
The last path that requires forming an initializing expression in Carbon is when
attempting to convert a non-reference expression into an ephemeral reference
expression: the expression is first converted to an initializing expression if
necessary, and then temporary storage is materialized to act as its output, and
as the referent of the resulting ephemeral reference expression.
Initializing expressions can also be created implicitly, when attempting to
convert an expression into an ephemeral entire reference expression
(particularly to match a `var` pattern): the expression is first converted to an
initializing expression if necessary, and then temporary storage is materialized
to act as its output, and as the referent of the resulting ephemeral reference
expression.
### Function calls and returns
Function calls in Carbon are modeled directly as initializing expressions --
they require storage as an input and when evaluated cause that storage to be
initialized with an object. This means that when a function call is used to
initialize some variable pattern as here:
The [result](#expression-forms) of a function call can have an almost arbitrary
form. The return clause of a function signature consists of `->` followed by a
_return form_, an expression-like syntax that specifies not only the type but
also the form of the function call's result. `return` expressions in the
function body are expected to have that form, and are converted to it if
necessary. When a function is declared without a return clause, it behaves from
the caller's point of view as if the return clause were `-> ()`, but `return`
statements in the function body don't take operands (and can be omitted at the
end of the function).
In the common case, the return form is a type expression, in which case calls
are modeled directly as initializing expressions -- they require storage as an
input and when evaluated cause that storage to be initialized with an object.
This means that when a function call is used to initialize some variable pattern
as here:
```carbon
fn CreateMyObject() -> MyType {
@@ -541,18 +665,64 @@ var x: MyType = CreateMyObject();
The `<return-expression>` in the `return` statement actually initializes the
storage provided for `x`. There is no "copy" or other step.
> **Future work:** Extend this to also apply when a variable pattern is
> initialized from a tuple/struct literal, or a tuple/struct pattern with
> variable subpatterns is initialized from a single function call.
In the body of such a function, all `return` statement expressions are required
to be initializing expressions and in fact initialize the storage provided to
the function's call expression. This in turn causes the property to hold
_transitively_ across an arbitrary number of function calls and returns. The
storage is forwarded at each stage and initialized exactly once.
All `return` statement expressions are required to be initializing expressions
and in fact initialize the storage provided to the function's call expression.
This in turn causes the property to hold _transitively_ across an arbitrary
number of function calls and returns. The storage is forwarded at each stage and
initialized exactly once.
More generally, the syntax and semantics of a return form are as follows:
Note that functions without a specified return type work exactly the same as
functions with a `()` return type for the purpose of expression categories.
- _return-clause_ ::= `->` _return-form_
- _return-form_ ::= _nesting-return-form_ | _auto-return-form_
- _nesting-return-form_ ::= _expression-return-form_ | _proper-return-form_
Return forms can usually be nested, but syntaxes involving `auto` can only occur
at top level. We further divide nesting return forms into expressions and
"proper" return forms, but this is just a technical means of avoiding formal
ambiguity in the grammar; it has no greater significance.
- _category-tag_ ::= `val` | `ref` | `var`
These tags are used to specify "value", "non-entire durable reference", or
"initializing" expression category (respectively). Note that there is no way to
express an entire or ephemeral reference category in a return form.
- _auto-return-form_ ::= _category-tag_? `auto`
This denotes a primitive form with runtime phase and deduced type. The category
is determined by _category-tag_ if present, or "initializing" otherwise.
- _proper-return-form_ ::= _category-tag_ _expression_
This denotes a primitive form with runtime phase, category _category-tag_, and
type "_expression_ `as type`".
- _expression-return-form_ ::= _expression_
An expression with no _category-tag_ is equivalent to "`var` _expression_".
- _proper-return-form_ ::= `(` [_expression-return-form_ `,`]\* _proper-return-form_
[`,` _nesting-return-form_]\* `,`? `)`
A tuple literal of return forms denotes a tuple form whose sub-forms are
specified by the comma-separated elements. To avoid formal ambiguity, this
grammar rule requires at least one of the sub-forms to be proper.
- _expression-field-form_ ::= _designator_ `:` _expression-return-form_
- _proper-field-form_ ::= _designator_ `:` _proper-return-form_
- _field-form_ ::= _field-decl_
- _field-form_ ::= _proper-field-form_
- _proper-return-form_ ::= `{` [_expression-field-form_ `,`]\* _proper-field-form_
[`,` _field-form_]\* `}`
A struct literal of return forms denotes a struct form whose field names and
their forms are specified by the comma-separated field forms. To avoid formal
ambiguity, this grammar rule requires at least one of the field forms to be
proper.
> **Open question:** Should there be a way to specify symbolic or template phase
> in return forms?
#### Deferred initialization from values and references
@@ -625,6 +795,295 @@ The model of initialization of returns also facilitates the use of
[`returned var` declarations](control_flow/return.md#returned-var). These
directly observe the storage provided for initialization of a function's return.
## Expression forms
We typically treat the category and type of an expression as independent
properties. However, in some cases we need to deal with them as an integrated
whole. The _form_ of an expression captures all of the information about it that
is visible to the type system, while abstracting away all other information
about it. Thus, forms are a generalization of types: what we conventionally call
"types" are really the types of objects and values, whereas forms are the types
of expressions and patterns.
A _primitive form_ currently consists of a type, an expression category, an
expression phase, and optionally a constant value (which is present if and only
if the expression phase is not "runtime"). When dealing with primitive forms,
which is the common case, we can treat each of those properties as independent.
For convenience, in this section we will use the notation `<T, C, P, V>` to
represent a primitive form with type `T`, category `C`, phase `P` and value `V`,
but this is not Carbon syntax.
Other forms are called _composite forms_, and there are two kinds:
A _tuple form_ can be thought of as a tuple of forms, just as a tuple type can
be thought of as a tuple of types. The form of a tuple literal is a tuple form,
whose elements are the forms of the literal elements.
> **TODO:** Extend this to support variadic forms.
A _struct form_ can be thought of as a struct whose fields are forms, just as a
struct type can be thought of as a struct whose fields are types. The form of a
struct literal is a struct form with the same field names, whose values are the
forms of the corresponding fields of the struct literal.
The _type component_ of a form is defined as follows:
- The type component of a primitive form `<T, C, P, V>` is `T`.
- The type component of a tuple form is a tuple of the type components of its
elements.
- The type component of a struct form is a struct whose field names are the
field names of the struct form and whose field types are the type components
of the corresponding elements.
The _category component_ and _phase component_ of a form are defined likewise.
The category component of a struct form is called a _struct category_, and the
category component of a tuple form is called a _tuple category_.
The type of an expression is the type component of the expression's form.
Evaluating an expression produces a _result_. It can be defined recursively in
terms of the expression's form:
- The result of an initializing expression is an
[initializing result](#initializing-results).
- The result of a value expression is a value.
- The result of a reference expression is a reference of the same kind.
- The result of an expression with tuple form is a tuple of results.
- The result of an expression with struct form is a struct of results.
An expression and its result always have the same form.
The code that accesses the result of an expression is said to _consume_ that
result, and every primitive-form result is consumed exactly once (except in
certain narrow contexts where the result is known not to be initializing). If a
result isn't explicitly accessed, such as when the expression is used as a
statement, it is said to be _discarded_, which consumes it in the absence of an
explicit consumer. Discarding an initializing result materializes and then
immediately destroys it. Discarding an entire ephemeral reference destroys the
object it refers to. Discarding a value or any other kind of reference is a
no-op.
### Initializing results
As discussed earlier, evaluation of an initializing expression takes as an input
the result location that it initializes, which is implicitly provided by the
context in which the evaluation takes place. In some cases, the context may
obtain the location from its own context, and so on. For example:
```carbon
class C {
private var i: i32;
fn Make() -> C {
return {.i = 0};
}
}
fn F() -> C {
return C.Make();
}
fn G() {
var c: C = F();
}
```
By default, a function call is an initializing expression, and a `return`
statement initializes the call's result location (which is passed as a hidden
output parameter). So when the declaration of `c` is evaluated, its storage is
implicitly passed into `F()` as an output parameter, which is initialized by the
`return` statement inside `F`. When that `return` statement is evaluated to
initialize the result location, it likewise implicitly passes the storage into
`C.Make()` as an output parameter, which is initialized by the `return`
statement inside `C.Make`. Finally, that `return` statement initializes the
result location (which is still the location of `c`'s storage) by
[direct initialization](#direct-initialization) from the value expression
`{.i = 0}`.
Notice that the implicit storage parameter propagates "backwards", into an
expression from the code that uses its result. In order to simplify the
description of the language, we usually won't explicitly discuss the result
locations of initializing expressions, or how they're propagated. Instead, this
propagation is encapsulated inside the _initializing result_, which is the
notional result of an initializing expression.
Whenever an initializing result is consumed, that implicitly means that the
consumer passes a result location into the evaluation of the initializing
expression. The source of that location depends on the consumer:
- If the consumer is a temporary materialization conversion, the result
location is newly-allocated temporary storage (which the consumer may
subsequently lifetime-extend to durable storage).
- If the consumer is a `return` statement, and the initializing result
corresponds to an initializing sub-form of the function's return form, the
result location is the implicit output parameter corresponding to that
initializing sub-form.
### Form conversions
A conversion between forms can be broken down into up to three steps: type
conversion, category conversion, and phase conversion. These convert the form to
a particular target type, category, and phase component (respectively). These
steps aren't fully orthogonal: type conversions can change the category and
phase components as a byproduct, and category conversions can change the phase
component. However, category conversions can't change the type component, and
phase conversions can't change either of the other two, so converting the type,
then category, then phase, ensures that we converge on the desired result.
Any of these steps may be omitted, depending on whether the context imposes
requirements on the corresponding component. Most commonly, an operand position
requires its operand to have a primitive form with a particular category,
usually with a particular type, and sometimes with a particular phase.
Phase conversions cannot change the form structure; they can only apply
primitive phase conversions to primitive sub-forms. Type and category
conversions are more complex, and are covered in the next two sections.
Note that these rules will implicitly convert between primitive and composite
forms in both directions (except that a composite containing references cannot
be converted to a primitive form). As a result, although the difference between
primitive and composite forms is observable by way of overloading, it can't
reliably carry any higher-level meaning, and should be used only as an
optimization tool.
Note that this section describes the _logical structure_ of form conversions. As
such, it primarily describes them "breadth-first", as a sequence of operations
that each applies to the whole expression by recursively operating on its parts.
However, the _physical execution_ of these conversions is actually depth-first,
applying as many operations as possible to a minimal subexpression before moving
on to the next one. The details of that process are described
[here](pattern_matching.md#evaluation-order).
#### Type conversions
See [here](expressions/implicit_conversions.md) for overall information about
type conversions. Conversions involving struct, tuple, and array types are
described here because of their unique interactions with expression forms.
> **TODO:** A forthcoming proposal is expected to update the type conversion
> interfaces to permit user-defined conversions to depend on the form of the
> input, and customize the form of the output. Once that is done, these "built
> in" conversions should be presented as implementations of those interfaces,
> possibly with some "magic" for things like introspecting on struct field
> names.
Each of the conversions described in this section is explicit if and only if it
invokes another explicit type conversion. Otherwise, it is implicit.
A type conversion of a primitive-form expression to a
[compatible type](generics/terminology.md#compatible-types) just re-interprets
the expression's result with a new type, so it requires no run-time work, and
has the same category as the input expression.
A result `source` that has a struct type can be converted to a struct type
`Dest` if they have the same set of field names:
- If the type of `source` is `Dest`, return `source`.
- If `source` is a struct result, for each field name `F` in `Dest`,
type-convert `source.F` to `Dest.F`. Return a struct result where each field
`F` is set to the result of the corresponding conversion.
- If `source` is a primitive result, convert it to a struct result by
[form decomposition](#category-conversions), and then type-convert the
result to `Dest` and return the result.
Note that the sub-conversions invoked here are not necessarily defined; if so,
the conversion itself is not defined.
There is a conversion to a class type `Dest` from a result `source` that has a
struct type, if there is a conversion from `source` to a struct type that has
the same field names as `Dest` (including a `.base` field if `Dest` is a derived
class), with the same types, in the same order. The conversion type-converts
`source` to that struct type, category-converts that to an initializing
expression of the struct type, and then reinterprets it as an initializing
expression of `Dest` (which is layout-compatible with the struct type by
construction).
Note that some fields of an object may be initialized directly by the evaluation
of the source expression, while others may be initialized by the conversions
described here. The conversions initialize fields in their declaration order,
but the evaluation of the source expression always happens before any of the
conversions, and happens in the source expression's lexical order, so the fields
of an object are not necessarily initialized in declaration order.
Conversions between tuple types are defined in the same way, treating tuples as
structs that have fields named `.0`, `.1`, etc, in numerical order.
There is a conversion to `array(T, N)` from any expression with a tuple form of
exactly `N` elements, whose type components are convertible to `T`. The
conversion is an initializing expression, which type-converts each source
element to `T`, and initializes the corresponding array element from the result
of that conversion.
#### Category conversions
_Form composition_ converts an expression of composite form with consistent
category to a primitive form as follows (where `min` as applied to phases uses
the ordering "runtime" < "symbolic" < "template"):
- An expression of tuple form
`(<T1, C, P1, V1>, <T2, C, P2, V2>, ... <TN, C, PN, VN>)` can be converted
to a primitive form
`<(T1, T2, ..., TN), C, min(P1, P2, ..., PN), (V1, V2, ... VN)>`.
- An expression of struct form
`{.a = <Ta, C, Pa, Va>, .b = <Tb, C, Pb, Vb>, ... .z = <Tz, C, Pz, Vz>}` can
be converted to a primitive form
`<{.a = Ta, .b = Tb, ... .z = Tz}, C, min(Pa, Pb, ... Pz), {.a = Va, .b = Vb, ... .z = Vz}>`.
When `C` is "value", composition forms a value representation of the aggregate
from value representations of the elements. When `C` is "initializing", it
transforms initializing expressions for each element into a single initializing
expression that initializes the whole aggregate. `C` cannot be a reference
category, because an aggregate of references to independent objects can't be
replaced by a reference to a single aggregate object in a single step.
_Form decomposition_ is the inverse of form composition. It converts a
primitive-form expression to a composite form as follows:
- An expression with primitive form `<(T0, T1, ..., TN), C, P, V>` can be
converted to a tuple form
`(<T0, CC, P, V.0>, <T1, CC, P, V.1>, ... <TN, CC, P, V.N>)`.
- An expression with primitive form
`<{.a = Ta, .b = Tb, ... .z = Tz}, C, P, V>` can be converted to a struct
form
`{.a = <Ta, CC, P, V.a>, .b = <Tb, CC, P, V.b>, ... .z = <Tz, CC, P, V.z>}`.
The category `CC` of the resulting sub-forms is the same as `C`, with two
exceptions:
- If `C` is "durable entire reference", `CC` will be "durable non-entire
reference", because the sub-forms don't refer to complete objects. This
doesn't apply to ephemeral entire references, because in that case form
decomposition implicitly ends the lifetime of the original aggregate,
promoting its elements to complete objects with independent lifetimes.
- If `C` is "initializing", the original expression is materialized before it
is decomposed, so `CC` will be "ephemeral entire reference".
By convention, form decomposition is a no-op when applied to an expression with
struct or tuple form.
_Category conversion_ converts an expression to have a given category component
without changing its type. The conversion works by combining form composition
and decomposition with primitive category conversions, and is defined
recursively:
- If the target category component is a tuple, the source form must have a
tuple type with the same arity. Convert the source to a tuple form by form
decomposition, and then category-convert each source sub-form to the
corresponding target sub-category.
- If the target category component is a struct, the source form must have a
struct type with the same set of field names in the same order. Convert the
source to a struct form by form decomposition, and then category-convert
each source sub-form to the corresponding target sub-category.
- If the target category is a primitive category `C`:
- If the source form is primitive, convert to `C` by applying primitive
category conversions.
- If the source form is composite and `C` is a reference category,
category-convert the source form to "initializing", and then convert the
result to `C` by applying primitive category conversions.
- If the source form is composite and `C` is not a reference category,
category-convert each source sub-form to `C`, and then convert the
aggregate result of these conversions to `C` by form composition.
## Pointers
Pointers in Carbon are the primary mechanism for _indirect access_ to storage
@@ -859,8 +1318,7 @@ functionality already proposed here or for [classes](/docs/design/classes.md):
the most appealing as it _doesn't_ have the combinatorial explosion. But it
is also very limited as it only applies to the implicit object parameter.
- Allow overloading between `var` and non-`var` parameters.
- Expand the `ref` technique from object parameters to all parameters, and
allow overloading based on it.
- Allow overloading between `ref` and non-`ref` parameters in general.
Perhaps more options will emerge as well. Again, the goal isn't to completely
preclude pursuing this direction, but instead to try to ensure it is only
@@ -1040,6 +1498,8 @@ itself.
- [Exclusively using references](/proposals/p2006.md#exclusively-using-references)
- [Alternative pointer syntaxes](/proposals/p2006.md#alternative-pointer-syntaxes)
- [Alternative syntaxes for locals](/proposals/p2006.md#alternative-syntaxes-for-locals)
- [Mixed expression categories](/proposals/p5545.md#mixed-expression-categories)
- [Don't implicitly convert to less-primitive forms](/proposals/p5545.md#dont-implicitly-convert-to-less-primitive-forms)
## References
@@ -1048,9 +1508,11 @@ itself.
- [Proposal #618: `var` ordering][p0618]
- [Proposal #851: auto keyword for vars][p0851]
- [Proposal #2006: Values, variables, and pointers][p2006]
- [Proposal #5545: Expression form basics][p5545]
[p0257]: /proposals/p0257.md
[p0339]: /proposals/p0339.md
[p0618]: /proposals/p0618.md
[p0851]: /proposals/p0851.md
[p2006]: /proposals/p2006.md
[p5545]: /proposals/p5545.md
+8
View File
@@ -23,6 +23,7 @@ SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
- [Responding to review comments](#responding-to-review-comments)
- [Responding to questions or confusion](#responding-to-questions-or-confusion)
- [Understand the feedback in the comments](#understand-the-feedback-in-the-comments)
- [Fixing conflicts with trunk](#fixing-conflicts-with-trunk)
- [Code reviewer guide](#code-reviewer-guide)
- [How quickly should you respond to a review request?](#how-quickly-should-you-respond-to-a-review-request)
- [What should be covered by a review?](#what-should-be-covered-by-a-review)
@@ -325,6 +326,13 @@ long delays between these iterations. Consider discussing over Discord chat or
scheduling a quick video chat on the specific issue. This can avoid multi-hour
-- or multi-day -- round trips.
### Fixing conflicts with trunk
If a PR has conflicts with trunk, those conflicts must be resolved before the PR
can be merged. If the PR is already in review, prefer to wait until review is
mostly done before fixing the conflicts. Conflicts should be fixed by way of a
merge commit rather than rebasing.
## Code reviewer guide
The specific goal for a particular review should always be to ensure that the
+107 -1
View File
@@ -22,6 +22,9 @@ contributions.
- [Main tools](#main-tools)
- [Running pre-commit](#running-pre-commit)
- [Optional tools](#optional-tools)
- [Jujutsu (`jj`)](#jujutsu-jj)
- [AI assistants](#ai-assistants)
- [Running tests with AddressSanitizer (ASan)](#running-tests-with-addresssanitizer-asan)
- [Manually building Clang and LLVM (not recommended)](#manually-building-clang-and-llvm-not-recommended)
- [Troubleshooting build issues](#troubleshooting-build-issues)
- [`bazel clean`](#bazel-clean)
@@ -159,7 +162,7 @@ These tools are essential for work on Carbon.
- To upgrade versions of `brew` packages, it will be necessary to
periodically run `brew upgrade`.
- [Python](https://python.org)
- Carbon requires Python 3.9 or newer.
- Carbon requires Python 3.10 or newer.
- To upgrade versions of pip-installed packages, it will be necessary
to periodically run `pipx list --outdated`, then
`pipx install -U <package>` to upgrade desired packages.
@@ -176,6 +179,10 @@ These tools are essential for work on Carbon.
- [gh CLI](https://github.com/cli/cli): Helps with GitHub.
- [pre-commit](https://pre-commit.com): Validates and cleans up git
commits.
- `autoupdate_testdata.py`: Updates expected output for tests.
- Usage: `./toolchain/autoupdate_testdata.py [files...]`
- This is essential when changes affect compiler output (diagnostics,
SemIR, etc.).
#### Running pre-commit
@@ -226,18 +233,117 @@ considering if they fit your workflow.
[GDB]((/toolchain/docs/debugging.md#debugging-with-gdb)
- [clangd](https://clangd.llvm.org/installation): An LSP server implementation
for C/C++.
- To ensure that `clangd` reports accurate diagnostics. It needs a
generated file called `compile_commands.json`. This can be generated by
invoking the command below:
```
./scripts/create_compdb.py
```
- **NOTE**: This assumes you have `python` 3 installed on your system.
- [`uv`](https://docs.astral.sh/uv/): A fast Python package manager.
- Notably, `uv` supports automatic management of even complex Python
dependencies for scripts: https://docs.astral.sh/uv/guides/scripts/
- Installation: https://docs.astral.sh/uv/getting-started/installation/
#### Jujutsu (`jj`)
[Jujutsu](https://github.com/jj-vcs/jj) is a Git-compatible version control
system that can be used instead of or alongside Git. See the
[documentation for using Jujutsu with GitHub](https://jj-vcs.github.io/jj/latest/github/)
for more information.
If you use `jj`, you may find the following configuration snippets (added to
`jj config path --user`) helpful for your workflow:
```sh
# Clean up untracked or abandoned commits.
jj config set --user aliases.abandon-untagged '["abandon", "all() & ~ancestors(@ | bookmarks() | remote_bookmarks())"]'
# Use Git-style conflict markers, which VS Code can provide merge support for.
jj config set --user ui.conflict-marker-style 'git'
# Produce Git-compatible diff format.
jj config set --user ui.diff.format 'git'
# Automatically add a trailer to commits to indicate that they were AI-assisted.
jj config set --user templates.commit_trailers "$(echo -e "'''\n\"Assisted-by: My AI Tool\"'''")"
# Make `jj bookmark advance` / `jj b a` only move bookmarks that point to
# mutable commits, and move them to the most recent non-empty descendant.
jj config set --user revsets.bookmark-advance-from 'heads(::to & bookmarks()) & ~immutable_heads()'
jj config set --user revsets.bookmark-advance-to 'heads(::@ & ~(description("") & empty() & ~merges()))'
```
<!-- google-doc-style-ignore -->
As well as this per-repository configuration (added to `jj config path --repo`)
describing how your GitHub checkout is configured:
```sh
# Automatically track all remote bookmarks.
jj config set --repo remotes.origin.auto-track-bookmarks '*'
# `trunk()` is a jj builtin, but defaults to `main@upstream`.
jj config set --repo 'revset-aliases."trunk()"' 'trunk@upstream'
# Treat github.com/carbon-language/carbon-lang as immutable, but treat your fork
# as mutable.
jj config set --repo 'revset-aliases."immutable_heads()"' 'remote_bookmarks(*, upstream)'
```
<!-- google-doc-style-resume -->
The above assumes that you have configured the remote name `origin` to refer to
your fork and `upstream` to refer to `github.com/carbon-language/carbon-lang`,
and will need to be adjusted if you use different remote names.
#### AI assistants
When using AI assistants and reviewing terminal commands, some commands which
may be helpful and reasonably safe to allowlist (assuming prefix-based
allowlisting) are:
```
# Carbon development commands.
bazelisk build
bazelisk test
bazelisk run //toolchain/testing:file_test --
clang-format
pre-commit run
./toolchain/autoupdate_testdata.py
# Shell commands. Note that these allow reading arbitrary files on your local
# file system.
cat
grep
head
ls
# VCS commands.
git diff
git log
git show
git status
```
### Running tests with AddressSanitizer (ASan)
By default, the Bazel build mode for the toolchain does not enable
AddressSanitizer (ASan). If you wish to enable ASan for local testing, you must
pass the `--config=asan` flag explicitly:
```shell
bazelisk test --config=asan //...
```
Note that our Continuous Integration (CI) infrastructure runs a separate
configuration for ASan to ensure test coverage without slowing down the default
test cycle.
### Manually building Clang and LLVM (not recommended)
We primarily test against [apt.llvm.org](https://apt.llvm.org) and Homebrew
+2
View File
@@ -11,6 +11,8 @@ import Core library "range";
import library "io_utils";
class Terrain {
impl as Core.UnformedInit {}
fn Read() -> Terrain {
returned var me: Terrain;
for (y: i32 in Core.Range(43)) {
+2
View File
@@ -24,6 +24,8 @@ fn PopCount(n: u256) -> i32 {
}
class Reachable {
impl as Core.UnformedInit {}
fn Make(terrain: Terrain) -> Reachable {
returned var me: Reachable;
var next: u256 = 1;
+2
View File
@@ -11,6 +11,8 @@ import library "day10_common";
import library "io_utils";
class PathsToTop {
impl as Core.UnformedInit {}
fn Make(terrain: Terrain) -> PathsToTop {
returned var me: PathsToTop;
for (y: i32 in Core.Range(43)) {
+2
View File
@@ -11,6 +11,8 @@ import library "day11_common";
import library "io_utils";
class Digits {
impl as Core.UnformedInit {}
fn Make() -> Digits {
returned var me: Digits;
for (digit: i32 in Core.Range(10)) {
+4
View File
@@ -11,6 +11,8 @@ import Core library "range";
import library "io_utils";
class Map {
impl as Core.UnformedInit {}
fn Read() -> Map {
returned var me: Self;
for (y: i32 in Core.Range(140)) {
@@ -32,6 +34,8 @@ class Map {
}
class DisjointSetForest {
impl as Core.UnformedInit {}
fn Make() -> DisjointSetForest {
returned var me: Self;
for (i: i32 in Core.Range(140 * 140)) {
+2
View File
@@ -23,6 +23,8 @@ fn Euclid(a: i64, b: i64) -> {.m: i64, .n: i64, .gcd: i64} {
}
class Machine {
impl as Core.UnformedInit {}
fn Read() -> Machine {
returned var me: Machine;
// "Button A: X+"

Some files were not shown because too many files have changed in this diff Show More