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 Some(items) = cx.expect_list(args, cx.attr_span) else {
100            return ::alloc::vec::Vec::new()vec![];
101        };
102
103        let mut result = Vec::new();
104        for item in items.mixed() {
105            let Some(arg) = item.meta_item() else {
106                cx.adcx().expected_not_literal(item.span());
107                continue;
108            };
109            let Some(ident) = arg.ident() else {
110                cx.adcx().expected_identifier(arg.span());
111                return ::alloc::vec::Vec::new()vec![];
112            };
113            let kind = match ident.name {
114                sym::align => RustcDumpLayoutKind::Align,
115                sym::backend_repr => RustcDumpLayoutKind::BackendRepr,
116                sym::debug => RustcDumpLayoutKind::Debug,
117                sym::homogeneous_aggregate => RustcDumpLayoutKind::HomogenousAggregate,
118                sym::size => RustcDumpLayoutKind::Size,
119                _ => {
120                    cx.adcx().expected_specific_argument(
121                        ident.span,
122                        &[
123                            sym::align,
124                            sym::backend_repr,
125                            sym::debug,
126                            sym::homogeneous_aggregate,
127                            sym::size,
128                        ],
129                    );
130                    continue;
131                }
132            };
133            result.push(kind);
134        }
135        result
136    }
137}
138
139pub(crate) struct RustcDumpObjectLifetimeDefaultsParser;
140
141impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpObjectLifetimeDefaultsParser {
142    const PATH: &[Symbol] = &[sym::rustc_dump_object_lifetime_defaults];
143    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
144        Allow(Target::AssocConst),
145        Allow(Target::AssocTy),
146        Allow(Target::Const),
147        Allow(Target::Enum),
148        Allow(Target::Fn),
149        Allow(Target::ForeignFn),
150        Allow(Target::Impl { of_trait: false }),
151        Allow(Target::Impl { of_trait: true }),
152        Allow(Target::Method(MethodKind::Inherent)),
153        Allow(Target::Method(MethodKind::Trait { body: false })),
154        Allow(Target::Method(MethodKind::Trait { body: true })),
155        Allow(Target::Method(MethodKind::TraitImpl)),
156        Allow(Target::Struct),
157        Allow(Target::Trait),
158        Allow(Target::TraitAlias),
159        Allow(Target::TyAlias),
160        Allow(Target::Union),
161    ]);
162    const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpObjectLifetimeDefaults;
163}
164
165pub(crate) struct RustcDumpPredicatesParser;
166
167impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpPredicatesParser {
168    const PATH: &[Symbol] = &[sym::rustc_dump_predicates];
169    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
170        Allow(Target::AssocConst),
171        Allow(Target::AssocTy),
172        Allow(Target::Const),
173        Allow(Target::Delegation { mac: false }),
174        Allow(Target::Delegation { mac: true }),
175        Allow(Target::Enum),
176        Allow(Target::Fn),
177        Allow(Target::Impl { of_trait: false }),
178        Allow(Target::Impl { of_trait: true }),
179        Allow(Target::Method(MethodKind::Inherent)),
180        Allow(Target::Method(MethodKind::Trait { body: false })),
181        Allow(Target::Method(MethodKind::Trait { body: true })),
182        Allow(Target::Method(MethodKind::TraitImpl)),
183        Allow(Target::Struct),
184        Allow(Target::Trait),
185        Allow(Target::TraitAlias),
186        Allow(Target::TyAlias),
187        Allow(Target::Union),
188    ]);
189    const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpPredicates;
190}
191
192pub(crate) struct RustcDumpSymbolNameParser;
193
194impl<S: Stage> SingleAttributeParser<S> for RustcDumpSymbolNameParser {
195    const PATH: &[Symbol] = &[sym::rustc_dump_symbol_name];
196    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
197        Allow(Target::Fn),
198        Allow(Target::Method(MethodKind::TraitImpl)),
199        Allow(Target::Method(MethodKind::Inherent)),
200        Allow(Target::Method(MethodKind::Trait { body: true })),
201        Allow(Target::ForeignFn),
202        Allow(Target::ForeignStatic),
203        Allow(Target::Impl { of_trait: false }),
204    ]);
205    const TEMPLATE: AttributeTemplate = ::rustc_feature::AttributeTemplate {
    word: true,
    list: None,
    one_of: &[],
    name_value_str: None,
    docs: None,
}template!(Word);
206    fn convert(cx: &mut AcceptContext<'_, '_, S>, args: &ArgParser) -> Option<AttributeKind> {
207        if let Err(span) = args.no_args() {
208            cx.adcx().expected_no_args(span);
209            return None;
210        }
211        Some(AttributeKind::RustcDumpSymbolName(cx.attr_span))
212    }
213}
214
215pub(crate) struct RustcDumpVariancesParser;
216
217impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpVariancesParser {
218    const PATH: &[Symbol] = &[sym::rustc_dump_variances];
219    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
220        Allow(Target::Enum),
221        Allow(Target::Fn),
222        Allow(Target::Method(MethodKind::Inherent)),
223        Allow(Target::Method(MethodKind::Trait { body: false })),
224        Allow(Target::Method(MethodKind::Trait { body: true })),
225        Allow(Target::Method(MethodKind::TraitImpl)),
226        Allow(Target::Struct),
227        Allow(Target::Union),
228    ]);
229    const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpVariances;
230}
231
232pub(crate) struct RustcDumpVariancesOfOpaquesParser;
233
234impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpVariancesOfOpaquesParser {
235    const PATH: &[Symbol] = &[sym::rustc_dump_variances_of_opaques];
236    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[Allow(Target::Crate)]);
237    const CREATE: fn(Span) -> AttributeKind = |_| AttributeKind::RustcDumpVariancesOfOpaques;
238}
239
240pub(crate) struct RustcDumpVtableParser;
241
242impl<S: Stage> NoArgsAttributeParser<S> for RustcDumpVtableParser {
243    const PATH: &[Symbol] = &[sym::rustc_dump_vtable];
244    const ALLOWED_TARGETS: AllowedTargets = AllowedTargets::AllowList(&[
245        Allow(Target::Impl { of_trait: true }),
246        Allow(Target::TyAlias),
247    ]);
248    const CREATE: fn(Span) -> AttributeKind = AttributeKind::RustcDumpVtable;
249}