1use crate::ToTokens;
2use proc_macro2::{Span, TokenStream};
3
4pub trait Spanned {
5 fn __span(&self) -> Span;
6}
7
8impl Spanned for Span {
9 fn __span(&self) -> Span {
10 *self
11 }
12}
13
14impl<T: ?Sized + ToTokens> Spanned for T {
15 fn __span(&self) -> Span {
16 join_spans(self.into_token_stream())
17 }
18}
19
20fn join_spans(tokens: TokenStream) -> Span {
21 let mut iter = tokens.into_iter().filter_map(|tt| {
22 let span = tt.span();
26 let debug = format!("{:?}", span);
27 if debug.ends_with("bytes(0..0)") {
28 None
29 } else {
30 Some(span)
31 }
32 });
33
34 let first = match iter.next() {
35 Some(span) => span,
36 None => return Span::call_site(),
37 };
38
39 iter.fold(None, |_prev, next| Some(next))
40 .and_then(|last| first.join(last))
41 .unwrap_or(first)
42}