rustc_attr_parsing/
lints.rs1use 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 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}