diff options
| author | Xiretza <xiretza@xiretza.xyz> | 2024-04-15 18:07:22 +0000 |
|---|---|---|
| committer | Xiretza <xiretza@xiretza.xyz> | 2024-05-21 20:16:39 +0000 |
| commit | 8004e6a3796f832eb7752dcd22252b8e6d04e240 (patch) | |
| tree | 832d257e8cc1c468cd95d084ae7000f5af3e1e66 /compiler/rustc_lint/src/context/diagnostics.rs | |
| parent | b7abf014ec85e362c10bd7dc222a1a71968bc427 (diff) | |
| download | rust-8004e6a3796f832eb7752dcd22252b8e6d04e240.tar.gz rust-8004e6a3796f832eb7752dcd22252b8e6d04e240.zip | |
Make early lints translatable
Diffstat (limited to 'compiler/rustc_lint/src/context/diagnostics.rs')
| -rw-r--r-- | compiler/rustc_lint/src/context/diagnostics.rs | 767 |
1 files changed, 327 insertions, 440 deletions
diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs index f298ed98d98..236eeee6152 100644 --- a/compiler/rustc_lint/src/context/diagnostics.rs +++ b/compiler/rustc_lint/src/context/diagnostics.rs @@ -1,64 +1,57 @@ #![allow(rustc::diagnostic_outside_of_impl)] #![allow(rustc::untranslatable_diagnostic)] +use std::borrow::Cow; + use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS; -use rustc_errors::{ - elided_lifetime_in_path_suggestion, pluralize, Diag, DiagMessage, LintDiagnostic, -}; -use rustc_errors::{Applicability, SuggestionStyle}; +use rustc_errors::Applicability; +use rustc_errors::{elided_lifetime_in_path_suggestion, DiagArgValue, MultiSpan}; use rustc_middle::middle::stability; -use rustc_session::lint::BuiltinLintDiag; -use rustc_session::Session; +use rustc_session::lint::{BuiltinLintDiag, Lint}; use rustc_span::BytePos; -use std::fmt::Write; +use crate::{lints, EarlyContext, LintContext as _}; mod check_cfg; -#[cfg(test)] -mod tests; - -pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Diag<'_, ()>) { +pub(super) fn emit_buffered_lint( + ctx: &EarlyContext<'_>, + lint: &'static Lint, + span: MultiSpan, + diagnostic: BuiltinLintDiag, +) { + let sess = ctx.sess(); match diagnostic { - BuiltinLintDiag::UnicodeTextFlow(span, content) => { + BuiltinLintDiag::UnicodeTextFlow(comment_span, content) => { let spans: Vec<_> = content .char_indices() .filter_map(|(i, c)| { TEXT_FLOW_CONTROL_CHARS.contains(&c).then(|| { - let lo = span.lo() + BytePos(2 + i as u32); - (c, span.with_lo(lo).with_hi(lo + BytePos(c.len_utf8() as u32))) + let lo = comment_span.lo() + BytePos(2 + i as u32); + (c, comment_span.with_lo(lo).with_hi(lo + BytePos(c.len_utf8() as u32))) }) }) .collect(); - let (an, s) = match spans.len() { - 1 => ("an ", ""), - _ => ("", "s"), - }; - diag.span_label( + let characters = spans + .iter() + .map(|&(c, span)| lints::UnicodeCharNoteSub { span, c_debug: format!("{c:?}") }) + .collect(); + let suggestions = (!spans.is_empty()).then_some(lints::UnicodeTextFlowSuggestion { + spans: spans.iter().map(|(_c, span)| *span).collect(), + }); + ctx.emit_span_lint( + lint, span, - format!( - "this comment contains {an}invisible unicode text flow control codepoint{s}", - ), - ); - for (c, span) in &spans { - diag.span_label(*span, format!("{c:?}")); - } - diag.note( - "these kind of unicode codepoints change the way text flows on \ - applications that support them, but can cause confusion because they \ - change the order of characters on the screen", - ); - if !spans.is_empty() { - diag.multipart_suggestion_with_style( - "if their presence wasn't intentional, you can remove them", - spans.into_iter().map(|(_, span)| (span, "".to_string())).collect(), - Applicability::MachineApplicable, - SuggestionStyle::HideCodeAlways, - ); - } - } - BuiltinLintDiag::AbsPathWithModule(span) => { - let (sugg, app) = match sess.source_map().span_to_snippet(span) { + lints::UnicodeTextFlow { + comment_span, + characters, + suggestions, + num_codepoints: spans.len(), + }, + ) + } + BuiltinLintDiag::AbsPathWithModule(mod_span) => { + let (replacement, applicability) = match sess.source_map().span_to_snippet(mod_span) { Ok(ref s) => { // FIXME(Manishearth) ideally the emitting code // can tell us whether or not this is global @@ -68,64 +61,90 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di } Err(_) => ("crate::<path>".to_string(), Applicability::HasPlaceholders), }; - diag.span_suggestion(span, "use `crate`", sugg, app); - } - BuiltinLintDiag::ProcMacroDeriveResolutionFallback { span, .. } => { - diag.span_label( + ctx.emit_span_lint( + lint, span, - "names from parent modules are not accessible without an explicit import", + lints::AbsPathWithModule { + sugg: lints::AbsPathWithModuleSugg { + span: mod_span, + applicability, + replacement, + }, + }, ); } - BuiltinLintDiag::MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def) => { - diag.span_note(span_def, "the macro is defined here"); - } + BuiltinLintDiag::ProcMacroDeriveResolutionFallback { span: macro_span, ns, ident } => ctx + .emit_span_lint( + lint, + span, + lints::ProcMacroDeriveResolutionFallback { span: macro_span, ns, ident }, + ), + BuiltinLintDiag::MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def) => ctx + .emit_span_lint( + lint, + span, + lints::MacroExpandedMacroExportsAccessedByAbsolutePaths { definition: span_def }, + ), BuiltinLintDiag::ElidedLifetimesInPaths(n, path_span, incl_angl_brckt, insertion_span) => { - diag.subdiagnostic( - sess.dcx(), - elided_lifetime_in_path_suggestion( - sess.source_map(), - n, - path_span, - incl_angl_brckt, - insertion_span, - ), + ctx.emit_span_lint( + lint, + span, + lints::ElidedLifetimesInPaths { + subdiag: elided_lifetime_in_path_suggestion( + sess.source_map(), + n, + path_span, + incl_angl_brckt, + insertion_span, + ), + }, ); } 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() { - diag.tool_only_multipart_suggestion( - fix_msg, - fixes, - Applicability::MachineApplicable, - ); - } + let sugg = candidate.map(|candidate| lints::UnknownCrateTypesSub { span, candidate }); + ctx.emit_span_lint(lint, span, lints::UnknownCrateTypes { sugg }); + } + BuiltinLintDiag::UnusedImports { + remove_whole_use, + num_to_remove, + remove_spans, + test_module_span, + span_snippets, + } => { + let sugg = if remove_whole_use { + lints::UnusedImportsSugg::RemoveWholeUse { span: remove_spans[0] } + } else { + lints::UnusedImportsSugg::RemoveImports { remove_spans, num_to_remove } + }; + let test_module_span = + test_module_span.map(|span| sess.source_map().guess_head_span(span)); - if let Some(span) = test_module_span { - diag.span_help( - sess.source_map().guess_head_span(span), - "if this is a test module, consider adding a `#[cfg(test)]` to the containing module", - ); - } + ctx.emit_span_lint( + lint, + span, + lints::UnusedImports { + sugg, + test_module_span, + num_snippets: span_snippets.len(), + span_snippets: DiagArgValue::StrListSepByAnd( + span_snippets.into_iter().map(Cow::Owned).collect(), + ), + }, + ); } BuiltinLintDiag::RedundantImport(spans, ident) => { - for (span, is_imported) in spans { - let introduced = if is_imported { "imported" } else { "defined" }; - let span_msg = if span.is_dummy() { "by the extern prelude" } else { "here" }; - diag.span_label( - span, - format!("the item `{ident}` is already {introduced} {span_msg}"), - ); - } + let subs = spans + .into_iter() + .map(|(span, is_imported)| { + (match (span.is_dummy(), is_imported) { + (false, true) => lints::RedundantImportSub::ImportedHere, + (false, false) => lints::RedundantImportSub::DefinedHere, + (true, true) => lints::RedundantImportSub::ImportedPrelude, + (true, false) => lints::RedundantImportSub::DefinedPrelude, + })(span) + }) + .collect(); + ctx.emit_span_lint(lint, span, lints::RedundantImport { subs, ident }); } BuiltinLintDiag::DeprecatedMacro { suggestion, @@ -139,106 +158,110 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di kind: "macro".to_owned(), suggestion, }); - let deprecated = - stability::Deprecated { sub, kind: "macro".to_owned(), path, note, since_kind }; - deprecated.decorate_lint(diag); + ctx.emit_span_lint( + lint, + span, + stability::Deprecated { sub, kind: "macro".to_owned(), path, note, since_kind }, + ); } - BuiltinLintDiag::UnusedDocComment(span) => { - diag.span_label(span, "rustdoc does not generate documentation for macro invocations"); - diag.help("to document an item produced by a macro, \ - the macro must produce the documentation as part of its expansion"); + BuiltinLintDiag::UnusedDocComment(attr_span) => { + ctx.emit_span_lint(lint, span, lints::UnusedDocComment { span: attr_span }); } - BuiltinLintDiag::PatternsInFnsWithoutBody { span, ident, .. } => { - diag.span_suggestion( + BuiltinLintDiag::PatternsInFnsWithoutBody { span: remove_span, ident, is_foreign } => { + let sub = lints::PatternsInFnsWithoutBodySub { ident, span: remove_span }; + + ctx.emit_span_lint( + lint, span, - "remove `mut` from the parameter", - ident, - Applicability::MachineApplicable, + if is_foreign { + lints::PatternsInFnsWithoutBody::Foreign { sub } + } else { + lints::PatternsInFnsWithoutBody::Bodiless { sub } + }, ); } - BuiltinLintDiag::MissingAbi(span, default_abi) => { - diag.span_label(span, "ABI should be specified here"); - diag.help(format!("the default ABI is {}", default_abi.name())); + BuiltinLintDiag::MissingAbi(label_span, default_abi) => { + ctx.emit_span_lint( + lint, + span, + lints::MissingAbi { span: label_span, default_abi: default_abi.name() }, + ); } - BuiltinLintDiag::LegacyDeriveHelpers(span) => { - diag.span_label(span, "the attribute is introduced here"); + BuiltinLintDiag::LegacyDeriveHelpers(label_span) => { + ctx.emit_span_lint(lint, span, lints::LegacyDeriveHelpers { span: label_span }); } - BuiltinLintDiag::ProcMacroBackCompat(note) => { - diag.note(note); + BuiltinLintDiag::ProcMacroBackCompat { crate_name, fixed_version } => { + ctx.emit_span_lint( + lint, + span, + lints::ProcMacroBackCompat { crate_name, fixed_version }, + ); } - BuiltinLintDiag::OrPatternsBackCompat(span, suggestion) => { - diag.span_suggestion( + BuiltinLintDiag::OrPatternsBackCompat(suggestion_span, suggestion) => { + ctx.emit_span_lint( + lint, span, - "use pat_param to preserve semantics", - suggestion, - Applicability::MachineApplicable, + lints::OrPatternsBackCompat { span: suggestion_span, suggestion }, ); } - BuiltinLintDiag::ReservedPrefix(span, _) => { - diag.span_label(span, "unknown prefix"); - diag.span_suggestion_verbose( - span.shrink_to_hi(), - "insert whitespace here to avoid this being parsed as a prefix in Rust 2021", - " ", - Applicability::MachineApplicable, + BuiltinLintDiag::ReservedPrefix(label_span, prefix) => { + ctx.emit_span_lint( + lint, + span, + lints::ReservedPrefix { + label: label_span, + suggestion: label_span.shrink_to_hi(), + prefix, + }, ); } BuiltinLintDiag::UnusedBuiltinAttribute { attr_name, macro_name, invoc_span } => { - diag.span_note( - invoc_span, - format!("the built-in attribute `{attr_name}` will be ignored, since it's applied to the macro invocation `{macro_name}`") - ); + ctx.emit_span_lint( + lint, + span, + lints::UnusedBuiltinAttribute { invoc_span, attr_name, macro_name }, + ); } BuiltinLintDiag::TrailingMacro(is_trailing, name) => { - if is_trailing { - diag.note("macro invocations at the end of a block are treated as expressions"); - diag.note(format!("to ignore the value produced by the macro, add a semicolon after the invocation of `{name}`")); - } - } - BuiltinLintDiag::BreakWithLabelAndLoop(span) => { - diag.multipart_suggestion( - "wrap this expression in parentheses", - vec![ - (span.shrink_to_lo(), "(".to_string()), - (span.shrink_to_hi(), ")".to_string()), - ], - Applicability::MachineApplicable, + ctx.emit_span_lint(lint, span, lints::TrailingMacro { is_trailing, name }); + } + BuiltinLintDiag::BreakWithLabelAndLoop(sugg_span) => { + ctx.emit_span_lint( + lint, + span, + lints::BreakWithLabelAndLoop { + sub: lints::BreakWithLabelAndLoopSub { + left: sugg_span.shrink_to_lo(), + right: sugg_span.shrink_to_hi(), + }, + }, ); } BuiltinLintDiag::UnexpectedCfgName(name, value) => { - check_cfg::unexpected_cfg_name(sess, diag, name, value) + ctx.emit_span_lint(lint, span, check_cfg::unexpected_cfg_name(sess, name, value)); } BuiltinLintDiag::UnexpectedCfgValue(name, value) => { - check_cfg::unexpected_cfg_value(sess, diag, name, value) - } - BuiltinLintDiag::DeprecatedWhereclauseLocation(sugg) => { - let left_sp = diag.span.primary_span().unwrap(); - match sugg { - Some((right_sp, sugg)) => diag.multipart_suggestion( - "move it to the end of the type declaration", - vec![(left_sp, String::new()), (right_sp, sugg)], - Applicability::MachineApplicable, - ), - None => diag.span_suggestion( - left_sp, - "remove this `where`", - "", - Applicability::MachineApplicable, - ), + ctx.emit_span_lint(lint, span, check_cfg::unexpected_cfg_value(sess, name, value)); + } + BuiltinLintDiag::DeprecatedWhereclauseLocation(left_sp, sugg) => { + let suggestion = match sugg { + Some((right_sp, sugg)) => lints::DeprecatedWhereClauseLocationSugg::MoveToEnd { + left: left_sp, + right: right_sp, + sugg, + }, + None => lints::DeprecatedWhereClauseLocationSugg::RemoveWhere { span: left_sp }, }; - diag.note("see issue #89122 <https://github.com/rust-lang/rust/issues/89122> for more information"); + ctx.emit_span_lint(lint, span, lints::DeprecatedWhereClauseLocation { suggestion }); } BuiltinLintDiag::SingleUseLifetime { param_span, use_span: Some((use_span, elide)), deletion_span, - .. + ident, } => { debug!(?param_span, ?use_span, ?deletion_span); - diag.span_label(param_span, "this lifetime..."); - diag.span_label(use_span, "...is used only here"); - if let Some(deletion_span) = deletion_span { - let msg = "elide the single-use lifetime"; + let suggestion = if let Some(deletion_span) = deletion_span { let (use_span, replace_lt) = if elide { let use_span = sess.source_map().span_extend_while_whitespace(use_span); (use_span, String::new()) @@ -249,26 +272,22 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di // issue 107998 for the case such as a wrong function pointer type // `deletion_span` is empty and there is no need to report lifetime uses here - let suggestions = if deletion_span.is_empty() { - vec![(use_span, replace_lt)] - } else { - vec![(deletion_span, String::new()), (use_span, replace_lt)] - }; - diag.multipart_suggestion(msg, suggestions, Applicability::MachineApplicable); - } + let deletion_span = + if deletion_span.is_empty() { None } else { Some(deletion_span) }; + Some(lints::SingleUseLifetimeSugg { deletion_span, use_span, replace_lt }) + } else { + None + }; + + ctx.emit_span_lint( + lint, + span, + lints::SingleUseLifetime { suggestion, param_span, use_span, ident }, + ); } - BuiltinLintDiag::SingleUseLifetime { - param_span: _, use_span: None, deletion_span, .. - } => { + BuiltinLintDiag::SingleUseLifetime { use_span: None, deletion_span, ident, .. } => { debug!(?deletion_span); - if let Some(deletion_span) = deletion_span { - diag.span_suggestion( - deletion_span, - "elide the unused lifetime", - "", - Applicability::MachineApplicable, - ); - } + ctx.emit_span_lint(lint, span, lints::UnusedLifetime { deletion_span, ident }); } BuiltinLintDiag::NamedArgumentUsedPositionally { position_sp_to_replace, @@ -277,19 +296,12 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di named_arg_name, is_formatting_arg, } => { - diag.span_label( - named_arg_sp, - "this named argument is referred to by position in formatting string", - ); - if let Some(positional_arg_for_msg) = position_sp_for_msg { - let msg = format!( - "this formatting argument uses named argument `{named_arg_name}` by position" - ); - diag.span_label(positional_arg_for_msg, msg); - } - - if let Some(positional_arg_to_replace) = position_sp_to_replace { - let name = if is_formatting_arg { named_arg_name + "$" } else { named_arg_name }; + let (suggestion, name) = if let Some(positional_arg_to_replace) = position_sp_to_replace + { + let mut name = named_arg_name.clone(); + if is_formatting_arg { + name.push('$') + }; let span_to_replace = if let Ok(positional_arg_content) = sess.source_map().span_to_snippet(positional_arg_to_replace) && positional_arg_content.starts_with(':') @@ -298,31 +310,40 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di } else { positional_arg_to_replace }; - diag.span_suggestion_verbose( - span_to_replace, - "use the named argument by name to avoid ambiguity", + (Some(span_to_replace), name) + } else { + (None, String::new()) + }; + + ctx.emit_span_lint( + lint, + span, + lints::NamedArgumentUsedPositionally { + named_arg_sp, + position_label_sp: position_sp_for_msg, + suggestion, name, - Applicability::MaybeIncorrect, - ); - } + named_arg_name, + }, + ) } - BuiltinLintDiag::ByteSliceInPackedStructWithDerive { .. } => { - diag.help("consider implementing the trait by hand, or remove the `packed` attribute"); + BuiltinLintDiag::ByteSliceInPackedStructWithDerive { ty } => { + ctx.emit_span_lint(lint, span, lints::ByteSliceInPackedStructWithDerive { ty }) } BuiltinLintDiag::UnusedExternCrate { removal_span } => { - diag.span_suggestion(removal_span, "remove it", "", Applicability::MachineApplicable); + ctx.emit_span_lint(lint, span, lints::UnusedExternCrate { removal_span }) } BuiltinLintDiag::ExternCrateNotIdiomatic { vis_span, ident_span } => { let suggestion_span = vis_span.between(ident_span); - diag.span_suggestion_verbose( - suggestion_span, - "convert it to a `use`", - if vis_span.is_empty() { "use " } else { " use " }, - Applicability::MachineApplicable, + let code = if vis_span.is_empty() { "use " } else { " use " }; + ctx.emit_span_lint( + lint, + span, + lints::ExternCrateNotIdiomatic { span: suggestion_span, code }, ); } BuiltinLintDiag::AmbiguousGlobImports { diag: ambiguity } => { - rustc_errors::report_ambiguity_error(diag, ambiguity); + ctx.emit_span_lint(lint, span, lints::AmbiguousGlobImports { ambiguity }); } BuiltinLintDiag::AmbiguousGlobReexports { name, @@ -330,15 +351,15 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di first_reexport_span, duplicate_reexport_span, } => { - diag.span_label( - first_reexport_span, - format!("the name `{name}` in the {namespace} namespace is first re-exported here"), - ); - diag.span_label( - duplicate_reexport_span, - format!( - "but the name `{name}` in the {namespace} namespace is also re-exported here" - ), + ctx.emit_span_lint( + lint, + span, + lints::AmbiguousGlobReexports { + first_reexport: first_reexport_span, + duplicate_reexport: duplicate_reexport_span, + name, + namespace, + }, ); } BuiltinLintDiag::HiddenGlobReexports { @@ -347,261 +368,127 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di glob_reexport_span, private_item_span, } => { - diag.span_note(glob_reexport_span, format!("the name `{name}` in the {namespace} namespace is supposed to be publicly re-exported here")); - diag.span_note(private_item_span, "but the private item here shadows it".to_owned()); + ctx.emit_span_lint( + lint, + span, + lints::HiddenGlobReexports { + glob_reexport: glob_reexport_span, + private_item: private_item_span, + + name, + namespace, + }, + ); } BuiltinLintDiag::UnusedQualifications { removal_span } => { - diag.span_suggestion_verbose( - removal_span, - "remove the unnecessary path segments", - "", - Applicability::MachineApplicable, - ); + ctx.emit_span_lint(lint, span, lints::UnusedQualifications { removal_span }); } - BuiltinLintDiag::AssociatedConstElidedLifetime { elided, span } => { - diag.span_suggestion_verbose( - if elided { span.shrink_to_hi() } else { span }, - "use the `'static` lifetime", - if elided { "'static " } else { "'static" }, - Applicability::MachineApplicable, + BuiltinLintDiag::AssociatedConstElidedLifetime { elided, span: lt_span } => { + let lt_span = if elided { lt_span.shrink_to_hi() } else { lt_span }; + let code = if elided { "'static " } else { "'static" }; + ctx.emit_span_lint( + lint, + span, + lints::AssociatedConstElidedLifetime { span: lt_span, code, elided }, ); } - BuiltinLintDiag::RedundantImportVisibility { max_vis, span, .. } => { - diag.span_note(span, format!("the most public imported item is `{max_vis}`")); - diag.help( - "reduce the glob import's visibility or increase visibility of imported items", + BuiltinLintDiag::RedundantImportVisibility { max_vis, span: vis_span, import_vis } => { + ctx.emit_span_lint( + lint, + span, + lints::RedundantImportVisibility { span: vis_span, help: (), max_vis, import_vis }, ); } - 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::AbsPathWithModule(_) => { - "absolute paths must start with `self`, `super`, `crate`, or an \ - external crate name in the 2018 edition" - .into() - } - BuiltinLintDiag::ProcMacroDeriveResolutionFallback { ns, ident, .. } => { - format!("cannot find {} `{}` in this scope", ns.descr(), ident).into() - } - BuiltinLintDiag::MacroExpandedMacroExportsAccessedByAbsolutePaths(_) => { - "macro-expanded `macro_export` macros from the current crate cannot \ - be referred to by absolute paths" - .into() - } - BuiltinLintDiag::ElidedLifetimesInPaths(_, _, _, _) => { - "hidden lifetime parameters in types are deprecated".into() - } - BuiltinLintDiag::UnknownCrateTypes { .. } => "invalid `crate_type` value".into(), - BuiltinLintDiag::UnusedImports { span_snippets, .. } => format!( - "unused import{}{}", - pluralize!(span_snippets.len()), - if !span_snippets.is_empty() { - format!(": {}", span_snippets.join(", ")) - } else { - String::new() - } - ) - .into(), - BuiltinLintDiag::RedundantImport(_, source) => { - format!("the item `{source}` is imported redundantly").into() - } - BuiltinLintDiag::DeprecatedMacro { since_kind, .. } => { - stability::Deprecated::msg_for_since_kind(since_kind) - } - BuiltinLintDiag::MissingAbi(_, _) => crate::fluent_generated::lint_extern_without_abi, - BuiltinLintDiag::UnusedDocComment(_) => "unused doc comment".into(), - BuiltinLintDiag::UnusedBuiltinAttribute { attr_name, .. } => { - format!("unused attribute `{attr_name}`").into() - } - BuiltinLintDiag::PatternsInFnsWithoutBody { is_foreign, .. } => { - if *is_foreign { - crate::fluent_generated::lint_pattern_in_foreign - } else { - crate::fluent_generated::lint_pattern_in_bodiless - } - } - BuiltinLintDiag::LegacyDeriveHelpers(_) => { - "derive helper attribute is used before it is introduced".into() - } - BuiltinLintDiag::ProcMacroBackCompat(_) => "using an old version of `rental`".into(), - BuiltinLintDiag::OrPatternsBackCompat(_, _) => { - "the meaning of the `pat` fragment specifier is changing in Rust 2021, \ - which may affect this macro" - .into() - } - BuiltinLintDiag::ReservedPrefix(_, prefix) => { - format!("prefix `{prefix}` is unknown").into() - } - BuiltinLintDiag::TrailingMacro(_, _) => { - "trailing semicolon in macro used in expression position".into() - } - BuiltinLintDiag::BreakWithLabelAndLoop(_) => { - "this labeled break expression is easy to confuse with an unlabeled break with a \ - labeled value expression" - .into() - } - BuiltinLintDiag::UnicodeTextFlow(_, _) => { - "unicode codepoint changing visible direction of text present in comment".into() - } - BuiltinLintDiag::UnexpectedCfgName((name, _), _) => { - format!("unexpected `cfg` condition name: `{}`", name).into() - } - BuiltinLintDiag::UnexpectedCfgValue(_, v) => if let Some((value, _)) = v { - format!("unexpected `cfg` condition value: `{value}`") - } else { - format!("unexpected `cfg` condition value: (none)") + BuiltinLintDiag::UnknownDiagnosticAttribute { span: typo_span, typo_name } => { + let typo = typo_name.map(|typo_name| lints::UnknownDiagnosticAttributeTypoSugg { + span: typo_span, + typo_name, + }); + ctx.emit_span_lint(lint, span, lints::UnknownDiagnosticAttribute { typo }); } - .into(), - BuiltinLintDiag::DeprecatedWhereclauseLocation(_) => { - crate::fluent_generated::lint_deprecated_where_clause_location + BuiltinLintDiag::MacroUseDeprecated => { + ctx.emit_span_lint(lint, span, lints::MacroUseDeprecated) } - BuiltinLintDiag::SingleUseLifetime { use_span, ident, .. } => { - if use_span.is_some() { - format!("lifetime parameter `{}` only used once", ident).into() - } else { - format!("lifetime parameter `{}` never used", ident).into() - } + BuiltinLintDiag::UnusedMacroUse => ctx.emit_span_lint(lint, span, lints::UnusedMacroUse), + BuiltinLintDiag::PrivateExternCrateReexport(ident) => { + ctx.emit_span_lint(lint, span, lints::PrivateExternCrateReexport { ident }) } - BuiltinLintDiag::NamedArgumentUsedPositionally { named_arg_name, .. } => { - format!("named argument `{}` is not used by name", named_arg_name).into() + BuiltinLintDiag::UnusedLabel => ctx.emit_span_lint(lint, span, lints::UnusedLabel), + BuiltinLintDiag::MacroIsPrivate(ident) => { + ctx.emit_span_lint(lint, span, lints::MacroIsPrivate { ident }) } - BuiltinLintDiag::ByteSliceInPackedStructWithDerive { ty } => { - format!("{ty} slice in a packed struct that derives a built-in trait").into() - } - BuiltinLintDiag::UnusedExternCrate { .. } => "unused extern crate".into(), - BuiltinLintDiag::ExternCrateNotIdiomatic { .. } => { - "`extern crate` is not idiomatic in the new edition".into() - } - BuiltinLintDiag::AmbiguousGlobImports { diag } => diag.msg.clone().into(), - BuiltinLintDiag::AmbiguousGlobReexports { .. } => "ambiguous glob re-exports".into(), - BuiltinLintDiag::HiddenGlobReexports { .. } => { - "private item shadows public glob re-export".into() - } - BuiltinLintDiag::UnusedQualifications { .. } => "unnecessary qualification".into(), - BuiltinLintDiag::AssociatedConstElidedLifetime { elided, .. } => if *elided { - "`&` without an explicit lifetime name cannot be used here" - } else { - "`'_` cannot be used here" - } - .into(), - BuiltinLintDiag::RedundantImportVisibility { import_vis, .. } => format!( - "glob import doesn't reexport anything with visibility `{}` \ - because no imported item is public enough", - 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() + ctx.emit_span_lint(lint, span, lints::UnusedMacroDefinition { name }) } BuiltinLintDiag::MacroRuleNeverUsed(n, name) => { - format!("rule #{} of macro `{}` is never used", n + 1, name).into() + ctx.emit_span_lint(lint, span, lints::MacroRuleNeverUsed { n: n + 1, name }) + } + BuiltinLintDiag::UnstableFeature(msg) => { + ctx.emit_span_lint(lint, span, lints::UnstableFeature { msg }) } - BuiltinLintDiag::UnstableFeature(msg) => msg.clone().into(), BuiltinLintDiag::AvoidUsingIntelSyntax => { - "avoid using `.intel_syntax`, Intel syntax is the default".into() + ctx.emit_span_lint(lint, span, lints::AvoidIntelSyntax) } BuiltinLintDiag::AvoidUsingAttSyntax => { - "avoid using `.att_syntax`, prefer using `options(att_syntax)` instead".into() + ctx.emit_span_lint(lint, span, lints::AvoidAttSyntax) } BuiltinLintDiag::IncompleteInclude => { - "include macro expected single expression in source".into() + ctx.emit_span_lint(lint, span, lints::IncompleteInclude) + } + BuiltinLintDiag::UnnameableTestItems => { + ctx.emit_span_lint(lint, span, lints::UnnameableTestItems) + } + BuiltinLintDiag::DuplicateMacroAttribute => { + ctx.emit_span_lint(lint, span, lints::DuplicateMacroAttribute) } - BuiltinLintDiag::UnnameableTestItems => crate::fluent_generated::lint_unnameable_test_items, - BuiltinLintDiag::DuplicateMacroAttribute => "duplicated attribute".into(), BuiltinLintDiag::CfgAttrNoAttributes => { - crate::fluent_generated::lint_cfg_attr_no_attributes + ctx.emit_span_lint(lint, span, lints::CfgAttrNoAttributes) } BuiltinLintDiag::CrateTypeInCfgAttr => { - crate::fluent_generated::lint_crate_type_in_cfg_attr_deprecated + ctx.emit_span_lint(lint, span, lints::CrateTypeInCfgAttr) } BuiltinLintDiag::CrateNameInCfgAttr => { - crate::fluent_generated::lint_crate_name_in_cfg_attr_deprecated + ctx.emit_span_lint(lint, span, lints::CrateNameInCfgAttr) + } + BuiltinLintDiag::MissingFragmentSpecifier => { + ctx.emit_span_lint(lint, span, lints::MissingFragmentSpecifier) } - BuiltinLintDiag::MissingFragmentSpecifier => "missing fragment specifier".into(), BuiltinLintDiag::MetaVariableStillRepeating(name) => { - format!("variable '{name}' is still repeating at this depth").into() + ctx.emit_span_lint(lint, span, lints::MetaVariableStillRepeating { name }) } BuiltinLintDiag::MetaVariableWrongOperator => { - "meta-variable repeats with different Kleene operator".into() + ctx.emit_span_lint(lint, span, lints::MetaVariableWrongOperator) + } + BuiltinLintDiag::DuplicateMatcherBinding => { + ctx.emit_span_lint(lint, span, lints::DuplicateMatcherBinding) } - 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(), + ctx.emit_span_lint(lint, span, lints::UnknownMacroVariable { name }) + } + BuiltinLintDiag::UnusedCrateDependency { extern_crate, local_crate } => ctx.emit_span_lint( + lint, + span, + lints::UnusedCrateDependency { extern_crate, local_crate }, + ), + BuiltinLintDiag::WasmCAbi => ctx.emit_span_lint(lint, span, lints::WasmCAbi), + BuiltinLintDiag::IllFormedAttributeInput { suggestions } => ctx.emit_span_lint( + lint, + span, + lints::IllFormedAttributeInput { + num_suggestions: suggestions.len(), + suggestions: DiagArgValue::StrListSepByAnd( + suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(), + ), + }, + ), + BuiltinLintDiag::InnerAttributeUnstable { is_macro } => ctx.emit_span_lint( + lint, + span, + if is_macro { + lints::InnerAttributeUnstable::InnerMacroAttribute + } else { + lints::InnerAttributeUnstable::CustomInnerAttribute + }, + ), } } |
