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