Auto merge of #147634 - fmease:mv-var-to-dyn-buf-lints-next, r=jdonszelmann

Move even more early buffered lints to dyn lint diagnostics

Follow-up to https://github.com/rust-lang/rust/pull/145881 and https://github.com/rust-lang/rust/pull/145747.

I originally wanted to migrate most if not the entire rest of the early buffered lints. However, when trying to migrate the buffered lints used by check-cfg I encountered a roadblock. Namely, it depends on `TyCtxt` (well, `Option<TyCtxt>`) which makes it quite hard to migrate (see also https://github.com/rust-lang/rust/pull/147634#issuecomment-3398174584, https://github.com/rust-lang/rust/pull/147634#issuecomment-3398207128 & rust-lang/rust#149215).

So for now, I won't migrate it (maybe rust-lang/rust#149215 will find a solution), nor will I migrate the rest since it's quite tedious to migrate these. I'll leave them for future me.
This commit is contained in:
bors 2025-12-02 07:33:36 +00:00
commit 47cd7120d9
12 changed files with 199 additions and 274 deletions

View file

@ -2049,22 +2049,6 @@ pub fn elided_lifetime_in_path_suggestion(
ElidedLifetimeInPathSubdiag { expected, indicate }
}
pub fn report_ambiguity_error<'a, G: EmissionGuarantee>(
diag: &mut Diag<'a, G>,
ambiguity: rustc_lint_defs::AmbiguityErrorDiag,
) {
diag.span_label(ambiguity.label_span, ambiguity.label_msg);
diag.note(ambiguity.note_msg);
diag.span_note(ambiguity.b1_span, ambiguity.b1_note_msg);
for help_msg in ambiguity.b1_help_msgs {
diag.help(help_msg);
}
diag.span_note(ambiguity.b2_span, ambiguity.b2_note_msg);
for help_msg in ambiguity.b2_help_msgs {
diag.help(help_msg);
}
}
/// Grammatical tool for displaying messages to end users in a nice form.
///
/// Returns "an" if the given string starts with a vowel, and "a" otherwise.

View file

