    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89

    use proc_macro2::{Ident, Span, TokenStream};
    use quote::ToTokens;
    use syn::LitStr;

    use std::ops::{Deref, DerefMut};

    /// An entity with a span attached.
    #[derive(Debug, Copy, Clone)]
    pub struct Sp<T> {
        val: T,
        span: Span,
    }

    impl<T> Sp<T> {
        pub fn new(val: T, span: Span) -> Self {
            Sp { val, span }
        }

        pub fn get(&self) -> &T {
            &self.val
        }

        pub fn span(&self) -> Span {
            self.span
        }
    }

    impl<T> Deref for Sp<T> {
        type Target = T;

        fn deref(&self) -> &T {
            &self.val
        }
    }

    impl<T> DerefMut for Sp<T> {
        fn deref_mut(&mut self) -> &mut T {
            &mut self.val
        }
    }

    impl From<Ident> for Sp<String> {
        fn from(ident: Ident) -> Self {
            Sp {
                val: ident.to_string(),
                span: ident.span(),
            }
        }
    }

    impl From<LitStr> for Sp<String> {
        fn from(lit: LitStr) -> Self {
            Sp {
                val: lit.value(),
                span: lit.span(),
            }
        }
    }

    impl<'a> From<Sp<&'a str>> for Sp<String> {
        fn from(sp: Sp<&'a str>) -> Self {
            Sp::new(sp.val.into(), sp.span)
        }
    }

    impl<U, T: PartialEq<U>> PartialEq<U> for Sp<T> {
        fn eq(&self, other: &U) -> bool {
            self.val == *other
        }
    }

    impl<T: AsRef<str>> AsRef<str> for Sp<T> {
        fn as_ref(&self) -> &str {
            self.val.as_ref()
        }
    }

    impl<T: ToTokens> ToTokens for Sp<T> {
        fn to_tokens(&self, stream: &mut TokenStream) {
            // this is the simplest way out of correct ones to change span on
            // arbitrary token tree I could come up with
            let tt = self.val.to_token_stream().into_iter().map(|mut tt| {
                tt.set_span(self.span);
                tt
            });

            stream.extend(tt);
        }
    }