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