This uses SSE2 to optimize the horizontal space skipping path when there
is more than a single character. That helps with indentation and other
edge cases and doesn't cost much because we only begin when >1
horizontal space to skip.
We use SSE2 here which is available ubiquitously as AVX2 doesn't provide
any significant advantage.
Agy's benchmarks (`./scripts/bench_runner.py --runs=12`, `-c opt
--copt=-march=x86-64-v3`, vs. `trunk`):
- `BM_HorizontalWhitespace/16`: -4.610% CPU time, +4.832% bytes/s &
tokens/s
- `BM_HorizontalWhitespace/64`: -45.977% CPU time, +85.106% bytes/s &
tokens/s
- `BM_HorizontalWhitespace/128`: 0.428x CPU time, 2.338x bytes/s &
tokens/s
Assisted-by: Antigravity with Gemini
---------
Co-authored-by: Geoff Romer <gromer@google.com>
The `memchr` approach didn't really fully capture what we can do with
AVX2, so build a dedicated optimized path for it.
The optimized path does carefully optimized 64-byte block scanning and
decodes the newline positions. I've tried to ensure there are enough
comments to understand the different micro-optimizations that went into
it getting the full performance potential.
My agent's benchmarks (`./scripts/bench_runner.py --runs=12`, `-c opt
--copt=-march=x86-64-v3`, vs. `trunk`):
- `BM_BlankLines/16`: -11.158% CPU time, +12.557% bytes/s & lines/s
- `BM_BlankLines/64`: -21.623% CPU time, +27.587% bytes/s & lines/s
- `BM_BlankLines/128`: -26.332% CPU time, +35.742% bytes/s & lines/s
- `BM_CommentLines/128/0/0`: -22.198% CPU time, +28.531% bytes/s &
lines/s
Assisted-by: Antigravity with Gemini
Determining that a type has trivial destruction requires checking
whether all of its subobjects have trivial destruction and whether its
type has a custom witness for `Destroy.Op`. This isn't possible when
`Destroy` is the custodian for `Destroy.Op` and `SubobjectDestroy.Op`,
so we need to make `SubobjectDestroy` its own interface.
`Destroy.SelfDestruct` becomes a standalone function because it depends
on `SubobjectDestroy` and `Destroy` being implemented, and is also
responsible for generating any custom witnesses for both interfaces.
Making `SelfDestruct` an interface was experimented with, but this
required a blanket impl that caused issues for facet types.
`Destroy` depends on `SubobjectDestroy` to be implemented. We'd ideally
use `require impls SubobjectDestroy`, but it isn't complete yet, and it
also causes problems when `Destroy` is implemented inside the class
definition. We work around this by temporarily renaming the `Destroy`
interface to `DestroyImpl`, and introducing a constraint called
`Destroy` so that user code doesn't need to write `Core.SubobjectDestroy
& Core.Destroy`.
`FinishAst` resolves C++ template instantiation. Template instantiation
can complete Carbon types, generate thunks, and call generic functions.
These operations can add new entries to `definitions_required_by_use()`.
Similarly, resolving any of those can generate more C++ templates that
need instantiating. This change moves `FinishAst` ahead of
`CheckRequiredDefinitions` and loops until no new Carbon definitions
have been added. This prevents later passes from crashing when
evaluating specifics on unresolved generics or uninstantiated templates.
`FinishAst` also disconnects the AST. Subsequent definitions and `impl`s
may depend on C++ interop, so the AST must remain connected until all
the Carbon end-of-file checks complete. We achieve this by decoupling
AST disconnection from finalisation.
Assisted-by: Antigravity with Gemini
Assisted-by: Antigravity with Claude Opus 5.5 Max
Add `BM_CompileApiFileRealisticHeader`, which models a typical C++
header. Each class defines 2 getters, 1 predicate, 2 forwarders, and 2
function definitions inline, and declares 2 methods along with the
private methods that the forwarders call. The dense declarations
benchmarks keep modeling a declaration-heavy API file.
The counts come from classifying, with libclang, the member functions
defined in class definitions in the hand-written headers that the
toolchain includes: 1,612 in the Carbon toolchain's headers, 10,406 in
LLVM's, and 13,366 in Clang's. Classified the same way, the generated
C++ defines 69% of its member functions inline in the class definition,
against 61-70% in the real headers. 78% of its inline definitions are a
single statement, against 72-82%, and 21% return the result of a member
call, against 19-21%. Only 2% have control flow, against 7-13%, because
most inline function definitions have only the three statements that
every plan-based definition has.
Assisted-by: Claude Code and Antigravity with Gemini
---------
Co-authored-by: Geoff Romer <gromer@google.com>
The primary performance challenge with `musttail` dispatch is register
allocation. We can use the `[[clang::preserve_none]]` calling convention
to address this, dramatically improving the register pressure across
these dispatched routines.
However, to be effective, we need to very carefully manage inlining to
keep out-of-line functions from breaking the ideal register allocation,
but keep the right functions out-of-line. A bunch of annontations are
added to push things in one direction or another.
This also requires us to move error handling out of the tight dispatch
loop in more places, for example by returning `LexResult::NoMatch()` and
letting the outer loop handle it.
Agy's benchmarks (`./scripts/bench_runner.py --runs=12`, `-c opt
--copt=-march=x86-64-v3`, vs. `trunk`):
- `BM_CompileApiFileDenseDecls<Lang::Carbon, Phase::Lex>/65536`: -9.594%
CPU time
- `BM_CompileApiFileDenseDecls<Lang::Carbon, Phase::Lex>/262144`:
-7.786% CPU time
- `BM_ValidIdentifiers<3, 5, true>`: -9.194% CPU time, +10.125% bytes/s
& tokens/s
- `BM_RandomSource`: -5.062% CPU time, +5.332% bytes/s, lines/s &
tokens/s
Assisted-by: Antigravity with Gemini
Adds support for exporting both the generic function decl with concrete
default arguments to clang, as well as exporting the monomorphized
concrete function def.
This required adding the `SpecificId` to the exported global variable
name, to avoid duplicate names in the global vars. I also now set up an
evaluated context in `clang_sema` when declaring the default arg
expression with clang, to avoid the problem of emitting concrete AST
expressions in an unevaluated context from the in-progress template
function decl context when exporting default values for generics.
Note: Default values for generic parameters of generic functions are not
yet supported.
Extract the allocation path (which is inherently cold due to growth).
Making the outlining effective requires both blocking further inlining
and using `preserve_most` so that the existence of the call doesn't
disrupt the register allocation.
We also mark the insertion statements with callbacks as `always_inline`
so it being cold doesn't cause it to be left out-of-line and further
disrupt register allocation. It's a bit strange to force inlining of a
cold-path function, but the register impact of the call extends back
into the hot-path.
Agy's benchmarks (`./scripts/bench_runner.py --runs=12`, `-c opt
--copt=-march=x86-64-v3`, vs. `trunk`):
- `BM_ValidIdentifiers<3, 5, true>`: -6.277% CPU time
- `BM_ValidIdentifiers<3, 16, true>`: -4.525% CPU time
- `BM_CompileApiFileDenseDecls<Lang::Carbon, Phase::Lex>/262144`:
-2.012% CPU time (47.5 ms ± 6.358% -> 46.54 ms ± 1.773%, p=0.0167)
Assisted-by: Antigravity with Gemini
The `var_name` string was built on the stack and then added to the
`IdentifierStore`. This lead to use-after-free, since `IdentifierStore`
just stores a `llvm::StringRef`.
Add it to `ast_context().Idents` to provide a longer-lived reference.
Bumps the npm_and_yarn group with 1 update in the /utils/vscode
directory: [markdown-it](https://github.com/markdown-it/markdown-it).
Updates `markdown-it` from 14.3.2 to 14.3.3
<details>
<summary>Changelog</summary>
<p><em>Sourced from <a
href="https://github.com/markdown-it/markdown-it/blob/14.3.3/CHANGELOG.md">markdown-it's
changelog</a>.</em></p>
<blockquote>
<h2>[14.3.3] - 2026-10-16</h2>
<h3>Security</h3>
<ul>
<li>Backported 15.0.3 fixes.</li>
</ul>
</blockquote>
</details>
<details>
<summary>Commits</summary>
<ul>
<li><a
href="https://github.com/markdown-it/markdown-it/commit/d372f0d8a68bef0b0acaa68868ce8ae8ba85b384"><code>d372f0d</code></a>
14.3.3 released</li>
<li><a
href="https://github.com/markdown-it/markdown-it/commit/d99f48839d37af6fd8a2617516c43dab90755503"><code>d99f488</code></a>
Backported 15.0.3 fixes</li>
<li>See full diff in <a
href="https://github.com/markdown-it/markdown-it/compare/14.3.2...14.3.3">compare
view</a></li>
</ul>
</details>
<br />
[](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>
This re-lands #8001 (reverted in #8009 after accidentally merging with
earlier unmerged PRs in the stack).
Build on the plan-based emission to make function definitions cover a
more representative breadth of the language: class-typed local
variables, and local variables declared with destructuring. This
requires some complexity to initialize and manage the class type
variables, but ultimately should make all of our compile time benchmark
data more representative by covering a more realistic breadth of the
language surface.
Claude's rough sampling of Carbon, Clang, and LLVM source suggests class
types range from 30% to 80% of the locals, and structured bindings range
from 0.2% to 2%. When synthesizing, we target approximately 50% of
declarations as class types and 2% as destructurings as we anticipate
destructuring to be of growing popularity and so want to ensure we're
measuring any overhead there.
Assisted-by: Claude Code and Antigravity with Gemini
Co-authored-by: Geoff Romer <gromer@google.com>
If a generic class inherits from a private parent (as allowed in C++),
and attempts to access a member of that private parent, an error should
be diagnosed via `DiagnoseInvalidQualifiedNameAccess`.
A couple changes are needed to make that work, because the access
constant in this case is not a `ClassType`. Instead, it's a
`StructValue` of type `ParameterizedClassType`. So, use
`TryGetTypeIdForTypeConstantId` instead of `GetTypeIdForTypeConstantId`
(to get `None` instead of asserting on a non-type constant), and allow
getting the class ID from both `ClassType` and `ParameterizedClassType`.
---------
Co-authored-by: Christopher Di Bella <cjdb.ns@gmail.com>
Drop dependencies on the prelude so it can be debugged with no prelude
import if needed. Ensure the return type of MakeC is used in C++ since
it's part of the imported function signature.
We use the dry-run mode for running benchmarks in a test. This is
important, but doesn't need to use large batches of files. Doing so
would cause the compilation benchmark to become excessively slow,
especially on GitHub runners.
Sadly, Google Benchmark doesn't expose its dry-run mode, but we already
have our own `main` function that injects custom logic for our
benchmarks. Extend that to detect the dry run flags and environment
variables so that we can customize the benchmark behavior in that mode.
Then we use that detection to reduce the batch size.
Also cleans up the counters computation to both be a bit better
organized (I think), and to avoid keeping the tokenized buffers we build
to count tokens around during the timed running of the benchmark.
Also cleans up a bug in some clamping code spotted while fixing this.
Assisted-by: Antigravity with Gemini
---------
Co-authored-by: Dana Jansens <danakj@orodu.net>
Adds a check for constrained facet types and extracts the type from the
constraints before supplying it for conversion to C++ types. Adds a test
for this functionality.
Now that we have a robust plan-based layer for generating function
definitions, we can use that when generating inline function definitions
rather than the very ad-hoc previous inline function definition
synthesis. This also requires switching some of the more ad-hoc
heuristics for governing the size of inline function definitions to more
robust histograms representing the desired distributions.
Some rough analysis of existing C++ code in Clang, Carbon, and LLVM
suggests that multi-statement inline function definitions and
out-of-line
definitions in implementation files have compatible distributions of
shape and statement kinds when their sizes overlap, and so we don't end
up needing to overly customize that part of the plan generation.
Getters, predicates, and forwarding functions continue to be separate
constructs from multi-statement function definitions. I looked at trying
to unify them, but that adds significantly more complexity. For now, the
plan-based synthesis is only used for definitions where we have >1
statements (happens to be >=3 because of the structure of these
definitions).
Assisted-by: Claude Code and Antigravity with Gemini
Fields have constraints on what types can be used distinct from other
uses. Previously, they shared a pool with inline function return types
when function definitions are included, the more general type pool used
for function declarations otherwise. However, fields have a unique
constraint: they cannot have the type currently being defined.
Sharing a type pool for both function returns and fields either
requires us to not use the last class in the pool (including in any
function returns), or it requires us to have a large number of function
returns inside the last class as every reference to that class can only
come from function returns inside the class. So we end up either with
an artificial constraint on return types, or being unable to have
a small number of functions per class. The latter is a pattern we want
to be able to use though, as it comes up frequently in implementation
files.
The other problem is that as we allow inline function definitions of
increasing complexity (similar to the out-of-line definitions from
plans in #7998), we end up needing different mechanisms for ensuring
return types (when class types) are spelled out a seed-independent
number of times compared to fields. Today, both inline return types
and field types are spelled out twice when class types. But inline
return types will need a more complex way of ensuring seed invariant
references once they use plan-based definitions as well.
This PR splits the shared pool into distinct pools, and does so
regardless of whether there are definitions being emitted. This in turn
allows us to simplify some things. We can omit the last class from the
pool entirely, and switch the pool to follow `declared_types_weight` in
fields. Previously it had deviated sharply from that weighting.
Assisted-by: Claude Code and Antigravity with Gemini
Previously, we only had the dense API declarations benchmark. This adds
a benchmark that aims to emulate what a realistic implementation file in
Carbon would look like, based on what `.cpp` files look like in Carbon,
Clang, and LLVM. It's still a little artificial in order to provide
stability, but it should give us coverage of compile time performance of
statements and function definitions at more realistic scales.
In order to generate more interesting and longer function definitions,
this introduces a plan-based approach to guide how each feature of a
definition is produced. Initially, it identifies these as roughly:
- local variables
- updates to variables
- `if`, `else`, `while` blocks
- "guard" statements -- conditions with a return, break, or continue
- read of a parameter
The plan also manages the nesting depth of these constructs.
Because the plan establishes how many of these constructs exist in a
function definition, and at what nesting depth, the emission can
randomize the order and arrangement without changing the size of the
function. This follows the pattern in all our benchmark source
generation of getting byte-identical stability while avoiding
predictable structures. Technically, I think the current approach goes a
bit too far because function definitions I suspect are somewhat
predictable in their structure in practice. But a conservative benchmark
I think is a good starting point. =]
The target distributions for definition sizes, maximum depths, and
statement mixes come from a very rough Claude-powered analysis of 10,697
function definitions in 533 Carbon toolchain, LLVM, and Clang
implementation files. These were analyzed and classified by Claude using
a one-off Python script and libclang. I haven't reviewed any of the
analysis carefully, the resulting distributions look plausible enough as
a starting point. Comparing real code against generated C++ from the
plans, each number per-definition average:
| statements | definitions | max depth | ifs | loops |
|------------|-------------|-------------|-------------|-------------|
| 7-9 | 10.9 / 11% | 1.25 / 1.23 | 1.74 / 1.86 | 0.23 / 0.15 |
| 14-19 | 7.3 / 7% | 1.89 / 1.88 | 3.53 / 3.71 | 0.61 / 0.42 |
| 28-39 | 3.3 / 3% | 2.76 / 2.75 | 7.75 / 8.46 | 1.26 / 1.27 |
| 60+ | 1.5 / 2% | 4.03 / 3.80 | 25.0 / 27.1 | 3.72 / 4.04 |
To maintain stability, every definition has an accumulator, a statement
reading its parameters, and a `return`, so real definitions of one to
three statements become three.
Note that updates are currently also used instead of calls to other
functions -- a later PR will switch those to calls so that we form more
plausible call graphs. In general, subsequent PRs will refine and expand
the plan to generate increasingly more realistic function definitions.
There are probably lots of improvements that could be made here, both to
generate higher quality definitions and to improve the generation logic
to be more efficient, etc. But already this has allowed _much_ more
extensive benchmarking of Carbon's compile-time performance so it seems
likely a reasonable increment.
Assisted-by: Claude Code and Antigravity with Gemini
---------
Co-authored-by: josh11b <15258583+josh11b@users.noreply.github.com>
A first step in expanding support for default values for parameters in
generic functions.
Adds code to parameter type deduction to include default values for
absent call arguments. In support of that, this PR also generalizes a
function from `export.cpp` that is useful to extract a default
`ConstantId` value from an arbitrary function paramater pattern.
`FindStorageArgForInitializerInSpecific` is missing a `SpecificConstant`
case, and crashes due to the function not expecting `SpecificConstant`.
`SpecificConstant` should be handled by this function, as it derives its
expression category from the instruction it wraps.
Consider this example:
```carbon
interface I {}
interface J {}
constraint C {
extend require impls I & J;
}
```
Calls, such as `I & J`, are initializing expressions. `extend require
impls` wraps the call in a `SpecificConstant`. This code crashes when
asking for its storage, such as during formatting for `--dump-sem-ir`.
This commit adds a case for `SpecificConstant`, deferring to its wrapped
instruction when transitive lookup is allowed, and reports no storage
otherwise.
Assisted-by: Antigravity with Claude Opus 5.5
Fixes#7802.
If a document-symbol or formatting request refers to an unknown Carbon
file, return an LSP `InvalidParams` error instead of leaving the client
waiting. This aligns both handlers with existing behavior for
position-based requests.
---------
Co-authored-by: kg290 <210736705+kg290@users.noreply.github.com>
The values in `IdentifiedFacetType` may contain `IdentifiedWitness`
instructions, and those insts need to be either converted to
`LookupImplWitness` and evaluated as such, or substituted by the user of
the `IdentifiedFacetType` with witnesses of its own.
This changes the API so that the user must go through a method doing one
of those two things to get to the underlying values in the
`IdentifiedFacetType`, unless they explcitly request to bypass them.
Then we split extend impls requirements out into their own set so that
the user can determine what is being extended _after_ evaluation or
substitution of `IdentifiedWitness` insts. This is critical because we
can not dedupe SpecificInterfaces until after that takes places, as
demonstrated by the test fixed by this PR.
Build on the plan-based emission to make function definitions cover a
more representative breadth of the language: class-typed local
variables, and local variables declared with destructuring. This
requires some complexity to initialize and manage the class type
variables, but ultimately should make all of our compile time benchmark
data more representative by covering a more realistic breadth of the
language surface.
Claude's rough sampling of Carbon, Clang, and LLVM source suggests class
types range from 30% to 80% of the locals, and structured bindings range
from 0.2% to 2%. When synthesizing, we target approximately 50% of
declarations as class types and 2% as destructurings as we anticipate
destructuring to be of growing popularity and so want to ensure we're
measuring any overhead there.
Assisted-by: Claude Code and Antigravity with Gemini
---------
Co-authored-by: Geoff Romer <gromer@google.com>
`IdentifiedFacetType` is a concept that is only used by check. It does
not appear in the semir output, unlike `DeclaredFacetType`s.
`IdentifiedFacetType` is used in check to collapse named constraints
together, building a single structure of requirements from a
`DeclaredFacetType` and any referenced named constraints. This is used
for operations like impl lookup, and building `FacetValue`s.
The outputs of `IdentifiedFacetType` are now in an intermediate state,
where they contain `IdentifiedWitness`es, and need to be processed
before they are used. We'd like to build that into the API of
`IdentifiedFacetType` so that their use is more robust. But the
`IdentifiedWitnesses` need to be replaced by subst, which is a part of
check, so we need to move `IdentifiedFacetType` to check in order to
build the type on top of subst.
Add support to the driver for CLI flags that select which CPU to target,
which CPU to tune performance for, and which CPU features to enable.
- `--target-cpu` selects the architecture of CPU to target, similar to
`-march` on x86. This combines `-march` with `armv*` strings and `-mcpu`
on Arm for specific CPU names. Similarly for RISC-V (if/when we support
and test it), etc. Notably, `--target-cpu=native` targets the current
native CPU.
- `--target-cpu-tune` maps to `-mtune`. This is expected to be rarely if
ever desirable, and I'm open to removing it, but if folks are relying on
this for performance I didn't want to hide the option.
- `--target-cpu-features` allows a "standard" (for LLVM) comma-separated
list of LLVM subtarget features, including `+feature` and `-feature`
syntax.
These flags, when provided, establish the default baseline for CPU
targeting and control how on-demand runtimes are built. They can be
changed or overridden by additional Clang flags when using
`--clang-arg`.
A critical part of this is building runtimes on demand using these
features. For that, we need to do some amount of canonicalization
(re-using Clang's canonicalization to ensure consistent behavior), and
extend the runtimes cache features to recognize these customizations.
Note that only the top-level Carbon flags impact runtimes, any
particular Clang arguments are only used by the specific compiles that
receive those arguments.
There is some nascent RISC-V support here, but it is incomplete and only
minimally tested. Still, it seemed better to record the parts we could
test than remove them.
Assisted-by: Antigravity with Gemini
- Resolve Specifics eagerly during evaluation. Previous import changes
have made deferral unnecessary. This simplifies the code and unblocks
the next item.
- Overload `GetConstantValue` for all ID kinds, rather than having a
separate `GetConstantValueOrPassThrough` function, so that callers don't
have to choose between them.
---------
Co-authored-by: Dana Jansens <danakj@orodu.net>
Update tests for observe equivalence chains to cover more cases and to
better test the things they meant to. The design is clarified to explain
that in an `interface` the types in an equivalence chain must all be
related to that interface except for one.
This is based on #7484 with some followup changes by me.
Co-authored by: ozguronsoy@gmail.com
We were explicitly marking the specifics of `require` decls as
`identified` when creating them during identify. But the require may
contain calls to other generics internally. And forming the specific for
the `require` can also form new specifics for those calls, if they
depend on `Self`. The resulting specific can have `IdentifiedWitness`
instructions in its arguments, in accesses or FacetValues, etc. Or they
may appear in the decl block as it's resolved. So it's very important
that the specifics be marked `identified`, as those witnesses may only
appear in `identified` specifics. This allows the new
`access_through_nested_specific_in_named_constraint.carbon` test to
succeed without any poisoning errors.
SemIR formatting is changed so that `identified` specifics are more
clearly differentiated where they are used, so that we can see if
`identified` specifics are misused outside of identifying.
Now that we construct more `identified` specifics, we also need to
ensure we remove the `identified` state from specifics that come out of
`EvaluateIdentifiedWitnesses` and `SubstIdentifiedWitnesses`. To do that
we add a new callback method on `SubstInstCallbacks` that we use to
build specifics during subst. Then during those operations, we drop the
`identified` flag from any specific that we form, because we know that
we have also removed any `IdentifiedWitness` instructions because:
- We replace them all from arguments during subst.
- We CHECK that we're not in the middle of identifying before starting
the subst.
However now an `IdentifiedFacetType` is not fully deduped, because it
may contain a non-identified specific that comes from a
`DeclaredFacetType` along with an identified specific that comes from a
named constraint, where they have the same arguments. That results in
the `IdentifiedFacetType` having two specific interfaces when it really
only refers to one. The
`fail_todo_impl_as_constraint_duplicates_interface.carbon` test
demonstrates this, and that we then diagnose an `impl` as invalid since
we find more than one specific interface being extended. To fix this we
need to dedupe and count specific interfaces _after_
substituting/evaluating away the IdentifiedWitnesses. This is left to
future work.
This allows a generic class to inherit from a virtual C++ class as long
as the subclass doesn't override any methods. See
toolchain/lower/testdata/interop/cpp/class/import/inherit.carbon for a
working example.
The TODO in `CheckCompleteClassType` is now in
`CarbonExternalASTSource::CompleteType`, and only triggers if virtual
function thunks need to be defined.
A fix in `FileContext::BuildVtable` is also needed: when looking up the
clang decl associated with the vtable, if the class is generic then the
`ClassTemplateSpecializationDecl` associated with the specific is
needed. This required adding `ConstantStore::Get`, since only `const`
access is allowed during lowering.
Adds code to track default values for function parameters in C++ export,
and to export them as global variables to C++ that are attached to
default value expressions in the clang AST.
Modifes lower to export global variables from another block, and adds
the variable initialization to the `global_init` block so their value
gets set at load time.
When building an impl witness thunk for a generic associated function,
trailing self-specific arguments could still mention outer interface
parameters (or `Self`) in their types. That left a SymbolicBinding that
did not belong to the thunk's generic, and evaluation aborted instead of
succeeding.
Substitute the outer specific arguments into those trailing arguments
with `SubstConstant` before adjusting bind indices.
Fixes#7919.
This fixes an error that would happen when opening neovim in a
non-git-controlled directory, where `root` is `nil` and therefore one
cannot `..` it as a string.
When checking `a[i]` for a non-array type, first try
`IndirectIndexWith.Ref`, falling back to `IndexWith.At`, per the
indexing design. This allows subscripting to produce a reference
expression, so that `a[i] = v` works and non-copyable elements can be
accessed.
Extracted from #7536 (the `Core.Slice` proposal).
Treat the function as having a `-> auto` return type. Reject calls to
functions that still have a non-deduced `-> auto` return type, and
rewrite the function to have the actual return type once it is known.
Assisted-by: Gemini via Antigravity
Split the `Carbon::` namespace into one semantic namespace tree, plus
one separate lookup-only namespace tree per Carbon file. Use the
semantic namespaces as the parents of entities, but use the lookup-only
namespaces when C++ name lookup names a Carbon namespace, in order to
use a different C++ name lookup table in each Carbon file.
Assisted-by: Gemini via Antigravity
When a deduced return type depends on the function's generic parameters,
it's computed by the definition's eval block, so resolve the specific's
definition at the call. Calling a specific during its own instantiation,
before the point where its return type is deduced, is diagnosed like any
other use of the function before its return type is known. Also allow
exporting such functions to C++.
Resolving such a specific from within a checked generic can perform
template actions with symbolic arguments. Perform delayed actions in a
discarded generic region so the instructions they create aren't attached
to the generic being checked, and check that evaluating a specific
doesn't add anything to an enclosing generic region.
Assisted-by: Claude via Antigravity
Matching the API as described in the update in #5434, with a `Ref`
rather than `Addr` function (and `ref` rather than pointer return form).
Also added a blanket `final` impl of `IndexWith` when the element type
impls `Copy` (since `IndexWith` requires copyable elements) - which
differs slightly from the design wording, which doesn't account for the
copyability requirement.
Proposal #5389 (in review) would rework these interfaces, but this
should do for now until that's finalized.
Tested using the interface directly - follow-up change will add the
subscript support to check.
Extracted from #7536 (the `Core.Slice` proposal).
Address some review comments from the review of PR#7935 on the changes
from PR#7933.
Consolidate `const_cast`s to a single place with an explanatory comment.
Improve test clarity and organization. Rename lookup-specific helper
function to avoid suggesting it is more broadly applicable.