Rollup merge of #103051 - davidtwco:translation-tidying-up, r=compiler-errors
translation: doc comments with derives, subdiagnostic-less enum variants, more derive use - Adds support for `doc` attributes in the diagnostic derives so that documentation comments don't result in the derive failing. - Adds support for enum variants in the subdiagnostic derive to not actually correspond to an addition to a diagnostic. - Made use of the derive in more places in the `rustc_ast_lowering`, `rustc_ast_passes`, `rustc_lint`, `rustc_session`, `rustc_infer` - taking advantage of recent additions like eager subdiagnostics, multispan suggestions, etc. cc #100717
This commit is contained in:
commit
e11511dfa6
17 changed files with 286 additions and 238 deletions
|
@ -1,7 +1,4 @@
|
|||
use rustc_errors::{
|
||||
fluent, AddToDiagnostic, Applicability, Diagnostic, DiagnosticArgFromDisplay,
|
||||
SubdiagnosticMessage,
|
||||
};
|
||||
use rustc_errors::DiagnosticArgFromDisplay;
|
||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
||||
use rustc_span::{symbol::Ident, Span, Symbol};
|
||||
|
||||
|
@ -15,25 +12,15 @@ pub struct GenericTypeWithParentheses {
|
|||
pub sub: Option<UseAngleBrackets>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Copy, Subdiagnostic)]
|
||||
#[multipart_suggestion(ast_lowering::use_angle_brackets, applicability = "maybe-incorrect")]
|
||||
pub struct UseAngleBrackets {
|
||||
#[suggestion_part(code = "<")]
|
||||
pub open_param: Span,
|
||||
#[suggestion_part(code = ">")]
|
||||
pub close_param: Span,
|
||||
}
|
||||
|
||||
impl AddToDiagnostic for UseAngleBrackets {
|
||||
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
|
||||
where
|
||||
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
|
||||
{
|
||||
diag.multipart_suggestion(
|
||||
fluent::ast_lowering::use_angle_brackets,
|
||||
vec![(self.open_param, String::from("<")), (self.close_param, String::from(">"))],
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(ast_lowering::invalid_abi, code = "E0703")]
|
||||
#[note]
|
||||
|
@ -68,30 +55,20 @@ pub struct AssocTyParentheses {
|
|||
pub sub: AssocTyParenthesesSub,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Copy, Subdiagnostic)]
|
||||
pub enum AssocTyParenthesesSub {
|
||||
Empty { parentheses_span: Span },
|
||||
NotEmpty { open_param: Span, close_param: Span },
|
||||
}
|
||||
|
||||
impl AddToDiagnostic for AssocTyParenthesesSub {
|
||||
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
|
||||
where
|
||||
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
|
||||
{
|
||||
match self {
|
||||
Self::Empty { parentheses_span } => diag.multipart_suggestion(
|
||||
fluent::ast_lowering::remove_parentheses,
|
||||
vec![(parentheses_span, String::new())],
|
||||
Applicability::MaybeIncorrect,
|
||||
),
|
||||
Self::NotEmpty { open_param, close_param } => diag.multipart_suggestion(
|
||||
fluent::ast_lowering::use_angle_brackets,
|
||||
vec![(open_param, String::from("<")), (close_param, String::from(">"))],
|
||||
Applicability::MaybeIncorrect,
|
||||
),
|
||||
};
|
||||
}
|
||||
#[multipart_suggestion(ast_lowering::remove_parentheses)]
|
||||
Empty {
|
||||
#[suggestion_part(code = "")]
|
||||
parentheses_span: Span,
|
||||
},
|
||||
#[multipart_suggestion(ast_lowering::use_angle_brackets)]
|
||||
NotEmpty {
|
||||
#[suggestion_part(code = "<")]
|
||||
open_param: Span,
|
||||
#[suggestion_part(code = ">")]
|
||||
close_param: Span,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
|
|
@ -14,6 +14,7 @@ use rustc_ast::*;
|
|||
use rustc_ast_pretty::pprust::{self, State};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_errors::{error_code, fluent, pluralize, struct_span_err, Applicability};
|
||||
use rustc_macros::Subdiagnostic;
|
||||
use rustc_parse::validate_attr;
|
||||
use rustc_session::lint::builtin::{
|
||||
DEPRECATED_WHERE_CLAUSE_LOCATION, MISSING_ABI, PATTERNS_IN_FNS_WITHOUT_BODY,
|
||||
|
@ -1805,15 +1806,17 @@ pub fn check_crate(session: &Session, krate: &Crate, lints: &mut LintBuffer) ->
|
|||
}
|
||||
|
||||
/// Used to forbid `let` expressions in certain syntactic locations.
|
||||
#[derive(Clone, Copy)]
|
||||
#[derive(Clone, Copy, Subdiagnostic)]
|
||||
pub(crate) enum ForbiddenLetReason {
|
||||
/// `let` is not valid and the source environment is not important
|
||||
GenericForbidden,
|
||||
/// A let chain with the `||` operator
|
||||
NotSupportedOr(Span),
|
||||
#[note(ast_passes::not_supported_or)]
|
||||
NotSupportedOr(#[primary_span] Span),
|
||||
/// A let chain with invalid parentheses
|
||||
///
|
||||
/// For example, `let 1 = 1 && (expr && expr)` is allowed
|
||||
/// but `(let 1 = 1 && (let 1 = 1 && (let 1 = 1))) && let a = 1` is not
|
||||
NotSupportedParentheses(Span),
|
||||
#[note(ast_passes::not_supported_parentheses)]
|
||||
NotSupportedParentheses(#[primary_span] Span),
|
||||
}
|
||||
|
|
|
@ -16,23 +16,6 @@ pub struct ForbiddenLet {
|
|||
pub(crate) reason: ForbiddenLetReason,
|
||||
}
|
||||
|
||||
impl AddToDiagnostic for ForbiddenLetReason {
|
||||
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
|
||||
where
|
||||
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
|
||||
{
|
||||
match self {
|
||||
Self::GenericForbidden => {}
|
||||
Self::NotSupportedOr(span) => {
|
||||
diag.span_note(span, fluent::ast_passes::not_supported_or);
|
||||
}
|
||||
Self::NotSupportedParentheses(span) => {
|
||||
diag.span_note(span, fluent::ast_passes::not_supported_parentheses);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(ast_passes::forbidden_let_stable)]
|
||||
#[note]
|
||||
|
|
|
@ -164,7 +164,9 @@ infer_region_explanation = {$pref_kind ->
|
|||
}
|
||||
|
||||
infer_mismatched_static_lifetime = incompatible lifetime on type
|
||||
infer_msl_impl_note = ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
|
||||
infer_does_not_outlive_static_from_impl = ...does not necessarily outlive the static lifetime introduced by the compatible `impl`
|
||||
infer_implicit_static_lifetime_note = this has an implicit `'static` lifetime requirement
|
||||
infer_implicit_static_lifetime_suggestion = consider relaxing the implicit `'static` requirement
|
||||
infer_msl_introduces_static = introduces a `'static` lifetime requirement
|
||||
infer_msl_unmet_req = because this has an unmet lifetime requirement
|
||||
infer_msl_trait_note = this has an implicit `'static` lifetime requirement
|
||||
|
|
|
@ -54,3 +54,7 @@ session_crate_name_empty = crate name must not be empty
|
|||
session_invalid_character_in_create_name = invalid character `{$character}` in crate name: `{$crate_name}`
|
||||
|
||||
session_expr_parentheses_needed = parentheses are required to parse this as an expression
|
||||
|
||||
session_skipping_const_checks = skipping const checks
|
||||
session_unleashed_feature_help_named = skipping check for `{$gate}` feature
|
||||
session_unleashed_feature_help_unnamed = skipping check that does not even have a feature gate
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
use crate::{
|
||||
fluent, DiagnosticArgValue, DiagnosticBuilder, Handler, IntoDiagnostic, IntoDiagnosticArg,
|
||||
};
|
||||
use rustc_target::abi::TargetDataLayoutErrors;
|
||||
use rustc_target::spec::{PanicStrategy, SplitDebuginfo, StackProtector, TargetTriple};
|
||||
|
||||
use rustc_ast as ast;
|
||||
use rustc_ast_pretty::pprust;
|
||||
use rustc_hir as hir;
|
||||
use rustc_lint_defs::Level;
|
||||
use rustc_span::edition::Edition;
|
||||
use rustc_span::symbol::{Ident, MacroRulesNormalizedIdent, Symbol};
|
||||
use rustc_target::abi::TargetDataLayoutErrors;
|
||||
use rustc_target::spec::{PanicStrategy, SplitDebuginfo, StackProtector, TargetTriple};
|
||||
use std::borrow::Cow;
|
||||
use std::fmt;
|
||||
use std::num::ParseIntError;
|
||||
|
@ -155,6 +155,21 @@ impl IntoDiagnosticArg for ast::token::TokenKind {
|
|||
}
|
||||
}
|
||||
|
||||
impl IntoDiagnosticArg for Level {
|
||||
fn into_diagnostic_arg(self) -> DiagnosticArgValue<'static> {
|
||||
DiagnosticArgValue::Str(Cow::Borrowed(match self {
|
||||
Level::Allow => "-A",
|
||||
Level::Warn => "-W",
|
||||
Level::ForceWarn(_) => "--force-warn",
|
||||
Level::Deny => "-D",
|
||||
Level::Forbid => "-F",
|
||||
Level::Expect(_) => {
|
||||
unreachable!("lints with the level of `expect` should not run this code");
|
||||
}
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
||||
impl IntoDiagnostic<'_, !> for TargetDataLayoutErrors<'_> {
|
||||
fn into_diagnostic(self, handler: &Handler) -> DiagnosticBuilder<'_, !> {
|
||||
let mut diag;
|
||||
|
|
|
@ -459,47 +459,34 @@ impl AddToDiagnostic for IntroducesStaticBecauseUnmetLifetimeReq {
|
|||
}
|
||||
}
|
||||
|
||||
pub struct ImplNote {
|
||||
pub impl_span: Option<Span>,
|
||||
// FIXME(#100717): replace with a `Option<Span>` when subdiagnostic supports that
|
||||
#[derive(Subdiagnostic)]
|
||||
pub enum DoesNotOutliveStaticFromImpl {
|
||||
#[note(infer::does_not_outlive_static_from_impl)]
|
||||
Spanned {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
#[note(infer::does_not_outlive_static_from_impl)]
|
||||
Unspanned,
|
||||
}
|
||||
|
||||
impl AddToDiagnostic for ImplNote {
|
||||
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
|
||||
where
|
||||
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
|
||||
{
|
||||
match self.impl_span {
|
||||
Some(span) => diag.span_note(span, fluent::infer::msl_impl_note),
|
||||
None => diag.note(fluent::infer::msl_impl_note),
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
pub enum TraitSubdiag {
|
||||
Note { span: Span },
|
||||
Sugg { span: Span },
|
||||
}
|
||||
|
||||
// FIXME(#100717) used in `Vec<TraitSubdiag>` so requires eager translation/list support
|
||||
impl AddToDiagnostic for TraitSubdiag {
|
||||
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
|
||||
where
|
||||
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
|
||||
{
|
||||
match self {
|
||||
TraitSubdiag::Note { span } => {
|
||||
diag.span_note(span, "this has an implicit `'static` lifetime requirement");
|
||||
}
|
||||
TraitSubdiag::Sugg { span } => {
|
||||
diag.span_suggestion_verbose(
|
||||
span,
|
||||
"consider relaxing the implicit `'static` requirement",
|
||||
" + '_".to_owned(),
|
||||
rustc_errors::Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
#[derive(Subdiagnostic)]
|
||||
pub enum ImplicitStaticLifetimeSubdiag {
|
||||
#[note(infer::implicit_static_lifetime_note)]
|
||||
Note {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
#[suggestion_verbose(
|
||||
infer::implicit_static_lifetime_suggestion,
|
||||
code = " + '_",
|
||||
applicability = "maybe-incorrect"
|
||||
)]
|
||||
Sugg {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
|
@ -512,7 +499,7 @@ pub struct MismatchedStaticLifetime<'a> {
|
|||
#[subdiagnostic]
|
||||
pub expl: Option<note_and_explain::RegionExplanation<'a>>,
|
||||
#[subdiagnostic]
|
||||
pub impl_note: ImplNote,
|
||||
#[subdiagnostic]
|
||||
pub trait_subdiags: Vec<TraitSubdiag>,
|
||||
pub does_not_outlive_static_from_impl: DoesNotOutliveStaticFromImpl,
|
||||
#[subdiagnostic(eager)]
|
||||
pub implicit_static_lifetimes: Vec<ImplicitStaticLifetimeSubdiag>,
|
||||
}
|
||||
|
|
|
@ -2,7 +2,9 @@
|
|||
//! to hold.
|
||||
|
||||
use crate::errors::{note_and_explain, IntroducesStaticBecauseUnmetLifetimeReq};
|
||||
use crate::errors::{ImplNote, MismatchedStaticLifetime, TraitSubdiag};
|
||||
use crate::errors::{
|
||||
DoesNotOutliveStaticFromImpl, ImplicitStaticLifetimeSubdiag, MismatchedStaticLifetime,
|
||||
};
|
||||
use crate::infer::error_reporting::nice_region_error::NiceRegionError;
|
||||
use crate::infer::lexical_region_resolve::RegionResolutionError;
|
||||
use crate::infer::{SubregionOrigin, TypeTrace};
|
||||
|
@ -56,7 +58,7 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
|||
note_and_explain::SuffixKind::Continues,
|
||||
);
|
||||
let mut impl_span = None;
|
||||
let mut trait_subdiags = Vec::new();
|
||||
let mut implicit_static_lifetimes = Vec::new();
|
||||
if let Some(impl_node) = self.tcx().hir().get_if_local(*impl_def_id) {
|
||||
// If an impl is local, then maybe this isn't what they want. Try to
|
||||
// be as helpful as possible with implicit lifetimes.
|
||||
|
@ -90,10 +92,12 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
|||
// Otherwise, point at all implicit static lifetimes
|
||||
|
||||
for span in &traits {
|
||||
trait_subdiags.push(TraitSubdiag::Note { span: *span });
|
||||
implicit_static_lifetimes
|
||||
.push(ImplicitStaticLifetimeSubdiag::Note { span: *span });
|
||||
// It would be nice to put this immediately under the above note, but they get
|
||||
// pushed to the end.
|
||||
trait_subdiags.push(TraitSubdiag::Sugg { span: span.shrink_to_hi() });
|
||||
implicit_static_lifetimes
|
||||
.push(ImplicitStaticLifetimeSubdiag::Sugg { span: span.shrink_to_hi() });
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -105,8 +109,10 @@ impl<'a, 'tcx> NiceRegionError<'a, 'tcx> {
|
|||
cause_span: cause.span,
|
||||
unmet_lifetime_reqs: multispan_subdiag,
|
||||
expl,
|
||||
impl_note: ImplNote { impl_span },
|
||||
trait_subdiags,
|
||||
does_not_outlive_static_from_impl: impl_span
|
||||
.map(|span| DoesNotOutliveStaticFromImpl::Spanned { span })
|
||||
.unwrap_or(DoesNotOutliveStaticFromImpl::Unspanned),
|
||||
implicit_static_lifetimes,
|
||||
};
|
||||
let reported = self.tcx().sess.emit_err(err);
|
||||
Some(reported)
|
||||
|
|
|
@ -88,34 +88,13 @@ pub struct BuiltinEllpisisInclusiveRangePatterns {
|
|||
pub replace: String,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[note(lint::requested_level)]
|
||||
pub struct RequestedLevel {
|
||||
pub level: Level,
|
||||
pub lint_name: String,
|
||||
}
|
||||
|
||||
impl AddToDiagnostic for RequestedLevel {
|
||||
fn add_to_diagnostic_with<F>(self, diag: &mut Diagnostic, _: F)
|
||||
where
|
||||
F: Fn(&mut Diagnostic, SubdiagnosticMessage) -> SubdiagnosticMessage,
|
||||
{
|
||||
diag.note(fluent::lint::requested_level);
|
||||
diag.set_arg(
|
||||
"level",
|
||||
match self.level {
|
||||
Level::Allow => "-A",
|
||||
Level::Warn => "-W",
|
||||
Level::ForceWarn(_) => "--force-warn",
|
||||
Level::Deny => "-D",
|
||||
Level::Forbid => "-F",
|
||||
Level::Expect(_) => {
|
||||
unreachable!("lints with the level of `expect` should not run this code");
|
||||
}
|
||||
},
|
||||
);
|
||||
diag.set_arg("lint_name", self.lint_name);
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(lint::unsupported_group, code = "E0602")]
|
||||
pub struct UnsupportedGroup {
|
||||
|
|
|
@ -5,7 +5,7 @@ use crate::diagnostics::error::{
|
|||
DiagnosticDeriveError,
|
||||
};
|
||||
use crate::diagnostics::utils::{
|
||||
build_field_mapping, report_error_if_not_applied_to_span, report_type_error,
|
||||
build_field_mapping, is_doc_comment, report_error_if_not_applied_to_span, report_type_error,
|
||||
should_generate_set_arg, type_is_unit, type_matches_path, FieldInfo, FieldInnerTy, FieldMap,
|
||||
HasFieldMap, SetOnce, SpannedOption, SubdiagnosticKind,
|
||||
};
|
||||
|
@ -152,8 +152,12 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
|||
fn parse_subdiag_attribute(
|
||||
&self,
|
||||
attr: &Attribute,
|
||||
) -> Result<(SubdiagnosticKind, Path), DiagnosticDeriveError> {
|
||||
let (subdiag, slug) = SubdiagnosticKind::from_attr(attr, self)?;
|
||||
) -> Result<Option<(SubdiagnosticKind, Path)>, DiagnosticDeriveError> {
|
||||
let Some((subdiag, slug)) = SubdiagnosticKind::from_attr(attr, self)? else {
|
||||
// Some attributes aren't errors - like documentation comments - but also aren't
|
||||
// subdiagnostics.
|
||||
return Ok(None);
|
||||
};
|
||||
|
||||
if let SubdiagnosticKind::MultipartSuggestion { .. } = subdiag {
|
||||
let meta = attr.parse_meta()?;
|
||||
|
@ -170,7 +174,7 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
|||
SubdiagnosticKind::MultipartSuggestion { .. } => unreachable!(),
|
||||
});
|
||||
|
||||
Ok((subdiag, slug))
|
||||
Ok(Some((subdiag, slug)))
|
||||
}
|
||||
|
||||
/// Establishes state in the `DiagnosticDeriveBuilder` resulting from the struct
|
||||
|
@ -182,6 +186,11 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
|||
) -> Result<TokenStream, DiagnosticDeriveError> {
|
||||
let diag = &self.parent.diag;
|
||||
|
||||
// Always allow documentation comments.
|
||||
if is_doc_comment(attr) {
|
||||
return Ok(quote! {});
|
||||
}
|
||||
|
||||
let name = attr.path.segments.last().unwrap().ident.to_string();
|
||||
let name = name.as_str();
|
||||
let meta = attr.parse_meta()?;
|
||||
|
@ -250,7 +259,11 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
|||
return Ok(tokens);
|
||||
}
|
||||
|
||||
let (subdiag, slug) = self.parse_subdiag_attribute(attr)?;
|
||||
let Some((subdiag, slug)) = self.parse_subdiag_attribute(attr)? else {
|
||||
// Some attributes aren't errors - like documentation comments - but also aren't
|
||||
// subdiagnostics.
|
||||
return Ok(quote! {});
|
||||
};
|
||||
let fn_ident = format_ident!("{}", subdiag);
|
||||
match subdiag {
|
||||
SubdiagnosticKind::Note | SubdiagnosticKind::Help | SubdiagnosticKind::Warn => {
|
||||
|
@ -291,6 +304,11 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
|||
.attrs
|
||||
.iter()
|
||||
.map(move |attr| {
|
||||
// Always allow documentation comments.
|
||||
if is_doc_comment(attr) {
|
||||
return quote! {};
|
||||
}
|
||||
|
||||
let name = attr.path.segments.last().unwrap().ident.to_string();
|
||||
let needs_clone =
|
||||
name == "primary_span" && matches!(inner_ty, FieldInnerTy::Vec(_));
|
||||
|
@ -397,8 +415,11 @@ impl<'a> DiagnosticDeriveVariantBuilder<'a> {
|
|||
_ => (),
|
||||
}
|
||||
|
||||
let (subdiag, slug) = self.parse_subdiag_attribute(attr)?;
|
||||
|
||||
let Some((subdiag, slug)) = self.parse_subdiag_attribute(attr)? else {
|
||||
// Some attributes aren't errors - like documentation comments - but also aren't
|
||||
// subdiagnostics.
|
||||
return Ok(quote! {});
|
||||
};
|
||||
let fn_ident = format_ident!("{}", subdiag);
|
||||
match subdiag {
|
||||
SubdiagnosticKind::Label => {
|
||||
|
|
|
@ -5,9 +5,9 @@ use crate::diagnostics::error::{
|
|||
DiagnosticDeriveError,
|
||||
};
|
||||
use crate::diagnostics::utils::{
|
||||
build_field_mapping, new_code_ident, report_error_if_not_applied_to_applicability,
|
||||
report_error_if_not_applied_to_span, FieldInfo, FieldInnerTy, FieldMap, HasFieldMap, SetOnce,
|
||||
SpannedOption, SubdiagnosticKind,
|
||||
build_field_mapping, is_doc_comment, new_code_ident,
|
||||
report_error_if_not_applied_to_applicability, report_error_if_not_applied_to_span, FieldInfo,
|
||||
FieldInnerTy, FieldMap, HasFieldMap, SetOnce, SpannedOption, SubdiagnosticKind,
|
||||
};
|
||||
use proc_macro2::TokenStream;
|
||||
use quote::{format_ident, quote};
|
||||
|
@ -41,8 +41,14 @@ impl SubdiagnosticDeriveBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
if matches!(ast.data, syn::Data::Enum(..)) {
|
||||
let is_enum = matches!(ast.data, syn::Data::Enum(..));
|
||||
if is_enum {
|
||||
for attr in &ast.attrs {
|
||||
// Always allow documentation comments.
|
||||
if is_doc_comment(attr) {
|
||||
continue;
|
||||
}
|
||||
|
||||
span_err(
|
||||
attr.span().unwrap(),
|
||||
"unsupported type attribute for subdiagnostic enum",
|
||||
|
@ -62,6 +68,7 @@ impl SubdiagnosticDeriveBuilder {
|
|||
span_field: None,
|
||||
applicability: None,
|
||||
has_suggestion_parts: false,
|
||||
is_enum,
|
||||
};
|
||||
builder.into_tokens().unwrap_or_else(|v| v.to_compile_error())
|
||||
});
|
||||
|
@ -79,7 +86,7 @@ impl SubdiagnosticDeriveBuilder {
|
|||
gen impl rustc_errors::AddToDiagnostic for @Self {
|
||||
fn add_to_diagnostic_with<__F>(self, #diag: &mut rustc_errors::Diagnostic, #f: __F)
|
||||
where
|
||||
__F: Fn(
|
||||
__F: core::ops::Fn(
|
||||
&mut rustc_errors::Diagnostic,
|
||||
rustc_errors::SubdiagnosticMessage
|
||||
) -> rustc_errors::SubdiagnosticMessage,
|
||||
|
@ -122,6 +129,9 @@ struct SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
|
|||
/// Set to true when a `#[suggestion_part]` field is encountered, used to generate an error
|
||||
/// during finalization if still `false`.
|
||||
has_suggestion_parts: bool,
|
||||
|
||||
/// Set to true when this variant is an enum variant rather than just the body of a struct.
|
||||
is_enum: bool,
|
||||
}
|
||||
|
||||
impl<'parent, 'a> HasFieldMap for SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
|
||||
|
@ -173,7 +183,11 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
|
|||
let mut kind_slugs = vec![];
|
||||
|
||||
for attr in self.variant.ast().attrs {
|
||||
let (kind, slug) = SubdiagnosticKind::from_attr(attr, self)?;
|
||||
let Some((kind, slug)) = SubdiagnosticKind::from_attr(attr, self)? else {
|
||||
// Some attributes aren't errors - like documentation comments - but also aren't
|
||||
// subdiagnostics.
|
||||
continue;
|
||||
};
|
||||
|
||||
let Some(slug) = slug else {
|
||||
let name = attr.path.segments.last().unwrap().ident.to_string();
|
||||
|
@ -227,6 +241,11 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
|
|||
ast.attrs
|
||||
.iter()
|
||||
.map(|attr| {
|
||||
// Always allow documentation comments.
|
||||
if is_doc_comment(attr) {
|
||||
return quote! {};
|
||||
}
|
||||
|
||||
let info = FieldInfo {
|
||||
binding,
|
||||
ty: inner_ty.inner_type().unwrap_or(&ast.ty),
|
||||
|
@ -290,6 +309,8 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
|
|||
report_error_if_not_applied_to_span(attr, &info)?;
|
||||
|
||||
let binding = info.binding.binding.clone();
|
||||
// FIXME(#100717): support `Option<Span>` on `primary_span` like in the
|
||||
// diagnostic derive
|
||||
self.span_field.set_once(binding, span);
|
||||
}
|
||||
|
||||
|
@ -443,10 +464,16 @@ impl<'parent, 'a> SubdiagnosticDeriveVariantBuilder<'parent, 'a> {
|
|||
pub fn into_tokens(&mut self) -> Result<TokenStream, DiagnosticDeriveError> {
|
||||
let kind_slugs = self.identify_kind()?;
|
||||
if kind_slugs.is_empty() {
|
||||
throw_span_err!(
|
||||
self.variant.ast().ident.span().unwrap(),
|
||||
"subdiagnostic kind not specified"
|
||||
);
|
||||
if self.is_enum {
|
||||
// It's okay for a variant to not be a subdiagnostic at all..
|
||||
return Ok(quote! {});
|
||||
} else {
|
||||
// ..but structs should always be _something_.
|
||||
throw_span_err!(
|
||||
self.variant.ast().ident.span().unwrap(),
|
||||
"subdiagnostic kind not specified"
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
let kind_stats: KindsStatistics = kind_slugs.iter().map(|(kind, _slug)| kind).collect();
|
||||
|
|
|
@ -477,7 +477,12 @@ impl SubdiagnosticKind {
|
|||
pub(super) fn from_attr(
|
||||
attr: &Attribute,
|
||||
fields: &impl HasFieldMap,
|
||||
) -> Result<(SubdiagnosticKind, Option<Path>), DiagnosticDeriveError> {
|
||||
) -> Result<Option<(SubdiagnosticKind, Option<Path>)>, DiagnosticDeriveError> {
|
||||
// Always allow documentation comments.
|
||||
if is_doc_comment(attr) {
|
||||
return Ok(None);
|
||||
}
|
||||
|
||||
let span = attr.span().unwrap();
|
||||
|
||||
let name = attr.path.segments.last().unwrap().ident.to_string();
|
||||
|
@ -526,7 +531,9 @@ impl SubdiagnosticKind {
|
|||
| SubdiagnosticKind::Note
|
||||
| SubdiagnosticKind::Help
|
||||
| SubdiagnosticKind::Warn
|
||||
| SubdiagnosticKind::MultipartSuggestion { .. } => return Ok((kind, None)),
|
||||
| SubdiagnosticKind::MultipartSuggestion { .. } => {
|
||||
return Ok(Some((kind, None)));
|
||||
}
|
||||
SubdiagnosticKind::Suggestion { .. } => {
|
||||
throw_span_err!(span, "suggestion without `code = \"...\"`")
|
||||
}
|
||||
|
@ -626,7 +633,7 @@ impl SubdiagnosticKind {
|
|||
| SubdiagnosticKind::MultipartSuggestion { .. } => {}
|
||||
}
|
||||
|
||||
Ok((kind, slug))
|
||||
Ok(Some((kind, slug)))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -654,3 +661,7 @@ impl quote::IdentFragment for SubdiagnosticKind {
|
|||
pub(super) fn should_generate_set_arg(field: &Field) -> bool {
|
||||
field.attrs.is_empty()
|
||||
}
|
||||
|
||||
pub(super) fn is_doc_comment(attr: &Attribute) -> bool {
|
||||
attr.path.segments.last().unwrap().ident.to_string() == "doc"
|
||||
}
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
use std::num::NonZeroU32;
|
||||
|
||||
use crate::cgu_reuse_tracker::CguReuse;
|
||||
use rustc_errors::{
|
||||
fluent, DiagnosticBuilder, ErrorGuaranteed, Handler, IntoDiagnostic, MultiSpan,
|
||||
};
|
||||
use rustc_errors::MultiSpan;
|
||||
use rustc_macros::Diagnostic;
|
||||
use rustc_span::{Span, Symbol};
|
||||
use rustc_target::spec::{SplitDebuginfo, StackProtector, TargetTriple};
|
||||
|
@ -148,24 +146,15 @@ pub struct CrateNameEmpty {
|
|||
pub span: Option<Span>,
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(session::invalid_character_in_create_name)]
|
||||
pub struct InvalidCharacterInCrateName<'a> {
|
||||
#[primary_span]
|
||||
pub span: Option<Span>,
|
||||
pub character: char,
|
||||
pub crate_name: &'a str,
|
||||
}
|
||||
|
||||
impl IntoDiagnostic<'_> for InvalidCharacterInCrateName<'_> {
|
||||
fn into_diagnostic(self, sess: &Handler) -> DiagnosticBuilder<'_, ErrorGuaranteed> {
|
||||
let mut diag = sess.struct_err(fluent::session::invalid_character_in_create_name);
|
||||
if let Some(sp) = self.span {
|
||||
diag.set_span(sp);
|
||||
}
|
||||
diag.set_arg("character", self.character);
|
||||
diag.set_arg("crate_name", self.crate_name);
|
||||
diag
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
#[multipart_suggestion(session::expr_parentheses_needed, applicability = "machine-applicable")]
|
||||
pub struct ExprParenthesesNeeded {
|
||||
|
@ -180,3 +169,25 @@ impl ExprParenthesesNeeded {
|
|||
ExprParenthesesNeeded { left: s.shrink_to_lo(), right: s.shrink_to_hi() }
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(session::skipping_const_checks)]
|
||||
pub struct SkippingConstChecks {
|
||||
#[subdiagnostic(eager)]
|
||||
pub unleashed_features: Vec<UnleashedFeatureHelp>,
|
||||
}
|
||||
|
||||
#[derive(Subdiagnostic)]
|
||||
pub enum UnleashedFeatureHelp {
|
||||
#[help(session::unleashed_feature_help_named)]
|
||||
Named {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
gate: Symbol,
|
||||
},
|
||||
#[help(session::unleashed_feature_help_unnamed)]
|
||||
Unnamed {
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -5,9 +5,10 @@ use crate::config::{self, CrateType, InstrumentCoverage, OptLevel, OutputType, S
|
|||
use crate::errors::{
|
||||
CannotEnableCrtStaticLinux, CannotMixAndMatchSanitizers, LinkerPluginToWindowsNotSupported,
|
||||
NotCircumventFeature, ProfileSampleUseFileDoesNotExist, ProfileUseFileDoesNotExist,
|
||||
SanitizerCfiEnabled, SanitizerNotSupported, SanitizersNotSupported,
|
||||
SanitizerCfiEnabled, SanitizerNotSupported, SanitizersNotSupported, SkippingConstChecks,
|
||||
SplitDebugInfoUnstablePlatform, StackProtectorNotSupportedForTarget,
|
||||
TargetRequiresUnwindTables, UnstableVirtualFunctionElimination, UnsupportedDwarfVersion,
|
||||
TargetRequiresUnwindTables, UnleashedFeatureHelp, UnstableVirtualFunctionElimination,
|
||||
UnsupportedDwarfVersion,
|
||||
};
|
||||
use crate::parse::{add_feature_diagnostics, ParseSess};
|
||||
use crate::search_paths::{PathKind, SearchPath};
|
||||
|
@ -232,21 +233,19 @@ impl Session {
|
|||
if !unleashed_features.is_empty() {
|
||||
let mut must_err = false;
|
||||
// Create a diagnostic pointing at where things got unleashed.
|
||||
// FIXME(#100717): needs eager translation/lists
|
||||
#[allow(rustc::untranslatable_diagnostic)]
|
||||
#[allow(rustc::diagnostic_outside_of_impl)]
|
||||
let mut diag = self.struct_warn("skipping const checks");
|
||||
for &(span, feature_gate) in unleashed_features.iter() {
|
||||
// FIXME: `span_label` doesn't do anything, so we use "help" as a hack.
|
||||
if let Some(gate) = feature_gate {
|
||||
diag.span_help(span, &format!("skipping check for `{gate}` feature"));
|
||||
// The unleash flag must *not* be used to just "hack around" feature gates.
|
||||
must_err = true;
|
||||
} else {
|
||||
diag.span_help(span, "skipping check that does not even have a feature gate");
|
||||
}
|
||||
}
|
||||
diag.emit();
|
||||
self.emit_warning(SkippingConstChecks {
|
||||
unleashed_features: unleashed_features
|
||||
.iter()
|
||||
.map(|(span, gate)| {
|
||||
gate.map(|gate| {
|
||||
must_err = true;
|
||||
UnleashedFeatureHelp::Named { span: *span, gate }
|
||||
})
|
||||
.unwrap_or(UnleashedFeatureHelp::Unnamed { span: *span })
|
||||
})
|
||||
.collect(),
|
||||
});
|
||||
|
||||
// If we should err, make sure we did.
|
||||
if must_err && self.has_errors().is_none() {
|
||||
// We have skipped a feature gate, and not run into other errors... reject.
|
||||
|
|
|
@ -749,3 +749,12 @@ struct SubdiagnosticEagerSuggestion {
|
|||
#[subdiagnostic(eager)]
|
||||
sub: SubdiagnosticWithSuggestion,
|
||||
}
|
||||
|
||||
/// with a doc comment on the type..
|
||||
#[derive(Diagnostic)]
|
||||
#[diag(compiletest::example, code = "E0123")]
|
||||
struct WithDocComment {
|
||||
/// ..and the field
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
}
|
||||
|
|
|
@ -237,7 +237,6 @@ enum V {
|
|||
var: String,
|
||||
},
|
||||
B {
|
||||
//~^ ERROR subdiagnostic kind not specified
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
var: String,
|
||||
|
@ -641,3 +640,24 @@ struct BJ {
|
|||
span: Span,
|
||||
r#type: String,
|
||||
}
|
||||
|
||||
/// with a doc comment on the type..
|
||||
#[derive(Subdiagnostic)]
|
||||
#[label(parser::add_paren)]
|
||||
struct BK {
|
||||
/// ..and the field
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
}
|
||||
|
||||
/// with a doc comment on the type..
|
||||
#[derive(Subdiagnostic)]
|
||||
enum BL {
|
||||
/// ..and the variant..
|
||||
#[label(parser::add_paren)]
|
||||
Foo {
|
||||
/// ..and the field
|
||||
#[primary_span]
|
||||
span: Span,
|
||||
}
|
||||
}
|
||||
|
|
|
@ -134,20 +134,14 @@ error: diagnostic slug must be first argument of a `#[label(...)]` attribute
|
|||
LL | #[label(code = "...")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: subdiagnostic kind not specified
|
||||
--> $DIR/subdiagnostic-derive.rs:239:5
|
||||
|
|
||||
LL | B {
|
||||
| ^
|
||||
|
||||
error: the `#[primary_span]` attribute can only be applied to fields of type `Span` or `MultiSpan`
|
||||
--> $DIR/subdiagnostic-derive.rs:251:5
|
||||
--> $DIR/subdiagnostic-derive.rs:250:5
|
||||
|
|
||||
LL | #[primary_span]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: label without `#[primary_span]` field
|
||||
--> $DIR/subdiagnostic-derive.rs:248:1
|
||||
--> $DIR/subdiagnostic-derive.rs:247:1
|
||||
|
|
||||
LL | / #[label(parser::add_paren)]
|
||||
LL | |
|
||||
|
@ -159,13 +153,13 @@ LL | | }
|
|||
| |_^
|
||||
|
||||
error: `#[applicability]` is only valid on suggestions
|
||||
--> $DIR/subdiagnostic-derive.rs:261:5
|
||||
--> $DIR/subdiagnostic-derive.rs:260:5
|
||||
|
|
||||
LL | #[applicability]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `#[bar]` is not a valid attribute
|
||||
--> $DIR/subdiagnostic-derive.rs:271:5
|
||||
--> $DIR/subdiagnostic-derive.rs:270:5
|
||||
|
|
||||
LL | #[bar]
|
||||
| ^^^^^^
|
||||
|
@ -173,13 +167,13 @@ LL | #[bar]
|
|||
= help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes
|
||||
|
||||
error: `#[bar = ...]` is not a valid attribute
|
||||
--> $DIR/subdiagnostic-derive.rs:282:5
|
||||
--> $DIR/subdiagnostic-derive.rs:281:5
|
||||
|
|
||||
LL | #[bar = "..."]
|
||||
| ^^^^^^^^^^^^^^
|
||||
|
||||
error: `#[bar(...)]` is not a valid attribute
|
||||
--> $DIR/subdiagnostic-derive.rs:293:5
|
||||
--> $DIR/subdiagnostic-derive.rs:292:5
|
||||
|
|
||||
LL | #[bar("...")]
|
||||
| ^^^^^^^^^^^^^
|
||||
|
@ -187,7 +181,7 @@ LL | #[bar("...")]
|
|||
= help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes
|
||||
|
||||
error: unexpected unsupported untagged union
|
||||
--> $DIR/subdiagnostic-derive.rs:309:1
|
||||
--> $DIR/subdiagnostic-derive.rs:308:1
|
||||
|
|
||||
LL | / union AC {
|
||||
LL | |
|
||||
|
@ -197,7 +191,7 @@ LL | | }
|
|||
| |_^
|
||||
|
||||
error: `#[label(parser::add_paren)]` is not a valid attribute
|
||||
--> $DIR/subdiagnostic-derive.rs:324:28
|
||||
--> $DIR/subdiagnostic-derive.rs:323:28
|
||||
|
|
||||
LL | #[label(parser::add_paren, parser::add_paren)]
|
||||
| ^^^^^^^^^^^^^^^^^
|
||||
|
@ -205,67 +199,67 @@ LL | #[label(parser::add_paren, parser::add_paren)]
|
|||
= help: a diagnostic slug must be the first argument to the attribute
|
||||
|
||||
error: specified multiple times
|
||||
--> $DIR/subdiagnostic-derive.rs:337:5
|
||||
--> $DIR/subdiagnostic-derive.rs:336:5
|
||||
|
|
||||
LL | #[primary_span]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: previously specified here
|
||||
--> $DIR/subdiagnostic-derive.rs:334:5
|
||||
--> $DIR/subdiagnostic-derive.rs:333:5
|
||||
|
|
||||
LL | #[primary_span]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
||||
error: subdiagnostic kind not specified
|
||||
--> $DIR/subdiagnostic-derive.rs:343:8
|
||||
--> $DIR/subdiagnostic-derive.rs:342:8
|
||||
|
|
||||
LL | struct AG {
|
||||
| ^^
|
||||
|
||||
error: specified multiple times
|
||||
--> $DIR/subdiagnostic-derive.rs:380:47
|
||||
--> $DIR/subdiagnostic-derive.rs:379:47
|
||||
|
|
||||
LL | #[suggestion(parser::add_paren, code = "...", code = "...")]
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
note: previously specified here
|
||||
--> $DIR/subdiagnostic-derive.rs:380:33
|
||||
--> $DIR/subdiagnostic-derive.rs:379:33
|
||||
|
|
||||
LL | #[suggestion(parser::add_paren, code = "...", code = "...")]
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: specified multiple times
|
||||
--> $DIR/subdiagnostic-derive.rs:398:5
|
||||
--> $DIR/subdiagnostic-derive.rs:397:5
|
||||
|
|
||||
LL | #[applicability]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
|
||||
note: previously specified here
|
||||
--> $DIR/subdiagnostic-derive.rs:395:5
|
||||
--> $DIR/subdiagnostic-derive.rs:394:5
|
||||
|
|
||||
LL | #[applicability]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: the `#[applicability]` attribute can only be applied to fields of type `Applicability`
|
||||
--> $DIR/subdiagnostic-derive.rs:408:5
|
||||
--> $DIR/subdiagnostic-derive.rs:407:5
|
||||
|
|
||||
LL | #[applicability]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
||||
error: suggestion without `code = "..."`
|
||||
--> $DIR/subdiagnostic-derive.rs:421:1
|
||||
--> $DIR/subdiagnostic-derive.rs:420:1
|
||||
|
|
||||
LL | #[suggestion(parser::add_paren)]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: invalid applicability
|
||||
--> $DIR/subdiagnostic-derive.rs:431:46
|
||||
--> $DIR/subdiagnostic-derive.rs:430:46
|
||||
|
|
||||
LL | #[suggestion(parser::add_paren, code ="...", applicability = "foo")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: suggestion without `#[primary_span]` field
|
||||
--> $DIR/subdiagnostic-derive.rs:449:1
|
||||
--> $DIR/subdiagnostic-derive.rs:448:1
|
||||
|
|
||||
LL | / #[suggestion(parser::add_paren, code = "...")]
|
||||
LL | |
|
||||
|
@ -275,25 +269,25 @@ LL | | }
|
|||
| |_^
|
||||
|
||||
error: unsupported type attribute for subdiagnostic enum
|
||||
--> $DIR/subdiagnostic-derive.rs:463:1
|
||||
--> $DIR/subdiagnostic-derive.rs:462:1
|
||||
|
|
||||
LL | #[label]
|
||||
| ^^^^^^^^
|
||||
|
||||
error: `var` doesn't refer to a field on this type
|
||||
--> $DIR/subdiagnostic-derive.rs:483:39
|
||||
--> $DIR/subdiagnostic-derive.rs:482:39
|
||||
|
|
||||
LL | #[suggestion(parser::add_paren, code ="{var}", applicability = "machine-applicable")]
|
||||
| ^^^^^^^
|
||||
|
||||
error: `var` doesn't refer to a field on this type
|
||||
--> $DIR/subdiagnostic-derive.rs:502:43
|
||||
--> $DIR/subdiagnostic-derive.rs:501:43
|
||||
|
|
||||
LL | #[suggestion(parser::add_paren, code ="{var}", applicability = "machine-applicable")]
|
||||
| ^^^^^^^
|
||||
|
||||
error: `#[suggestion_part]` is not a valid attribute
|
||||
--> $DIR/subdiagnostic-derive.rs:525:5
|
||||
--> $DIR/subdiagnostic-derive.rs:524:5
|
||||
|
|
||||
LL | #[suggestion_part]
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
@ -301,7 +295,7 @@ LL | #[suggestion_part]
|
|||
= help: `#[suggestion_part(...)]` is only valid in multipart suggestions, use `#[primary_span]` instead
|
||||
|
||||
error: `#[suggestion_part(...)]` is not a valid attribute
|
||||
--> $DIR/subdiagnostic-derive.rs:528:5
|
||||
--> $DIR/subdiagnostic-derive.rs:527:5
|
||||
|
|
||||
LL | #[suggestion_part(code = "...")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
@ -309,7 +303,7 @@ LL | #[suggestion_part(code = "...")]
|
|||
= help: `#[suggestion_part(...)]` is only valid in multipart suggestions
|
||||
|
||||
error: suggestion without `#[primary_span]` field
|
||||
--> $DIR/subdiagnostic-derive.rs:522:1
|
||||
--> $DIR/subdiagnostic-derive.rs:521:1
|
||||
|
|
||||
LL | / #[suggestion(parser::add_paren, code = "...")]
|
||||
LL | |
|
||||
|
@ -321,7 +315,7 @@ LL | | }
|
|||
| |_^
|
||||
|
||||
error: `#[multipart_suggestion(code = ...)]` is not a valid attribute
|
||||
--> $DIR/subdiagnostic-derive.rs:537:43
|
||||
--> $DIR/subdiagnostic-derive.rs:536:43
|
||||
|
|
||||
LL | #[multipart_suggestion(parser::add_paren, code = "...", applicability = "machine-applicable")]
|
||||
| ^^^^^^^^^^^^
|
||||
|
@ -329,7 +323,7 @@ LL | #[multipart_suggestion(parser::add_paren, code = "...", applicability = "ma
|
|||
= help: only `applicability` is a valid nested attributes
|
||||
|
||||
error: multipart suggestion without any `#[suggestion_part(...)]` fields
|
||||
--> $DIR/subdiagnostic-derive.rs:537:1
|
||||
--> $DIR/subdiagnostic-derive.rs:536:1
|
||||
|
|
||||
LL | / #[multipart_suggestion(parser::add_paren, code = "...", applicability = "machine-applicable")]
|
||||
LL | |
|
||||
|
@ -340,19 +334,19 @@ LL | | }
|
|||
| |_^
|
||||
|
||||
error: `#[suggestion_part(...)]` attribute without `code = "..."`
|
||||
--> $DIR/subdiagnostic-derive.rs:547:5
|
||||
--> $DIR/subdiagnostic-derive.rs:546:5
|
||||
|
|
||||
LL | #[suggestion_part]
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `#[suggestion_part(...)]` attribute without `code = "..."`
|
||||
--> $DIR/subdiagnostic-derive.rs:555:5
|
||||
--> $DIR/subdiagnostic-derive.rs:554:5
|
||||
|
|
||||
LL | #[suggestion_part()]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `#[primary_span]` is not a valid attribute
|
||||
--> $DIR/subdiagnostic-derive.rs:564:5
|
||||
--> $DIR/subdiagnostic-derive.rs:563:5
|
||||
|
|
||||
LL | #[primary_span]
|
||||
| ^^^^^^^^^^^^^^^
|
||||
|
@ -360,7 +354,7 @@ LL | #[primary_span]
|
|||
= help: multipart suggestions use one or more `#[suggestion_part]`s rather than one `#[primary_span]`
|
||||
|
||||
error: multipart suggestion without any `#[suggestion_part(...)]` fields
|
||||
--> $DIR/subdiagnostic-derive.rs:561:1
|
||||
--> $DIR/subdiagnostic-derive.rs:560:1
|
||||
|
|
||||
LL | / #[multipart_suggestion(parser::add_paren)]
|
||||
LL | |
|
||||
|
@ -372,19 +366,19 @@ LL | | }
|
|||
| |_^
|
||||
|
||||
error: `#[suggestion_part(...)]` attribute without `code = "..."`
|
||||
--> $DIR/subdiagnostic-derive.rs:572:5
|
||||
--> $DIR/subdiagnostic-derive.rs:571:5
|
||||
|
|
||||
LL | #[suggestion_part]
|
||||
| ^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `#[suggestion_part(...)]` attribute without `code = "..."`
|
||||
--> $DIR/subdiagnostic-derive.rs:575:5
|
||||
--> $DIR/subdiagnostic-derive.rs:574:5
|
||||
|
|
||||
LL | #[suggestion_part()]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: `#[suggestion_part(foo = ...)]` is not a valid attribute
|
||||
--> $DIR/subdiagnostic-derive.rs:578:23
|
||||
--> $DIR/subdiagnostic-derive.rs:577:23
|
||||
|
|
||||
LL | #[suggestion_part(foo = "bar")]
|
||||
| ^^^^^^^^^^^
|
||||
|
@ -392,31 +386,31 @@ LL | #[suggestion_part(foo = "bar")]
|
|||
= help: `code` is the only valid nested attribute
|
||||
|
||||
error: the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
|
||||
--> $DIR/subdiagnostic-derive.rs:581:5
|
||||
--> $DIR/subdiagnostic-derive.rs:580:5
|
||||
|
|
||||
LL | #[suggestion_part(code = "...")]
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: the `#[suggestion_part(...)]` attribute can only be applied to fields of type `Span` or `MultiSpan`
|
||||
--> $DIR/subdiagnostic-derive.rs:584:5
|
||||
--> $DIR/subdiagnostic-derive.rs:583:5
|
||||
|
|
||||
LL | #[suggestion_part()]
|
||||
| ^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
error: specified multiple times
|
||||
--> $DIR/subdiagnostic-derive.rs:592:37
|
||||
--> $DIR/subdiagnostic-derive.rs:591:37
|
||||
|
|
||||
LL | #[suggestion_part(code = "...", code = ",,,")]
|
||||
| ^^^^^^^^^^^^
|
||||
|
|
||||
note: previously specified here
|
||||
--> $DIR/subdiagnostic-derive.rs:592:23
|
||||
--> $DIR/subdiagnostic-derive.rs:591:23
|
||||
|
|
||||
LL | #[suggestion_part(code = "...", code = ",,,")]
|
||||
| ^^^^^^^^^^^^
|
||||
|
||||
error: `#[applicability]` has no effect if all `#[suggestion]`/`#[multipart_suggestion]` attributes have a static `applicability = "..."`
|
||||
--> $DIR/subdiagnostic-derive.rs:621:5
|
||||
--> $DIR/subdiagnostic-derive.rs:620:5
|
||||
|
|
||||
LL | #[applicability]
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
|
@ -458,19 +452,19 @@ LL | #[bar("...")]
|
|||
| ^^^
|
||||
|
||||
error: cannot find attribute `bar` in this scope
|
||||
--> $DIR/subdiagnostic-derive.rs:271:7
|
||||
--> $DIR/subdiagnostic-derive.rs:270:7
|
||||
|
|
||||
LL | #[bar]
|
||||
| ^^^
|
||||
|
||||
error: cannot find attribute `bar` in this scope
|
||||
--> $DIR/subdiagnostic-derive.rs:282:7
|
||||
--> $DIR/subdiagnostic-derive.rs:281:7
|
||||
|
|
||||
LL | #[bar = "..."]
|
||||
| ^^^
|
||||
|
||||
error: cannot find attribute `bar` in this scope
|
||||
--> $DIR/subdiagnostic-derive.rs:293:7
|
||||
--> $DIR/subdiagnostic-derive.rs:292:7
|
||||
|
|
||||
LL | #[bar("...")]
|
||||
| ^^^
|
||||
|
@ -481,6 +475,6 @@ error[E0425]: cannot find value `slug` in module `rustc_errors::fluent`
|
|||
LL | #[label(slug)]
|
||||
| ^^^^ not found in `rustc_errors::fluent`
|
||||
|
||||
error: aborting due to 68 previous errors
|
||||
error: aborting due to 67 previous errors
|
||||
|
||||
For more information about this error, try `rustc --explain E0425`.
|
||||
|
|
Loading…
Add table
Reference in a new issue