rustc_attr_data_structures/
lib.rs1#![allow(internal_features)]
7#![doc(rust_logo)]
8#![feature(rustdoc_internals)]
9mod attributes;
12mod encode_cross_crate;
13mod stability;
14mod version;
15
16pub mod lints;
17
18use std::num::NonZero;
19
20pub use attributes::*;
21pub use encode_cross_crate::EncodeCrossCrate;
22use rustc_abi::Align;
23use rustc_ast::token::CommentKind;
24use rustc_ast::{AttrStyle, IntTy, UintTy};
25use rustc_ast_pretty::pp::Printer;
26use rustc_span::hygiene::Transparency;
27use rustc_span::{Span, Symbol};
28pub use stability::*;
29use thin_vec::ThinVec;
30pub use version::*;
31
32pub trait HashStableContext: rustc_ast::HashStableContext + rustc_abi::HashStableContext {}
36
37pub trait PrintAttribute {
44 fn should_render(&self) -> bool;
48
49 fn print_attribute(&self, p: &mut Printer);
50}
51
52impl PrintAttribute for u128 {
53 fn should_render(&self) -> bool {
54 true
55 }
56
57 fn print_attribute(&self, p: &mut Printer) {
58 p.word(self.to_string())
59 }
60}
61
62impl<T: PrintAttribute> PrintAttribute for &T {
63 fn should_render(&self) -> bool {
64 T::should_render(self)
65 }
66
67 fn print_attribute(&self, p: &mut Printer) {
68 T::print_attribute(self, p)
69 }
70}
71impl<T: PrintAttribute> PrintAttribute for Option<T> {
72 fn should_render(&self) -> bool {
73 self.as_ref().is_some_and(|x| x.should_render())
74 }
75
76 fn print_attribute(&self, p: &mut Printer) {
77 if let Some(i) = self {
78 T::print_attribute(i, p)
79 }
80 }
81}
82impl<T: PrintAttribute> PrintAttribute for ThinVec<T> {
83 fn should_render(&self) -> bool {
84 self.is_empty() || self[0].should_render()
85 }
86
87 fn print_attribute(&self, p: &mut Printer) {
88 let mut last_printed = false;
89 p.word("[");
90 for i in self {
91 if last_printed {
92 p.word_space(",");
93 }
94 i.print_attribute(p);
95 last_printed = i.should_render();
96 }
97 p.word("]");
98 }
99}
100macro_rules! print_skip {
101 ($($t: ty),* $(,)?) => {$(
102 impl PrintAttribute for $t {
103 fn should_render(&self) -> bool { false }
104 fn print_attribute(&self, _: &mut Printer) { }
105 })*
106 };
107}
108
109macro_rules! print_disp {
110 ($($t: ty),* $(,)?) => {$(
111 impl PrintAttribute for $t {
112 fn should_render(&self) -> bool { true }
113 fn print_attribute(&self, p: &mut Printer) {
114 p.word(format!("{}", self));
115 }
116 }
117 )*};
118}
119macro_rules! print_debug {
120 ($($t: ty),* $(,)?) => {$(
121 impl PrintAttribute for $t {
122 fn should_render(&self) -> bool { true }
123 fn print_attribute(&self, p: &mut Printer) {
124 p.word(format!("{:?}", self));
125 }
126 }
127 )*};
128}
129
130macro_rules! print_tup {
131 (num_should_render $($ts: ident)*) => { 0 $(+ $ts.should_render() as usize)* };
132 () => {};
133 ($t: ident $($ts: ident)*) => {
134 #[allow(non_snake_case, unused)]
135 impl<$t: PrintAttribute, $($ts: PrintAttribute),*> PrintAttribute for ($t, $($ts),*) {
136 fn should_render(&self) -> bool {
137 let ($t, $($ts),*) = self;
138 print_tup!(num_should_render $t $($ts)*) != 0
139 }
140
141 fn print_attribute(&self, p: &mut Printer) {
142 let ($t, $($ts),*) = self;
143 let parens = print_tup!(num_should_render $t $($ts)*) > 1;
144 if parens {
145 p.popen();
146 }
147
148 let mut printed_anything = $t.should_render();
149
150 $t.print_attribute(p);
151
152 $(
153 if $ts.should_render() {
154 if printed_anything {
155 p.word_space(",");
156 }
157 printed_anything = true;
158 }
159 $ts.print_attribute(p);
160 )*
161
162 if parens {
163 p.pclose();
164 }
165 }
166 }
167
168 print_tup!($($ts)*);
169 };
170}
171
172print_tup!(A B C D E F G H);
173print_skip!(Span, ());
174print_disp!(u16, bool, NonZero<u32>);
175print_debug!(Symbol, UintTy, IntTy, Align, AttrStyle, CommentKind, Transparency);
176
177#[macro_export]
196macro_rules! find_attr {
197 ($attributes_list: expr, $pattern: pat $(if $guard: expr)?) => {{
198 $crate::find_attr!($attributes_list, $pattern $(if $guard)? => ()).is_some()
199 }};
200
201 ($attributes_list: expr, $pattern: pat $(if $guard: expr)? => $e: expr) => {{
202 'done: {
203 for i in $attributes_list {
204 let i: &rustc_hir::Attribute = i;
205 match i {
206 rustc_hir::Attribute::Parsed($pattern) $(if $guard)? => {
207 break 'done Some($e);
208 }
209 _ => {}
210 }
211 }
212
213 None
214 }
215 }};
216}