rustc_attr_parsing/
early_parsed.rs

1use rustc_ast::EarlyParsedAttribute;
2use rustc_ast::attr::data_structures::CfgEntry;
3use rustc_hir::Attribute;
4use rustc_hir::attrs::AttributeKind;
5use rustc_span::{Span, Symbol, sym};
6use thin_vec::ThinVec;
7
8pub(crate) const EARLY_PARSED_ATTRIBUTES: &[&[Symbol]] =
9    &[&[sym::cfg_trace], &[sym::cfg_attr_trace]];
10
11/// This struct contains the state necessary to convert early parsed attributes to hir attributes
12/// The only conversion that really happens here is that multiple early parsed attributes are
13/// merged into a single hir attribute, representing their combined state.
14/// FIXME: We should make this a nice and extendable system if this is going to be used more often
15#[derive(Default)]
16pub(crate) struct EarlyParsedState {
17    /// Attribute state for `#[cfg]` trace attributes
18    cfg_trace: ThinVec<(CfgEntry, Span)>,
19
20    /// Attribute state for `#[cfg_attr]` trace attributes
21    /// The arguments of these attributes is no longer relevant for any later passes, only their presence.
22    /// So we discard the arguments here.
23    cfg_attr_trace: bool,
24}
25
26impl EarlyParsedState {
27    pub(crate) fn accept_early_parsed_attribute(
28        &mut self,
29        attr_span: Span,
30        lower_span: impl Copy + Fn(Span) -> Span,
31        parsed: &EarlyParsedAttribute,
32    ) {
33        match parsed {
34            EarlyParsedAttribute::CfgTrace(cfg) => {
35                let mut cfg = cfg.clone();
36                cfg.lower_spans(lower_span);
37                self.cfg_trace.push((cfg, attr_span));
38            }
39            EarlyParsedAttribute::CfgAttrTrace => {
40                self.cfg_attr_trace = true;
41            }
42        }
43    }
44
45    pub(crate) fn finalize_early_parsed_attributes(self, attributes: &mut Vec<Attribute>) {
46        if !self.cfg_trace.is_empty() {
47            attributes.push(Attribute::Parsed(AttributeKind::CfgTrace(self.cfg_trace)));
48        }
49        if self.cfg_attr_trace {
50            attributes.push(Attribute::Parsed(AttributeKind::CfgAttrTrace));
51        }
52    }
53}