rustc_attr_parsing/
lints.rs

1use rustc_errors::{DiagArgValue, LintEmitter};
2use rustc_hir::lints::{AttributeLint, AttributeLintKind};
3use rustc_hir::{HirId, Target};
4use rustc_span::sym;
5
6use crate::session_diagnostics;
7
8pub fn emit_attribute_lint<L: LintEmitter>(lint: &AttributeLint<HirId>, lint_emitter: L) {
9    let AttributeLint { id, span, kind } = lint;
10
11    match kind {
12        &AttributeLintKind::UnusedDuplicate { this, other, warning } => lint_emitter
13            .emit_node_span_lint(
14                rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
15                *id,
16                *span,
17                session_diagnostics::UnusedDuplicate { this, other, warning },
18            ),
19        AttributeLintKind::IllFormedAttributeInput { suggestions } => {
20            lint_emitter.emit_node_span_lint(
21                rustc_session::lint::builtin::ILL_FORMED_ATTRIBUTE_INPUT,
22                *id,
23                *span,
24                session_diagnostics::IllFormedAttributeInput {
25                    num_suggestions: suggestions.len(),
26                    suggestions: DiagArgValue::StrListSepByAnd(
27                        suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(),
28                    ),
29                },
30            );
31        }
32        AttributeLintKind::EmptyAttribute { first_span } => lint_emitter.emit_node_span_lint(
33            rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
34            *id,
35            *first_span,
36            session_diagnostics::EmptyAttributeList { attr_span: *first_span },
37        ),
38        &AttributeLintKind::InvalidTarget { name, target, ref applied, only } => lint_emitter
39            .emit_node_span_lint(
40                // This check is here because `deprecated` had its own lint group and removing this would be a breaking change
41                if name == sym::deprecated
42                    && ![Target::Closure, Target::Expression, Target::Statement, Target::Arm]
43                        .contains(&target)
44                {
45                    rustc_session::lint::builtin::USELESS_DEPRECATED
46                } else {
47                    rustc_session::lint::builtin::UNUSED_ATTRIBUTES
48                },
49                *id,
50                *span,
51                session_diagnostics::InvalidTargetLint {
52                    name,
53                    target: target.plural_name(),
54                    applied: applied.clone(),
55                    only,
56                    attr_span: *span,
57                },
58            ),
59    }
60}