diff options
Diffstat (limited to 'third_party/rust/quote/src/spanned.rs')
-rw-r--r-- | third_party/rust/quote/src/spanned.rs | 43 |
1 files changed, 43 insertions, 0 deletions
diff --git a/third_party/rust/quote/src/spanned.rs b/third_party/rust/quote/src/spanned.rs new file mode 100644 index 0000000000..f64c8f5dfe --- /dev/null +++ b/third_party/rust/quote/src/spanned.rs @@ -0,0 +1,43 @@ +use crate::ToTokens; +use proc_macro2::{Span, TokenStream}; + +pub trait Spanned { + fn __span(&self) -> Span; +} + +impl Spanned for Span { + fn __span(&self) -> Span { + *self + } +} + +impl<T: ?Sized + ToTokens> Spanned for T { + fn __span(&self) -> Span { + join_spans(self.into_token_stream()) + } +} + +fn join_spans(tokens: TokenStream) -> Span { + #[cfg(not(needs_invalid_span_workaround))] + let mut iter = tokens.into_iter().map(|tt| tt.span()); + + #[cfg(needs_invalid_span_workaround)] + let mut iter = tokens.into_iter().filter_map(|tt| { + let span = tt.span(); + let debug = format!("{:?}", span); + if debug.ends_with("bytes(0..0)") { + None + } else { + Some(span) + } + }); + + let first = match iter.next() { + Some(span) => span, + None => return Span::call_site(), + }; + + iter.fold(None, |_prev, next| Some(next)) + .and_then(|last| first.join(last)) + .unwrap_or(first) +} |