-
Notifications
You must be signed in to change notification settings - Fork 5.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Support multi-span errors and warnings #21
Comments
Can you explain a little more what you mean by this? |
Yeah, so our error renderer in
|
A good one to start might be "not declared as mutable... but used as mutable here ^". What do you think? |
related: #346 |
Another error that might benefit from this: #751. "Function ^ is being redefined. It was already previously defined ^" |
One more issue that would benefit from this: #3532. The CEI pattern analysis would highlight just two lines: the one with the external call and the one with storage modification or some other effect. |
I recall that we tried to do this but then reverted the change for some reason? Is this too difficult to implement? I do find myself needing this often. cc @sezna. Also, if it's too complex, we should probably remove the |
There was a bug previously where the compiler would panic if the two errors were from different files, which was usually the case, so we reverted the old implementation. |
Here is the progress so far and two open questions to agree on. Please provide your feedback on the questions. Before and after :-)Open QuestionsStructure of compile messagesWhat do we want to support in our compile messages and how much freedom, or restriction do we want to offer. For the sake of consistency, I am for a limited, clearly defined number of elements that we can embed in a compile message. This way we can impose consistency across all our messages. So far I support these elements, and enforce them via the compile message (CM) API:
You can spot all of these elements on the above image. What do you think of this approach? Do you see any other elements that we could need? Declarative APIAt the moments messages are declared imperatively, pretty much like the way we do warnings right now. This means a lot of clutter and boilerplate. E,g,:
The proposal is to define our own macros for simplifying the message definition. Something along these lines:
|
I really like this approach. In general having a formal set of items we can use to explain a problem to the user is the right way to go. I guess if I had to criticize this I would say that it's not very clear at a glance to the compiler dev what a "label" or an "info" is and how different they will look to the user. Ideally I'd want it to be easy to design a decent error without having to look up the spec. Another thing is that this: #[label("Constants cannot be shadowed")]
#[error(name.span(), "Variable \"{name}\" shadows constant with the same name.")]
#[info(constant_span, "Constant \"{name}\" is declared here.")]
#[help("Unlike variables, constants cannot be shadowed by other constants or variables, nor they can shadow variables.")]
VariableShadowsConstant { name: Ident, constant_span: Span }, is probably expressed as a single proc-macro: #[error(
name = name.span(),
msg = "Variable \"{name}\" shadows constant with the same name.",
label = "Constants cannot be shadowed",
info = (constant_span, "Constant \"{name}\" is declared here."),
help = "Unlike variables, constants cannot be shadowed by other constants or variables, nor they can shadow variables.",
)]
VariableShadowsConstant { name: Ident, constant_span: Span }, One may also want to have more than a single "info", though I would expect the cases where this is necessary are rare. |
Completely agree that the terminology is very confusing. I wasn't happy with it either, especially when modeling the corresponding structs in code ( After pondering about it (a lot) and also partially inspired with the The Anatomy of Error Messages in Rust talk (@IGI-111 thanks for the suggestion) I propose the following: The whole thing is called Diagnostic and has:
To this, we should also add id (or code) as suggested in #3512. It's the unique identifier of the reason actually. I wouldn't call it error code simply because it can be a warning code as well. The mandatory fields are:
Everything else is optional. We can have arbitrary number of hints spanning different files and arbitrary number of help lines. I love the proposal of having a single proc-macro! And it doesn't mean that we cannot have several hints or help lines that way. E.g.:
|
For the record, a very inspiring paper titled Concepts Error Messages for Humans. It emphasize the importance of good (great!) error messages and provides concrete tips how to formulate them. For the purpose of this discussion, everything proposed in the paper can be achieved with the intentionally restricted number of supported elements in Diagnostics, listed above. The article also mentions the miette crate. Miette is an all-in-one library for defining, collecting, and rendering errors, compatible with
(Yes, at glance, it looks like what we did developing our own infrastructure and combining |
The new version looks better, I'm really looking forward to having error ids, if only because once we do we'll be able to provide I do think we made the right choice rolling our own error rendering if only because it gives us flexibility in how we want to tackle the problem, but miette is indeed pretty good and we could certainly take cues out of how it's designed. |
## Description A new `Diagnostic` type is introduced for detail description of compile errors and warnings. The change is backward compatible. The existing `CompileWarning`s and `CompileError`s will continue render as they had before. The `Diagnostic` is formed out of a: - _Level_: Error or Warning. - _Code_: Unique error or warning code. Placeholder for future. Not used at the moment. - _Reason_: Short description of the diagnostic, not related to a specific error/warning. Answers the question "Why is this an error/warning?" E.g., Because - "Constants cannot be shadowed". - _Issue_: Short description of the concrete case that the compiler has found. E.g., "Variable "X" shadows imported constant with the same name" - _Hints_: Detailed description of the diagnostic placed in the source code. - _Help_: Additional friendly information that helps understanding and solving the issue, but which is not related to a place in code. ![07C Constant shadowing - Alias - After 02 - Terminology](https://github.com/FuelLabs/sway/assets/4142833/50c639a1-43f5-4bc2-afa2-5717652f0172) The `Diagnostic`s are defined imperatively in code right now, pretty much the sam way we do `CompilWarning`s at the moment. Development of a proc-macro that should make de definitions declarative is out of scope of #21. ## Known Limitations The `annotate-snippets` library has a bug and a missing functionality for which I opened issues: - Wrong display of line numbers when using folding of lines of code. This issue is fixed but there is no patch release provided: rust-lang/annotate-snippets-rs#52 (comment) - No possibility to remove the "note:" prefix as shown on the image above: rust-lang/annotate-snippets-rs#59 These two issues are not blocking. Proposal is to wait for the official support in the library, or contribute or in the worst case make a workaround in our code. ## Demo (Before and After) ### Errors ![07A Constant shadowing - Alias - Before](https://github.com/FuelLabs/sway/assets/4142833/5d67c5e5-d456-4762-b7c7-6fcf7340d6b3) ![07C Constant shadowing - Alias - After 02](https://github.com/FuelLabs/sway/assets/4142833/02691b39-3d08-4776-ba93-5ffeca4546ed) ### Warnings ![06A NonScreamingSnakeCaseConstName - Before](https://github.com/FuelLabs/sway/assets/4142833/c27279d4-0e6c-4d05-9b00-da7121bb60ad) ![06B NonScreamingSnakeCaseConstName - After](https://github.com/FuelLabs/sway/assets/4142833/483044f3-f190-4506-9e9e-2d03d70cb3f2) Closes #21 ## Checklist - [x] I have linked to any relevant issues. - [x] I have commented my code, particularly in hard-to-understand areas. - [ ] I have updated the documentation where relevant (API docs, the reference, and the Sway book). - [x] I have added tests that prove my fix is effective or that my feature works. - [ ] I have added (or requested a maintainer to add) the necessary `Breaking*` or `New Feature` labels where relevant. - [x] I have done my best to ensure that my PR adheres to [the Fuel Labs Code Review Standards](https://github.com/FuelLabs/rfcs/blob/master/text/code-standards/external-contributors.md). - [x] I have requested a review from the relevant team or maintainers.
@Voxelot @freesig here we go, definitely speeds up the `fuel-core` build quite a bit locally, and slims the binary size by about a third! Here are the changes I'm seeing with `fuel-core` `0.10.1`: **Before** ``` $ ldd ./result/bin/fuel-core linux-vdso.so.1 (0x00007ffe3e3eb000) libstdc++.so.6 => /nix/store/k2a429wpxgfwp4jaacl9iaqw4kxqjaxa-gcc-11.3.0-lib/lib/libstdc++.so.6 (0x00007f20236ed000) libgcc_s.so.1 => /nix/store/7fz6dhhriwv6n4kdg05qi8cwf7mfqza9-glibc-2.35-163/lib/libgcc_s.so.1 (0x00007f20236d3000) libm.so.6 => /nix/store/7fz6dhhriwv6n4kdg05qi8cwf7mfqza9-glibc-2.35-163/lib/libm.so.6 (0x00007f20235f3000) libc.so.6 => /nix/store/7fz6dhhriwv6n4kdg05qi8cwf7mfqza9-glibc-2.35-163/lib/libc.so.6 (0x00007f20233e9000) /nix/store/7fz6dhhriwv6n4kdg05qi8cwf7mfqza9-glibc-2.35-163/lib/ld-linux-x86-64.so.2 => /nix/store/bzd91shky9j9d43girrrj6vmqlw7x9m8-glibc-2.35-163/lib64/ld-linux-x86-64.so.2 (0x00007f2024b94000) $ ls -ahl ./result/bin/fuel-core -r-xr-xr-x 1 root root 22M Jan 1 1970 fuel-core ``` **After** ``` $ ldd ./result/bin/fuel-core linux-vdso.so.1 (0x00007ffe1af53000) librocksdb.so.7 => /nix/store/n8fl280p0hdnz9qajwihzsn707jfgkdw-rocksdb-7.4.5/lib/librocksdb.so.7 (0x00007f62e74af000) libgcc_s.so.1 => /nix/store/7fz6dhhriwv6n4kdg05qi8cwf7mfqza9-glibc-2.35-163/lib/libgcc_s.so.1 (0x00007f62e7495000) libm.so.6 => /nix/store/7fz6dhhriwv6n4kdg05qi8cwf7mfqza9-glibc-2.35-163/lib/libm.so.6 (0x00007f62e73b5000) libc.so.6 => /nix/store/7fz6dhhriwv6n4kdg05qi8cwf7mfqza9-glibc-2.35-163/lib/libc.so.6 (0x00007f62e71ab000) libsnappy.so.1 => /nix/store/hpmn4gz49wzm5zszg9s24y8sanp29i8c-snappy-1.1.9/lib/libsnappy.so.1 (0x00007f62e719b000) libz.so.1 => /nix/store/z18zgvspmxi88ipmk3f3nicvasfq3199-zlib-1.2.12/lib/libz.so.1 (0x00007f62e717d000) libbz2.so.1 => /nix/store/1pbdai0n0n16z01nk9yybrll4g2a6mls-bzip2-1.0.8/lib/libbz2.so.1 (0x00007f62e716a000) liblz4.so.1 => /nix/store/94ky79f8slvqz77vrc03n228m2xjrvs5-lz4-1.9.3/lib/liblz4.so.1 (0x00007f62e7136000) libzstd.so.1 => /nix/store/dq2hx1zvsf8zq1n3b3f7ipzh2kjk7hww-zstd-1.5.2/lib/libzstd.so.1 (0x00007f62e7071000) libstdc++.so.6 => /nix/store/k2a429wpxgfwp4jaacl9iaqw4kxqjaxa-gcc-11.3.0-lib/lib/libstdc++.so.6 (0x00007f62e6e58000) libpthread.so.0 => /nix/store/7fz6dhhriwv6n4kdg05qi8cwf7mfqza9-glibc-2.35-163/lib/libpthread.so.0 (0x00007f62e6e53000) /nix/store/7fz6dhhriwv6n4kdg05qi8cwf7mfqza9-glibc-2.35-163/lib/ld-linux-x86-64.so.2 => /nix/store/bzd91shky9j9d43girrrj6vmqlw7x9m8-glibc-2.35-163/lib64/ld-linux-x86-64.so.2 (0x00007f62e8c18000) $ ls -ahl ./result/bin/fuel-core -r-xr-xr-x 1 root root 15M Jan 1 1970 fuel-core ``` Note that it seems we still need to keep clang around for bindgen in order for the rocksdb build script to generate the bindings from its headers. Closes #19.
Often, you want to display help text or render multiple spans in an error.
The text was updated successfully, but these errors were encountered: