Overhaul const-checking diagnostics
The primary purpose of this PR was to remove `NonConstOp::STOPS_CONST_CHECKING`, which causes any additional errors found by the const-checker to be silenced. I used this flag to preserve diagnostic parity with `qualify_min_const_fn.rs`, which has since been removed.
However, simply removing the flag caused a deluge of errors in some cases, since an error would be emitted any time a local or temporary had a wrong type. To remedy this, I added an alternative system (`DiagnosticImportance`) to silence additional error messages that were likely to distract the user from the underlying issue. When an error of the highest importance occurs, all less important errors are silenced. When no error of the highest importance occurs, all less important errors are emitted after checking is complete. Following the suggestions from the important error is usually enough to fix the less important errors, so this should lead to better UX most of the time.
There's also some unrelated diagnostics improvements in this PR isolated in their own commits. Splitting them out would be possible, but a bit of a pain. This isn't as tidy as some of my other PRs, but it should *only* affect diagnostics, never whether or not something passes const-checking. Note that there are a few trivial exceptions to this, like banning `Yield` in all const-contexts, not just `const fn`.
As always, meant to be reviewed commit-by-commit.
r? `@oli-obk`
This patch adds support for the LLVM cmse_nonsecure_entry attribute.
This is a target-dependent attribute that only has sense for the
thumbv8m Rust targets.
You can find more information about this attribute here:
https://developer.arm.com/documentation/ecm0359818/latest/
Signed-off-by: Hugues de Valon <hugues.devalon@arm.com>
Improve unresolved use error message
"use of undeclared type or module `foo`" doesn't mention that it could be a crate.
This error can happen when users forget to add a dependency to `Cargo.toml`, so I think it's important to mention that it could be a missing crate.
I've used a heuristic based on Rust's naming conventions. It complains about an unknown type if the ident starts with an upper-case letter, and crate or module otherwise. It seems to work very well. The expanded error help covers both an unknown type and a missing crate case.
Add derive macro for specifying diagnostics using attributes.
Introduces `#[derive(SessionDiagnostic)]`, a derive macro for specifying structs that can be converted to Diagnostics using directions given by attributes on the struct and its fields. Currently, the following attributes have been implemented:
- `#[code = "..."]` -- this sets the Diagnostic's error code, and must be provided on the struct iself (ie, not on a field). Equivalent to calling `code`.
- `#[message = "..."]` -- this sets the Diagnostic's primary error message.
- `#[label = "..."]` -- this must be applied to fields of type `Span`, and is equivalent to `span_label`
- `#[suggestion(..)]` -- this allows a suggestion message to be supplied. This attribute must be applied to a field of type `Span` or `(Span, Applicability)`, and is equivalent to calling `span_suggestion`. Valid arguments are:
- `message = "..."` -- this sets the suggestion message.
- (Optional) `code = "..."` -- this suggests code for the suggestion. Defaults to empty.
`suggestion`also comes with other variants: `#[suggestion_short(..)]`, `#[suggestion_hidden(..)]` and `#[suggestion_verbose(..)]` which all take the same keys.
Within the strings passed to each attribute, fields can be referenced without needing to be passed explicitly into the format string -- eg, `#[error = "{ident} already declared"] ` will set the error message to `format!("{} already declared", &self.ident)`. Any fields on the struct can be referenced in this way.
Additionally, for any of these attributes, Option fields can be used to only optionally apply the decoration -- for example:
```rust
#[derive(SessionDiagnostic)]
#[code = "E0123"]
struct SomeKindOfError {
...
#[suggestion(message = "informative error message")]
opt_sugg: Option<(Span, Applicability)>
...
}
```
will not emit a suggestion if `opt_sugg` is `None`.
We plan on iterating on this macro further; this PR is a start.
Closes#61132.
r? `@oli-obk`
Give a better error message for duplicate built-in macros
Minor follow-up to https://github.com/rust-lang/rust/pull/75176 giving a better error message for duplicate builtin macros. This would have made it a little easier to debug.
r? @petrochenkov
Previously, this would say no such macro existed, but this was
misleading, since the macro _did_ exist, it was just already seen.
- Say where the macro was previously defined
- Add long-form error message