The images beside the samples were screenshots taken by hand, so they
drifted: they still showed `package Carbon api;`, syntax the language
dropped in 2024.
`render_sample.py` renders a sample the way the grammar in this
repository actually highlights it, using `tmlanguage.py`, a small
TextMate tokenizer. VS Code runs grammars under Oniguruma, which we
cannot depend on here, but this grammar uses no Oniguruma-only syntax,
so `re` runs its regexes unchanged and the two agree on every character
of every Carbon file in the repository. The output is SVG, so
regenerating needs nothing but Python, and a later grammar change gets a
same-path image diff showing what it did to real code.
The samples change where a construct left the language (`api`, `Carbon`
as the package name, `StringView`, `destructor`), refresh the
`keywords.carbon` inventory against `token_kind.def`, and add sections
for octal, raw and block literals, character literals, lambdas, and raw
identifiers. `interop.carbon` is new, covering inline C++. These are
highlighting fixtures rather than programs, so the deliberately invalid
lines stay.
Assisted-by: Claude Code
---------
Co-authored-by: Dana Jansens <danakj@orodu.net>
Use a single `SemIR::Function` per `Core` interface method, whether it's
generated locally or imported. This prevents generating duplicate
functions, which lead to different types when the witness appears in a
`FacetValue` as part of a specific for a class.
We use a `CanonicalValueStore` of `GeneratedFunction` objects that allow
finding an existing FunctionId for a `Generated` special function before
(re-)generating it. Mangling for `Generated` functions is also moved to
use the values from the `GeneratedFunction`'s canonicalization key, so
that we have a consistent source of truth for the unique ID of a
`Generated` function across all files.
New tests are in
`toolchain/check/testdata/impl/custom_witness/destroy.carbon`.
Update the rules for member access:
- Simple member access `a.b`
- If `a` names a scope, performs name lookup and optionally `impl`
lookup.
- Otherwise, `a.b` is shorthand for `a.(typeof(a).b)` and always
performs instance binding.
- Compound member access `a.(m)` does optional `impl` lookup and always
performs instance binding.
- This is a change from only performing instance binding if `m` is an
instance member.
- New operation `a.impl(m)` is introduced. It always performs `impl`
lookup, and nothing else.
- The `BindToType` interface is removed. Only instance binding may be
customized (using the `BindToValue` and `BindToRef` interfaces).
As a result, member access doesn't use whether the right operand is an
instance member anymore. Instead, instance binding is performed whenever
it would be plausible, and a new syntax is used to opt out.
Assisted-by: Gemini via Antigravity
---------
Co-authored-by: Josh L <josh11b@users.noreply.github.com>
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Some `google-` prefixed rules have been renamed to rules without the
prefix. The `google-` prefix still remains as an alias to these new
rules. Since we turn on the `google-` prefix rules and use those in
NOLINT expressions, disable the new aliased names. Otherwise we have to
put both names in NOLINT expressions.
This is a style choice we often agree with, and call out in code review.
But there are many cases where we do want to split apart nested ifs,
such as when working with LLVM apis like `dyn_cast`:
```
if (auto* thing = dyn_cast<Thing>(other)) {
if (thing->foo()) {
...
}
}
```
Or we may have TODOs or other comments in the scope of the outer if,
which the tidy check ignores.
Since this doesn't lead to bugs, we disable the check and leave this to
reviews and authors for their discretion.
The diagnostics documentation covers how a diagnostic is produced and
worded, not the form it takes on a terminal. This adds
`toolchain/docs/diagnostics_rendering.md`: what a diagnostic is made
of, its layout, color, character set, and width, and how each degrades
when the terminal can't render it.
A diagnostic is one message plus labels read against the code they
mark, `Primary` or `Info`; a context and a path are set out apart. It
renders as one frame, anchored per file, with no headline: the message
hangs off the range that is wrong, led by the level word on a heavy
mark, with `->` in the margin on the reported lines. Labels read in
the order of their ranges, connectors that cross earlier rows break
around them, and a path draws only for the message's own location.
Ten rows on the shared example, against Clang's six and rustc's eleven.
Nothing a diagnostic says is dropped for width: source is windowed,
words wrap past the level word, connectors slide, and a label that
still can't hang is out-dented. Under sixty columns the compact form
takes over, one located line per part. Color is named per element with
a ramp per level and a light-background palette; ASCII keeps every
distinction with `^`, `.`, and the level word. The `file:line:column:`
header is the road not taken: structure comes from the language
server, and the compact form covers a grep-able line.
Assisted-by: Claude Code
---------
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
Instead of running on the "current" `@` (the state at which the previous
`jj` command happened to be run), intentionally trigger a working copy
snapshot from `jj_prek`.
Assisted-by: Claude Opus 5 via Antigravity
The hashing code is generic over the type of the value being given to
sizeof() so ideally this warning would not happen at all, but it does.
Possibly because the value is the return of an overload set, so it's not
obvious that it's the templated type. One of those overloads returns
`const void*` but change that to an integer does not remove the warning
still.
Clang is synthesizing a cast when using an enum value from a template
parameter, and then clang-tidy is finding and reporting that cast.
Upstream bug: https://github.com/llvm/llvm-project/issues/222793
clang-tidy 24 warns on C-style variadics, and we don't need to use one
here anymore. Instead of a function call with an argument list, use a
concept to determine if a type can be list initialized.
This check allows styles that we don't use so it's not really useful for
enforcing our style guide. And prevents the use of `_1` or similar in
destructuring declarations where want to use `_` for multiple variables,
such as `auto [_1, _2, foo] = bar()`.
The warning wants all classes inherited as CRTP base classes to hide all
their constrcuctors and friend all uses of them. We use CRTP quite a lot
and across different components of the toolchain, which would make
maintaining friend lists frustrating.
### 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.
While we do adhere to its expectations most of the time, we don't
always. This is a low value check, and it's a stylistic choice to use
`#if defined(...)` when paired with `#elif defined(...)`.
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.
We use multiple inheritance extensively, such as with our
EntityWithParamsBase subclasses. But we don't do this for
vtables/virtual, we do it for composing fields.