• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 use crate::ToTokens;
2 use proc_macro2::extra::DelimSpan;
3 use proc_macro2::{Span, TokenStream};
4 
5 // Not public API other than via the syn crate. Use syn::spanned::Spanned.
6 pub trait Spanned: private::Sealed {
__span(&self) -> Span7     fn __span(&self) -> Span;
8 }
9 
10 impl Spanned for Span {
__span(&self) -> Span11     fn __span(&self) -> Span {
12         *self
13     }
14 }
15 
16 impl Spanned for DelimSpan {
__span(&self) -> Span17     fn __span(&self) -> Span {
18         self.join()
19     }
20 }
21 
22 impl<T: ?Sized + ToTokens> Spanned for T {
__span(&self) -> Span23     fn __span(&self) -> Span {
24         join_spans(self.into_token_stream())
25     }
26 }
27 
join_spans(tokens: TokenStream) -> Span28 fn join_spans(tokens: TokenStream) -> Span {
29     let mut iter = tokens.into_iter().map(|tt| tt.span());
30 
31     let first = match iter.next() {
32         Some(span) => span,
33         None => return Span::call_site(),
34     };
35 
36     iter.fold(None, |_prev, next| Some(next))
37         .and_then(|last| first.join(last))
38         .unwrap_or(first)
39 }
40 
41 mod private {
42     use crate::ToTokens;
43     use proc_macro2::extra::DelimSpan;
44     use proc_macro2::Span;
45 
46     pub trait Sealed {}
47     impl Sealed for Span {}
48     impl Sealed for DelimSpan {}
49     impl<T: ?Sized + ToTokens> Sealed for T {}
50 }
51