rustc_attr_parsing/
lints.rs

1use std::borrow::Cow;
2
3use rustc_errors::{DiagArgValue, LintEmitter};
4use rustc_hir::lints::{AttributeLint, AttributeLintKind};
5use rustc_hir::{HirId, Target};
6use rustc_span::sym;
7
8use crate::session_diagnostics;
9
10pub fn emit_attribute_lint<L: LintEmitter>(lint: &AttributeLint<HirId>, 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                    && ![Target::Closure, Target::Expression, Target::Statement, Target::Arm]
45                        .contains(target)
46                {
47                    rustc_session::lint::builtin::USELESS_DEPRECATED
48                } else {
49                    rustc_session::lint::builtin::UNUSED_ATTRIBUTES
50                },
51                *id,
52                *span,
53                session_diagnostics::InvalidTargetLint {
54                    name,
55                    target: target.plural_name(),
56                    applied: DiagArgValue::StrListSepByAnd(
57                        applied.into_iter().map(|i| Cow::Owned(i.to_string())).collect(),
58                    ),
59                    only,
60                    attr_span: *span,
61                },
62            ),
63    }
64}