@ -257,9 +257,6 @@ 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_crate_not_idiomatic = `extern crate` is not idiomatic in the new edition
.suggestion = convert it to a `use`
lint_for_loops_over_fallibles =
for loop over {$article} `{$ref_prefix}{$ty}`. This is more readably written as an `if let` statement
.suggestion = consider using `if let` to clear intent
@ -467,9 +464,6 @@ lint_lintpass_by_hand = implementing `LintPass` by hand
lint_macro_expr_fragment_specifier_2024_migration =
the `expr` fragment specifier will accept more expressions in the 2024 edition
.suggestion = to keep the existing behavior, use the `expr_2021` fragment specifier
lint_macro_is_private = macro `{$ident}` is private
lint_macro_rule_never_used = rule #{$n} of macro `{$name}` is never used
lint_malformed_attribute = malformed lint attribute input
@ -648,10 +642,6 @@ lint_opaque_hidden_inferred_bound = opaque type `{$ty}` does not satisfy its ass
lint_opaque_hidden_inferred_bound_sugg = add this bound
lint_out_of_scope_macro_calls = cannot find macro `{$path}` in the current scope when looking from {$location}
.label = not found from {$location}
.help = import `macro_rules` with `use` to make it callable above its definition
lint_overflowing_bin_hex = literal out of range for `{$ty}`
.negative_note = the literal `{$lit}` (decimal `{$dec}`) does not fit into the type `{$ty}`
.negative_becomes_note = and the value `-{$lit}` will become `{$actually}{$ty}`
@ -687,9 +677,6 @@ lint_pattern_in_bodiless = patterns aren't allowed in functions without bodies
lint_pattern_in_foreign = patterns aren't allowed in foreign function declarations
.label = pattern not allowed in foreign function
lint_private_extern_crate_reexport = extern crate `{$ident}` is private and cannot be re-exported
.suggestion = consider making the `extern crate` item publicly accessible
lint_query_instability = using `{$query}` can result in unstable query results
.note = if you believe this case to be fine, allow this lint and add a comment explaining your rationale
@ -715,10 +702,6 @@ lint_redundant_import = the item `{$ident}` is imported redundantly
.label_imported_prelude = the item `{$ident}` is already imported by the extern prelude
.label_defined_prelude = the item `{$ident}` is already defined by the extern prelude
lint_redundant_import_visibility = glob import doesn't reexport anything with visibility `{$import_vis}` because no imported item is public enough
.note = the most public imported item is `{$max_vis}`
.help = reduce the glob import's visibility or increase visibility of imported items
lint_redundant_semicolons =
unnecessary trailing {$multiple ->
[true] semicolons
@ -878,9 +861,6 @@ lint_unicode_text_flow = unicode codepoint changing visible direction of text pr
lint_unit_bindings = binding has unit type `()`
.label = this pattern is inferred to be the unit type `()`
lint_unknown_diagnostic_attribute = unknown diagnostic attribute
lint_unknown_diagnostic_attribute_typo_sugg = an attribute with a similar name exists
lint_unknown_gated_lint =
unknown lint: `{$name}`
.note = the `{$name}` lint is unstable
@ -962,8 +942,6 @@ lint_unused_imports = {$num_snippets ->
lint_unused_lifetime = lifetime parameter `{$ident}` never used
.suggestion = elide the unused lifetime
lint_unused_macro_definition = unused macro definition: `{$name}`
lint_unused_op = unused {$op} that must be used
.label = the {$op} produces a value
.suggestion = use `let _ = ...` to ignore the resulting value

View file

@ -251,15 +251,6 @@ pub fn decorate_builtin_lint(
}
.decorate_lint(diag);
}
BuiltinLintDiag::ExternCrateNotIdiomatic { vis_span, ident_span } => {
let suggestion_span = vis_span.between(ident_span);
let code = if vis_span.is_empty() { "use " } else { " use " };
lints::ExternCrateNotIdiomatic { span: suggestion_span, code }.decorate_lint(diag);
}
BuiltinLintDiag::AmbiguousGlobImports { diag: ambiguity } => {
lints::AmbiguousGlobImports { ambiguity }.decorate_lint(diag);
}
BuiltinLintDiag::AmbiguousGlobReexports {
name,
namespace,
@ -317,33 +308,6 @@ pub fn decorate_builtin_lint(
}
.decorate_lint(diag);
}
BuiltinLintDiag::RedundantImportVisibility { max_vis, span: vis_span, import_vis } => {
lints::RedundantImportVisibility { span: vis_span, help: (), max_vis, import_vis }
.decorate_lint(diag);
}
BuiltinLintDiag::UnknownDiagnosticAttribute { span: typo_span, typo_name } => {
let typo = typo_name.map(|typo_name| lints::UnknownDiagnosticAttributeTypoSugg {
span: typo_span,
typo_name,
});
lints::UnknownDiagnosticAttribute { typo }.decorate_lint(diag);
}
BuiltinLintDiag::PrivateExternCrateReexport { source: ident, extern_crate_span } => {
lints::PrivateExternCrateReexport { ident, sugg: extern_crate_span.shrink_to_lo() }
.decorate_lint(diag);
}
BuiltinLintDiag::MacroIsPrivate(ident) => {
lints::MacroIsPrivate { ident }.decorate_lint(diag);
}
BuiltinLintDiag::UnusedMacroDefinition(name) => {
lints::UnusedMacroDefinition { name }.decorate_lint(diag);
}
BuiltinLintDiag::MacroRuleNeverUsed(n, name) => {
lints::MacroRuleNeverUsed { n: n + 1, name }.decorate_lint(diag);
}
BuiltinLintDiag::UnstableFeature(msg) => {
lints::UnstableFeature { msg }.decorate_lint(diag);
}
BuiltinLintDiag::UnusedCrateDependency { extern_crate, local_crate } => {
lints::UnusedCrateDependency { extern_crate, local_crate }.decorate_lint(diag)
}
@ -358,8 +322,5 @@ pub fn decorate_builtin_lint(
}
.decorate_lint(diag)
}
BuiltinLintDiag::OutOfScopeMacroCalls { span, path, location } => {
lints::OutOfScopeMacroCalls { span, path, location }.decorate_lint(diag)
}
}
}

View file

