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::InvalidMacroExportArguments { suggestions } => lint_emitter
35 .emit_node_span_lint(
36 rustc_session::lint::builtin::INVALID_MACRO_EXPORT_ARGUMENTS,
37 *id,
38 *span,
39 session_diagnostics::IllFormedAttributeInput {
40 num_suggestions: suggestions.len(),
41 suggestions: DiagArgValue::StrListSepByAnd(
42 suggestions.into_iter().map(|s| format!("`{s}`").into()).collect(),
43 ),
44 },
45 ),
46 AttributeLintKind::EmptyAttribute { first_span, attr_path, valid_without_list } => {
47 lint_emitter.emit_node_span_lint(
48 rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
49 *id,
50 *first_span,
51 session_diagnostics::EmptyAttributeList {
52 attr_span: *first_span,
53 attr_path: attr_path.clone(),
54 valid_without_list: *valid_without_list,
55 },
56 )
57 }
58 AttributeLintKind::InvalidTarget { name, target, applied, only } => lint_emitter
59 .emit_node_span_lint(
60 if name.segments[0].name == sym::deprecated
62 && ![
63 Target::Closure,
64 Target::Expression,
65 Target::Statement,
66 Target::Arm,
67 Target::MacroCall,
68 ]
69 .contains(target)
70 {
71 rustc_session::lint::builtin::USELESS_DEPRECATED
72 } else {
73 rustc_session::lint::builtin::UNUSED_ATTRIBUTES
74 },
75 *id,
76 *span,
77 session_diagnostics::InvalidTargetLint {
78 name: name.clone(),
79 target: target.plural_name(),
80 applied: DiagArgValue::StrListSepByAnd(
81 applied.into_iter().map(|i| Cow::Owned(i.to_string())).collect(),
82 ),
83 only,
84 attr_span: *span,
85 },
86 ),
87
88 &AttributeLintKind::InvalidStyle { ref name, is_used_as_inner, target, target_span } => {
89 lint_emitter.emit_node_span_lint(
90 rustc_session::lint::builtin::UNUSED_ATTRIBUTES,
91 *id,
92 *span,
93 session_diagnostics::InvalidAttrStyle {
94 name: name.clone(),
95 is_used_as_inner,
96 target_span: (!is_used_as_inner).then_some(target_span),
97 target,
98 },
99 )
100 }
101 }
102}