Commit Graph
23 Commits
Author SHA1 Message Date
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 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
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
Chandler Carruth 08669493b5 Add a config subcommand for exposing build system info (#6637)
This makes it easy to wire up build systems like Bazel that need to know
the actual include paths used. It also gives us a convenient place to
export any other information that build systems or integrations need,
and to get debugging info from users.

Most of the complexity is computing the Clang header search paths, but
I couldn't see a direct way to get closer to the source-of-truth than
this, and it doesn't seem _too_ unreasonable.

Depends on #6636 - start review at commit
[643fdab1](6637/commits/643fdab1)
2026-01-21 21:28:22 +00:00
Geoff Romer 4821eec2f8 Add support for ref patterns (#6283)
Support for `bound`, and for the `ref` tag on arguments, is left as
future work.
2025-10-29 16:28:56 +00:00
d49cb3ecfb Start building Clang runtimes on-demand (#5338)
This is the first step to having Clang's runtime libraries fully
available for the Carbon toolchain. This PR focuses on the lowest level
runtimes, the CRT files and the builtins library.

The goal is to intercept Clang runs where it needs these
target-dependent pieces to be available, and build them on demand using
our Clang-running infrastructure. This avoids most of the subprocess
overhead, but there is still some due to missing features in Clang.

This requires exporting the sources for these runtimes from the Bazel
build, and installing them in our target-independent resource directory.
We then build a simplified "build" of these sources within the
`ClangRunner` itself to produce the specific artifacts and layout
expected by Clang.

It also required fixing our use of Clang on macOS to have a default
system root in order to successfully compile or link.

It also required cleaning up how the `ClangRunner` used target
information more generally -- instead of taking the target as
a constructor parameter, it manages its target internally and relies on
the Clang target-specifying command line flags.

I looked at whether we could split this into another layer separate from
the `ClangRunner`, but that proved frustratingly difficult to manage.
While we support building these on-demand as part of a detected link,
that doesn't seem feasible as we don't have the necessary separation
between compilation runs of Clang and link runs of Clang. However,
I have tried to factor the internals to provide as clear of separation
as I could across these.

I have also created a stand-alone subcommand to directly build the
runtimes which allows for easy testing. It also supports building them
into a specific directory, and that directory can in turn be passed to
a Clang invocation. This is designed to work both at the API level with
`ClangRunner` and at the subcommand level.

Currently, the only part of the commandline that is detected and
forwarded to the runtimes build is the target. Eventually, the plan is
to expand this so that we can build a maximally tailored set of runtimes
for a given compilation.

The other big TODO here is to actually implement caching storage of
these runtimes so they aren't built on every execution. Right now, this
uses a somewhat hack-y build of a temporary directory, but this isn't
expected to be suitable long-term. Building these runtimes on *every*
link makes those commands take approximately 15 seconds with an ASan
build like our default development build, and just over 2 seconds in an
optimized build. Because of this, I've kept all of this disabled by
default for now. The goal is that once caching and some other
improvements land, we can enable this by default.

---------

Co-authored-by: Jon Ross-Perkins <jperkins@google.com>
Co-authored-by: Richard Smith <richard@metafoo.co.uk>
2025-08-22 03:05:21 +00:00
Richard Smith 25681901bd Improve mapping of Clang diagnostics into Carbon diagnostics (#5894)
Instead of taking the complete text of the Clang diagnostic and using it
as the message portion of a Carbon diagnostic, generate the individual
pieces separately and pass them into the Carbon diagnostic
infrastructure.

* Clang's context lines are generated by running a custom "diagnostic
renderer" and tracking which lines it wants to print as context for a
given source location. When mapping from a C++ source location back to a
Carbon location, the Carbon `Loc` structure is now fully populated,
including filling in the context line and the column number.
* Clang's snippet is generated by running a custom diagnostic renderer
that is a cut-down version of the full text diagnostic renderer that
only prints a snippet. This is then attached to the Carbon diagnostic
manually as an override for the snippet we'd usually create.

We no longer repeat the file location twice on each diagnostic, and no
longer produce a bogus "in import" line for all locations coming from
clang that point arbitrarily to the first C++ import in the Carbon file.
The `[diagnostic kind]` marker is now displayed at the end of the
diagnostic message, not on a line of its own after the snippet.
2025-08-01 01:24:31 +00:00
Jon Ross-Perkins d599023c19 Change CodeGen to use a diagnostic consumer (#5847)
We've been trying to have errors/warnings all go through the diagnostics
consumers instead of straight to stderr.
2025-07-24 21:44:44 +00:00
Richard SmithandChandler Carruth 553dd6e531 Build the clang::CompilerInvocation in the driver. (#5784)
Add driver flags to specify clang driver arguments.

---------

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2025-07-18 16:30:47 +00:00
Richard SmithandChandler Carruth 3776e464e0 Properly set up C++ include paths and similar environment settings when parsing imported C++. (#5767)
Stop using the clang tooling library to build an ASTUnit; that library
is set up to process clang frontend arguments, assuming that something
has already built frontend arguments from the compiler arguments. It is
also too encapsulated and doesn't let us inspect and modify the compiler
invocation before it's executed.

Instead, build the AST unit directly in two phases:

* FIrst, take a list of clang driver arguments and convert them into a
list of compiler arguments, using `clang::createInvocation`. Internally,
this uses the clang driver to build a frontend invocation, including
building system-specific include paths as needed.
* Then, directly build an ASTUnit from this compiler invocation.

I've factored this so that we can split out the `createInvocation` step,
with the intention that we may want to move it out of check and into the
carbon driver with the rest of the driver-level argument handling, and
we may want to customize some of the clang options before we invoke the
clang frontend with that set of options.

In order to make the invocation reusable, it no longer depends on the
name of the carbon file importing the C++ code. In place of synthesizing
a header file name as `<foo.carbon>.generated.cpp_imports.h`, we now
insert line marker directives into the generated header so that errors
in that header cause Clang to point a diagnostic back at the Carbon
source file itself. This results in a minor improvement in the
diagnostic output: we no longer refer to a nonexistent generated file.
But the snippet still contains text that doesn't match the source code,
so it remains imperfect.

---------

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2025-07-09 03:09:43 +00:00
Richard SmithandGeoff Romer 80529aaef9 Convert the scrutinee of a binding pattern to the right category. (#5662)
When the binding pattern appears within a `var` pattern, convert to a
reference. Otherwise, convert to a value.

This gets the advent of code examples to produce the right answers again
:)

---------

Co-authored-by: Geoff Romer <gromer@google.com>
2025-06-17 16:45:19 +00:00
Boaz Brickner ec97ec9664 Use InImport pointing to C++ imports in ConvertLocInFile() instead of adding a separate InCppImport when emitting (#5614)
I believe we will need to eventually add the specific C++ import
information in `LocId`.

This also seems to fix the `LanguageServerDiagnosticInWrongFile` issue
(#5604).

We're still not in the state we want to be according to
https://github.com/carbon-language/carbon-lang/pull/5246#issuecomment-2784301206.
Will look into removing the location part from the `"In file included
from ..."` line.

Part of #5245.
2025-06-10 09:02:45 +00:00
Jon Ross-Perkins 20c20595ba Fix language-server crash with cpp_ast (#5604)
Removes the nullptr default for safety.

Note, I think cpp support doesn't allow things like `<version>` or
inline code yet, and language-server support doesn't allow non-hermetic
files, so the best I can test is an error.
2025-06-03 22:09:51 +00:00
Jon Ross-Perkins acbe6530c3 Move diagnostics into a namespace (#5173)
What this really does is avoids shadowing names, so that we can
comfortable have things like `Check::DiagnosticEmitter` or
`Check::DiagnosticLoc` without shadowing being a concern.

Note, down this path I'm also thinking about:

- Renaming misc DiagnosticConsumer/DiagnosticEmitter classes, possibly
just to DiagnosticConsumer/DiagnosticEmitter (so
`Check::DiagnosticEmitter` instead of `SemIRLocDiagnosticEmitter`).
- Dropping `Diagnostic` from `Emitter::DiagnosticBuilder`.
- But not for `Check::DiagnosticBuilder`, because `Check::Builder` would
be ambiguous.
- Renaming diagnostics/diagnostic_* to drop "diagnostic".

[Discussion about SemIRLoc ->
DiagnosticLoc](https://discord.com/channels/655572317891461132/655578254970716160/1353771570463768698)
reminded me of this (in particular the older [Check::DiagnosticBuilder
discussion](https://discord.com/channels/655572317891461132/655578254970716160/1344363562608627763)),
but I'd only do that rename if there's matching consensus about a path
forward where we keep SemIRLoc, and in a way that it's only ever used
for diagnostics (the divergence from which is at the root of current
LocId discussion).

I'm trying to keep that separate from a namespace addition for clarity.
2025-03-26 19:12:10 +00:00
Jon Ross-PerkinsandDana Jansens 467e510d40 Document abbreviation style things (#4996)
We had a long discussion of this, so trying to document what seems to be
the conclusion... and also clean up the exceptions that I could find.

---------

Co-authored-by: Dana Jansens <danakj@orodu.net>
2025-02-27 02:13:17 +00:00
Jon Ross-Perkins f89985d0f4 Add support for publishDiagnostics (#4912)
<img width="536" alt="Screenshot 2025-02-06 at 3 02 18 PM"
src="https://github.com/user-attachments/assets/27b7673d-f8d4-4f9f-9e5d-20c3a88b8c78"
/>

Requires the caching work in #4897
2025-02-07 23:04:35 +00:00
Jon Ross-PerkinsandChandler Carruth 7befe2ce9f Switch custom error stream output to diagnostic (#4846)
This switches most error printing to use diagnostics instead of direct
stream writes, even when not a specific file diagnostic. I'm allowing
empty filenames for this use-case.

This allows a little more specific testing to validate coverage of
output using the diagnostic coverage test. I'm adding a few tests to
cover things that weren't previously tested.

Separately, this also forces a little more standardization in format...
considering how changes like #4568 show effort being spent to _mirror_
diagnostic style, my thought is now to just use diagnostic code where
possible.

Note this also allows incrementally better testing of the language
server; I'm changing the crash fix from #4847 in favor of diagnostic
testing.

---------

Co-authored-by: Chandler Carruth <chandlerc@gmail.com>
2025-01-30 01:58:07 +00:00
Boaz Brickner 5b70a3ea91 Generate AST when importing a cpp file (#4790)
Ignore the AST and support a single Cpp import, for now.
Report cpp compilation errors and warnings.
Part of #4666
2025-01-14 20:45:50 +00:00
Richard Smith bc395eb889 Represent integer literals as IntLiteral not as i32. (#4532)
When an `IntLiteral` appears as an operand of an `if` expression,
convert it to `i32` for now, so that we don't reject things like `if
cond then 1 else 2` due to having a non-constant value of type
`IntLiteral`.

For tuple indexing expressions such as `(a, b).0`, convert the index to
type `IntLiteral`, not to type `i32`. This isn't strictly necessary to
do in this PR, but avoids the need to provide an `IntLiteral` -> `i32`
implicit conversion for `no_prelude` tests using this syntax.
2024-11-15 23:24:15 +00:00
Jon Ross-Perkins fa95892a37 Add diagnostic coverage, remove possibly-unreachable unary op diagnostic (#4519)
I'm working to make sure remaining diagnostics have coverage, at least
the ones I'd previously added a TODO for. Note in particular that I
couldn't figure out a repro for UnaryOperatorRequiresWhitespace; if you
have one, I can add a test, but otherwise maybe it's actually
unreachable due to being diagnosed through infix logic (or, maybe
this'll let fuzzing tell me an example).
2024-11-13 18:04:25 +00:00
josh11bandJosh L bbeb66b5fe Test class with multiple extend (#4504)
Adds coverage for an existing diagnostic. Code appears to work without
modification.

---------

Co-authored-by: Josh L <josh11b@users.noreply.github.com>
2024-11-08 16:29:53 +00:00
josh11bandJosh L 534100e87b Add test coverage for ImplOfUndefinedInterface diagnostic (#4484)
Co-authored-by: Josh L <josh11b@users.noreply.github.com>
2024-11-05 16:31:32 +00:00
Jon Ross-Perkins e58ce3e1bb Add coverage testing for parse node kinds. (#4436)
This refactors the diagnostic kind coverage check into something that
also works for node kinds. Then, since this points out a few node kinds
that aren't having their parse verified, I'm adding minor tests for
those.
2024-10-23 18:16:32 +00:00