@ -15,7 +15,6 @@ use rustc_macros::{LintDiagnostic, Subdiagnostic};
use rustc_middle::ty::inhabitedness::InhabitedPredicate;
use rustc_middle::ty::{Clause, PolyExistentialTraitRef, Ty, TyCtxt};
use rustc_session::Session;
use rustc_session::lint::AmbiguityErrorDiag;
use rustc_span::edition::Edition;
use rustc_span::{Ident, Span, Symbol, sym};
@ -2575,43 +2574,6 @@ pub(crate) mod unexpected_cfg_value {
}
}
#[derive(LintDiagnostic)]
#[diag(lint_private_extern_crate_reexport, code = E0365)]
pub(crate) struct PrivateExternCrateReexport {
pub ident: Ident,
#[suggestion(code = "pub ", style = "verbose", applicability = "maybe-incorrect")]
pub sugg: Span,
}
#[derive(LintDiagnostic)]
#[diag(lint_macro_is_private)]
pub(crate) struct MacroIsPrivate {
pub ident: Ident,
}
#[derive(LintDiagnostic)]
#[diag(lint_unused_macro_definition)]
pub(crate) struct UnusedMacroDefinition {
pub name: Symbol,
}
#[derive(LintDiagnostic)]
#[diag(lint_macro_rule_never_used)]
pub(crate) struct MacroRuleNeverUsed {
pub n: usize,
pub name: Symbol,
}
pub(crate) struct UnstableFeature {
pub msg: DiagMessage,
}
impl<'a> LintDiagnostic<'a, ()> for UnstableFeature {
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
diag.primary_message(self.msg);
}
}
#[derive(LintDiagnostic)]
#[diag(lint_unused_crate_dependency)]
#[help]
@ -2631,26 +2593,6 @@ pub(crate) struct IllFormedAttributeInput {
pub docs: &'static str,
}
#[derive(LintDiagnostic)]
#[diag(lint_unknown_diagnostic_attribute)]
pub(crate) struct UnknownDiagnosticAttribute {
#[subdiagnostic]
pub typo: Option<UnknownDiagnosticAttributeTypoSugg>,
}
#[derive(Subdiagnostic)]
#[suggestion(
lint_unknown_diagnostic_attribute_typo_sugg,
style = "verbose",
code = "{typo_name}",
applicability = "machine-applicable"
)]
pub(crate) struct UnknownDiagnosticAttributeTypoSugg {
#[primary_span]
pub span: Span,
pub typo_name: Symbol,
}
#[derive(LintDiagnostic)]
#[diag(lint_unicode_text_flow)]
#[note]
@ -2893,27 +2835,6 @@ pub(crate) struct NamedArgumentUsedPositionally {
pub named_arg_name: String,
}
#[derive(LintDiagnostic)]
#[diag(lint_extern_crate_not_idiomatic)]
pub(crate) struct ExternCrateNotIdiomatic {
#[suggestion(style = "verbose", code = "{code}", applicability = "machine-applicable")]
pub span: Span,
pub code: &'static str,
}
// FIXME: make this translatable
pub(crate) struct AmbiguousGlobImports {
pub ambiguity: AmbiguityErrorDiag,
}
impl<'a, G: EmissionGuarantee> LintDiagnostic<'a, G> for AmbiguousGlobImports {
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, G>) {
diag.primary_message(self.ambiguity.msg.clone());
rustc_errors::report_ambiguity_error(diag, self.ambiguity);
}
}
#[derive(LintDiagnostic)]
#[diag(lint_ambiguous_glob_reexport)]
pub(crate) struct AmbiguousGlobReexports {
@ -2959,18 +2880,6 @@ pub(crate) struct AssociatedConstElidedLifetime {
pub lifetimes_in_scope: MultiSpan,
}
#[derive(LintDiagnostic)]
#[diag(lint_redundant_import_visibility)]
pub(crate) struct RedundantImportVisibility {
#[note]
pub span: Span,
#[help]
pub help: (),
pub import_vis: String,
pub max_vis: String,
}
#[derive(LintDiagnostic)]
#[diag(lint_unsafe_attr_outside_unsafe)]
pub(crate) struct UnsafeAttrOutsideUnsafe {
@ -2992,16 +2901,6 @@ pub(crate) struct UnsafeAttrOutsideUnsafeSuggestion {
pub right: Span,
}
#[derive(LintDiagnostic)]
#[diag(lint_out_of_scope_macro_calls)]
#[help]
pub(crate) struct OutOfScopeMacroCalls {
#[label]
pub span: Span,
pub path: String,
pub location: String,
}
#[derive(LintDiagnostic)]
#[diag(lint_static_mut_refs_lint)]
pub(crate) struct RefOfMutStatic<'a> {

View file

@ -6,7 +6,7 @@ use rustc_data_structures::fx::FxIndexSet;
use rustc_data_structures::stable_hasher::{
HashStable, StableCompare, StableHasher, ToStableHashKey,
};
use rustc_error_messages::{DiagArgValue, DiagMessage, IntoDiagArg, MultiSpan};
use rustc_error_messages::{DiagArgValue, IntoDiagArg, MultiSpan};
use rustc_hir_id::{HashStableContext, HirId, ItemLocalId};
use rustc_macros::{Decodable, Encodable, HashStable_Generic};
use rustc_span::def_id::DefPathHash;
@ -593,21 +593,6 @@ impl StableCompare for LintId {
}
}
#[derive(Debug)]
pub struct AmbiguityErrorDiag {
pub msg: String,
pub span: Span,
pub label_span: Span,
pub label_msg: String,
pub note_msg: String,
pub b1_span: Span,
pub b1_note_msg: String,
pub b1_help_msgs: Vec<String>,
pub b2_span: Span,
pub b2_note_msg: String,
pub b2_help_msgs: Vec<String>,
}
#[derive(Debug, Clone)]
pub enum DeprecatedSinceKind {
InEffect,
@ -678,13 +663,6 @@ pub enum BuiltinLintDiag {
/// Indicates if the named argument is used as a width/precision for formatting
is_formatting_arg: bool,
},
ExternCrateNotIdiomatic {
vis_span: Span,
ident_span: Span,
},
AmbiguousGlobImports {
diag: AmbiguityErrorDiag,
},
AmbiguousGlobReexports {
/// The name for which collision(s) have occurred.
name: String,
@ -718,23 +696,6 @@ pub enum BuiltinLintDiag {
span: Span,
lifetimes_in_scope: MultiSpan,
},
RedundantImportVisibility {
span: Span,
max_vis: String,
import_vis: String,
},
UnknownDiagnosticAttribute {
span: Span,
typo_name: Option<Symbol>,
},
PrivateExternCrateReexport {
source: Ident,
extern_crate_span: Span,
},
MacroIsPrivate(Ident),
UnusedMacroDefinition(Symbol),
MacroRuleNeverUsed(usize, Symbol),
UnstableFeature(DiagMessage),
UnusedCrateDependency {
extern_crate: Symbol,
local_crate: Symbol,
@ -743,11 +704,6 @@ pub enum BuiltinLintDiag {
suggestions: Vec<String>,
docs: Option<&'static str>,
},
OutOfScopeMacroCalls {
span: Span,
path: String,
location: String,
},
}
pub type RegisteredTools = FxIndexSet<Ident>;

View file

@ -146,6 +146,9 @@ resolve_explicit_unsafe_traits =
resolve_extern_crate_loading_macro_not_at_crate_root =
an `extern crate` loading macros must be at the crate root
resolve_extern_crate_not_idiomatic = `extern crate` is not idiomatic in the new edition
.suggestion = convert it to a `use`
resolve_extern_crate_self_requires_renaming =
`extern crate self;` requires renaming
.suggestion = rename the `self` crate to be able to import it
@ -280,6 +283,10 @@ resolve_macro_extern_deprecated =
`#[macro_escape]` is a deprecated synonym for `#[macro_use]`
.help = try an outer attribute: `#[macro_use]`
resolve_macro_is_private = macro `{$ident}` is private
resolve_macro_rule_never_used = rule #{$n} of macro `{$name}` is never used
resolve_macro_use_deprecated =
applying the `#[macro_use]` attribute to an `extern crate` item is deprecated
.help = remove it and import macros at use sites with a `use` item instead
@ -335,6 +342,10 @@ resolve_note_and_refers_to_the_item_defined_here =
}
}
resolve_out_of_scope_macro_calls = cannot find macro `{$path}` in the current scope when looking from {$location}
.label = not found from {$location}
.help = import `macro_rules` with `use` to make it callable above its definition
resolve_outer_ident_is_not_publicly_reexported =
{$outer_ident_descr} `{$outer_ident}` is not publicly re-exported
@ -355,12 +366,19 @@ resolve_param_in_ty_of_const_param =
resolve_pattern_doesnt_bind_name = pattern doesn't bind `{$name}`
resolve_private_extern_crate_reexport = extern crate `{$ident}` is private and cannot be re-exported
.suggestion = consider making the `extern crate` item publicly accessible
resolve_proc_macro_derive_resolution_fallback = cannot find {$ns_descr} `{$ident}` in this scope
.label = names from parent modules are not accessible without an explicit import
resolve_proc_macro_same_crate = can't use a procedural macro from the same crate that defines it
.help = you can define integration tests in a directory named `tests`
resolve_redundant_import_visibility = glob import doesn't reexport anything with visibility `{$import_vis}` because no imported item is public enough
.note = the most public imported item is `{$max_vis}`
.help = reduce the glob import's visibility or increase visibility of imported items
resolve_reexport_of_crate_public =
re-export of crate public `{$ident}`
@ -466,6 +484,9 @@ resolve_unexpected_res_change_ty_to_const_param_sugg =
resolve_unexpected_res_use_at_op_in_slice_pat_with_range_sugg =
if you meant to collect the rest of the slice in `{$ident}`, use the at operator
resolve_unknown_diagnostic_attribute = unknown diagnostic attribute
resolve_unknown_diagnostic_attribute_typo_sugg = an attribute with a similar name exists
resolve_unnamed_crate_root_import =
crate root imports need to be explicitly named: `use crate as name;`
@ -493,6 +514,8 @@ resolve_unused_extern_crate = unused extern crate
resolve_unused_label = unused label
resolve_unused_macro_definition = unused macro definition: `{$name}`
resolve_unused_macro_use = unused `#[macro_use]` import
resolve_variable_bound_with_different_mode =

View file

@ -228,11 +228,15 @@ impl<'a, 'ra, 'tcx> UnusedImportCheckVisitor<'a, 'ra, 'tcx> {
.span
.find_ancestor_inside(extern_crate.span)
.unwrap_or(extern_crate.ident.span);
self.r.lint_buffer.buffer_lint(
UNUSED_EXTERN_CRATES,
extern_crate.id,
extern_crate.span,
BuiltinLintDiag::ExternCrateNotIdiomatic { vis_span, ident_span },
crate::errors::ExternCrateNotIdiomatic {
span: vis_span.between(ident_span),
code: if vis_span.is_empty() { "use " } else { " use " },
},
);
}
}

