### Description
When looking up default initializers for class elements in
`ConvertStructToClass`, the compiler previously assumed that every
member looked up from the class scope was a `FieldDecl` and called
`GetAs<SemIR::FieldDecl>` directly.
For a derived class with a base class, looking up `base` returns a
`BaseDecl`, which caused a `CHECK` assertion failure when casting to
`FieldDecl`. Use `TryGetAs<SemIR::FieldDecl>` instead so non-`FieldDecl`
entries like `BaseDecl` are recognized as having no default initializer,
cleanly diagnosing that the `base` field is missing.
Fixes#7722
Assisted-by: Google Deepmind Antigravity
The StringRef represents a bounded region of a string, but using data()
drops the end bound, and makes LLVM construct a new StringRef starting
in the same position and going until a nul terminator. If this worked
correctly before, it was because the StringRef was always pointing to a
full `std::string` or the tail of one.
Avoid CHECK failure when performing member access on a runtime type
value. We will just fail to find the CanonicalFacetOrTypeValue and then
fail lookup.
A check for `args.verbose` was missing for one line of autoupdate's
verbose output. Add a wrapper function to print verbose output to fix
this and to make it easier to get verbose output right in future.
This prevents different template instantiations from getting
over-eagerly merged. Unfortunately we don't have a good middle-ground
yet, and this effectively disables all merging for templates. We may be
able to find some smart way to fingerprint spliced instructions so that
we can still merge template instantiations, but for now this change is
just fixing the wrong-code bug.
Test passing a template argument or a symbolic argument to a template.
Fix a bug in the template case where we'd crash when instantiating a
dependent discarded expression, because conversion produced an
`InstId::None` which the actions machinery did not expect and crashed
on.
Updates the pattern matching code to support unspecified default values.
Adds logic to decl and def merge code to diagnose mismatches in defaults
if specified in both places, or if let entirely unspecified.
Per https://github.com/carbon-language/carbon-lang/pull/7521.
Add basic support for lowering templates: we can now lower `SpliceInst`
in the case where the generic and specific are from the same file (and
we don't support importing templates from other files yet in general).
In order for this to work, lowering needs to be able to query the
expression category, and to handle instructions that appear to be
(template) constants in the generic but turn out to be non-constant in
the specific, so support for that is added.
Switch `type_of_inst` from being added as an action inst to being added
as a normal inst, since it's not an action and the old approach led to a
crash in lowering.
SemIR::FacetValue lowers to context.GetTypeAsValue(), which produces a
constant of LLVM type %type (context.GetTypeType()). However,
SemIR::FacetType previously fell back to an anonymous empty struct {},
causing an argument type mismatch assertion failure when passing a
FacetValue to a function expecting a FacetType parameter.
Identified by @danakj in #7731
Assisted-by: Antigravity with Gemini
### Description
When lowering symbols (functions, global variables, and vtables), a new
`SemIR::Mangler` was being created on each call. Each `Mangler` creates
its own `InstFingerprinter` with a fresh store, preventing any
fingerprint computations from being reused across manglings.
This PR caches a single `SemIR::Mangler` instance in `FileContext` so
that the underlying fingerprint cache is preserved and reused across all
symbol manglings within the file.
Assisted-by: Google Deepmind Antigravity
Makes following changes to Carbon::Format()
- TokenKind::Period (i.e. `.`) should never have a space before or after
it.
- TokenKind::CloseSquareParen (i.e. `]`) should be treated as packed
content (no space preceeding it)
- Only exception I can think of is `impl forall [...]`
- Remove preceeding space from `[` and `(` if previous token was an
identifier (or identifier-ish token)
- Remove seperator following `++` / `--` unary operators.
- Explicit gaps in source code should be retained, up to 2 new lines.
Multiple test files were added to test formatting.
I imagine eventually this will need to be updated to read parse tree to
gather more context but this atleast lets us get a decent-ish format for
many of our current sample files (e.g. sieve.carbon)
Assisted-With: Gemini / Antigravity
---------
Co-authored-by: David Blaikie <dblaikie@gmail.com>
Replace `refine_type_action` with `refine_inst_action`, and generate a
`specific_inst` instead of an `as_compatible` to represent the specific
version of an instruction that's used as an input to a template action.
This gives us a place to handle other properties of the instruction that
might vary from generic to specific beyond its type, such as its
constant value and its expression category.
For now, we provide a non-template-dependent constant value to the
`specific_inst` in addition to the non-template-dependent type we have
traditionally provided. This doesn't seem to matter for any current
actions, but sets us up to better handle future actions. The
`specific_inst` representation also allows downstream consumers of the
instruction to track which specific they should be requesting
information from. Providing a correct expression category for
`specific_inst` will be handled in a future PR.
Adds a virtual node to `DefaultValuePattern` to end the
`ExprRegionForPattern` before checking the expression
for the default value.
When checking the default value expression, the context
was still configured to interpret expressions as patterns,
which caused some corruption of state with tuple-pattern
subpatterns.
Corrects an assertion failure I found while working on
feedback from #7665.
`TemplateInst` wraps another inst. If that inst is symbolic, it is
treated as a template by `OperandDependence`.
Use this to replace `CallCppTemplateAction` with the more general
`CallAction`.
Don't wait until we reach the end of the eval block to set the value
block on the specific. This is a prerequisite for allowing template
actions to read from the specific.
Also add a default for `EqWith.NotEqual`.
Switch advent examples to use these named constraints, and also go
through all the other TODOs in the advent examples and fix the ones that
are trivially fixable now.
Two somewhat related fixes. The first is call-specific for now (because
it's the first action to take a `MetaInstId`), and the second is general
across all actions, but it seems like calls are the easiest place to hit
it.
1) Add support for refining inst blocks as action operands. Refine all
the insts in the block, using the appropriate InstId-derived type.
2) When an action operand is a `MetaInstId` referring to an unattached
constant, form a corresponding attached constant. This comes up when
forming (for example) an implicit `AddWith(%T)` call, where the `%T`
operand is an unattached constant.
This causes us to form correct specifics in more cases, where previously
we formed specifics that contained values that were still
template-dependent.
This unfortunately causes some existing template tests to produce more
errors, but those errors reflect cases where we were previously silently
doing the wrong thing.
`GetCallee` is sometimes called on a spliced instruction, and is
checking its exact inst operand to see if it's a `BoundMethod`. This
fails if the `BoundMethod` is wrapped in another instruction, such as a
splice. Normally our approach for such a situation would be to
constant-evaluate the operand, but that doesn't work here because the
`BoundMethod` will be non-constant if its bound `self` is. So instead we
now step through splice instructions manually when looking for the
`BoundMethod`.
Use a version of Brent's algorithm, suitably adapted to work for our
worklist-based graph traversal, to very cheaply detect if instruction
fingerprinting fell into a cycle and terminate cleanly with a dump of
the cycle.
The algorithm does not immediately catch when we enter a cycle, but is
guaranteed to catch it eventually (generally after running through the
cycle no more than twice).
Adds check functionality to transform the parse node to SemIR. Only
supported for single declarations of functions, re-declaration and
imports to come in a subsequent PR.
Per #7521.
Adds parsing support only for default value expressions in pattern
lists, including leaving the default value unspecified with an
underscore `_`.
Per #7521.
With this set, autoupdate will print messages indicating what it's
doing, such as the command that it's invoking to execute bazel. For
example:
```console
$ ./toolchain/autoupdate_testdata.py -v toolchain/check/testdata/basics/empty.carbon
Detected --compilation_mode: fastbuild
/home/zygoloid/carbon-lang/scripts/run_bazel.py run -c fastbuild --experimental_convenience_symlinks=ignore --ui_event_filters=-info,-stdout,-stderr,-finish //toolchain/testing:file_test -- --autoupdate --print_slowest_tests 0 --file_tests=toolchain/check/testdata/basics/empty.carbon
[... normal output ...]
```
Implements formatting support within LSP. Current implementation
performs while file formatting, we just replace file with output of
Carbon::Format()
https://github.com/carbon-language/carbon-lang/pull/7687 independently
improves formatting so that this output is somewhat decent.
Assisted-With: Gemini / Antigravity
Calls with template callee or args can now be deferred via an
InstAction. This allows code like this to check:
```carbon
import Cpp inline '''
template<typename T>
struct C {};
''';
fn F(generic T: type) {
let unused c: Cpp.C(T) = Cpp.C(T).C();
}
```
This should handle over-long lines. I had tried to make the normalize
method work, but it doesn't seem promising and so let's at least enable
this version.
Assisted-by: Antigravity with Gemini
Follow the pattern used by eval_inst.h's `EvalConstantInst` to generate
declarations of an overload set that handles some but not all typed inst
classes. The pattern is:
* A template computes the signature to use for a particular overload,
producing a fallback `() -> void` signature for overloads that should
not exist.
* The `.def` file is used to generate a declaration per instruction
kind, whose signature is generated by the template.
* The `() -> void` signature that all the "should not exist" cases
generate is explicitly deleted.
This avoids the redundancy of manually declaring all the overloads, as
we did for `PerformAction`, and is less error-prone as it both catches
signature errors and definitions of overloads that are dead code and
should not exist, as it did for the `FacetAccessType` overload of
`LowerInst`.
- Move formatted printing to `hashing.cpp` instead of `hashing.h`
- Separate APInt and APFloat hashing specializations into a new
`hashing_llvm.h`
- Update toolchain/base dependencies and include sites that hash LLVM
data types to include `hashing_llvm.h`
Combined, this reduces the transitive includes caused by `hashing.h`.
Assisted-by: Antigravity with Gemini
We track a "next" index into each bucket when we insert instructions.
The insert loop effectively shifts each element in the "next" vector
left by one place, so if we instead start the bucket counts shifted one
place to the right, we can use the same vector for "next" and for the
bucket start indexes.
Assisted-by: Claude Code
---------
Co-authored-by: Geoff Romer <gromer@google.com>
This allows generated functions to have different forms for different
parameters, and by-ref or by-value return forms. As a byproduct, this
allows generated functions to supply a return type _inst_ ID when they
have one, which preserves things like location information.
Example:
```carbon
import Cpp library "<vector>";
class C(T: type) {
var v: Cpp.std.vector(T);
}
inline Cpp '''
void F() {
Carbon::C<int> c;
c.v.push_back(123);
std::cout << c.v.back() << std::endl;
}
''';
```
A new `CallCppTemplateAction` is used to delay performing the C++
template call until non-symbolic arguments are known.
We previously passed in the start of file token, classified as
BracketTokenKind::Other, which allowed the bracket fixer to consider
corrections where it inserted tokens (such as a `{`) *before* the
start-of-file token.
Fixes#7672.
Treat `InstConstantKind::InstAction` the same as
`InstConstantKind::ConstInstAction`. Drop `ConstInstAction`, since the
two now behave the same.
Fix eval for specifics in a couple places to handle `InstId::None`.
`-Wunused-template` was added to `-Wunused`, so clean up the things it
found. One of them was a bug in the Clang warning that I've worked
around and reported upstream:
https://github.com/llvm/llvm-project/issues/218429