1#![deny(unconditional_recursion)]
4
5use proc_macro2::{Span, TokenStream};
6use syn::{
7 punctuated::{Pair, Punctuated},
8 Token,
9};
10
11pub trait Spanned {
19 fn span(&self) -> Span;
24
25 fn set_span(&mut self, span: Span);
27
28 #[inline]
30 fn with_span(mut self, span: Span) -> Self
31 where
32 Self: Sized,
33 {
34 self.set_span(span);
35 self
36 }
37}
38
39fn _object_safe(_: &dyn Spanned) {}
40
41impl Spanned for Span {
42 #[inline]
43 fn span(&self) -> Span {
44 *self
45 }
46
47 #[inline]
48 fn set_span(&mut self, span: Span) {
49 *self = span;
50 }
51}
52
53impl Spanned for TokenStream {
54 #[inline]
55 fn span(&self) -> Span {
56 syn::spanned::Spanned::span(self)
57 }
58
59 #[inline]
60 fn set_span(&mut self, span: Span) {
61 *self = self.clone().with_span(span);
62 }
63
64 fn with_span(self, span: Span) -> Self {
65 self.into_iter()
66 .map(|mut tt| {
67 tt.set_span(span);
68 tt
69 })
70 .collect()
71 }
72}
73
74impl<T: Spanned> Spanned for Option<T> {
75 #[inline]
76 fn span(&self) -> Span {
77 match self {
78 Some(t) => t.span(),
79 None => Span::call_site(),
80 }
81 }
82
83 #[inline]
84 fn set_span(&mut self, span: Span) {
85 if let Some(t) = self {
86 t.set_span(span);
87 }
88 }
89}
90
91impl<T: ?Sized + Spanned> Spanned for &T {
92 #[inline]
93 fn span(&self) -> Span {
94 (**self).span()
95 }
96
97 #[inline]
98 #[track_caller]
99 fn set_span(&mut self, _span: Span) {
100 unimplemented!("cannot set span of borrowed Spanned: {:?}", std::any::type_name::<&T>())
101 }
102}
103
104impl<T: Spanned> Spanned for [T] {
105 #[inline]
106 fn span(&self) -> Span {
107 join_spans(self)
108 }
109
110 #[inline]
111 fn set_span(&mut self, span: Span) {
112 set_spans(self, span);
113 }
114}
115
116impl<T: Spanned, P: Spanned> Spanned for Punctuated<T, P> {
117 fn span(&self) -> Span {
118 join_spans(self.pairs())
119 }
120
121 fn set_span(&mut self, span: Span) {
122 set_spans(self.pairs_mut(), span);
123 }
124}
125
126impl<T: Spanned, P: Spanned> Spanned for Pair<T, P> {
127 fn span(&self) -> Span {
128 let span = self.value().span();
129 self.punct().and_then(|punct| span.join(punct.span())).unwrap_or(span)
130 }
131
132 fn set_span(&mut self, span: Span) {
133 self.value_mut().set_span(span);
134 self.punct_mut().set_span(span);
135 }
136}
137
138macro_rules! deref_impls {
139 ($($(#[$attr:meta])* [$($gen:tt)*] $t:ty),+ $(,)?) => {$(
140 $(#[$attr])*
141 impl<$($gen)*> Spanned for $t {
142 #[inline]
143 fn span(&self) -> Span {
144 (**self).span()
145 }
146
147 #[inline]
148 fn set_span(&mut self, span: Span) {
149 (**self).set_span(span)
150 }
151 }
152 )+};
153}
154
155deref_impls! {
156 [T: ?Sized + Spanned] &mut T,
157 [T: ?Sized + Spanned] Box<T>,
158 [T: Spanned] Vec<T>,
159}
160
161macro_rules! inherent_impl {
162 ($($t:ty),* $(,)?) => {$(
163 impl Spanned for $t {
164 #[inline]
165 fn span(&self) -> Span {
166 self.span()
167 }
168
169 #[inline]
170 fn set_span(&mut self, span: Span) {
171 self.set_span(span);
172 }
173 }
174 )*};
175}
176
177inherent_impl!(
178 proc_macro2::TokenTree,
179 proc_macro2::Group,
180 proc_macro2::Punct,
181 proc_macro2::Ident,
182 proc_macro2::Literal,
183 syn::Lifetime,
184 syn::Lit,
185 syn::LitStr,
186 syn::LitByteStr,
187 syn::LitByte,
188 syn::LitChar,
189 syn::LitInt,
190 syn::LitFloat,
191 syn::LitBool,
192);
193
194macro_rules! kw_impl {
198 ($([$($t:tt)+])+) => { $(kw_impl!($($t)+);)+ };
199
200 (__more $t:tt) => {
201 impl Spanned for Token![$t] {
202 #[inline]
203 fn span(&self) -> Span {
204 self.spans.span()
205 }
206
207 #[inline]
208 fn set_span(&mut self, span: Span) {
209 self.spans.set_span(span);
210 }
211 }
212 };
213
214 ($t:tt) => {
215 impl Spanned for Token![$t] {
216 #[inline]
217 fn span(&self) -> Span {
218 self.span
219 }
220
221 #[inline]
222 fn set_span(&mut self, span: Span) {
223 self.span = span;
224 }
225 }
226 };
227}
228
229kw_impl! {
230 [abstract]
231 [as]
232 [async]
233 [auto]
234 [await]
235 [become]
236 [box]
237 [break]
238 [const]
239 [continue]
240 [crate]
241 [default]
242 [do]
243 [dyn]
244 [else]
245 [enum]
246 [extern]
247 [final]
248 [fn]
249 [for]
250 [if]
251 [impl]
252 [in]
253 [let]
254 [loop]
255 [macro]
256 [match]
257 [mod]
258 [move]
259 [mut]
260 [override]
261 [priv]
262 [pub]
263 [ref]
264 [return]
265 [Self]
266 [self]
267 [static]
268 [struct]
269 [super]
270 [trait]
271 [try]
272 [type]
273 [typeof]
274 [union]
275 [unsafe]
276 [unsized]
277 [use]
278 [virtual]
279 [where]
280 [while]
281 [yield]
282 [&]
283 [__more &&]
284 [__more &=]
285 [@]
286 [^]
287 [__more ^=]
288 [:]
289 [,]
290 [$]
291 [.]
292 [__more ..]
293 [__more ...]
294 [__more ..=]
295 [=]
296 [__more ==]
297 [__more =>]
298 [__more >=]
299 [>]
300 [__more <-]
301 [__more <=]
302 [<]
303 [-]
304 [__more -=]
305 [__more !=]
306 [!]
307 [|]
308 [__more |=]
309 [__more ||]
310 [__more ::]
311 [%]
312 [__more %=]
313 [+]
314 [__more +=]
315 [#]
316 [?]
317 [__more ->]
318 [;]
319 [__more <<]
320 [__more <<=]
321 [__more >>]
322 [__more >>=]
323 [/]
324 [__more /=]
325 [*]
326 [__more *=]
327 [~]
328 [_]
329}
330
331macro_rules! delim_impl {
332 ($($t:path),* $(,)?) => {$(
333 impl Spanned for $t {
334 #[inline]
335 fn span(&self) -> Span {
336 self.span.join()
337 }
338
339 #[inline]
340 fn set_span(&mut self, span: Span) {
341 *self = $t(span);
342 }
343
344 #[inline]
345 fn with_span(self, span: Span) -> Self {
346 $t(span)
347 }
348 }
349 )*};
350}
351
352delim_impl!(syn::token::Brace, syn::token::Bracket, syn::token::Paren);
353
354pub fn join_spans<T: Spanned, I: IntoIterator<Item = T>>(items: I) -> Span {
356 items
357 .into_iter()
358 .map(|t| t.span())
359 .reduce(|span, other| span.join(other).unwrap_or(span))
360 .unwrap_or_else(Span::call_site)
361}
362
363pub fn set_spans<T: Spanned, I: IntoIterator<Item = T>>(items: I, span: Span) {
365 for mut item in items {
366 item.set_span(span);
367 }
368}