rustc_attr_parsing/
early_parsed.rs1use 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#[derive(Default)]
16pub(crate) struct EarlyParsedState {
17 cfg_trace: ThinVec<(CfgEntry, Span)>,
19
20 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}