From 7f1119f992c279acd1d029272bf1740b018d8f13 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Sun, 12 Mar 2023 15:00:31 -0700 Subject: [PATCH] Generalize quote_spanned to accept DelimSpan as span --- src/lib.rs | 10 +++++----- src/runtime.rs | 19 +++++++++++++++++++ tests/ui/wrong-type-span.stderr | 10 +++++++--- 3 files changed, 31 insertions(+), 8 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index e41e313..4932857 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -619,14 +619,14 @@ macro_rules! quote_spanned { #[macro_export] macro_rules! quote_spanned { ($span:expr=>) => {{ - let _: $crate::__private::Span = $span; + let _ = $crate::__private::IntoSpan::into_span($span); $crate::__private::TokenStream::new() }}; // Special case rule for a single tt, for performance. ($span:expr=> $tt:tt) => {{ let mut _s = $crate::__private::TokenStream::new(); - let _span: $crate::__private::Span = $span; + let _span = $crate::__private::IntoSpan::into_span($span); $crate::quote_token_spanned!{$tt _s _span} _s }}; @@ -634,13 +634,13 @@ macro_rules! quote_spanned { // Special case rules for two tts, for performance. ($span:expr=> # $var:ident) => {{ let mut _s = $crate::__private::TokenStream::new(); - let _: $crate::__private::Span = $span; + let _ = $crate::__private::IntoSpan::into_span($span); $crate::ToTokens::to_tokens(&$var, &mut _s); _s }}; ($span:expr=> $tt1:tt $tt2:tt) => {{ let mut _s = $crate::__private::TokenStream::new(); - let _span: $crate::__private::Span = $span; + let _span = $crate::__private::IntoSpan::into_span($span); $crate::quote_token_spanned!{$tt1 _s _span} $crate::quote_token_spanned!{$tt2 _s _span} _s @@ -649,7 +649,7 @@ macro_rules! quote_spanned { // Rule for any other number of tokens. ($span:expr=> $($tt:tt)*) => {{ let mut _s = $crate::__private::TokenStream::new(); - let _span: $crate::__private::Span = $span; + let _span = $crate::__private::IntoSpan::into_span($span); $crate::quote_each_token_spanned!{_s _span $($tt)*} _s }}; diff --git a/src/runtime.rs b/src/runtime.rs index b8d733e..c94e082 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -2,6 +2,7 @@ use crate::{IdentFragment, ToTokens, TokenStreamExt}; use core::fmt; use core::iter; use core::ops::BitOr; +use proc_macro2::extra::DelimSpan; use proc_macro2::{Group, Ident, Punct, Spacing, TokenTree}; pub use core::option::Option; @@ -165,6 +166,24 @@ impl ToTokens for RepInterp { } } +pub trait IntoSpan { + fn into_span(self) -> Span; +} + +impl IntoSpan for Span { + #[inline] + fn into_span(self) -> Span { + self + } +} + +impl IntoSpan for DelimSpan { + #[inline] + fn into_span(self) -> Span { + self.join() + } +} + pub fn push_group(tokens: &mut TokenStream, delimiter: Delimiter, inner: TokenStream) { tokens.append(Group::new(delimiter, inner)); } diff --git a/tests/ui/wrong-type-span.stderr b/tests/ui/wrong-type-span.stderr index b4290e9..6192067 100644 --- a/tests/ui/wrong-type-span.stderr +++ b/tests/ui/wrong-type-span.stderr @@ -1,8 +1,12 @@ -error[E0308]: mismatched types +error[E0277]: the trait bound `&str: IntoSpan` is not satisfied --> tests/ui/wrong-type-span.rs:6:20 | 6 | quote_spanned!(span=> #x); | ---------------^^^^------ | | | - | | expected `Span`, found `&str` - | expected due to this + | | the trait `IntoSpan` is not implemented for `&str` + | required by a bound introduced by this call + | + = help: the following other types implement trait `IntoSpan`: + Span + proc_macro2::extra::DelimSpan