Skip to main content

rustc_attr_parsing/
synthetic.rs

1use rustc_ast::SyntheticAttr;
2use rustc_ast::attr::data_structures::CfgEntry;
3use rustc_hir::Attribute;
4use rustc_hir::attrs::AttributeKind;
5use rustc_span::Span;
6use thin_vec::ThinVec;
7
8/// This struct contains the state necessary to convert synthetic attributes to hir attributes
9/// The only conversion that really happens here is that multiple synthetic attributes are
10/// merged into a single hir attribute, representing their combined state.
11/// FIXME: We should make this a nice and extendable system if this is going to be used more often
12#[derive(#[automatically_derived]
impl ::core::default::Default for SyntheticAttrState {
    #[inline]
    fn default() -> SyntheticAttrState {
        SyntheticAttrState {
            cfg_trace: ::core::default::Default::default(),
            cfg_attr_trace: ::core::default::Default::default(),
        }
    }
}Default)]
13pub(crate) struct SyntheticAttrState {
14    /// Attribute state for `SyntheticAttr::CfgTrace` attributes.
15    cfg_trace: ThinVec<(CfgEntry, Span)>,
16
17    /// Attribute state for `SyntheticAttr::CfgAttrTrace` attributes.
18    cfg_attr_trace: ThinVec<(CfgEntry, Span)>,
19}
20
21impl SyntheticAttrState {
22    pub(crate) fn accept_synthetic_attr(
23        &mut self,
24        attr_span: Span,
25        lower_span: impl Copy + Fn(Span) -> Span,
26        synthetic: &SyntheticAttr,
27    ) {
28        match synthetic {
29            SyntheticAttr::CfgTrace(cfg) => {
30                let mut cfg = cfg.clone();
31                cfg.lower_spans(lower_span);
32                self.cfg_trace.push((cfg, attr_span));
33            }
34            SyntheticAttr::CfgAttrTrace(cfg) => {
35                let mut cfg = cfg.clone();
36                cfg.lower_spans(lower_span);
37                self.cfg_attr_trace.push((cfg, attr_span));
38            }
39        }
40    }
41
42    pub(crate) fn finalize_synthetic_attrs(self, attributes: &mut Vec<Attribute>) {
43        if !self.cfg_trace.is_empty() {
44            attributes.push(Attribute::Parsed(AttributeKind::CfgTrace(self.cfg_trace)));
45        }
46        if !self.cfg_attr_trace.is_empty() {
47            attributes.push(Attribute::Parsed(AttributeKind::CfgAttrTrace(self.cfg_attr_trace)));
48        }
49    }
50}