View file

@ -11,7 +11,7 @@ use rustc_data_structures::unord::{UnordMap, UnordSet};
use rustc_errors::codes::*;
use rustc_errors::{
Applicability, Diag, DiagCtxtHandle, ErrorGuaranteed, MultiSpan, SuggestionStyle,
report_ambiguity_error, struct_span_code_err,
struct_span_code_err,
};
use rustc_feature::BUILTIN_ATTRIBUTES;
use rustc_hir::attrs::{AttributeKind, CfgEntry, StrippedCfgItem};
@ -22,16 +22,16 @@ use rustc_hir::{PrimTy, Stability, StabilityLevel, find_attr};
use rustc_middle::bug;
use rustc_middle::ty::TyCtxt;
use rustc_session::Session;
use rustc_session::lint::BuiltinLintDiag;
use rustc_session::lint::builtin::{
ABSOLUTE_PATHS_NOT_STARTING_WITH_CRATE, AMBIGUOUS_GLOB_IMPORTS,
MACRO_EXPANDED_MACRO_EXPORTS_ACCESSED_BY_ABSOLUTE_PATHS,
};
use rustc_session::lint::{AmbiguityErrorDiag, BuiltinLintDiag};
use rustc_session::utils::was_invoked_from_cargo;
use rustc_span::edit_distance::find_best_match_for_name;
use rustc_span::edition::Edition;
use rustc_span::hygiene::MacroKind;
use rustc_span::source_map::SourceMap;
use rustc_span::source_map::{SourceMap, Spanned};
use rustc_span::{BytePos, Ident, Macros20NormalizedIdent, Span, Symbol, SyntaxContext, kw, sym};
use thin_vec::{ThinVec, thin_vec};
use tracing::{debug, instrument};
@ -145,7 +145,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
}
for ambiguity_error in &self.ambiguity_errors {
let diag = self.ambiguity_diagnostics(ambiguity_error);
let diag = self.ambiguity_diagnostic(ambiguity_error);
if ambiguity_error.warning {
let NameBindingKind::Import { import, .. } = ambiguity_error.b1.0.kind else {
unreachable!()
@ -153,13 +154,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
self.lint_buffer.buffer_lint(
AMBIGUOUS_GLOB_IMPORTS,
import.root_id,
ambiguity_error.ident.span,
BuiltinLintDiag::AmbiguousGlobImports { diag },
diag.ident.span,
diag,
);
} else {
let mut err = struct_span_code_err!(self.dcx(), diag.span, E0659, "{}", diag.msg);
report_ambiguity_error(&mut err, diag);
err.emit();
self.dcx().emit_err(diag);
}
}
@ -1995,7 +1994,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
}
}
fn ambiguity_diagnostics(&self, ambiguity_error: &AmbiguityError<'ra>) -> AmbiguityErrorDiag {
fn ambiguity_diagnostic(&self, ambiguity_error: &AmbiguityError<'ra>) -> errors::Ambiguity {
let AmbiguityError { kind, ident, b1, b2, misc1, misc2, .. } = *ambiguity_error;
let extern_prelude_ambiguity = || {
self.extern_prelude.get(&Macros20NormalizedIdent::new(ident)).is_some_and(|entry| {
@ -2038,8 +2037,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
}
(
b.span,
note_msg,
Spanned { node: note_msg, span: b.span },
help_msgs
.iter()
.enumerate()
@ -2050,20 +2048,15 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
.collect::<Vec<_>>(),
)
};
let (b1_span, b1_note_msg, b1_help_msgs) = could_refer_to(b1, misc1, "");
let (b2_span, b2_note_msg, b2_help_msgs) = could_refer_to(b2, misc2, " also");
let (b1_note, b1_help_msgs) = could_refer_to(b1, misc1, "");
let (b2_note, b2_help_msgs) = could_refer_to(b2, misc2, " also");
AmbiguityErrorDiag {
msg: format!("`{ident}` is ambiguous"),
span: ident.span,
label_span: ident.span,
label_msg: "ambiguous name".to_string(),
note_msg: format!("ambiguous because of {}", kind.descr()),
b1_span,
b1_note_msg,
errors::Ambiguity {
ident,
kind: kind.descr(),
b1_note,
b1_help_msgs,
b2_span,
b2_note_msg,
b2_note,
b2_help_msgs,
}
}

View file

@ -1,9 +1,10 @@
use rustc_errors::codes::*;
use rustc_errors::{
Applicability, Diag, ElidedLifetimeInPathSubdiag, EmissionGuarantee, IntoDiagArg, MultiSpan,
Subdiagnostic,
Applicability, Diag, DiagCtxtHandle, DiagMessage, Diagnostic, ElidedLifetimeInPathSubdiag,
EmissionGuarantee, IntoDiagArg, Level, LintDiagnostic, MultiSpan, Subdiagnostic,
};
use rustc_macros::{Diagnostic, LintDiagnostic, Subdiagnostic};
use rustc_span::source_map::Spanned;
use rustc_span::{Ident, Span, Symbol};
use crate::late::PatternSource;
@ -812,6 +813,14 @@ pub(crate) struct CannotBeReexportedCratePublicNS {
pub(crate) ident: Ident,
}
#[derive(LintDiagnostic)]
#[diag(resolve_private_extern_crate_reexport, code = E0365)]
pub(crate) struct PrivateExternCrateReexport {
pub ident: Ident,
#[suggestion(code = "pub ", style = "verbose", applicability = "maybe-incorrect")]
pub sugg: Span,
}
#[derive(Subdiagnostic)]
#[help(resolve_consider_adding_macro_export)]
pub(crate) struct ConsiderAddingMacroExport {
@ -1359,3 +1368,121 @@ pub(crate) struct UnusedMacroUse;
#[diag(resolve_macro_use_deprecated)]
#[help]
pub(crate) struct MacroUseDeprecated;
#[derive(LintDiagnostic)]
#[diag(resolve_macro_is_private)]
pub(crate) struct MacroIsPrivate {
pub ident: Ident,
}
#[derive(LintDiagnostic)]
#[diag(resolve_unused_macro_definition)]
pub(crate) struct UnusedMacroDefinition {
pub name: Symbol,
}
#[derive(LintDiagnostic)]
#[diag(resolve_macro_rule_never_used)]
pub(crate) struct MacroRuleNeverUsed {
pub n: usize,
pub name: Symbol,
}
pub(crate) struct UnstableFeature {
pub msg: DiagMessage,
}
impl<'a> LintDiagnostic<'a, ()> for UnstableFeature {
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
diag.primary_message(self.msg);
}
}
#[derive(LintDiagnostic)]
#[diag(resolve_extern_crate_not_idiomatic)]
pub(crate) struct ExternCrateNotIdiomatic {
#[suggestion(style = "verbose", code = "{code}", applicability = "machine-applicable")]
pub span: Span,
pub code: &'static str,
}
#[derive(LintDiagnostic)]
#[diag(resolve_out_of_scope_macro_calls)]
#[help]
pub(crate) struct OutOfScopeMacroCalls {
#[label]
pub span: Span,
pub path: String,
pub location: String,
}
#[derive(LintDiagnostic)]
#[diag(resolve_redundant_import_visibility)]
pub(crate) struct RedundantImportVisibility {
#[note]
pub span: Span,
#[help]
pub help: (),
pub import_vis: String,
pub max_vis: String,
}
#[derive(LintDiagnostic)]
#[diag(resolve_unknown_diagnostic_attribute)]
pub(crate) struct UnknownDiagnosticAttribute {
#[subdiagnostic]
pub typo: Option<UnknownDiagnosticAttributeTypoSugg>,
}
#[derive(Subdiagnostic)]
#[suggestion(
resolve_unknown_diagnostic_attribute_typo_sugg,
style = "verbose",
code = "{typo_name}",
applicability = "machine-applicable"
)]
pub(crate) struct UnknownDiagnosticAttributeTypoSugg {
#[primary_span]
pub span: Span,
pub typo_name: Symbol,
}
// FIXME: Make this properly translatable.
pub(crate) struct Ambiguity {
pub ident: Ident,
pub kind: &'static str,
pub b1_note: Spanned<String>,
pub b1_help_msgs: Vec<String>,
pub b2_note: Spanned<String>,
pub b2_help_msgs: Vec<String>,
}
impl Ambiguity {
fn decorate<'a>(self, diag: &mut Diag<'a, impl EmissionGuarantee>) {
diag.primary_message(format!("`{}` is ambiguous", self.ident));
diag.span_label(self.ident.span, "ambiguous name");
diag.note(format!("ambiguous because of {}", self.kind));
diag.span_note(self.b1_note.span, self.b1_note.node);
for help_msg in self.b1_help_msgs {
diag.help(help_msg);
}
diag.span_note(self.b2_note.span, self.b2_note.node);
for help_msg in self.b2_help_msgs {
diag.help(help_msg);
}
}
}
impl<'a, G: EmissionGuarantee> Diagnostic<'a, G> for Ambiguity {
fn into_diag(self, dcx: DiagCtxtHandle<'a>, level: Level) -> Diag<'a, G> {
let mut diag = Diag::new(dcx, level, "").with_span(self.ident.span).with_code(E0659);
self.decorate(&mut diag);
diag
}
}
impl<'a> LintDiagnostic<'a, ()> for Ambiguity {
fn decorate_lint<'b>(self, diag: &'b mut Diag<'a, ()>) {
self.decorate(diag);
}
}

