macros: subdiagnostic derive

Add a new derive, `#[derive(SessionSubdiagnostic)]`, which enables
deriving structs for labels, notes, helps and suggestions.

Signed-off-by: David Wood <david.wood@huawei.com>
This commit is contained in:
David Wood 2022-04-26 11:59:45 +01:00
parent aa2abc9d12
commit 49ec909ca7
10 changed files with 1735 additions and 151 deletions

View File

@ -82,3 +82,11 @@ typeck-value-of-associated-struct-already-specified =
typeck-address-of-temporary-taken = cannot take address of a temporary typeck-address-of-temporary-taken = cannot take address of a temporary
.label = temporary value .label = temporary value
typeck-add-return-type-add = try adding a return type
typeck-add-return-type-missing-here = a return type might be missing here
typeck-expected-default-return-type = expected `()` because of default return type
typeck-expected-return-type = expected `{$expected}` because of return type

View File

@ -78,6 +78,13 @@ impl<'source> Into<FluentValue<'source>> for DiagnosticArgValue<'source> {
} }
} }
/// Trait implemented by error types. This should not be implemented manually. Instead, use
/// `#[derive(SessionSubdiagnostic)]` -- see [rustc_macros::SessionSubdiagnostic].
pub trait AddSubdiagnostic {
/// Add a subdiagnostic to an existing diagnostic.
fn add_to_diagnostic(self, diag: &mut Diagnostic);
}
#[must_use] #[must_use]
#[derive(Clone, Debug, Encodable, Decodable)] #[derive(Clone, Debug, Encodable, Decodable)]
pub struct Diagnostic { pub struct Diagnostic {
@ -768,6 +775,13 @@ impl Diagnostic {
self self
} }
/// Add a subdiagnostic from a type that implements `SessionSubdiagnostic` - see
/// [rustc_macros::SessionSubdiagnostic].
pub fn subdiagnostic(&mut self, subdiagnostic: impl AddSubdiagnostic) -> &mut Self {
subdiagnostic.add_to_diagnostic(self);
self
}
pub fn set_span<S: Into<MultiSpan>>(&mut self, sp: S) -> &mut Self { pub fn set_span<S: Into<MultiSpan>>(&mut self, sp: S) -> &mut Self {
self.span = sp.into(); self.span = sp.into();
if let Some(span) = self.span.primary_span() { if let Some(span) = self.span.primary_span() {

View File

@ -530,6 +530,11 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
name: impl Into<Cow<'static, str>>, name: impl Into<Cow<'static, str>>,
arg: DiagnosticArgValue<'static>, arg: DiagnosticArgValue<'static>,
) -> &mut Self); ) -> &mut Self);
forward!(pub fn subdiagnostic(
&mut self,
subdiagnostic: impl crate::AddSubdiagnostic
) -> &mut Self);
} }
impl<G: EmissionGuarantee> Debug for DiagnosticBuilder<'_, G> { impl<G: EmissionGuarantee> Debug for DiagnosticBuilder<'_, G> {

View File

@ -370,8 +370,8 @@ impl fmt::Display for ExplicitBug {
impl error::Error for ExplicitBug {} impl error::Error for ExplicitBug {}
pub use diagnostic::{ pub use diagnostic::{
Diagnostic, DiagnosticArg, DiagnosticArgValue, DiagnosticId, DiagnosticStyledString, AddSubdiagnostic, Diagnostic, DiagnosticArg, DiagnosticArgValue, DiagnosticId,
IntoDiagnosticArg, SubDiagnostic, DiagnosticStyledString, IntoDiagnosticArg, SubDiagnostic,
}; };
pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee}; pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee};
use std::backtrace::Backtrace; use std::backtrace::Backtrace;

View File

@ -1,5 +1,6 @@
#![feature(proc_macro_diagnostic)]
#![feature(allow_internal_unstable)] #![feature(allow_internal_unstable)]
#![feature(let_else)]
#![feature(proc_macro_diagnostic)]
#![allow(rustc::default_hash_types)] #![allow(rustc::default_hash_types)]
#![recursion_limit = "128"] #![recursion_limit = "128"]
@ -77,3 +78,18 @@ decl_derive!(
suggestion_hidden, suggestion_hidden,
suggestion_verbose)] => session_diagnostic::session_diagnostic_derive suggestion_verbose)] => session_diagnostic::session_diagnostic_derive
); );
decl_derive!(
[SessionSubdiagnostic, attributes(
// struct/variant attributes
label,
help,
note,
suggestion,
suggestion_short,
suggestion_hidden,
suggestion_verbose,
// field attributes
skip_arg,
primary_span,
applicability)] => session_diagnostic::session_subdiagnostic_derive
);

