Skip to main content

rustc_attr_parsing/attributes/
rustc_dump.rs

1use rustc_hir::attrs::{AttributeKind, RustcDumpLayoutKind};
2use rustc_hir::{MethodKind, Target};
3use rustc_span::{Span, Symbol, sym};
4
5use super::prelude::*;
6use crate::context::Stage;
7use crate::target_checking::AllowedTargets;
8
9pub(crate) struct RustcDumpUserArgsParser;
10
11impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpUserArgsParser {
12    const PATH: &[Symbol] = &[sym::rustc_dump_user_args];
13    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
14    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
15    const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpUserArgs;
16}
17
18pub(crate) struct RustcDumpDefParentsParser;
19
20impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpDefParentsParser {
21    const PATH: &[Symbol] = &[sym::rustc_dump_def_parents];
22    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
23    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Fn)]);
24    const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpDefParents;
25}
26
27pub(crate) struct RustcDumpDefPathParser;
28
29impl<S: Stage> SingleAttributeParser<S> for RustcDumpDefPathParser {
30    const PATH: &[Symbol] = &[sym::rustc_dump_def_path];
31    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
32        Allow(Target::Fn),
33        Allow(Target::Method(MethodKind::TraitImpl)),
34        Allow(Target::Method(MethodKind::Inherent)),
35        Allow(Target::Method(MethodKind::Trait { body: true })),
36        Allow(Target::ForeignFn),
37        Allow(Target::ForeignStatic),
38        Allow(Target::Impl { of_trait: false }),
39    ]);
40    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
41    const TEMPLATE: AttributeTemplate = ::rustc_feature::AttributeTemplate {
    word: true,
    list: None,
    one_of: &[],
    name_value_str: None,
    docs: None,
}template!(Word);
42    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
43        if let Err(span) = args.no_args() {
44            cx.adcx().expected_no_args(span);
45            return None;
46        }
47        Some(AttributeKind::RustcDumpDefPath(cx.attr_span))
48    }
49}
50
51pub(crate) struct RustcDumpHiddenTypeOfOpaquesParser;
52
53impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpHiddenTypeOfOpaquesParser {
54    const PATH: &[Symbol] = &[sym::rustc_dump_hidden_type_of_opaques];
55    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
56    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
57    const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpHiddenTypeOfOpaques;
58}
59
60pub(crate) struct RustcDumpInferredOutlivesParser;
61
62impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpInferredOutlivesParser {
63    const PATH: &[Symbol] = &[sym::rustc_dump_inferred_outlives];
64    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
65    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
66        Allow(Target::Struct),
67        Allow(Target::Enum),
68        Allow(Target::Union),
69        Allow(Target::TyAlias),
70    ]);
71    const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpInferredOutlives;
72}
73
74pub(crate) struct RustcDumpItemBoundsParser;
75
76impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpItemBoundsParser {
77    const PATH: &[Symbol] = &[sym::rustc_dump_item_bounds];
78    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
79    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::AssocTy)]);
80    const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpItemBounds;
81}
82
83pub(crate) struct RustcDumpLayoutParser;
84
85impl<S: Stage> CombineAttributeParser<S> for RustcDumpLayoutParser {
86    const PATH: &[Symbol] = &[sym::rustc_dump_layout];
87
88    type Item = RustcDumpLayoutKind;
89
90    const CONVERT: ConvertFn<Self::Item> = |items, _| AttributeKind::RustcDumpLayout(items);
91
92    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
93        Allow(Target::Struct),
94        Allow(Target::Enum),
95        Allow(Target::Union),
96        Allow(Target::TyAlias),
97    ]);
98
99    const TEMPLATE: AttributeTemplate =
100        ::rustc_feature::AttributeTemplate {
    word: false,
    list: Some(&["abi", "align", "size", "homogenous_aggregate", "debug"]),
    one_of: &[],
    name_value_str: None,
    docs: None,
}template!(List: &["abi", "align", "size", "homogenous_aggregate", "debug"]);
101    fn extend(
102        cx: &mut AcceptContext<'_, '_, S>,
103        args: &ArgParser,
104    ) -> impl IntoIterator<Item = Self::Item> {
105        let ArgParser::List(items) = args else {
106            let attr_span = cx.attr_span;
107            cx.adcx().expected_list(attr_span, args);
108            return ::alloc::vec::Vec::new()vec![];
109        };
110
111        let mut result = Vec::new();
112        for item in items.mixed() {
113            let Some(arg) = item.meta_item() else {
114                cx.adcx().expected_not_literal(item.span());
115                continue;
116            };
117            let Some(ident) = arg.ident() else {
118                cx.adcx().expected_identifier(arg.span());
119                return ::alloc::vec::Vec::new()vec![];
120            };
121            let kind = match ident.name {
122                sym::align => RustcDumpLayoutKind::Align,
123                sym::backend_repr => RustcDumpLayoutKind::BackendRepr,
124                sym::debug => RustcDumpLayoutKind::Debug,
125                sym::homogeneous_aggregate => RustcDumpLayoutKind::HomogenousAggregate,
126                sym::size => RustcDumpLayoutKind::Size,
127                _ => {
128                    cx.adcx().expected_specific_argument(
129                        ident.span,
130                        &[
131                            sym::align,
132                            sym::backend_repr,
133                            sym::debug,
134                            sym::homogeneous_aggregate,
135                            sym::size,
136                        ],
137                    );
138                    continue;
139                }
140            };
141            result.push(kind);
142        }
143        result
144    }
145}
146
147pub(crate) struct RustcDumpObjectLifetimeDefaultsParser;
148
149impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpObjectLifetimeDefaultsParser {
150    const PATH: &[Symbol] = &[sym::rustc_dump_object_lifetime_defaults];
151    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
152    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
153        Allow(Target::AssocConst),
154        Allow(Target::AssocTy),
155        Allow(Target::Const),
156        Allow(Target::Enum),
157        Allow(Target::Fn),
158        Allow(Target::ForeignFn),
159        Allow(Target::Impl { of_trait: false }),
160        Allow(Target::Impl { of_trait: true }),
161        Allow(Target::Method(MethodKind::Inherent)),
162        Allow(Target::Method(MethodKind::Trait { body: false })),
163        Allow(Target::Method(MethodKind::Trait { body: true })),
164        Allow(Target::Method(MethodKind::TraitImpl)),
165        Allow(Target::Struct),
166        Allow(Target::Trait),
167        Allow(Target::TraitAlias),
168        Allow(Target::TyAlias),
169        Allow(Target::Union),
170    ]);
171    const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpObjectLifetimeDefaults;
172}
173
174pub(crate) struct RustcDumpPredicatesParser;
175
176impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpPredicatesParser {
177    const PATH: &[Symbol] = &[sym::rustc_dump_predicates];
178    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
179    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
180        Allow(Target::AssocConst),
181        Allow(Target::AssocTy),
182        Allow(Target::Const),
183        Allow(Target::Delegation { mac: false }),
184        Allow(Target::Delegation { mac: true }),
185        Allow(Target::Enum),
186        Allow(Target::Fn),
187        Allow(Target::Impl { of_trait: false }),
188        Allow(Target::Impl { of_trait: true }),
189        Allow(Target::Method(MethodKind::Inherent)),
190        Allow(Target::Method(MethodKind::Trait { body: false })),
191        Allow(Target::Method(MethodKind::Trait { body: true })),
192        Allow(Target::Method(MethodKind::TraitImpl)),
193        Allow(Target::Struct),
194        Allow(Target::Trait),
195        Allow(Target::TraitAlias),
196        Allow(Target::TyAlias),
197        Allow(Target::Union),
198    ]);
199    const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpPredicates;
200}
201
202pub(crate) struct RustcDumpSymbolNameParser;
203
204impl<S: Stage> SingleAttributeParser<S> for RustcDumpSymbolNameParser {
205    const PATH: &[Symbol] = &[sym::rustc_dump_symbol_name];
206    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
207        Allow(Target::Fn),
208        Allow(Target::Method(MethodKind::TraitImpl)),
209        Allow(Target::Method(MethodKind::Inherent)),
210        Allow(Target::Method(MethodKind::Trait { body: true })),
211        Allow(Target::ForeignFn),
212        Allow(Target::ForeignStatic),
213        Allow(Target::Impl { of_trait: false }),
214    ]);
215    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
216    const TEMPLATE: AttributeTemplate = ::rustc_feature::AttributeTemplate {
    word: true,
    list: None,
    one_of: &[],
    name_value_str: None,
    docs: None,
}template!(Word);
217    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
218        if let Err(span) = args.no_args() {
219            cx.adcx().expected_no_args(span);
220            return None;
221        }
222        Some(AttributeKind::RustcDumpSymbolName(cx.attr_span))
223    }
224}
225
226pub(crate) struct RustcDumpVariancesParser;
227
228impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpVariancesParser {
229    const PATH: &[Symbol] = &[sym::rustc_dump_variances];
230    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
231    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
232        Allow(Target::Enum),
233        Allow(Target::Fn),
234        Allow(Target::Method(MethodKind::Inherent)),
235        Allow(Target::Method(MethodKind::Trait { body: false })),
236        Allow(Target::Method(MethodKind::Trait { body: true })),
237        Allow(Target::Method(MethodKind::TraitImpl)),
238        Allow(Target::Struct),
239        Allow(Target::Union),
240    ]);
241    const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpVariances;
242}
243
244pub(crate) struct RustcDumpVariancesOfOpaquesParser;
245
246impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpVariancesOfOpaquesParser {
247    const PATH: &[Symbol] = &[sym::rustc_dump_variances_of_opaques];
248    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Warn;
249    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
250    const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpVariancesOfOpaques;
251}
252
253pub(crate) struct RustcDumpVtableParser;
254
255impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpVtableParser {
256    const PATH: &[Symbol] = &[sym::rustc_dump_vtable];
257    const ON_DUPLICATE: OnDuplicate<S> = OnDuplicate::Error;
258    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
259        Allow(Target::Impl { of_trait: true }),
260        Allow(Target::TyAlias),
261    ]);
262    const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcDumpVtable;
263}