rustc_attr_parsing/
lints.rs

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