File diff suppressed because it is too large Load Diff

View File

@ -1,5 +1,6 @@
use super::FnCtxt; use super::FnCtxt;
use crate::astconv::AstConv; use crate::astconv::AstConv;
use crate::errors::{AddReturnTypeSuggestion, ExpectedReturnTypeLabel};
use rustc_ast::util::parser::ExprPrecedence; use rustc_ast::util::parser::ExprPrecedence;
use rustc_errors::{Applicability, Diagnostic, MultiSpan}; use rustc_errors::{Applicability, Diagnostic, MultiSpan};
@ -527,28 +528,18 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// haven't set a return type at all (and aren't `fn main()` or an impl). // haven't set a return type at all (and aren't `fn main()` or an impl).
match (&fn_decl.output, found.is_suggestable(self.tcx), can_suggest, expected.is_unit()) { match (&fn_decl.output, found.is_suggestable(self.tcx), can_suggest, expected.is_unit()) {
(&hir::FnRetTy::DefaultReturn(span), true, true, true) => { (&hir::FnRetTy::DefaultReturn(span), true, true, true) => {
err.span_suggestion( err.subdiagnostic(AddReturnTypeSuggestion::Add { span, found });
span,
"try adding a return type",
format!("-> {} ", found),
Applicability::MachineApplicable,
);
true true
} }
(&hir::FnRetTy::DefaultReturn(span), false, true, true) => { (&hir::FnRetTy::DefaultReturn(span), false, true, true) => {
// FIXME: if `found` could be `impl Iterator` or `impl Fn*`, we should suggest // FIXME: if `found` could be `impl Iterator` or `impl Fn*`, we should suggest
// that. // that.
err.span_suggestion( err.subdiagnostic(AddReturnTypeSuggestion::MissingHere { span });
span,
"a return type might be missing here",
"-> _ ".to_string(),
Applicability::HasPlaceholders,
);
true true
} }
(&hir::FnRetTy::DefaultReturn(span), _, false, true) => { (&hir::FnRetTy::DefaultReturn(span), _, false, true) => {
// `fn main()` must return `()`, do not suggest changing return type // `fn main()` must return `()`, do not suggest changing return type
err.span_label(span, "expected `()` because of default return type"); err.subdiagnostic(ExpectedReturnTypeLabel::Unit { span });
true true
} }
// expectation was caused by something else, not the default return // expectation was caused by something else, not the default return
@ -557,16 +548,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
// Only point to return type if the expected type is the return type, as if they // Only point to return type if the expected type is the return type, as if they
// are not, the expectation must have been caused by something else. // are not, the expectation must have been caused by something else.
debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.kind); debug!("suggest_missing_return_type: return type {:?} node {:?}", ty, ty.kind);
let sp = ty.span; let span = ty.span;
let ty = <dyn AstConv<'_>>::ast_ty_to_ty(self, ty); let ty = <dyn AstConv<'_>>::ast_ty_to_ty(self, ty);
debug!("suggest_missing_return_type: return type {:?}", ty); debug!("suggest_missing_return_type: return type {:?}", ty);
debug!("suggest_missing_return_type: expected type {:?}", ty); debug!("suggest_missing_return_type: expected type {:?}", ty);
let bound_vars = self.tcx.late_bound_vars(fn_id); let bound_vars = self.tcx.late_bound_vars(fn_id);
let ty = Binder::bind_with_vars(ty, bound_vars); let ty = Binder::bind_with_vars(ty, bound_vars);
let ty = self.normalize_associated_types_in(sp, ty); let ty = self.normalize_associated_types_in(span, ty);
let ty = self.tcx.erase_late_bound_regions(ty); let ty = self.tcx.erase_late_bound_regions(ty);
if self.can_coerce(expected, ty) { if self.can_coerce(expected, ty) {
err.span_label(sp, format!("expected `{}` because of return type", expected)); err.subdiagnostic(ExpectedReturnTypeLabel::Other { span, expected });
self.try_suggest_return_impl_trait(err, expected, ty, fn_id); self.try_suggest_return_impl_trait(err, expected, ty, fn_id);
return true; return true;
} }

View File

@ -1,6 +1,6 @@
//! Errors emitted by typeck. //! Errors emitted by typeck.
use rustc_errors::Applicability; use rustc_errors::Applicability;
use rustc_macros::SessionDiagnostic; use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic};
use rustc_middle::ty::Ty; use rustc_middle::ty::Ty;
use rustc_span::{symbol::Ident, Span, Symbol}; use rustc_span::{symbol::Ident, Span, Symbol};
@ -190,3 +190,41 @@ pub struct AddressOfTemporaryTaken {
#[label] #[label]
pub span: Span, pub span: Span,
} }
#[derive(SessionSubdiagnostic)]
pub enum AddReturnTypeSuggestion<'tcx> {
#[suggestion(
slug = "typeck-add-return-type-add",
code = "-> {found} ",
applicability = "machine-applicable"
)]
Add {
#[primary_span]
span: Span,
found: Ty<'tcx>,
},
#[suggestion(
slug = "typeck-add-return-type-missing-here",
code = "-> _ ",
applicability = "has-placeholders"
)]
MissingHere {
#[primary_span]
span: Span,
},
}
#[derive(SessionSubdiagnostic)]
pub enum ExpectedReturnTypeLabel<'tcx> {
#[label(slug = "typeck-expected-default-return-type")]
Unit {
#[primary_span]
span: Span,
},
#[label(slug = "typeck-expected-return-type")]
Other {
#[primary_span]
span: Span,
expected: Ty<'tcx>,
},
}