View file

@ -1095,10 +1095,11 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
UNUSED_IMPORTS,
id,
import.span,
BuiltinLintDiag::RedundantImportVisibility {
crate::errors::RedundantImportVisibility {
span: import.span,
help: (),
max_vis: max_vis.to_string(def_id, self.tcx),
import_vis: import.vis.to_string(def_id, self.tcx),
span: import.span,
},
);
}
@ -1330,13 +1331,14 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
if !any_successful_reexport {
let (ns, binding) = reexport_error.unwrap();
if let Some(extern_crate_id) = pub_use_of_private_extern_crate_hack(import, binding) {
let extern_crate_sp = self.tcx.source_span(self.local_def_id(extern_crate_id));
self.lint_buffer.buffer_lint(
PUB_USE_OF_PRIVATE_EXTERN_CRATE,
import_id,
import.span,
BuiltinLintDiag::PrivateExternCrateReexport {
source: ident,
extern_crate_span: self.tcx.source_span(self.local_def_id(extern_crate_id)),
crate::errors::PrivateExternCrateReexport {
ident,
sugg: extern_crate_sp.shrink_to_lo(),
},
);
} else if ns == TypeNS {

View file

@ -73,7 +73,6 @@ use rustc_middle::ty::{
ResolverGlobalCtxt, TyCtxt, TyCtxtFeed, Visibility,
};
use rustc_query_system::ich::StableHashingContext;
use rustc_session::lint::BuiltinLintDiag;
use rustc_session::lint::builtin::PRIVATE_MACRO_USE;
use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind, SyntaxContext, Transparency};
use rustc_span::{DUMMY_SP, Ident, Macros20NormalizedIdent, Span, Symbol, kw, sym};
@ -2067,7 +2066,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
PRIVATE_MACRO_USE,
import.root_id,
ident.span,
BuiltinLintDiag::MacroIsPrivate(ident),
errors::MacroIsPrivate { ident },
);
}
}

