rustc_attr_parsing/attributes/
confusables.rs
1use rustc_attr_data_structures::AttributeKind;
2use rustc_span::{Span, Symbol, sym};
3use thin_vec::ThinVec;
4
5use super::{AcceptMapping, AttributeParser};
6use crate::context::FinalizeContext;
7use crate::session_diagnostics;
8
9#[derive(Default)]
10pub(crate) struct ConfusablesParser {
11 confusables: ThinVec<Symbol>,
12 first_span: Option<Span>,
13}
14
15impl AttributeParser for ConfusablesParser {
16 const ATTRIBUTES: AcceptMapping<Self> = &[(&[sym::rustc_confusables], |this, cx, args| {
17 let Some(list) = args.list() else {
18 return;
22 };
23
24 if list.is_empty() {
25 cx.emit_err(session_diagnostics::EmptyConfusables { span: cx.attr_span });
26 }
27
28 for param in list.mixed() {
29 let span = param.span();
30
31 let Some(lit) = param.lit() else {
32 cx.emit_err(session_diagnostics::IncorrectMetaItem {
33 span,
34 suggestion: Some(session_diagnostics::IncorrectMetaItemSuggestion {
35 lo: span.shrink_to_lo(),
36 hi: span.shrink_to_hi(),
37 }),
38 });
39 continue;
40 };
41
42 this.confusables.push(lit.symbol);
43 }
44
45 this.first_span.get_or_insert(cx.attr_span);
46 })];
47
48 fn finalize(self, _cx: &FinalizeContext<'_>) -> Option<AttributeKind> {
49 if self.confusables.is_empty() {
50 return None;
51 }
52
53 Some(AttributeKind::Confusables {
54 symbols: self.confusables,
55 first_span: self.first_span.unwrap(),
56 })
57 }
58}