mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-21 22:34:05 +00:00
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:
parent
aa2abc9d12
commit
49ec909ca7
@ -82,3 +82,11 @@ typeck-value-of-associated-struct-already-specified =
|
||||
|
||||
typeck-address-of-temporary-taken = cannot take address of a temporary
|
||||
.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
|
||||
|
@ -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]
|
||||
#[derive(Clone, Debug, Encodable, Decodable)]
|
||||
pub struct Diagnostic {
|
||||
@ -768,6 +775,13 @@ impl Diagnostic {
|
||||
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 {
|
||||
self.span = sp.into();
|
||||
if let Some(span) = self.span.primary_span() {
|
||||
|
@ -530,6 +530,11 @@ impl<'a, G: EmissionGuarantee> DiagnosticBuilder<'a, G> {
|
||||
name: impl Into<Cow<'static, str>>,
|
||||
arg: DiagnosticArgValue<'static>,
|
||||
) -> &mut Self);
|
||||
|
||||
forward!(pub fn subdiagnostic(
|
||||
&mut self,
|
||||
subdiagnostic: impl crate::AddSubdiagnostic
|
||||
) -> &mut Self);
|
||||
}
|
||||
|
||||
impl<G: EmissionGuarantee> Debug for DiagnosticBuilder<'_, G> {
|
||||
|
@ -370,8 +370,8 @@ impl fmt::Display for ExplicitBug {
|
||||
impl error::Error for ExplicitBug {}
|
||||
|
||||
pub use diagnostic::{
|
||||
Diagnostic, DiagnosticArg, DiagnosticArgValue, DiagnosticId, DiagnosticStyledString,
|
||||
IntoDiagnosticArg, SubDiagnostic,
|
||||
AddSubdiagnostic, Diagnostic, DiagnosticArg, DiagnosticArgValue, DiagnosticId,
|
||||
DiagnosticStyledString, IntoDiagnosticArg, SubDiagnostic,
|
||||
};
|
||||
pub use diagnostic_builder::{DiagnosticBuilder, EmissionGuarantee};
|
||||
use std::backtrace::Backtrace;
|
||||
|
@ -1,5 +1,6 @@
|
||||
#![feature(proc_macro_diagnostic)]
|
||||
#![feature(allow_internal_unstable)]
|
||||
#![feature(let_else)]
|
||||
#![feature(proc_macro_diagnostic)]
|
||||
#![allow(rustc::default_hash_types)]
|
||||
#![recursion_limit = "128"]
|
||||
|
||||
@ -77,3 +78,18 @@ decl_derive!(
|
||||
suggestion_hidden,
|
||||
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
@ -1,5 +1,6 @@
|
||||
use super::FnCtxt;
|
||||
use crate::astconv::AstConv;
|
||||
use crate::errors::{AddReturnTypeSuggestion, ExpectedReturnTypeLabel};
|
||||
|
||||
use rustc_ast::util::parser::ExprPrecedence;
|
||||
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).
|
||||
match (&fn_decl.output, found.is_suggestable(self.tcx), can_suggest, expected.is_unit()) {
|
||||
(&hir::FnRetTy::DefaultReturn(span), true, true, true) => {
|
||||
err.span_suggestion(
|
||||
span,
|
||||
"try adding a return type",
|
||||
format!("-> {} ", found),
|
||||
Applicability::MachineApplicable,
|
||||
);
|
||||
err.subdiagnostic(AddReturnTypeSuggestion::Add { span, found });
|
||||
true
|
||||
}
|
||||
(&hir::FnRetTy::DefaultReturn(span), false, true, true) => {
|
||||
// FIXME: if `found` could be `impl Iterator` or `impl Fn*`, we should suggest
|
||||
// that.
|
||||
err.span_suggestion(
|
||||
span,
|
||||
"a return type might be missing here",
|
||||
"-> _ ".to_string(),
|
||||
Applicability::HasPlaceholders,
|
||||
);
|
||||
err.subdiagnostic(AddReturnTypeSuggestion::MissingHere { span });
|
||||
true
|
||||
}
|
||||
(&hir::FnRetTy::DefaultReturn(span), _, false, true) => {
|
||||
// `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
|
||||
}
|
||||
// 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
|
||||
// are not, the expectation must have been caused by something else.
|
||||
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);
|
||||
debug!("suggest_missing_return_type: return type {:?}", ty);
|
||||
debug!("suggest_missing_return_type: expected type {:?}", ty);
|
||||
let bound_vars = self.tcx.late_bound_vars(fn_id);
|
||||
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);
|
||||
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);
|
||||
return true;
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
//! Errors emitted by typeck.
|
||||
use rustc_errors::Applicability;
|
||||
use rustc_macros::SessionDiagnostic;
|
||||
use rustc_macros::{SessionDiagnostic, SessionSubdiagnostic};
|
||||
use rustc_middle::ty::Ty;
|
||||
use rustc_span::{symbol::Ident, Span, Symbol};
|
||||
|
||||
@ -190,3 +190,41 @@ pub struct AddressOfTemporaryTaken {
|
||||
#[label]
|
||||
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>,
|
||||
},
|
||||
}
|
||||
|
501
src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs
Normal file
501
src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs
Normal 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,
|
||||
}
|
||||
}
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user