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