From b7abf014ec85e362c10bd7dc222a1a71968bc427 Mon Sep 17 00:00:00 2001 From: Xiretza Date: Sun, 14 Apr 2024 20:11:14 +0000 Subject: [PATCH] Convert uses of BuiltinLintDiag::Normal to custom variants This ensures all diagnostic messages are created at diagnostic emission time, making them translatable. --- compiler/rustc_builtin_macros/messages.ftl | 2 - compiler/rustc_builtin_macros/src/asm.rs | 9 +- .../rustc_builtin_macros/src/source_util.rs | 5 +- .../rustc_builtin_macros/src/test_harness.rs | 5 +- compiler/rustc_builtin_macros/src/util.rs | 6 +- compiler/rustc_expand/src/config.rs | 15 +- compiler/rustc_expand/src/mbe/macro_check.rs | 26 ++-- compiler/rustc_interface/src/util.rs | 27 +--- compiler/rustc_lint/messages.ftl | 14 ++ .../rustc_lint/src/context/diagnostics.rs | 137 ++++++++++++++++-- compiler/rustc_lint_defs/src/lib.rs | 56 +++++-- compiler/rustc_metadata/messages.ftl | 2 - compiler/rustc_metadata/src/creader.rs | 25 ++-- compiler/rustc_parse/src/validate_attr.rs | 32 ++-- compiler/rustc_resolve/src/check_unused.rs | 15 +- compiler/rustc_resolve/src/imports.rs | 9 +- compiler/rustc_resolve/src/late.rs | 9 +- compiler/rustc_resolve/src/lib.rs | 10 +- compiler/rustc_resolve/src/macros.rs | 47 +++--- compiler/rustc_session/src/parse.rs | 17 --- 20 files changed, 295 insertions(+), 173 deletions(-) diff --git a/compiler/rustc_builtin_macros/messages.ftl b/compiler/rustc_builtin_macros/messages.ftl index 0f158990319..a3d6a1c7360 100644 --- a/compiler/rustc_builtin_macros/messages.ftl +++ b/compiler/rustc_builtin_macros/messages.ftl @@ -247,5 +247,3 @@ builtin_macros_unexpected_lit = expected path to a trait, found literal .label = not a trait .str_lit = try using `#[derive({$sym})]` .other = for example, write `#[derive(Debug)]` for `Debug` - -builtin_macros_unnameable_test_items = cannot test inner items diff --git a/compiler/rustc_builtin_macros/src/asm.rs b/compiler/rustc_builtin_macros/src/asm.rs index 49b1b8cf992..bf2a5813af6 100644 --- a/compiler/rustc_builtin_macros/src/asm.rs +++ b/compiler/rustc_builtin_macros/src/asm.rs @@ -1,6 +1,7 @@ use crate::errors; use crate::util::expr_to_spanned_string; use ast::token::IdentIsRaw; +use lint::BuiltinLintDiag; use rustc_ast as ast; use rustc_ast::ptr::P; use rustc_ast::token::{self, Delimiter}; @@ -509,19 +510,19 @@ fn expand_preparsed_asm( }; if template_str.contains(".intel_syntax") { - ecx.psess().buffer_lint( + ecx.psess().buffer_lint_with_diagnostic( lint::builtin::BAD_ASM_STYLE, find_span(".intel_syntax"), ecx.current_expansion.lint_node_id, - "avoid using `.intel_syntax`, Intel syntax is the default", + BuiltinLintDiag::AvoidUsingIntelSyntax, ); } if template_str.contains(".att_syntax") { - ecx.psess().buffer_lint( + ecx.psess().buffer_lint_with_diagnostic( lint::builtin::BAD_ASM_STYLE, find_span(".att_syntax"), ecx.current_expansion.lint_node_id, - "avoid using `.att_syntax`, prefer using `options(att_syntax)` instead", + BuiltinLintDiag::AvoidUsingAttSyntax, ); } } diff --git a/compiler/rustc_builtin_macros/src/source_util.rs b/compiler/rustc_builtin_macros/src/source_util.rs index 47b2ee975ca..15d2546ba86 100644 --- a/compiler/rustc_builtin_macros/src/source_util.rs +++ b/compiler/rustc_builtin_macros/src/source_util.rs @@ -11,6 +11,7 @@ resolve_path, DummyResult, ExpandResult, ExtCtxt, MacEager, MacResult, MacroExpanderResult, }; use rustc_expand::module::DirOwnership; +use rustc_lint_defs::BuiltinLintDiag; use rustc_parse::new_parser_from_file; use rustc_parse::parser::{ForceCollect, Parser}; use rustc_session::lint::builtin::INCOMPLETE_INCLUDE; @@ -143,11 +144,11 @@ impl<'a> MacResult for ExpandInclude<'a> { fn make_expr(mut self: Box>) -> Option> { let expr = parse_expr(&mut self.p).ok()?; if self.p.token != token::Eof { - self.p.psess.buffer_lint( + self.p.psess.buffer_lint_with_diagnostic( INCOMPLETE_INCLUDE, self.p.token.span, self.node_id, - "include macro expected single expression in source", + BuiltinLintDiag::IncompleteInclude, ); } Some(expr) diff --git a/compiler/rustc_builtin_macros/src/test_harness.rs b/compiler/rustc_builtin_macros/src/test_harness.rs index 8cf431482ff..f6c35a75228 100644 --- a/compiler/rustc_builtin_macros/src/test_harness.rs +++ b/compiler/rustc_builtin_macros/src/test_harness.rs @@ -9,6 +9,7 @@ use rustc_expand::base::{ExtCtxt, ResolverExpand}; use rustc_expand::expand::{AstFragment, ExpansionConfig}; use rustc_feature::Features; +use rustc_lint_defs::BuiltinLintDiag; use rustc_session::lint::builtin::UNNAMEABLE_TEST_ITEMS; use rustc_session::Session; use rustc_span::hygiene::{AstPass, SyntaxContext, Transparency}; @@ -159,11 +160,11 @@ struct InnerItemLinter<'a> { impl<'a> Visitor<'a> for InnerItemLinter<'_> { fn visit_item(&mut self, i: &'a ast::Item) { if let Some(attr) = attr::find_by_name(&i.attrs, sym::rustc_test_marker) { - self.sess.psess.buffer_lint( + self.sess.psess.buffer_lint_with_diagnostic( UNNAMEABLE_TEST_ITEMS, attr.span, i.id, - crate::fluent_generated::builtin_macros_unnameable_test_items, + BuiltinLintDiag::UnnameableTestItems, ); } } diff --git a/compiler/rustc_builtin_macros/src/util.rs b/compiler/rustc_builtin_macros/src/util.rs index 8dc7bc14ec3..f08238ad460 100644 --- a/compiler/rustc_builtin_macros/src/util.rs +++ b/compiler/rustc_builtin_macros/src/util.rs @@ -5,7 +5,7 @@ use rustc_expand::base::{Annotatable, ExpandResult, ExtCtxt}; use rustc_expand::expand::AstFragment; use rustc_feature::AttributeTemplate; -use rustc_lint_defs::builtin::DUPLICATE_MACRO_ATTRIBUTES; +use rustc_lint_defs::{builtin::DUPLICATE_MACRO_ATTRIBUTES, BuiltinLintDiag}; use rustc_parse::{parser, validate_attr}; use rustc_session::errors::report_lit_error; use rustc_span::{BytePos, Span, Symbol}; @@ -42,11 +42,11 @@ pub(crate) fn warn_on_duplicate_attribute(ecx: &ExtCtxt<'_>, item: &Annotatable, }; if let Some(attrs) = attrs { if let Some(attr) = attr::find_by_name(attrs, name) { - ecx.psess().buffer_lint( + ecx.psess().buffer_lint_with_diagnostic( DUPLICATE_MACRO_ATTRIBUTES, attr.span, ecx.current_expansion.lint_node_id, - "duplicated attribute", + BuiltinLintDiag::DuplicateMacroAttribute, ); } } diff --git a/compiler/rustc_expand/src/config.rs b/compiler/rustc_expand/src/config.rs index 35f0d8abffc..45d87d5e5a5 100644 --- a/compiler/rustc_expand/src/config.rs +++ b/compiler/rustc_expand/src/config.rs @@ -14,6 +14,7 @@ use rustc_data_structures::flat_map_in_place::FlatMapInPlace; use rustc_feature::Features; use rustc_feature::{ACCEPTED_FEATURES, REMOVED_FEATURES, UNSTABLE_FEATURES}; +use rustc_lint_defs::BuiltinLintDiag; use rustc_parse::validate_attr; use rustc_session::parse::feature_err; use rustc_session::Session; @@ -248,7 +249,6 @@ fn process_cfg_attr(&self, attr: &Attribute) -> Vec { /// Gives a compiler warning when the `cfg_attr` contains no attributes and /// is in the original source file. Gives a compiler error if the syntax of /// the attribute is incorrect. - #[allow(rustc::untranslatable_diagnostic)] // FIXME: make this translatable pub(crate) fn expand_cfg_attr(&self, attr: &Attribute, recursive: bool) -> Vec { let Some((cfg_predicate, expanded_attrs)) = rustc_parse::parse_cfg_attr(attr, &self.sess.psess) @@ -258,11 +258,11 @@ pub(crate) fn expand_cfg_attr(&self, attr: &Attribute, recursive: bool) -> Vec Vec= occurrence_ops.len() { let mut span = MultiSpan::from_span(span); span.push_span_label(binder.span, "expected repetition"); - let message = format!("variable '{name}' is still repeating at this depth"); - buffer_lint(psess, span, node_id, message); + buffer_lint(psess, span, node_id, BuiltinLintDiag::MetaVariableStillRepeating(name)); return; } let occurrence = &occurrence_ops[i]; @@ -637,21 +637,15 @@ fn ops_is_prefix( let mut span = MultiSpan::from_span(span); span.push_span_label(binder.span, "expected repetition"); span.push_span_label(occurrence.span, "conflicting repetition"); - let message = "meta-variable repeats with different Kleene operator"; - buffer_lint(psess, span, node_id, message); + buffer_lint(psess, span, node_id, BuiltinLintDiag::MetaVariableWrongOperator); return; } } } -fn buffer_lint( - psess: &ParseSess, - span: MultiSpan, - node_id: NodeId, - message: impl Into, -) { +fn buffer_lint(psess: &ParseSess, span: MultiSpan, node_id: NodeId, diag: BuiltinLintDiag) { // Macros loaded from other crates have dummy node ids. if node_id != DUMMY_NODE_ID { - psess.buffer_lint(META_VARIABLE_MISUSE, span, node_id, message); + psess.buffer_lint_with_diagnostic(META_VARIABLE_MISUSE, span, node_id, diag); } } diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index de7005a541b..cb25bcac368 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -399,30 +399,17 @@ pub(crate) fn check_attr_crate_type( if let ast::MetaItemKind::NameValue(spanned) = a.meta_kind().unwrap() { let span = spanned.span; - let lev_candidate = find_best_match_for_name( + let candidate = find_best_match_for_name( &CRATE_TYPES.iter().map(|(k, _)| *k).collect::>(), n, None, ); - if let Some(candidate) = lev_candidate { - lint_buffer.buffer_lint_with_diagnostic( - lint::builtin::UNKNOWN_CRATE_TYPES, - ast::CRATE_NODE_ID, - span, - BuiltinLintDiag::UnknownCrateTypes( - span, - "did you mean".to_string(), - format!("\"{candidate}\""), - ), - ); - } else { - lint_buffer.buffer_lint( - lint::builtin::UNKNOWN_CRATE_TYPES, - ast::CRATE_NODE_ID, - span, - "invalid `crate_type` value", - ); - } + lint_buffer.buffer_lint_with_diagnostic( + lint::builtin::UNKNOWN_CRATE_TYPES, + ast::CRATE_NODE_ID, + span, + BuiltinLintDiag::UnknownCrateTypes { span, candidate }, + ); } } else { // This is here mainly to check for using a macro, such as diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index e1b0aec6c96..7abba3bb5c4 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -156,6 +156,9 @@ lint_builtin_unused_doc_comment = unused doc comment lint_builtin_while_true = denote infinite loops with `loop {"{"} ... {"}"}` .suggestion = use `loop` +lint_cfg_attr_no_attributes = + `#[cfg_attr]` does not expand to any attributes + lint_check_name_unknown_tool = unknown lint tool: `{$tool_name}` lint_command_line_source = `forbid` lint level was set on command line @@ -164,6 +167,12 @@ lint_confusable_identifier_pair = found both `{$existing_sym}` and `{$sym}` as i .current_use = this identifier can be confused with `{$existing_sym}` .other_use = other identifier used here +lint_crate_name_in_cfg_attr_deprecated = + `crate_name` within an `#![cfg_attr] attribute is deprecated` + +lint_crate_type_in_cfg_attr_deprecated = + `crate_type` within an `#![cfg_attr] attribute is deprecated` + lint_cstring_ptr = getting the inner pointer of a temporary `CString` .as_ptr_label = this pointer will be invalid .unwrap_label = this `CString` is deallocated at the end of the statement, bind it to a variable to extend its lifetime @@ -662,6 +671,8 @@ lint_unknown_lint = lint_unknown_tool_in_scoped_lint = unknown tool name `{$tool_name}` found in scoped lint: `{$tool_name}::{$lint_name}` .help = add `#![register_tool({$tool_name})]` to the crate root +lint_unnameable_test_items = cannot test inner items + lint_unsupported_group = `{$lint_group}` lint group is not supported with ´--force-warn´ lint_untranslatable_diag = diagnostics should be created using translatable messages @@ -701,3 +712,6 @@ lint_unused_result = unused result of type `{$ty}` lint_variant_size_differences = enum variant is more than three times larger ({$largest} bytes) than the next largest + +lint_wasm_c_abi = + older versions of the `wasm-bindgen` crate will be incompatible with future versions of Rust; please update to `wasm-bindgen` v0.2.88 diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs index 70aa14a565d..f298ed98d98 100644 --- a/compiler/rustc_lint/src/context/diagnostics.rs +++ b/compiler/rustc_lint/src/context/diagnostics.rs @@ -11,8 +11,13 @@ use rustc_session::Session; use rustc_span::BytePos; +use std::fmt::Write; + mod check_cfg; +#[cfg(test)] +mod tests; + pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Diag<'_, ()>) { match diagnostic { BuiltinLintDiag::UnicodeTextFlow(span, content) => { @@ -52,7 +57,6 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di ); } } - BuiltinLintDiag::Normal(_) => (), BuiltinLintDiag::AbsPathWithModule(span) => { let (sugg, app) = match sess.source_map().span_to_snippet(span) { Ok(ref s) => { @@ -87,8 +91,15 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di ), ); } - BuiltinLintDiag::UnknownCrateTypes(span, note, sugg) => { - diag.span_suggestion(span, note, sugg, Applicability::MaybeIncorrect); + BuiltinLintDiag::UnknownCrateTypes { span, candidate } => { + if let Some(candidate) = candidate { + diag.span_suggestion( + span, + "did you mean", + format!(r#""{candidate}""#), + Applicability::MaybeIncorrect, + ); + } } BuiltinLintDiag::UnusedImports { fix_msg, fixes, test_module_span, .. } => { if !fixes.is_empty() { @@ -361,20 +372,46 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di "reduce the glob import's visibility or increase visibility of imported items", ); } - BuiltinLintDiag::MaybeTypo { span, name } => { - diag.span_suggestion_verbose( - span, - "an attribute with a similar name exists", - name, - Applicability::MachineApplicable, - ); + BuiltinLintDiag::UnknownDiagnosticAttribute { span, typo_name } => { + if let Some(typo_name) = typo_name { + diag.span_suggestion_verbose( + span, + "an attribute with a similar name exists", + typo_name, + Applicability::MachineApplicable, + ); + } } + BuiltinLintDiag::MacroUseDeprecated + | BuiltinLintDiag::UnusedMacroUse + | BuiltinLintDiag::PrivateExternCrateReexport(_) + | BuiltinLintDiag::UnusedLabel + | BuiltinLintDiag::MacroIsPrivate(_) + | BuiltinLintDiag::UnusedMacroDefinition(_) + | BuiltinLintDiag::MacroRuleNeverUsed(_, _) + | BuiltinLintDiag::UnstableFeature(_) + | BuiltinLintDiag::AvoidUsingIntelSyntax + | BuiltinLintDiag::AvoidUsingAttSyntax + | BuiltinLintDiag::IncompleteInclude + | BuiltinLintDiag::UnnameableTestItems + | BuiltinLintDiag::DuplicateMacroAttribute + | BuiltinLintDiag::CfgAttrNoAttributes + | BuiltinLintDiag::CrateTypeInCfgAttr + | BuiltinLintDiag::CrateNameInCfgAttr + | BuiltinLintDiag::MissingFragmentSpecifier + | BuiltinLintDiag::MetaVariableStillRepeating(_) + | BuiltinLintDiag::MetaVariableWrongOperator + | BuiltinLintDiag::DuplicateMatcherBinding + | BuiltinLintDiag::UnknownMacroVariable(_) + | BuiltinLintDiag::UnusedExternCrate2 { .. } + | BuiltinLintDiag::WasmCAbi + | BuiltinLintDiag::IllFormedAttributeInput { .. } + | BuiltinLintDiag::InnerAttributeUnstable { .. } => {} } } pub(super) fn builtin_message(diagnostic: &BuiltinLintDiag) -> DiagMessage { match diagnostic { - BuiltinLintDiag::Normal(msg) => msg.clone(), BuiltinLintDiag::AbsPathWithModule(_) => { "absolute paths must start with `self`, `super`, `crate`, or an \ external crate name in the 2018 edition" @@ -391,7 +428,7 @@ pub(super) fn builtin_message(diagnostic: &BuiltinLintDiag) -> DiagMessage { BuiltinLintDiag::ElidedLifetimesInPaths(_, _, _, _) => { "hidden lifetime parameters in types are deprecated".into() } - BuiltinLintDiag::UnknownCrateTypes(_, _, _) => "invalid `crate_type` value".into(), + BuiltinLintDiag::UnknownCrateTypes { .. } => "invalid `crate_type` value".into(), BuiltinLintDiag::UnusedImports { span_snippets, .. } => format!( "unused import{}{}", pluralize!(span_snippets.len()), @@ -490,5 +527,81 @@ pub(super) fn builtin_message(diagnostic: &BuiltinLintDiag) -> DiagMessage { import_vis ) .into(), + BuiltinLintDiag::MacroUseDeprecated => "deprecated `#[macro_use]` attribute used to \ + import macros should be replaced at use sites \ + with a `use` item to import the macro \ + instead" + .into(), + BuiltinLintDiag::UnusedMacroUse => "unused `#[macro_use]` import".into(), + BuiltinLintDiag::PrivateExternCrateReexport(ident) => format!( + "extern crate `{ident}` is private, and cannot be \ + re-exported (error E0365), consider declaring with \ + `pub`" + ) + .into(), + BuiltinLintDiag::UnusedLabel => "unused label".into(), + BuiltinLintDiag::MacroIsPrivate(ident) => format!("macro `{ident}` is private").into(), + BuiltinLintDiag::UnusedMacroDefinition(name) => { + format!("unused macro definition: `{}`", name).into() + } + BuiltinLintDiag::MacroRuleNeverUsed(n, name) => { + format!("rule #{} of macro `{}` is never used", n + 1, name).into() + } + BuiltinLintDiag::UnstableFeature(msg) => msg.clone().into(), + BuiltinLintDiag::AvoidUsingIntelSyntax => { + "avoid using `.intel_syntax`, Intel syntax is the default".into() + } + BuiltinLintDiag::AvoidUsingAttSyntax => { + "avoid using `.att_syntax`, prefer using `options(att_syntax)` instead".into() + } + BuiltinLintDiag::IncompleteInclude => { + "include macro expected single expression in source".into() + } + BuiltinLintDiag::UnnameableTestItems => crate::fluent_generated::lint_unnameable_test_items, + BuiltinLintDiag::DuplicateMacroAttribute => "duplicated attribute".into(), + BuiltinLintDiag::CfgAttrNoAttributes => { + crate::fluent_generated::lint_cfg_attr_no_attributes + } + BuiltinLintDiag::CrateTypeInCfgAttr => { + crate::fluent_generated::lint_crate_type_in_cfg_attr_deprecated + } + BuiltinLintDiag::CrateNameInCfgAttr => { + crate::fluent_generated::lint_crate_name_in_cfg_attr_deprecated + } + BuiltinLintDiag::MissingFragmentSpecifier => "missing fragment specifier".into(), + BuiltinLintDiag::MetaVariableStillRepeating(name) => { + format!("variable '{name}' is still repeating at this depth").into() + } + BuiltinLintDiag::MetaVariableWrongOperator => { + "meta-variable repeats with different Kleene operator".into() + } + BuiltinLintDiag::DuplicateMatcherBinding => "duplicate matcher binding".into(), + BuiltinLintDiag::UnknownMacroVariable(name) => { + format!("unknown macro variable `{name}`").into() + } + BuiltinLintDiag::UnusedExternCrate2 { extern_crate, local_crate } => format!( + "external crate `{}` unused in `{}`: remove the dependency or add `use {} as _;`", + extern_crate, local_crate, extern_crate + ) + .into(), + BuiltinLintDiag::WasmCAbi => crate::fluent_generated::lint_wasm_c_abi, + BuiltinLintDiag::IllFormedAttributeInput { suggestions } => suggestions + .iter() + .enumerate() + .fold("attribute must be of the form ".to_string(), |mut acc, (i, sugg)| { + if i != 0 { + write!(acc, " or ").unwrap(); + } + write!(acc, "`{sugg}`").unwrap(); + acc + }) + .into(), + BuiltinLintDiag::InnerAttributeUnstable { is_macro } => if *is_macro { + "inner macro attributes are unstable" + } else { + "custom inner attributes are unstable" + } + .into(), + BuiltinLintDiag::UnknownDiagnosticAttribute { .. } => "unknown diagnostic attribute".into(), } } diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 53238ed9629..4dacafaaea6 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -5,12 +5,13 @@ use rustc_data_structures::stable_hasher::{ HashStable, StableCompare, StableHasher, ToStableHashKey, }; -use rustc_error_messages::{DiagMessage, MultiSpan}; +use rustc_error_messages::MultiSpan; use rustc_hir::def::Namespace; use rustc_hir::HashStableContext; use rustc_hir::HirId; use rustc_macros::{Decodable, Encodable, HashStable_Generic}; use rustc_span::edition::Edition; +use rustc_span::symbol::MacroRulesNormalizedIdent; use rustc_span::{sym, symbol::Ident, Span, Symbol}; use rustc_target::spec::abi::Abi; @@ -577,7 +578,6 @@ pub enum DeprecatedSinceKind { // becomes hacky (and it gets allocated). #[derive(Debug)] pub enum BuiltinLintDiag { - Normal(DiagMessage), AbsPathWithModule(Span), ProcMacroDeriveResolutionFallback { span: Span, @@ -586,7 +586,10 @@ pub enum BuiltinLintDiag { }, MacroExpandedMacroExportsAccessedByAbsolutePaths(Span), ElidedLifetimesInPaths(usize, Span, bool, Span), - UnknownCrateTypes(Span, String, String), + UnknownCrateTypes { + span: Span, + candidate: Option, + }, UnusedImports { fix_msg: String, fixes: Vec<(Span, String)>, @@ -694,9 +697,42 @@ pub enum BuiltinLintDiag { max_vis: String, import_vis: String, }, - MaybeTypo { + UnknownDiagnosticAttribute { span: Span, - name: Symbol, + typo_name: Option, + }, + MacroUseDeprecated, + UnusedMacroUse, + PrivateExternCrateReexport(Ident), + UnusedLabel, + MacroIsPrivate(Ident), + UnusedMacroDefinition(Symbol), + MacroRuleNeverUsed(usize, Symbol), + UnstableFeature(String), + AvoidUsingIntelSyntax, + AvoidUsingAttSyntax, + IncompleteInclude, + UnnameableTestItems, + DuplicateMacroAttribute, + CfgAttrNoAttributes, + CrateTypeInCfgAttr, + CrateNameInCfgAttr, + MissingFragmentSpecifier, + MetaVariableStillRepeating(MacroRulesNormalizedIdent), + MetaVariableWrongOperator, + DuplicateMatcherBinding, + UnknownMacroVariable(MacroRulesNormalizedIdent), + // FIXME: combine with UnusedExternCrate? + UnusedExternCrate2 { + extern_crate: Symbol, + local_crate: Symbol, + }, + WasmCAbi, + IllFormedAttributeInput { + suggestions: Vec, + }, + InnerAttributeUnstable { + is_macro: bool, }, } @@ -745,16 +781,6 @@ pub fn take(&mut self, id: NodeId) -> Vec { self.map.swap_remove(&id).unwrap_or_default() } - pub fn buffer_lint( - &mut self, - lint: &'static Lint, - id: NodeId, - sp: impl Into, - msg: impl Into, - ) { - self.add_lint(lint, id, sp.into(), BuiltinLintDiag::Normal(msg.into())) - } - pub fn buffer_lint_with_diagnostic( &mut self, lint: &'static Lint, diff --git a/compiler/rustc_metadata/messages.ftl b/compiler/rustc_metadata/messages.ftl index 3d0846ae6de..2f5dfad265c 100644 --- a/compiler/rustc_metadata/messages.ftl +++ b/compiler/rustc_metadata/messages.ftl @@ -284,8 +284,6 @@ metadata_unsupported_abi = metadata_unsupported_abi_i686 = ABI not supported by `#[link(kind = "raw-dylib")]` on i686 -metadata_wasm_c_abi = - older versions of the `wasm-bindgen` crate will be incompatible with future versions of Rust; please update to `wasm-bindgen` v0.2.88 metadata_wasm_import_form = wasm import module must be of the form `wasm_import_module = "string"` diff --git a/compiler/rustc_metadata/src/creader.rs b/compiler/rustc_metadata/src/creader.rs index e3205fc1d30..394222cdb35 100644 --- a/compiler/rustc_metadata/src/creader.rs +++ b/compiler/rustc_metadata/src/creader.rs @@ -20,7 +20,7 @@ use rustc_middle::ty::{TyCtxt, TyCtxtFeed}; use rustc_session::config::{self, CrateType, ExternLocation}; use rustc_session::cstore::{CrateDepKind, CrateSource, ExternCrate, ExternCrateSource}; -use rustc_session::lint; +use rustc_session::lint::{self, BuiltinLintDiag}; use rustc_session::output::validate_crate_name; use rustc_session::search_paths::PathKind; use rustc_span::edition::Edition; @@ -974,16 +974,15 @@ fn report_unused_deps(&mut self, krate: &ast::Crate) { continue; } - self.sess.psess.buffer_lint( - lint::builtin::UNUSED_CRATE_DEPENDENCIES, - span, - ast::CRATE_NODE_ID, - format!( - "external crate `{}` unused in `{}`: remove the dependency or add `use {} as _;`", - name, - self.tcx.crate_name(LOCAL_CRATE), - name), - ); + self.sess.psess.buffer_lint_with_diagnostic( + lint::builtin::UNUSED_CRATE_DEPENDENCIES, + span, + ast::CRATE_NODE_ID, + BuiltinLintDiag::UnusedExternCrate2 { + extern_crate: name_interned, + local_crate: self.tcx.crate_name(LOCAL_CRATE), + }, + ); } } @@ -1016,11 +1015,11 @@ fn report_future_incompatible_deps(&self, krate: &ast::Crate) { // Make a point span rather than covering the whole file let span = krate.spans.inner_span.shrink_to_lo(); - self.sess.psess.buffer_lint( + self.sess.psess.buffer_lint_with_diagnostic( lint::builtin::WASM_C_ABI, span, ast::CRATE_NODE_ID, - crate::fluent_generated::metadata_wasm_c_abi, + BuiltinLintDiag::WasmCAbi, ); } } diff --git a/compiler/rustc_parse/src/validate_attr.rs b/compiler/rustc_parse/src/validate_attr.rs index f88edf29dce..3cfc68507d5 100644 --- a/compiler/rustc_parse/src/validate_attr.rs +++ b/compiler/rustc_parse/src/validate_attr.rs @@ -10,6 +10,7 @@ use rustc_feature::{AttributeTemplate, BuiltinAttribute, BUILTIN_ATTRIBUTE_MAP}; use rustc_session::errors::report_lit_error; use rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT; +use rustc_session::lint::BuiltinLintDiag; use rustc_session::parse::ParseSess; use rustc_span::{sym, Span, Symbol}; @@ -176,37 +177,26 @@ fn emit_malformed_attribute( }; let error_msg = format!("malformed `{name}` attribute input"); - let mut msg = "attribute must be of the form ".to_owned(); let mut suggestions = vec![]; - let mut first = true; let inner = if style == ast::AttrStyle::Inner { "!" } else { "" }; if template.word { - first = false; - let code = format!("#{inner}[{name}]"); - msg.push_str(&format!("`{code}`")); - suggestions.push(code); + suggestions.push(format!("#{inner}[{name}]")); } if let Some(descr) = template.list { - if !first { - msg.push_str(" or "); - } - first = false; - let code = format!("#{inner}[{name}({descr})]"); - msg.push_str(&format!("`{code}`")); - suggestions.push(code); + suggestions.push(format!("#{inner}[{name}({descr})]")); } if let Some(descr) = template.name_value_str { - if !first { - msg.push_str(" or "); - } - let code = format!("#{inner}[{name} = \"{descr}\"]"); - msg.push_str(&format!("`{code}`")); - suggestions.push(code); + suggestions.push(format!("#{inner}[{name} = \"{descr}\"]")); } - suggestions.sort(); if should_warn(name) { - psess.buffer_lint(ILL_FORMED_ATTRIBUTE_INPUT, span, ast::CRATE_NODE_ID, msg); + psess.buffer_lint_with_diagnostic( + ILL_FORMED_ATTRIBUTE_INPUT, + span, + ast::CRATE_NODE_ID, + BuiltinLintDiag::IllFormedAttributeInput { suggestions: suggestions.clone() }, + ); } else { + suggestions.sort(); psess .dcx .struct_span_err(span, error_msg) diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index 2a8eb940ccf..55b2d91260e 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -388,14 +388,11 @@ pub(crate) fn check_unused(&mut self, krate: &ast::Crate) { { if let ImportKind::MacroUse { .. } = import.kind { if !import.span.is_dummy() { - self.lint_buffer.buffer_lint( + self.lint_buffer.buffer_lint_with_diagnostic( MACRO_USE_EXTERN_CRATE, import.root_id, import.span, - "deprecated `#[macro_use]` attribute used to \ - import macros should be replaced at use sites \ - with a `use` item to import the macro \ - instead", + BuiltinLintDiag::MacroUseDeprecated, ); } } @@ -412,8 +409,12 @@ pub(crate) fn check_unused(&mut self, krate: &ast::Crate) { } } ImportKind::MacroUse { .. } => { - let msg = "unused `#[macro_use]` import"; - self.lint_buffer.buffer_lint(UNUSED_IMPORTS, import.root_id, import.span, msg); + self.lint_buffer.buffer_lint_with_diagnostic( + UNUSED_IMPORTS, + import.root_id, + import.span, + BuiltinLintDiag::UnusedMacroUse, + ); } _ => {} } diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index 55a0382a8e8..fb734895049 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -1246,16 +1246,11 @@ fn finalize_import(&mut self, import: Import<'a>) -> Option "inner macro attributes are unstable", - Res::NonMacroAttr(..) => "custom inner attributes are unstable", + let is_macro = match res { + Res::Def(..) => true, + Res::NonMacroAttr(..) => false, _ => unreachable!(), }; if soft_custom_inner_attributes_gate { - self.tcx.sess.psess.buffer_lint(SOFT_UNSTABLE, path.span, node_id, msg); + self.tcx.sess.psess.buffer_lint_with_diagnostic( + SOFT_UNSTABLE, + path.span, + node_id, + BuiltinLintDiag::InnerAttributeUnstable { is_macro }, + ); } else { + // FIXME: deduplicate with rustc_lint (`BuiltinLintDiag::InnerAttributeUnstable`) + let msg = if is_macro { + "inner macro attributes are unstable" + } else { + "custom inner attributes are unstable" + }; feature_err(&self.tcx.sess, sym::custom_inner_attributes, path.span, msg).emit(); } } @@ -572,17 +583,13 @@ fn smart_resolve_macro_path( let distance = edit_distance(attribute.ident.name.as_str(), sym::on_unimplemented.as_str(), 5); - let help = if distance.is_some() { - BuiltinLintDiag::MaybeTypo { span: attribute.span(), name: sym::on_unimplemented } - } else { - BuiltinLintDiag::Normal - }; + let typo_name = distance.map(|_| sym::on_unimplemented); + self.tcx.sess.psess.buffer_lint_with_diagnostic( UNKNOWN_OR_MALFORMED_DIAGNOSTIC_ATTRIBUTES, attribute.span(), node_id, - "unknown diagnostic attribute", - help, + BuiltinLintDiag::UnknownDiagnosticAttribute { span: attribute.span(), typo_name }, ); } @@ -835,8 +842,14 @@ fn check_stability_and_deprecation( let allowed_by_implication = implied_by.is_some_and(|feature| is_allowed(feature)); if !is_allowed(feature) && !allowed_by_implication { let lint_buffer = &mut self.lint_buffer; - let soft_handler = - |lint, span, msg: String| lint_buffer.buffer_lint(lint, node_id, span, msg); + let soft_handler = |lint, span, msg: String| { + lint_buffer.buffer_lint_with_diagnostic( + lint, + node_id, + span, + BuiltinLintDiag::UnstableFeature(msg), + ) + }; stability::report_unstable( self.tcx.sess, feature, diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index 59281f96126..3db586622e5 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -300,23 +300,6 @@ pub fn clone_source_map(&self) -> Lrc { self.source_map.clone() } - pub fn buffer_lint( - &self, - lint: &'static Lint, - span: impl Into, - node_id: NodeId, - msg: impl Into, - ) { - self.buffered_lints.with_lock(|buffered_lints| { - buffered_lints.push(BufferedEarlyLint { - span: span.into(), - node_id, - lint_id: LintId::of(lint), - diagnostic: BuiltinLintDiag::Normal(msg.into()), - }); - }); - } - pub fn buffer_lint_with_diagnostic( &self, lint: &'static Lint,