diff options
| author | bors <bors@rust-lang.org> | 2020-09-08 00:58:43 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2020-09-08 00:58:43 +0000 |
| commit | 71569e420107ab034910a4687f382385975fa0b3 (patch) | |
| tree | e98903281ee0502675b01212bded5148710b6d90 /compiler/rustc_session/src | |
| parent | 0e2c1281e909ca38479b97962fc9248f75d66412 (diff) | |
| parent | 5956254172ab2bb6fd7c98faf51509925341c321 (diff) | |
| download | rust-71569e420107ab034910a4687f382385975fa0b3.tar.gz rust-71569e420107ab034910a4687f382385975fa0b3.zip | |
Auto merge of #75138 - jumbatm:session-diagnostic-derive, r=oli-obk
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`
Diffstat (limited to 'compiler/rustc_session/src')
| -rw-r--r-- | compiler/rustc_session/src/session.rs | 11 |
1 files changed, 11 insertions, 0 deletions
diff --git a/compiler/rustc_session/src/session.rs b/compiler/rustc_session/src/session.rs index ff22b4ce4ad..974f4c31bb6 100644 --- a/compiler/rustc_session/src/session.rs +++ b/compiler/rustc_session/src/session.rs @@ -237,6 +237,14 @@ enum DiagnosticBuilderMethod { // Add more variants as needed to support one-time diagnostics. } +/// Trait implemented by error types. This should not be implemented manually. Instead, use +/// `#[derive(SessionDiagnostic)]` -- see [rustc_macros::SessionDiagnostic]. +pub trait SessionDiagnostic<'a> { + /// Write out as a diagnostic out of `sess`. + #[must_use] + fn into_diagnostic(self, sess: &'a Session) -> DiagnosticBuilder<'a>; +} + /// Diagnostic message ID, used by `Session.one_time_diagnostics` to avoid /// emitting the same message more than once. #[derive(Clone, Copy, Debug, PartialEq, Eq, Hash)] @@ -392,6 +400,9 @@ impl Session { pub fn err(&self, msg: &str) { self.diagnostic().err(msg) } + pub fn emit_err<'a>(&'a self, err: impl SessionDiagnostic<'a>) { + err.into_diagnostic(self).emit() + } pub fn err_count(&self) -> usize { self.diagnostic().err_count() } |
