diff options
Diffstat (limited to 'compiler')
26 files changed, 212 insertions, 130 deletions
diff --git a/compiler/rustc_ast_passes/messages.ftl b/compiler/rustc_ast_passes/messages.ftl index a3731e94276..31a184fe921 100644 --- a/compiler/rustc_ast_passes/messages.ftl +++ b/compiler/rustc_ast_passes/messages.ftl @@ -55,9 +55,6 @@ ast_passes_const_without_body = ast_passes_constraint_on_negative_bound = associated type constraints not allowed on negative bounds -ast_passes_deprecated_where_clause_location = - where clause not allowed here - ast_passes_equality_in_where = equality constraints are not yet supported in `where` clauses .label = not supported .suggestion = if `{$ident}` is an associated type you're trying to set, use the associated type binding syntax @@ -80,8 +77,6 @@ ast_passes_extern_types_cannot = `type`s inside `extern` blocks cannot have {$de .suggestion = remove the {$remove_descr} .label = `extern` block begins here -ast_passes_extern_without_abi = extern declarations without an explicit ABI are deprecated - ast_passes_feature_on_non_nightly = `#![feature]` may not be used on the {$channel} release channel .suggestion = remove the attribute .stable_since = the feature `{$name}` has been stable since `{$since}` and no longer requires an attribute to enable diff --git a/compiler/rustc_ast_passes/src/ast_validation.rs b/compiler/rustc_ast_passes/src/ast_validation.rs index 9d07683f8d6..c287f6e4b3d 100644 --- a/compiler/rustc_ast_passes/src/ast_validation.rs +++ b/compiler/rustc_ast_passes/src/ast_validation.rs @@ -27,7 +27,6 @@ use std::ops::{Deref, DerefMut}; use thin_vec::thin_vec; use crate::errors; -use crate::fluent_generated as fluent; /// Is `self` allowed semantically as the first parameter in an `FnDecl`? enum SelfSemantic { @@ -770,7 +769,6 @@ impl<'a> AstValidator<'a> { MISSING_ABI, id, span, - fluent::ast_passes_extern_without_abi, BuiltinLintDiag::MissingAbi(span, abi::Abi::FALLBACK), ) } @@ -1428,17 +1426,15 @@ impl<'a> Visitor<'a> for AstValidator<'a> { Self::check_decl_no_pat(&sig.decl, |span, ident, mut_ident| { if mut_ident && matches!(ctxt, FnCtxt::Assoc(_)) { if let Some(ident) = ident { - let msg = match ctxt { - FnCtxt::Foreign => fluent::ast_passes_pattern_in_foreign, - _ => fluent::ast_passes_pattern_in_bodiless, - }; - let diag = BuiltinLintDiag::PatternsInFnsWithoutBody(span, ident); self.lint_buffer.buffer_lint_with_diagnostic( PATTERNS_IN_FNS_WITHOUT_BODY, id, span, - msg, - diag, + BuiltinLintDiag::PatternsInFnsWithoutBody { + span, + ident, + is_foreign: matches!(ctxt, FnCtxt::Foreign), + }, ) } } else { @@ -1514,7 +1510,6 @@ impl<'a> Visitor<'a> for AstValidator<'a> { DEPRECATED_WHERE_CLAUSE_LOCATION, item.id, err.span, - fluent::ast_passes_deprecated_where_clause_location, BuiltinLintDiag::DeprecatedWhereclauseLocation(sugg), ); } diff --git a/compiler/rustc_ast_passes/src/errors.rs b/compiler/rustc_ast_passes/src/errors.rs index 25a125f8393..a95a7bdaf6d 100644 --- a/compiler/rustc_ast_passes/src/errors.rs +++ b/compiler/rustc_ast_passes/src/errors.rs @@ -669,6 +669,7 @@ pub struct ConstAndCVariadic { #[derive(Diagnostic)] #[diag(ast_passes_pattern_in_foreign, code = E0130)] +// FIXME: deduplicate with rustc_lint (`BuiltinLintDiag::PatternsInFnsWithoutBody`) pub struct PatternInForeign { #[primary_span] #[label] @@ -677,6 +678,7 @@ pub struct PatternInForeign { #[derive(Diagnostic)] #[diag(ast_passes_pattern_in_bodiless, code = E0642)] +// FIXME: deduplicate with rustc_lint (`BuiltinLintDiag::PatternsInFnsWithoutBody`) pub struct PatternInBodiless { #[primary_span] #[label] diff --git a/compiler/rustc_attr/src/builtin.rs b/compiler/rustc_attr/src/builtin.rs index c08bf287733..1ac2e15c327 100644 --- a/compiler/rustc_attr/src/builtin.rs +++ b/compiler/rustc_attr/src/builtin.rs @@ -532,11 +532,6 @@ pub fn cfg_matches( UNEXPECTED_CFGS, cfg.span, lint_node_id, - if let Some(value) = cfg.value { - format!("unexpected `cfg` condition value: `{value}`") - } else { - format!("unexpected `cfg` condition value: (none)") - }, BuiltinLintDiag::UnexpectedCfgValue( (cfg.name, cfg.name_span), cfg.value.map(|v| (v, cfg.value_span.unwrap())), @@ -548,7 +543,6 @@ pub fn cfg_matches( UNEXPECTED_CFGS, cfg.span, lint_node_id, - format!("unexpected `cfg` condition name: `{}`", cfg.name), BuiltinLintDiag::UnexpectedCfgName( (cfg.name, cfg.name_span), cfg.value.map(|v| (v, cfg.value_span.unwrap())), diff --git a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs index 46949f731aa..18dca4b2615 100644 --- a/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs +++ b/compiler/rustc_builtin_macros/src/deriving/generic/mod.rs @@ -1625,10 +1625,9 @@ impl<'a> TraitDef<'a> { BYTE_SLICE_IN_PACKED_STRUCT_WITH_DERIVE, sp, ast::CRATE_NODE_ID, - format!( - "{ty} slice in a packed struct that derives a built-in trait" - ), - rustc_lint_defs::BuiltinLintDiag::ByteSliceInPackedStructWithDerive, + rustc_lint_defs::BuiltinLintDiag::ByteSliceInPackedStructWithDerive { + ty: ty.to_string(), + }, ); } else { // Wrap the expression in `{...}`, causing a copy. diff --git a/compiler/rustc_builtin_macros/src/format.rs b/compiler/rustc_builtin_macros/src/format.rs index a5fc74f1d66..5cb0407bd59 100644 --- a/compiler/rustc_builtin_macros/src/format.rs +++ b/compiler/rustc_builtin_macros/src/format.rs @@ -556,7 +556,6 @@ fn make_format_args( let arg_name = args.explicit_args()[index].kind.ident().unwrap(); ecx.buffered_early_lint.push(BufferedEarlyLint { span: arg_name.span.into(), - msg: format!("named argument `{}` is not used by name", arg_name.name).into(), node_id: rustc_ast::CRATE_NODE_ID, lint_id: LintId::of(NAMED_ARGUMENTS_USED_POSITIONALLY), diagnostic: BuiltinLintDiag::NamedArgumentUsedPositionally { diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 12868a66605..c7ca515afc4 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -1370,7 +1370,6 @@ fn pretty_printing_compatibility_hack(item: &Item, sess: &Session) -> bool { PROC_MACRO_BACK_COMPAT, item.ident.span, ast::CRATE_NODE_ID, - "using an old version of `rental`", BuiltinLintDiag::ProcMacroBackCompat( "older versions of the `rental` crate will stop compiling in future versions of Rust; \ please update to `rental` v0.5.6, or switch to one of the `rental` alternatives".to_string() diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index a049ac251e1..02e4f5e0f9e 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -1803,7 +1803,6 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { UNUSED_DOC_COMMENTS, current_span, self.cx.current_expansion.lint_node_id, - "unused doc comment", BuiltinLintDiag::UnusedDocComment(attr.span), ); } else if rustc_attr::is_builtin_attr(attr) { @@ -1815,7 +1814,6 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { UNUSED_ATTRIBUTES, attr.span, self.cx.current_expansion.lint_node_id, - format!("unused attribute `{attr_name}`"), BuiltinLintDiag::UnusedBuiltinAttribute { attr_name, macro_name: pprust::path_to_string(&call.path), diff --git a/compiler/rustc_expand/src/mbe/macro_rules.rs b/compiler/rustc_expand/src/mbe/macro_rules.rs index 8f18055f838..fee7ba099aa 100644 --- a/compiler/rustc_expand/src/mbe/macro_rules.rs +++ b/compiler/rustc_expand/src/mbe/macro_rules.rs @@ -83,7 +83,6 @@ impl<'a> ParserAnyMacro<'a> { SEMICOLON_IN_EXPRESSIONS_FROM_MACROS, parser.token.span, lint_node_id, - "trailing semicolon in macro used in expression position", BuiltinLintDiag::TrailingMacro(is_trailing_mac, macro_ident), ); } @@ -1158,7 +1157,6 @@ fn check_matcher_core<'tt>( RUST_2021_INCOMPATIBLE_OR_PATTERNS, span, ast::CRATE_NODE_ID, - "the meaning of the `pat` fragment specifier is changing in Rust 2021, which may affect this macro", BuiltinLintDiag::OrPatternsBackCompat(span, suggestion), ); } diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index ce2382b9501..de7005a541b 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -409,7 +409,6 @@ pub(crate) fn check_attr_crate_type( lint::builtin::UNKNOWN_CRATE_TYPES, ast::CRATE_NODE_ID, span, - "invalid `crate_type` value", BuiltinLintDiag::UnknownCrateTypes( span, "did you mean".to_string(), diff --git a/compiler/rustc_lint/messages.ftl b/compiler/rustc_lint/messages.ftl index 6ad13c01812..e1b0aec6c96 100644 --- a/compiler/rustc_lint/messages.ftl +++ b/compiler/rustc_lint/messages.ftl @@ -180,6 +180,9 @@ lint_deprecated_lint_name = .suggestion = change it to .help = change it to {$replace} +lint_deprecated_where_clause_location = + where clause not allowed here + lint_diag_out_of_impl = diagnostics should only be created in `Diagnostic`/`Subdiagnostic`/`LintDiagnostic` impls @@ -209,6 +212,8 @@ lint_expectation = this lint expectation is unfulfilled .note = the `unfulfilled_lint_expectations` lint can't be expected and will always produce this message .rationale = {$rationale} +lint_extern_without_abi = extern declarations without an explicit ABI are deprecated + lint_for_loops_over_fallibles = for loop over {$article} `{$ty}`. This is more readably written as an `if let` statement .suggestion = consider using `if let` to clear intent @@ -521,6 +526,12 @@ lint_path_statement_drop = path statement drops value lint_path_statement_no_effect = path statement with no effect +lint_pattern_in_bodiless = patterns aren't allowed in functions without bodies + .label = pattern not allowed in function without body + +lint_pattern_in_foreign = patterns aren't allowed in foreign function declarations + .label = pattern not allowed in foreign function + lint_ptr_null_checks_fn_ptr = function pointers are not nullable, so checking them for null will always return false .help = wrap the function pointer inside an `Option` and use `Option::is_none` to check for null pointer value .label = expression has type `{$orig_ty}` diff --git a/compiler/rustc_lint/src/context.rs b/compiler/rustc_lint/src/context.rs index 62ba9ef5c11..563d96d9519 100644 --- a/compiler/rustc_lint/src/context.rs +++ b/compiler/rustc_lint/src/context.rs @@ -539,12 +539,11 @@ pub trait LintContext { &self, lint: &'static Lint, span: Option<impl Into<MultiSpan>>, - msg: impl Into<DiagMessage>, decorate: impl for<'a, 'b> FnOnce(&'b mut Diag<'a, ()>), diagnostic: BuiltinLintDiag, ) { // We first generate a blank diagnostic. - self.opt_span_lint(lint, span, msg, |db| { + self.opt_span_lint(lint, span, diagnostics::builtin_message(&diagnostic), |db| { // Now, set up surrounding context. diagnostics::builtin(self.sess(), diagnostic, db); // Rewrap `db`, and pass control to the user. diff --git a/compiler/rustc_lint/src/context/diagnostics.rs b/compiler/rustc_lint/src/context/diagnostics.rs index b8aac6c15d9..df012b2d10b 100644 --- a/compiler/rustc_lint/src/context/diagnostics.rs +++ b/compiler/rustc_lint/src/context/diagnostics.rs @@ -2,7 +2,7 @@ #![allow(rustc::untranslatable_diagnostic)] use rustc_ast::util::unicode::TEXT_FLOW_CONTROL_CHARS; -use rustc_errors::{elided_lifetime_in_path_suggestion, Diag}; +use rustc_errors::{elided_lifetime_in_path_suggestion, pluralize, Diag, DiagMessage}; use rustc_errors::{Applicability, SuggestionStyle}; use rustc_middle::middle::stability; use rustc_session::lint::BuiltinLintDiag; @@ -50,7 +50,7 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di ); } } - BuiltinLintDiag::Normal => (), + BuiltinLintDiag::Normal(_) => (), BuiltinLintDiag::AbsPathWithModule(span) => { let (sugg, app) = match sess.source_map().span_to_snippet(span) { Ok(ref s) => { @@ -64,7 +64,7 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di }; diag.span_suggestion(span, "use `crate`", sugg, app); } - BuiltinLintDiag::ProcMacroDeriveResolutionFallback(span) => { + BuiltinLintDiag::ProcMacroDeriveResolutionFallback { span, .. } => { diag.span_label( span, "names from parent modules are not accessible without an explicit import", @@ -88,16 +88,16 @@ 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::UnusedImports(message, replaces, in_test_module) => { - if !replaces.is_empty() { + BuiltinLintDiag::UnusedImports { fix_msg, fixes, test_module_span, .. } => { + if !fixes.is_empty() { diag.tool_only_multipart_suggestion( - message, - replaces, + fix_msg, + fixes, Applicability::MachineApplicable, ); } - if let Some(span) = in_test_module { + 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", @@ -114,7 +114,7 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di ); } } - BuiltinLintDiag::DeprecatedMacro(suggestion, span) => { + BuiltinLintDiag::DeprecatedMacro { suggestion, span, .. } => { stability::deprecation_suggestion(diag, "macro", suggestion, span) } BuiltinLintDiag::UnusedDocComment(span) => { @@ -122,7 +122,7 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di diag.help("to document an item produced by a macro, \ the macro must produce the documentation as part of its expansion"); } - BuiltinLintDiag::PatternsInFnsWithoutBody(span, ident) => { + BuiltinLintDiag::PatternsInFnsWithoutBody { span, ident, .. } => { diag.span_suggestion( span, "remove `mut` from the parameter", @@ -148,7 +148,7 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di Applicability::MachineApplicable, ); } - BuiltinLintDiag::ReservedPrefix(span) => { + BuiltinLintDiag::ReservedPrefix(span, _) => { diag.span_label(span, "unknown prefix"); diag.span_suggestion_verbose( span.shrink_to_hi(), @@ -206,6 +206,7 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di param_span, use_span: Some((use_span, elide)), deletion_span, + .. } => { debug!(?param_span, ?use_span, ?deletion_span); diag.span_label(param_span, "this lifetime..."); @@ -230,7 +231,9 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di diag.multipart_suggestion(msg, suggestions, Applicability::MachineApplicable); } } - BuiltinLintDiag::SingleUseLifetime { param_span: _, use_span: None, deletion_span } => { + BuiltinLintDiag::SingleUseLifetime { + param_span: _, use_span: None, deletion_span, .. + } => { debug!(?deletion_span); if let Some(deletion_span) = deletion_span { diag.span_suggestion( @@ -277,7 +280,7 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di ); } } - BuiltinLintDiag::ByteSliceInPackedStructWithDerive => { + BuiltinLintDiag::ByteSliceInPackedStructWithDerive { .. } => { diag.help("consider implementing the trait by hand, or remove the `packed` attribute"); } BuiltinLintDiag::UnusedExternCrate { removal_span } => { @@ -337,7 +340,7 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di Applicability::MachineApplicable, ); } - BuiltinLintDiag::RedundantImportVisibility { max_vis, span } => { + 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", @@ -353,3 +356,122 @@ pub(super) fn builtin(sess: &Session, diagnostic: BuiltinLintDiag, diag: &mut Di } } } + +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" + .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 { message, .. } => message.clone().into(), + 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)") + } + .into(), + BuiltinLintDiag::DeprecatedWhereclauseLocation(_) => { + crate::fluent_generated::lint_deprecated_where_clause_location + } + 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::NamedArgumentUsedPositionally { named_arg_name, .. } => { + format!("named argument `{}` is not used by name", named_arg_name).into() + } + 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(), + } +} diff --git a/compiler/rustc_lint/src/early.rs b/compiler/rustc_lint/src/early.rs index 3f627baf770..80cb70ba277 100644 --- a/compiler/rustc_lint/src/early.rs +++ b/compiler/rustc_lint/src/early.rs @@ -44,14 +44,8 @@ impl<'a, T: EarlyLintPass> EarlyContextAndPass<'a, T> { #[allow(rustc::diagnostic_outside_of_impl)] fn inlined_check_id(&mut self, id: ast::NodeId) { for early_lint in self.context.buffered.take(id) { - let BufferedEarlyLint { span, msg, node_id: _, lint_id, diagnostic } = early_lint; - self.context.span_lint_with_diagnostics( - lint_id.lint, - Some(span), - msg, - |_| {}, - diagnostic, - ); + let BufferedEarlyLint { span, node_id: _, lint_id, diagnostic } = early_lint; + self.context.span_lint_with_diagnostics(lint_id.lint, Some(span), |_| {}, diagnostic); } } diff --git a/compiler/rustc_lint_defs/src/lib.rs b/compiler/rustc_lint_defs/src/lib.rs index 7da65ba0eec..a0b24d02561 100644 --- a/compiler/rustc_lint_defs/src/lib.rs +++ b/compiler/rustc_lint_defs/src/lib.rs @@ -6,6 +6,7 @@ use rustc_data_structures::stable_hasher::{ HashStable, StableCompare, StableHasher, ToStableHashKey, }; use rustc_error_messages::{DiagMessage, MultiSpan}; +use rustc_hir::def::Namespace; use rustc_hir::HashStableContext; use rustc_hir::HirId; use rustc_macros::{Decodable, Encodable, HashStable_Generic}; @@ -569,15 +570,28 @@ pub struct AmbiguityErrorDiag { // becomes hacky (and it gets allocated). #[derive(Debug)] pub enum BuiltinLintDiag { - Normal, + Normal(DiagMessage), AbsPathWithModule(Span), - ProcMacroDeriveResolutionFallback(Span), + ProcMacroDeriveResolutionFallback { + span: Span, + ns: Namespace, + ident: Ident, + }, MacroExpandedMacroExportsAccessedByAbsolutePaths(Span), ElidedLifetimesInPaths(usize, Span, bool, Span), UnknownCrateTypes(Span, String, String), - UnusedImports(String, Vec<(Span, String)>, Option<Span>), + UnusedImports { + fix_msg: String, + fixes: Vec<(Span, String)>, + test_module_span: Option<Span>, + span_snippets: Vec<String>, + }, RedundantImport(Vec<(Span, bool)>, Ident), - DeprecatedMacro(Option<Symbol>, Span), + DeprecatedMacro { + suggestion: Option<Symbol>, + span: Span, + message: String, + }, MissingAbi(Span, Abi), UnusedDocComment(Span), UnusedBuiltinAttribute { @@ -585,11 +599,15 @@ pub enum BuiltinLintDiag { macro_name: String, invoc_span: Span, }, - PatternsInFnsWithoutBody(Span, Ident), + PatternsInFnsWithoutBody { + span: Span, + ident: Ident, + is_foreign: bool, + }, LegacyDeriveHelpers(Span), ProcMacroBackCompat(String), OrPatternsBackCompat(Span, String), - ReservedPrefix(Span), + ReservedPrefix(Span, String), TrailingMacro(bool, Ident), BreakWithLabelAndLoop(Span), UnicodeTextFlow(Span, String), @@ -605,6 +623,7 @@ pub enum BuiltinLintDiag { /// Span of the single use, or None if the lifetime is never used. /// If true, the lifetime will be fully elided. use_span: Option<(Span, bool)>, + ident: Ident, }, NamedArgumentUsedPositionally { /// Span where the named argument is used by position and will be replaced with the named @@ -619,7 +638,10 @@ pub enum BuiltinLintDiag { /// Indicates if the named argument is used as a width/precision for formatting is_formatting_arg: bool, }, - ByteSliceInPackedStructWithDerive, + ByteSliceInPackedStructWithDerive { + // FIXME: enum of byte/string + ty: String, + }, UnusedExternCrate { removal_span: Span, }, @@ -661,6 +683,7 @@ pub enum BuiltinLintDiag { RedundantImportVisibility { span: Span, max_vis: String, + import_vis: String, }, MaybeTypo { span: Span, @@ -675,9 +698,6 @@ pub struct BufferedEarlyLint { /// The span of code that we are linting on. pub span: MultiSpan, - /// The lint message. - pub msg: DiagMessage, - /// The `NodeId` of the AST node that generated the lint. pub node_id: NodeId, @@ -705,12 +725,10 @@ impl LintBuffer { lint: &'static Lint, node_id: NodeId, span: MultiSpan, - msg: impl Into<DiagMessage>, diagnostic: BuiltinLintDiag, ) { let lint_id = LintId::of(lint); - let msg = msg.into(); - self.add_early_lint(BufferedEarlyLint { lint_id, node_id, span, msg, diagnostic }); + self.add_early_lint(BufferedEarlyLint { lint_id, node_id, span, diagnostic }); } pub fn take(&mut self, id: NodeId) -> Vec<BufferedEarlyLint> { @@ -725,7 +743,7 @@ impl LintBuffer { sp: impl Into<MultiSpan>, msg: impl Into<DiagMessage>, ) { - self.add_lint(lint, id, sp.into(), msg, BuiltinLintDiag::Normal) + self.add_lint(lint, id, sp.into(), BuiltinLintDiag::Normal(msg.into())) } pub fn buffer_lint_with_diagnostic( @@ -733,10 +751,9 @@ impl LintBuffer { lint: &'static Lint, id: NodeId, sp: impl Into<MultiSpan>, - msg: impl Into<DiagMessage>, diagnostic: BuiltinLintDiag, ) { - self.add_lint(lint, id, sp.into(), msg, diagnostic) + self.add_lint(lint, id, sp.into(), diagnostic) } } diff --git a/compiler/rustc_middle/src/middle/stability.rs b/compiler/rustc_middle/src/middle/stability.rs index 67bd53f53da..75ed408e644 100644 --- a/compiler/rustc_middle/src/middle/stability.rs +++ b/compiler/rustc_middle/src/middle/stability.rs @@ -200,8 +200,8 @@ pub fn early_report_deprecation( return; } - let diag = BuiltinLintDiag::DeprecatedMacro(suggestion, span); - lint_buffer.buffer_lint_with_diagnostic(lint, node_id, span, message, diag); + let diag = BuiltinLintDiag::DeprecatedMacro { suggestion, span, message }; + lint_buffer.buffer_lint_with_diagnostic(lint, node_id, span, diag); } fn late_report_deprecation( diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index d2d200a91af..cdb1cf62cf7 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -374,7 +374,6 @@ impl<'psess, 'src> StringReader<'psess, 'src> { TEXT_DIRECTION_CODEPOINT_IN_COMMENT, span, ast::CRATE_NODE_ID, - "unicode codepoint changing visible direction of text present in comment", BuiltinLintDiag::UnicodeTextFlow(span, content.to_string()), ); } @@ -727,8 +726,7 @@ impl<'psess, 'src> StringReader<'psess, 'src> { RUST_2021_PREFIXES_INCOMPATIBLE_SYNTAX, prefix_span, ast::CRATE_NODE_ID, - format!("prefix `{prefix}` is unknown"), - BuiltinLintDiag::ReservedPrefix(prefix_span), + BuiltinLintDiag::ReservedPrefix(prefix_span, prefix.to_string()), ); } } diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index d2d21624150..be4a52a9bc4 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -1917,7 +1917,6 @@ impl<'a> Parser<'a> { BREAK_WITH_LABEL_AND_LOOP, lo.to(expr.span), ast::CRATE_NODE_ID, - "this labeled break expression is easy to confuse with an unlabeled break with a labeled value expression", BuiltinLintDiag::BreakWithLabelAndLoop(expr.span), ); } diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index 180e7f6def3..2a8eb940ccf 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -32,7 +32,7 @@ use rustc_ast as ast; use rustc_ast::visit::{self, Visitor}; use rustc_data_structures::fx::{FxHashMap, FxIndexMap, FxIndexSet}; use rustc_data_structures::unord::UnordSet; -use rustc_errors::{pluralize, MultiSpan}; +use rustc_errors::MultiSpan; use rustc_hir::def::{DefKind, Res}; use rustc_session::lint::builtin::{MACRO_USE_EXTERN_CRATE, UNUSED_EXTERN_CRATES}; use rustc_session::lint::builtin::{UNUSED_IMPORTS, UNUSED_QUALIFICATIONS}; @@ -155,7 +155,6 @@ impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> { UNUSED_EXTERN_CRATES, extern_crate.id, span, - "unused extern crate", BuiltinLintDiag::UnusedExternCrate { removal_span: extern_crate.span_with_attributes, }, @@ -208,7 +207,6 @@ impl<'a, 'b, 'tcx> UnusedImportCheckVisitor<'a, 'b, 'tcx> { UNUSED_EXTERN_CRATES, extern_crate.id, extern_crate.span, - "`extern crate` is not idiomatic in the new edition", BuiltinLintDiag::ExternCrateNotIdiomatic { vis_span, ident_span }, ); } @@ -459,16 +457,6 @@ impl Resolver<'_, '_> { .collect::<Vec<String>>(); span_snippets.sort(); - let msg = format!( - "unused import{}{}", - pluralize!(ms.primary_spans().len()), - if !span_snippets.is_empty() { - format!(": {}", span_snippets.join(", ")) - } else { - String::new() - } - ); - let fix_msg = if fixes.len() == 1 && fixes[0].0 == unused.item_span { "remove the whole `use` item" } else if ms.primary_spans().len() > 1 { @@ -505,8 +493,12 @@ impl Resolver<'_, '_> { UNUSED_IMPORTS, unused.use_tree_id, ms, - msg, - BuiltinLintDiag::UnusedImports(fix_msg.into(), fixes, test_module_span), + BuiltinLintDiag::UnusedImports { + fix_msg: fix_msg.into(), + fixes, + test_module_span, + span_snippets, + }, ); } @@ -556,7 +548,6 @@ impl Resolver<'_, '_> { UNUSED_QUALIFICATIONS, unn_qua.node_id, unn_qua.path_span, - "unnecessary qualification", BuiltinLintDiag::UnusedQualifications { removal_span: unn_qua.removal_span }, ); } diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index b28312fa473..791d777b3d4 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -128,13 +128,10 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { self.report_with_use_injections(krate); for &(span_use, span_def) in &self.macro_expanded_macro_export_errors { - let msg = "macro-expanded `macro_export` macros from the current crate \ - cannot be referred to by absolute paths"; self.lint_buffer.buffer_lint_with_diagnostic( MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS, CRATE_NODE_ID, span_use, - msg, BuiltinLintDiag::MacroExpandedMacroExportsAccessedByAbsolutePaths(span_def), ); } @@ -149,7 +146,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { AMBIGUOUS_GLOB_IMPORTS, import.root_id, ambiguity_error.ident.span, - diag.msg.to_string(), BuiltinLintDiag::AmbiguousGlobImports { diag }, ); } else { @@ -530,8 +526,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, node_id, root_span, - "absolute paths must start with `self`, `super`, \ - `crate`, or an external crate name in the 2018 edition", diag, ); } diff --git a/compiler/rustc_resolve/src/ident.rs b/compiler/rustc_resolve/src/ident.rs index f88725830f1..d1fd19e9953 100644 --- a/compiler/rustc_resolve/src/ident.rs +++ b/compiler/rustc_resolve/src/ident.rs @@ -528,14 +528,11 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { PROC_MACRO_DERIVE_RESOLUTION_FALLBACK, lint_id, orig_ident.span, - format!( - "cannot find {} `{}` in this scope", - ns.descr(), - ident - ), - BuiltinLintDiag::ProcMacroDeriveResolutionFallback( - orig_ident.span, - ), + BuiltinLintDiag::ProcMacroDeriveResolutionFallback { + span: orig_ident.span, + ns, + ident, + }, ); } let misc_flags = if module == this.graph_root { diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index f53bcb0e9d0..55a0382a8e8 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -623,7 +623,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { AMBIGUOUS_GLOB_REEXPORTS, import.root_id, import.root_span, - "ambiguous glob re-exports", BuiltinLintDiag::AmbiguousGlobReexports { name: key.ident.to_string(), namespace: key.ns.descr().to_string(), @@ -659,7 +658,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { HIDDEN_GLOB_REEXPORTS, binding_id, binding.span, - "private item shadows public glob re-export", BuiltinLintDiag::HiddenGlobReexports { name: key.ident.name.to_string(), namespace: key.ns.descr().to_owned(), @@ -1015,17 +1013,13 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { && !max_vis.is_at_least(import_vis, self.tcx) { let def_id = self.local_def_id(id); - let msg = format!( - "glob import doesn't reexport anything with visibility `{}` because no imported item is public enough", - import_vis.to_string(def_id, self.tcx) - ); self.lint_buffer.buffer_lint_with_diagnostic( UNUSED_IMPORTS, id, import.span, - msg, BuiltinLintDiag::RedundantImportVisibility { max_vis: max_vis.to_string(def_id, self.tcx), + import_vis: import_vis.to_string(def_id, self.tcx), span: import.span, }, ); @@ -1397,7 +1391,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { UNUSED_IMPORTS, id, import.span, - format!("the item `{source}` is imported redundantly"), BuiltinLintDiag::RedundantImport(redundant_spans, source), ); */ diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 0f585aafdd5..9442741b6cc 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1675,16 +1675,10 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { return; } LifetimeRibKind::AnonymousWarn(node_id) => { - let msg = if elided { - "`&` without an explicit lifetime name cannot be used here" - } else { - "`'_` cannot be used here" - }; self.r.lint_buffer.buffer_lint_with_diagnostic( lint::builtin::ELIDED_LIFETIMES_IN_ASSOCIATED_CONSTANT, node_id, lifetime.ident.span, - msg, lint::BuiltinLintDiag::AssociatedConstElidedLifetime { elided, span: lifetime.ident.span, @@ -1970,7 +1964,6 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { lint::builtin::ELIDED_LIFETIMES_IN_PATHS, segment_id, elided_lifetime_span, - "hidden lifetime parameters in types are deprecated", lint::BuiltinLintDiag::ElidedLifetimesInPaths( expected_lifetimes, path_span, diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 1958fdf1cbc..ce14c98b0d6 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -2655,11 +2655,11 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { lint::builtin::SINGLE_USE_LIFETIMES, param.id, param.ident.span, - format!("lifetime parameter `{}` only used once", param.ident), lint::BuiltinLintDiag::SingleUseLifetime { param_span: param.ident.span, use_span: Some((use_span, elidable)), deletion_span, + ident: param.ident, }, ); } @@ -2673,11 +2673,11 @@ impl<'a: 'ast, 'ast, 'tcx> LateResolutionVisitor<'a, '_, 'ast, 'tcx> { lint::builtin::UNUSED_LIFETIMES, param.id, param.ident.span, - format!("lifetime parameter `{}` never used", param.ident), lint::BuiltinLintDiag::SingleUseLifetime { param_span: param.ident.span, use_span: None, deletion_span, + ident: param.ident, }, ); } diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index f8d245f94e5..0e0e6ffc136 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -786,7 +786,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> { LEGACY_DERIVE_HELPERS, node_id, ident.span, - "derive helper attribute is used before it is introduced", BuiltinLintDiag::LegacyDeriveHelpers(binding.span), ); } diff --git a/compiler/rustc_session/src/parse.rs b/compiler/rustc_session/src/parse.rs index f6053f43fbd..59281f96126 100644 --- a/compiler/rustc_session/src/parse.rs +++ b/compiler/rustc_session/src/parse.rs @@ -311,9 +311,8 @@ impl ParseSess { buffered_lints.push(BufferedEarlyLint { span: span.into(), node_id, - msg: msg.into(), lint_id: LintId::of(lint), - diagnostic: BuiltinLintDiag::Normal, + diagnostic: BuiltinLintDiag::Normal(msg.into()), }); }); } @@ -323,14 +322,12 @@ impl ParseSess { lint: &'static Lint, span: impl Into<MultiSpan>, node_id: NodeId, - msg: impl Into<DiagMessage>, diagnostic: BuiltinLintDiag, ) { self.buffered_lints.with_lock(|buffered_lints| { buffered_lints.push(BufferedEarlyLint { span: span.into(), node_id, - msg: msg.into(), lint_id: LintId::of(lint), diagnostic, }); |