View file

@ -21,7 +21,6 @@ use rustc_hir::def::{self, DefKind, MacroKinds, Namespace, NonMacroAttrKind};
use rustc_hir::def_id::{CrateNum, DefId, LocalDefId};
use rustc_middle::middle::stability;
use rustc_middle::ty::{RegisteredTools, TyCtxt};
use rustc_session::lint::BuiltinLintDiag;
use rustc_session::lint::builtin::{
LEGACY_DERIVE_HELPERS, OUT_OF_SCOPE_MACRO_CALLS, UNKNOWN_DIAGNOSTIC_ATTRIBUTES,
UNUSED_MACRO_RULES, UNUSED_MACROS,
@ -340,7 +339,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
UNUSED_MACROS,
node_id,
ident.span,
BuiltinLintDiag::UnusedMacroDefinition(ident.name),
errors::UnusedMacroDefinition { name: ident.name },
);
// Do not report unused individual rules if the entire macro is unused
self.unused_macro_rules.swap_remove(&node_id);
@ -361,7 +360,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> {
UNUSED_MACRO_RULES,
node_id,
rule_span,
BuiltinLintDiag::MacroRuleNeverUsed(arm_i, ident.name),
errors::MacroRuleNeverUsed { n: arm_i + 1, name: ident.name },
);
}
}
@ -687,23 +686,24 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
feature_err(&self.tcx.sess, sym::custom_inner_attributes, path.span, msg).emit();
}
const DIAG_ATTRS: &[Symbol] =
&[sym::on_unimplemented, sym::do_not_recommend, sym::on_const];
if res == Res::NonMacroAttr(NonMacroAttrKind::Tool)
&& let [namespace, attribute, ..] = &*path.segments
&& namespace.ident.name == sym::diagnostic
&& ![sym::on_unimplemented, sym::do_not_recommend, sym::on_const]
.contains(&attribute.ident.name)
&& !DIAG_ATTRS.contains(&attribute.ident.name)
{
let typo_name = find_best_match_for_name(
&[sym::on_unimplemented, sym::do_not_recommend, sym::on_const],
attribute.ident.name,
Some(5),
);
let span = attribute.span();
let typo = find_best_match_for_name(DIAG_ATTRS, attribute.ident.name, Some(5))
.map(|typo_name| errors::UnknownDiagnosticAttributeTypoSugg { span, typo_name });
self.tcx.sess.psess.buffer_lint(
UNKNOWN_DIAGNOSTIC_ATTRIBUTES,
attribute.span(),
span,
node_id,
BuiltinLintDiag::UnknownDiagnosticAttribute { span: attribute.span(), typo_name },
errors::UnknownDiagnosticAttribute { typo },
);
}
@ -1031,10 +1031,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
lint,
node_id,
span,
BuiltinLintDiag::UnstableFeature(
// FIXME make this translatable
msg.into(),
),
// FIXME make this translatable
errors::UnstableFeature { msg: msg.into() },
)
};
stability::report_unstable(
@ -1132,9 +1130,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> {
OUT_OF_SCOPE_MACRO_CALLS,
path.span,
node_id,
BuiltinLintDiag::OutOfScopeMacroCalls {
errors::OutOfScopeMacroCalls {
span: path.span,
path: pprust::path_to_string(path),
// FIXME: Make this translatable.
location,
},
);