View File

@ -0,0 +1,501 @@
// check-fail
// Tests error conditions for specifying subdiagnostics using #[derive(SessionSubdiagnostic)]
// The proc_macro2 crate handles spans differently when on beta/stable release rather than nightly,
// changing the output of this test. Since SessionSubdiagnostic is strictly internal to the compiler
// the test is just ignored on stable and beta:
// ignore-beta
// ignore-stable
#![feature(rustc_private)]
#![crate_type = "lib"]
extern crate rustc_errors;
extern crate rustc_session;
extern crate rustc_span;
extern crate rustc_macros;
use rustc_errors::Applicability;
use rustc_span::Span;
use rustc_macros::SessionSubdiagnostic;
#[derive(SessionSubdiagnostic)]
#[label(slug = "label-a")]
struct A {
#[primary_span]
span: Span,
var: String,
}
#[derive(SessionSubdiagnostic)]
enum B {
#[label(slug = "label-b-a")]
A {
#[primary_span]
span: Span,
var: String,
},
#[label(slug = "label-b-b")]
B {
#[primary_span]
span: Span,
var: String,
}
}
#[derive(SessionSubdiagnostic)]
#[label(slug = "label-c")]
//~^ ERROR label without `#[primary_span]` field
struct C {
var: String,
}
#[derive(SessionSubdiagnostic)]
#[label]
//~^ ERROR `#[label]` is not a valid `SessionSubdiagnostic` attribute
struct D {
#[primary_span]
span: Span,
var: String,
}
#[derive(SessionSubdiagnostic)]
#[foo]
//~^ ERROR `#[foo]` is not a valid `SessionSubdiagnostic` attribute
//~^^ ERROR cannot find attribute `foo` in this scope
struct E {
#[primary_span]
span: Span,
var: String,
}
#[derive(SessionSubdiagnostic)]
#[label = "..."]
//~^ ERROR `#[label = ...]` is not a valid `SessionSubdiagnostic` attribute
struct F {
#[primary_span]
span: Span,
var: String,
}
#[derive(SessionSubdiagnostic)]
#[label(bug = "...")]
//~^ ERROR `#[label(bug = ...)]` is not a valid `SessionSubdiagnostic` attribute
struct G {
#[primary_span]
span: Span,
var: String,
}
#[derive(SessionSubdiagnostic)]
#[label("...")]
//~^ ERROR `#[label("...")]` is not a valid `SessionSubdiagnostic` attribute
struct H {
#[primary_span]
span: Span,
var: String,
}
#[derive(SessionSubdiagnostic)]
#[label(slug = 4)]
//~^ ERROR `#[label(slug = ...)]` is not a valid `SessionSubdiagnostic` attribute
struct J {
#[primary_span]
span: Span,
var: String,
}
#[derive(SessionSubdiagnostic)]
#[label(slug("..."))]
//~^ ERROR `#[label(slug(...))]` is not a valid `SessionSubdiagnostic` attribute
struct K {
#[primary_span]
span: Span,
var: String,
}
#[derive(SessionSubdiagnostic)]
#[label(slug)]
//~^ ERROR `#[label(slug)]` is not a valid `SessionSubdiagnostic` attribute
struct L {
#[primary_span]
span: Span,
var: String,
}
#[derive(SessionSubdiagnostic)]
#[label()]
//~^ ERROR `slug` must be set in a `#[label(...)]` attribute
struct M {
#[primary_span]
span: Span,
var: String,
}
#[derive(SessionSubdiagnostic)]
#[label(code = "...")]
//~^ ERROR `code` is not a valid nested attribute of a `label` attribute
struct N {
#[primary_span]
span: Span,
var: String,
}
#[derive(SessionSubdiagnostic)]
#[foo]
//~^ ERROR cannot find attribute `foo` in this scope
//~^^ ERROR unsupported type attribute for subdiagnostic enum
enum O {
#[label(slug = "...")]
A {
#[primary_span]
span: Span,
var: String,
}
}
#[derive(SessionSubdiagnostic)]
enum P {
#[bar]
//~^ ERROR `#[bar]` is not a valid `SessionSubdiagnostic` attribute
//~^^ ERROR cannot find attribute `bar` in this scope
A {
#[primary_span]
span: Span,
var: String,
}
}
#[derive(SessionSubdiagnostic)]
enum Q {
#[bar = "..."]
//~^ ERROR `#[bar = ...]` is not a valid `SessionSubdiagnostic` attribute
//~^^ ERROR cannot find attribute `bar` in this scope
A {
#[primary_span]
span: Span,
var: String,
}
}
#[derive(SessionSubdiagnostic)]
enum R {
#[bar = 4]
//~^ ERROR `#[bar = ...]` is not a valid `SessionSubdiagnostic` attribute
//~^^ ERROR cannot find attribute `bar` in this scope
A {
#[primary_span]
span: Span,
var: String,
}
}
#[derive(SessionSubdiagnostic)]
enum S {
#[bar("...")]
//~^ ERROR `#[bar("...")]` is not a valid `SessionSubdiagnostic` attribute
//~^^ ERROR cannot find attribute `bar` in this scope
A {
#[primary_span]
span: Span,
var: String,
}
}
#[derive(SessionSubdiagnostic)]
enum T {
#[label(code = "...")]
//~^ ERROR `code` is not a valid nested attribute of a `label`
A {
#[primary_span]
span: Span,
var: String,
}
}
#[derive(SessionSubdiagnostic)]
enum U {
#[label(slug = "label-u")]
A {
#[primary_span]
span: Span,
var: String,
},
B {
//~^ ERROR subdiagnostic kind not specified
#[primary_span]
span: Span,
var: String,
}
}
#[derive(SessionSubdiagnostic)]
#[label(slug = "...")]
//~^ ERROR label without `#[primary_span]` field
struct V {
#[primary_span]
//~^ ERROR the `#[primary_span]` attribute can only be applied to fields of type `Span`
span: String,
}
#[derive(SessionSubdiagnostic)]
#[label(slug = "...")]
struct W {
#[primary_span]
span: Span,
#[applicability]
//~^ ERROR `#[applicability]` is only valid on suggestions
applicability: Applicability,
}
#[derive(SessionSubdiagnostic)]
#[label(slug = "...")]
struct X {
#[primary_span]
span: Span,
#[bar]
//~^ ERROR `#[bar]` is not a valid `SessionSubdiagnostic` field attribute
//~^^ ERROR cannot find attribute `bar` in this scope
bar: String,
}
#[derive(SessionSubdiagnostic)]
#[label(slug = "...")]
struct Y {
#[primary_span]
span: Span,
#[bar = "..."]
//~^ ERROR `#[bar = ...]` is not a valid `SessionSubdiagnostic` field attribute
//~^^ ERROR cannot find attribute `bar` in this scope
bar: String,
}
#[derive(SessionSubdiagnostic)]
#[label(slug = "...")]
struct Z {
#[primary_span]
span: Span,
#[bar("...")]
//~^ ERROR `#[bar(...)]` is not a valid `SessionSubdiagnostic` field attribute
//~^^ ERROR cannot find attribute `bar` in this scope
bar: String,
}
#[derive(SessionSubdiagnostic)]
#[label(slug = "label-aa")]
struct AA {
#[primary_span]
span: Span,
#[skip_arg]
z: Z
}
#[derive(SessionSubdiagnostic)]
union AB {
//~^ ERROR unexpected unsupported untagged union
span: u32,
b: u64
}
#[derive(SessionSubdiagnostic)]
#[label(slug = "label-ac-1")]
//~^ NOTE previously specified here
//~^^ NOTE previously specified here
#[label(slug = "label-ac-2")]
//~^ ERROR specified multiple times
//~^^ ERROR specified multiple times
struct AC {
#[primary_span]
span: Span,
}
#[derive(SessionSubdiagnostic)]
#[label(slug = "label-ad-1", slug = "label-ad-2")]
//~^ ERROR specified multiple times
//~^^ NOTE previously specified here
struct AD {
#[primary_span]
span: Span,
}
#[derive(SessionSubdiagnostic)]
#[label(slug = "label-ad-1")]
struct AE {
#[primary_span]
//~^ NOTE previously specified here
span_a: Span,
#[primary_span]
//~^ ERROR specified multiple times
span_b: Span,
}
#[derive(SessionSubdiagnostic)]
struct AF {
//~^ ERROR subdiagnostic kind not specified
#[primary_span]
span: Span,
}
#[derive(SessionSubdiagnostic)]
#[suggestion(slug = "suggestion-af", code = "...")]
struct AG {
#[primary_span]
span: Span,
#[applicability]
applicability: Applicability,
var: String,
}
#[derive(SessionSubdiagnostic)]
enum AH {
#[suggestion(slug = "suggestion-ag-a", code = "...")]
A {
#[primary_span]
span: Span,
#[applicability]
applicability: Applicability,
var: String,
},
#[suggestion(slug = "suggestion-ag-b", code = "...")]
B {
#[primary_span]
span: Span,
#[applicability]
applicability: Applicability,
var: String,
}
}
#[derive(SessionSubdiagnostic)]
#[suggestion(slug = "...", code = "...", code = "...")]
//~^ ERROR specified multiple times
//~^^ NOTE previously specified here
struct AI {
#[primary_span]
span: Span,
#[applicability]
applicability: Applicability,
}
#[derive(SessionSubdiagnostic)]
#[suggestion(slug = "...", code = "...")]
struct AJ {
#[primary_span]
span: Span,
#[applicability]
//~^ NOTE previously specified here
applicability_a: Applicability,
#[applicability]
//~^ ERROR specified multiple times
applicability_b: Applicability,
}
#[derive(SessionSubdiagnostic)]
#[suggestion(slug = "...", code = "...")]
//~^ ERROR suggestion without `applicability`
struct AK {
#[primary_span]
span: Span,
#[applicability]
//~^ ERROR the `#[applicability]` attribute can only be applied to fields of type `Applicability`
applicability: Span,
}
#[derive(SessionSubdiagnostic)]
#[suggestion(slug = "...", code = "...")]
//~^ ERROR suggestion without `applicability`
struct AL {
#[primary_span]
span: Span,
}
#[derive(SessionSubdiagnostic)]
#[suggestion(slug = "...")]
//~^ ERROR suggestion without `code = "..."`
struct AM {
#[primary_span]
span: Span,
#[applicability]
applicability: Applicability,
}
#[derive(SessionSubdiagnostic)]
#[suggestion(slug = "...", code ="...", applicability = "foo")]
//~^ ERROR invalid applicability
struct AN {
#[primary_span]
span: Span,
}
#[derive(SessionSubdiagnostic)]
#[help(slug = "label-am")]
struct AO {
var: String
}
#[derive(SessionSubdiagnostic)]
#[note(slug = "label-an")]
struct AP;
#[derive(SessionSubdiagnostic)]
#[suggestion(slug = "...", code = "...")]
//~^ ERROR suggestion without `applicability`
//~^^ ERROR suggestion without `#[primary_span]` field
struct AQ {
var: String,
}
#[derive(SessionSubdiagnostic)]
#[suggestion(slug = "...", code ="...", applicability = "machine-applicable")]
struct AR {
#[primary_span]
span: Span,
}
#[derive(SessionSubdiagnostic)]
#[label]
//~^ ERROR unsupported type attribute for subdiagnostic enum
enum AS {
#[label(slug = "...")]
A {
#[primary_span]
span: Span,
var: String,
}
}
#[derive(SessionSubdiagnostic)]
#[suggestion(slug = "...", code ="{var}", applicability = "machine-applicable")]
struct AT {
#[primary_span]
span: Span,
var: String,
}
#[derive(SessionSubdiagnostic)]
#[suggestion(slug = "...", code ="{var}", applicability = "machine-applicable")]
//~^ ERROR `var` doesn't refer to a field on this type
struct AU {
#[primary_span]
span: Span,
}
#[derive(SessionSubdiagnostic)]
enum AV {
#[suggestion(slug = "...", code ="{var}", applicability = "machine-applicable")]
A {
#[primary_span]
span: Span,
var: String,
}
}
#[derive(SessionSubdiagnostic)]
enum AW {
#[suggestion(slug = "...", code ="{var}", applicability = "machine-applicable")]
//~^ ERROR `var` doesn't refer to a field on this type
A {
#[primary_span]
span: Span,
}
}

