mirror of
https://github.com/carbon-language/carbon-lang.git
synced 2026-11-15 20:48:11 +00:00
Render diagnostics through the terminal library (#7683)
Diagnostic rendering was part of the data model: `Loc::FormatLocation` and `Loc::FormatSnippet` wrote plain text to a stream, so no capability, color, or terminal width could reach them. A diagnostic is now one message with labels, contexts, and location information attached, and `Diagnostics::Renderer` draws it into a `Terminal::Buffer`. The design is in `toolchain/docs/diagnostics_rendering.md` (#7668), authoring in `toolchain/docs/diagnostics.md`. Before: ``` example.carbon:6:3: error: 1 argument passed to function expecting 0 arguments Run0(1); ^~~~~~~ example.carbon:3:1: note: calling function declared here fn Run0() {} ^~~~~~~~~~~ ``` After: ``` error: 1 argument passed to function expecting 0 arguments ╭─┤ example.carbon:6:3 ┆ 3 │ fn Run0() {} · ─────┬───── · ╰──┤ calling function declared here ┆ -> 6 │ Run0(1); · ─────── ╰──────────── ``` `--no-diagnostic-snippets` gives a compact form, `example.carbon:6:3-9`. File tests use it; the rendering tests under `toolchain/diagnostics/testdata` ask for snippets. C++ interop diagnostics are data now rather than text Clang drew: `SemIR::ClangSourceLocId` names a `clang::SourceRange`, and a Clang location is marked as the point it names. `StreamConsumer` moves to a `:renderer` target that `:emitter` does not depend on, keeping `common/terminal` out of `consumer.h`. Capabilities come from the file behind the error stream, so tests get plain ASCII. `renderer_fuzzer` draws diagnostics built from fuzzer bytes with every capability combination, since a shape the renderer doesn't expect must never be why the compiler dies while reporting a problem. TODOs mark the follow-ups: line weights and crossing lines, wrapping that keeps a quoted type whole, and ordering diagnostics that share a byte offset. Also: `IncorrectExtension`'s hint moves into its message, since its note had no location of its own, and `strip_noise` in `check_diagnostics.py` blanks multi-line `#define`s instead of deleting them. Assisted-by: Claude Code
This commit is contained in:
1 parent
e1c8c1f855
commit
2c9739799b
1205 files changed
+20291
-24988
No files matched your search
@@ -25,57 +25,29 @@ auto foo2(ForwardDeclaredStruct) -> void;
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
// CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE+8]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: ./decl_value_param_type.h:4:6: error: argument type 'ForwardDeclaredStruct' is incomplete [CppInteropParseError]
|
||||
// CHECK:STDERR: 4 | auto foo1(ForwardDeclaredStruct) -> void;
|
||||
// CHECK:STDERR: | ^~~~
|
||||
// CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE+4]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: included from: fail_import_decl_value_param_type.carbon:[[@LINE+3]]:10 [InCppInclude]
|
||||
// CHECK:STDERR: ./decl_value_param_type.h:4:6-9: error: argument type 'ForwardDeclaredStruct' is incomplete [CppInteropParseError]
|
||||
// CHECK:STDERR: ./decl_value_param_type.h:2:8: note: forward declaration of 'ForwardDeclaredStruct' [CppInteropParseNote]
|
||||
// CHECK:STDERR: 2 | struct ForwardDeclaredStruct;
|
||||
// CHECK:STDERR: | ^
|
||||
import Cpp library "decl_value_param_type.h";
|
||||
|
||||
fn F(p: Cpp.ForwardDeclaredStruct*) {
|
||||
// CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE+12]]:3: note: in thunk for C++ function used here [InCppThunk]
|
||||
// CHECK:STDERR: Cpp.foo1(*p);
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~
|
||||
// CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE+5]]:3-14: note: in thunk for C++ function used here [InCppThunk]
|
||||
// CHECK:STDERR:
|
||||
// CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE-7]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: ./decl_value_param_type.h:5:6: error: argument type 'ForwardDeclaredStruct' is incomplete [CppInteropParseError]
|
||||
// CHECK:STDERR: 5 | auto foo2(ForwardDeclaredStruct) -> void;
|
||||
// CHECK:STDERR: | ^~~~
|
||||
// CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE-11]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: included from: fail_import_decl_value_param_type.carbon:[[@LINE-5]]:10 [InCppInclude]
|
||||
// CHECK:STDERR: ./decl_value_param_type.h:5:6-9: error: argument type 'ForwardDeclaredStruct' is incomplete [CppInteropParseError]
|
||||
// CHECK:STDERR: ./decl_value_param_type.h:2:8: note: forward declaration of 'ForwardDeclaredStruct' [CppInteropParseNote]
|
||||
// CHECK:STDERR: 2 | struct ForwardDeclaredStruct;
|
||||
// CHECK:STDERR: | ^
|
||||
Cpp.foo1(*p);
|
||||
// CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE+28]]:3: note: in thunk for C++ function used here [InCppThunk]
|
||||
// CHECK:STDERR: Cpp.foo2(*p);
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~
|
||||
// CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE+12]]:3-14: note: in thunk for C++ function used here [InCppThunk]
|
||||
// CHECK:STDERR:
|
||||
// CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE-5]]:12: error: forming value of incomplete type `Cpp.ForwardDeclaredStruct` [IncompleteTypeInValueConversion]
|
||||
// CHECK:STDERR: Cpp.foo1(*p);
|
||||
// CHECK:STDERR: ^~
|
||||
// CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE-23]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE-3]]:12-13: error: forming value of incomplete type `Cpp.ForwardDeclaredStruct` [IncompleteTypeInValueConversion]
|
||||
// CHECK:STDERR: included from: fail_import_decl_value_param_type.carbon:[[@LINE-12]]:10 [InCppInclude]
|
||||
// CHECK:STDERR: ./decl_value_param_type.h:2:8: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR: struct ForwardDeclaredStruct;
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE-27]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: ./decl_value_param_type.h:4:32: note: initializing function parameter [InCallToFunctionParam]
|
||||
// CHECK:STDERR: auto foo1(ForwardDeclaredStruct) -> void;
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR:
|
||||
// CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE+12]]:12: error: forming value of incomplete type `Cpp.ForwardDeclaredStruct` [IncompleteTypeInValueConversion]
|
||||
// CHECK:STDERR: Cpp.foo2(*p);
|
||||
// CHECK:STDERR: ^~
|
||||
// CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE-35]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE+5]]:12-13: error: forming value of incomplete type `Cpp.ForwardDeclaredStruct` [IncompleteTypeInValueConversion]
|
||||
// CHECK:STDERR: included from: fail_import_decl_value_param_type.carbon:[[@LINE-17]]:10 [InCppInclude]
|
||||
// CHECK:STDERR: ./decl_value_param_type.h:2:8: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR: struct ForwardDeclaredStruct;
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR: fail_import_decl_value_param_type.carbon:[[@LINE-39]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: ./decl_value_param_type.h:5:32: note: initializing function parameter [InCallToFunctionParam]
|
||||
// CHECK:STDERR: auto foo2(ForwardDeclaredStruct) -> void;
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR:
|
||||
Cpp.foo2(*p);
|
||||
}
|
||||
@@ -118,25 +90,15 @@ auto foo_non_copyable(NonCopyableStruct) -> void;
|
||||
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
// CHECK:STDERR: fail_import_non_copyable_param_type.carbon:[[@LINE+12]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: ./non_copyable_param_type.h:6:6: error: call to deleted constructor of 'NonCopyableStruct' [CppInteropParseError]
|
||||
// CHECK:STDERR: 6 | auto foo_non_copyable(NonCopyableStruct) -> void;
|
||||
// CHECK:STDERR: | ^~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR: fail_import_non_copyable_param_type.carbon:[[@LINE+8]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: included from: fail_import_non_copyable_param_type.carbon:[[@LINE+4]]:10 [InCppInclude]
|
||||
// CHECK:STDERR: ./non_copyable_param_type.h:6:6-21: error: call to deleted constructor of 'NonCopyableStruct' [CppInteropParseError]
|
||||
// CHECK:STDERR: ./non_copyable_param_type.h:3:3: note: 'NonCopyableStruct' has been explicitly marked deleted here [CppInteropParseNote]
|
||||
// CHECK:STDERR: 3 | NonCopyableStruct(const NonCopyableStruct&) = delete;
|
||||
// CHECK:STDERR: | ^
|
||||
// CHECK:STDERR: fail_import_non_copyable_param_type.carbon:[[@LINE+4]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: ./non_copyable_param_type.h:6:40: note: passing argument to parameter here [CppInteropParseNote]
|
||||
// CHECK:STDERR: 6 | auto foo_non_copyable(NonCopyableStruct) -> void;
|
||||
// CHECK:STDERR: | ^
|
||||
import Cpp library "non_copyable_param_type.h";
|
||||
|
||||
fn F(s: Cpp.NonCopyableStruct) {
|
||||
//@dump-sem-ir-begin
|
||||
// CHECK:STDERR: fail_import_non_copyable_param_type.carbon:[[@LINE+4]]:3: note: in thunk for C++ function used here [InCppThunk]
|
||||
// CHECK:STDERR: Cpp.foo_non_copyable(s);
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR: fail_import_non_copyable_param_type.carbon:[[@LINE+2]]:3-25: note: in thunk for C++ function used here [InCppThunk]
|
||||
// CHECK:STDERR:
|
||||
Cpp.foo_non_copyable(s);
|
||||
//@dump-sem-ir-end
|
||||
@@ -321,13 +283,9 @@ library "[[@TEST_NAME]]";
|
||||
import Cpp library "incomplete.h";
|
||||
|
||||
fn F() {
|
||||
// CHECK:STDERR: fail_import_incomplete.carbon:[[@LINE+8]]:3: error: member access into incomplete class `Cpp.IncompleteStruct` [QualifiedExprInIncompleteClassScope]
|
||||
// CHECK:STDERR: Cpp.IncompleteStruct.foo();
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR: fail_import_incomplete.carbon:[[@LINE-6]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: fail_import_incomplete.carbon:[[@LINE+4]]:3-26: error: member access into incomplete class `Cpp.IncompleteStruct` [QualifiedExprInIncompleteClassScope]
|
||||
// CHECK:STDERR: included from: fail_import_incomplete.carbon:[[@LINE-4]]:10 [InCppInclude]
|
||||
// CHECK:STDERR: ./incomplete.h:2:8: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR: struct IncompleteStruct;
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR:
|
||||
Cpp.IncompleteStruct.foo();
|
||||
}
|
||||
@@ -391,36 +349,19 @@ auto foo_decl_value_return() -> DeclValueReturnStruct;
|
||||
library "[[@TEST_NAME]]";
|
||||
|
||||
// TODO: We should only produce one error here.
|
||||
// CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE+12]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: ./decl_value_return_type.h:4:6: error: calling 'foo_decl_value_return' with incomplete return type 'DeclValueReturnStruct' [CppInteropParseError]
|
||||
// CHECK:STDERR: 4 | auto foo_decl_value_return() -> DeclValueReturnStruct;
|
||||
// CHECK:STDERR: | ^~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE+8]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: included from: fail_import_decl_value_return_type.carbon:[[@LINE+4]]:10 [InCppInclude]
|
||||
// CHECK:STDERR: ./decl_value_return_type.h:4:6-26: error: calling 'foo_decl_value_return' with incomplete return type 'DeclValueReturnStruct' [CppInteropParseError]
|
||||
// CHECK:STDERR: ./decl_value_return_type.h:4:6: note: 'foo_decl_value_return' declared here [CppInteropParseNote]
|
||||
// CHECK:STDERR: 4 | auto foo_decl_value_return() -> DeclValueReturnStruct;
|
||||
// CHECK:STDERR: | ^
|
||||
// CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE+4]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: ./decl_value_return_type.h:2:8: note: forward declaration of 'DeclValueReturnStruct' [CppInteropParseNote]
|
||||
// CHECK:STDERR: 2 | struct DeclValueReturnStruct;
|
||||
// CHECK:STDERR: | ^
|
||||
import Cpp library "decl_value_return_type.h";
|
||||
|
||||
fn F() {
|
||||
// CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE+16]]:3: note: in thunk for C++ function used here [InCppThunk]
|
||||
// CHECK:STDERR: Cpp.foo_decl_value_return();
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE+7]]:3-29: note: in thunk for C++ function used here [InCppThunk]
|
||||
// CHECK:STDERR:
|
||||
// CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE+12]]:3: error: function returns incomplete type `Cpp.DeclValueReturnStruct` [IncompleteTypeInFunctionReturnType]
|
||||
// CHECK:STDERR: Cpp.foo_decl_value_return();
|
||||
// CHECK:STDERR: ^~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
// CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE-10]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE+5]]:3-29: error: function returns incomplete type `Cpp.DeclValueReturnStruct` [IncompleteTypeInFunctionReturnType]
|
||||
// CHECK:STDERR: included from: fail_import_decl_value_return_type.carbon:[[@LINE-6]]:10 [InCppInclude]
|
||||
// CHECK:STDERR: ./decl_value_return_type.h:2:8: note: class was forward declared here [ClassForwardDeclaredHere]
|
||||
// CHECK:STDERR: struct DeclValueReturnStruct;
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR: fail_import_decl_value_return_type.carbon:[[@LINE-14]]:10: in file included here [InCppInclude]
|
||||
// CHECK:STDERR: ./decl_value_return_type.h:4:33: note: return type declared here [IncompleteReturnTypeHere]
|
||||
// CHECK:STDERR: auto foo_decl_value_return() -> DeclValueReturnStruct;
|
||||
// CHECK:STDERR: ^
|
||||
// CHECK:STDERR:
|
||||
Cpp.foo_decl_value_return();
|
||||
}
|
||||
@@ -559,7 +500,7 @@ fn F() {
|
||||
// CHECK:STDOUT:
|
||||
// CHECK:STDOUT: fn @F(%s.param: %NonCopyableStruct) {
|
||||
// CHECK:STDOUT: !entry:
|
||||
// CHECK:STDOUT: %Cpp.ref.loc24: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %Cpp.ref.loc14: <namespace> = name_ref Cpp, imports.%Cpp [concrete = imports.%Cpp]
|
||||
// CHECK:STDOUT: %foo_non_copyable.ref: %foo_non_copyable.cpp_overload_set.type = name_ref foo_non_copyable, imports.%foo_non_copyable.cpp_overload_set.value [concrete = constants.%foo_non_copyable.cpp_overload_set.value]
|
||||
// CHECK:STDOUT: %s.ref: %NonCopyableStruct = name_ref s, %s
|
||||
// CHECK:STDOUT: %foo_non_copyable.call: init %empty_tuple.type = call imports.%foo_non_copyable.decl(%s.ref)
|
||||
|
||||
Reference in new issue
Block a user