View File

@ -0,0 +1,387 @@
error: label without `#[primary_span]` field
--> $DIR/subdiagnostic-derive.rs:47:1
|
LL | / #[label(slug = "label-c")]
LL | |
LL | | struct C {
LL | | var: String,
LL | | }
| |_^
error: `#[label]` is not a valid `SessionSubdiagnostic` attribute
--> $DIR/subdiagnostic-derive.rs:54:1
|
LL | #[label]
| ^^^^^^^^
error: `#[foo]` is not a valid `SessionSubdiagnostic` attribute
--> $DIR/subdiagnostic-derive.rs:63:1
|
LL | #[foo]
| ^^^^^^
error: `#[label = ...]` is not a valid `SessionSubdiagnostic` attribute
--> $DIR/subdiagnostic-derive.rs:73:1
|
LL | #[label = "..."]
| ^^^^^^^^^^^^^^^^
error: `#[label(bug = ...)]` is not a valid `SessionSubdiagnostic` attribute
--> $DIR/subdiagnostic-derive.rs:82:9
|
LL | #[label(bug = "...")]
| ^^^^^^^^^^^
error: `#[label("...")]` is not a valid `SessionSubdiagnostic` attribute
--> $DIR/subdiagnostic-derive.rs:91:1
|
LL | #[label("...")]
| ^^^^^^^^^^^^^^^
error: `#[label(slug = ...)]` is not a valid `SessionSubdiagnostic` attribute
--> $DIR/subdiagnostic-derive.rs:100:9
|
LL | #[label(slug = 4)]
| ^^^^^^^^
|
= help: value must be a string
error: `#[label(slug(...))]` is not a valid `SessionSubdiagnostic` attribute
--> $DIR/subdiagnostic-derive.rs:109:9
|
LL | #[label(slug("..."))]
| ^^^^^^^^^^^
error: `#[label(slug)]` is not a valid `SessionSubdiagnostic` attribute
--> $DIR/subdiagnostic-derive.rs:118:9
|
LL | #[label(slug)]
| ^^^^
error: `slug` must be set in a `#[label(...)]` attribute
--> $DIR/subdiagnostic-derive.rs:127:1
|
LL | #[label()]
| ^^^^^^^^^^
error: `code` is not a valid nested attribute of a `label` attribute
--> $DIR/subdiagnostic-derive.rs:136:1
|
LL | #[label(code = "...")]
| ^^^^^^^^^^^^^^^^^^^^^^
error: unsupported type attribute for subdiagnostic enum
--> $DIR/subdiagnostic-derive.rs:145:1
|
LL | #[foo]
| ^^^^^^
error: `#[bar]` is not a valid `SessionSubdiagnostic` attribute
--> $DIR/subdiagnostic-derive.rs:159:5
|
LL | #[bar]
| ^^^^^^
error: `#[bar = ...]` is not a valid `SessionSubdiagnostic` attribute
--> $DIR/subdiagnostic-derive.rs:171:5
|
LL | #[bar = "..."]
| ^^^^^^^^^^^^^^
error: `#[bar = ...]` is not a valid `SessionSubdiagnostic` attribute
--> $DIR/subdiagnostic-derive.rs:183:5
|
LL | #[bar = 4]
| ^^^^^^^^^^
error: `#[bar("...")]` is not a valid `SessionSubdiagnostic` attribute
--> $DIR/subdiagnostic-derive.rs:195:5
|
LL | #[bar("...")]
| ^^^^^^^^^^^^^
error: `code` is not a valid nested attribute of a `label` attribute
--> $DIR/subdiagnostic-derive.rs:207:5
|
LL | #[label(code = "...")]
| ^^^^^^^^^^^^^^^^^^^^^^
error: subdiagnostic kind not specified
--> $DIR/subdiagnostic-derive.rs:224:5
|
LL | B {
| ^
error: the `#[primary_span]` attribute can only be applied to fields of type `Span`
--> $DIR/subdiagnostic-derive.rs:236:5
|
LL | #[primary_span]
| ^^^^^^^^^^^^^^^
error: label without `#[primary_span]` field
--> $DIR/subdiagnostic-derive.rs:233:1
|
LL | / #[label(slug = "...")]
LL | |
LL | | struct V {
LL | | #[primary_span]
LL | |
LL | | span: String,
LL | | }
| |_^
error: `#[applicability]` is only valid on suggestions
--> $DIR/subdiagnostic-derive.rs:246:5
|
LL | #[applicability]
| ^^^^^^^^^^^^^^^^
error: `#[bar]` is not a valid `SessionSubdiagnostic` field attribute
--> $DIR/subdiagnostic-derive.rs:256:5
|
LL | #[bar]
| ^^^^^^
error: `#[bar = ...]` is not a valid `SessionSubdiagnostic` field attribute
--> $DIR/subdiagnostic-derive.rs:267:5
|
LL | #[bar = "..."]
| ^^^^^^^^^^^^^^
error: `#[bar(...)]` is not a valid `SessionSubdiagnostic` field attribute
--> $DIR/subdiagnostic-derive.rs:278:5
|
LL | #[bar("...")]
| ^^^^^^^^^^^^^
error: unexpected unsupported untagged union
--> $DIR/subdiagnostic-derive.rs:294:1
|
LL | / union AB {
LL | |
LL | | span: u32,
LL | | b: u64
LL | | }
| |_^
error: specified multiple times
--> $DIR/subdiagnostic-derive.rs:304:9
|
LL | #[label(slug = "label-ac-2")]
| ^^^^^^^^^^^^^^^^^^^
|
note: previously specified here
--> $DIR/subdiagnostic-derive.rs:301:9
|
LL | #[label(slug = "label-ac-1")]
| ^^^^^^^^^^^^^^^^^^^
error: specified multiple times
--> $DIR/subdiagnostic-derive.rs:304:1
|
LL | #[label(slug = "label-ac-2")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
note: previously specified here
--> $DIR/subdiagnostic-derive.rs:301:1
|
LL | #[label(slug = "label-ac-1")]
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
error: specified multiple times
--> $DIR/subdiagnostic-derive.rs:313:30
|
LL | #[label(slug = "label-ad-1", slug = "label-ad-2")]
| ^^^^^^^^^^^^^^^^^^^
|
note: previously specified here
--> $DIR/subdiagnostic-derive.rs:313:9
|
LL | #[label(slug = "label-ad-1", slug = "label-ad-2")]
| ^^^^^^^^^^^^^^^^^^^
error: specified multiple times
--> $DIR/subdiagnostic-derive.rs:327:5
|
LL | #[primary_span]
| ^^^^^^^^^^^^^^^
|
note: previously specified here
--> $DIR/subdiagnostic-derive.rs:324:5
|
LL | #[primary_span]
| ^^^^^^^^^^^^^^^
error: subdiagnostic kind not specified
--> $DIR/subdiagnostic-derive.rs:333:8
|
LL | struct AF {
| ^^
error: specified multiple times
--> $DIR/subdiagnostic-derive.rs:370:42
|
LL | #[suggestion(slug = "...", code = "...", code = "...")]
| ^^^^^^^^^^^^
|
note: previously specified here
--> $DIR/subdiagnostic-derive.rs:370:28
|
LL | #[suggestion(slug = "...", code = "...", code = "...")]
| ^^^^^^^^^^^^
error: specified multiple times
--> $DIR/subdiagnostic-derive.rs:388:5
|
LL | #[applicability]
| ^^^^^^^^^^^^^^^^
|
note: previously specified here
--> $DIR/subdiagnostic-derive.rs:385:5
|
LL | #[applicability]
| ^^^^^^^^^^^^^^^^
error: the `#[applicability]` attribute can only be applied to fields of type `Applicability`
--> $DIR/subdiagnostic-derive.rs:399:5
|
LL | #[applicability]
| ^^^^^^^^^^^^^^^^
error: suggestion without `applicability`
--> $DIR/subdiagnostic-derive.rs:394:1
|
LL | / #[suggestion(slug = "...", code = "...")]
LL | |
LL | | struct AK {
LL | | #[primary_span]
... |
LL | | applicability: Span,
LL | | }
| |_^
error: suggestion without `applicability`
--> $DIR/subdiagnostic-derive.rs:405:1
|
LL | / #[suggestion(slug = "...", code = "...")]
LL | |
LL | | struct AL {
LL | | #[primary_span]
LL | | span: Span,
LL | | }
| |_^
error: suggestion without `code = "..."`
--> $DIR/subdiagnostic-derive.rs:413:1
|
LL | / #[suggestion(slug = "...")]
LL | |
LL | | struct AM {
LL | | #[primary_span]
... |
LL | | applicability: Applicability,
LL | | }
| |_^
error: invalid applicability
--> $DIR/subdiagnostic-derive.rs:423:41
|
LL | #[suggestion(slug = "...", code ="...", applicability = "foo")]
| ^^^^^^^^^^^^^^^^^^^^^
error: suggestion without `applicability`
--> $DIR/subdiagnostic-derive.rs:441:1
|
LL | / #[suggestion(slug = "...", code = "...")]
LL | |
LL | |
LL | | struct AQ {
LL | | var: String,
LL | | }
| |_^
error: suggestion without `#[primary_span]` field
--> $DIR/subdiagnostic-derive.rs:441:1
|
LL | / #[suggestion(slug = "...", code = "...")]
LL | |
LL | |
LL | | struct AQ {
LL | | var: String,
LL | | }
| |_^
error: unsupported type attribute for subdiagnostic enum
--> $DIR/subdiagnostic-derive.rs:456:1
|
LL | #[label]
| ^^^^^^^^
error: `var` doesn't refer to a field on this type
--> $DIR/subdiagnostic-derive.rs:476:34
|
LL | #[suggestion(slug = "...", code ="{var}", applicability = "machine-applicable")]
| ^^^^^^^
error: `var` doesn't refer to a field on this type
--> $DIR/subdiagnostic-derive.rs:495:38
|
LL | #[suggestion(slug = "...", code ="{var}", applicability = "machine-applicable")]
| ^^^^^^^
error: cannot find attribute `foo` in this scope
--> $DIR/subdiagnostic-derive.rs:63:3
|
LL | #[foo]
| ^^^
error: cannot find attribute `foo` in this scope
--> $DIR/subdiagnostic-derive.rs:145:3
|
LL | #[foo]
| ^^^
error: cannot find attribute `bar` in this scope
--> $DIR/subdiagnostic-derive.rs:159:7
|
LL | #[bar]
| ^^^
error: cannot find attribute `bar` in this scope
--> $DIR/subdiagnostic-derive.rs:171:7
|
LL | #[bar = "..."]
| ^^^
error: cannot find attribute `bar` in this scope
--> $DIR/subdiagnostic-derive.rs:183:7
|
LL | #[bar = 4]
| ^^^
error: cannot find attribute `bar` in this scope
--> $DIR/subdiagnostic-derive.rs:195:7
|
LL | #[bar("...")]
| ^^^
error: cannot find attribute `bar` in this scope
--> $DIR/subdiagnostic-derive.rs:256:7
|
LL | #[bar]
| ^^^
error: cannot find attribute `bar` in this scope
--> $DIR/subdiagnostic-derive.rs:267:7
|
LL | #[bar = "..."]
| ^^^
error: cannot find attribute `bar` in this scope
--> $DIR/subdiagnostic-derive.rs:278:7
|
LL | #[bar("...")]
| ^^^
error: aborting due to 51 previous errors