Skip to content

Commit

Permalink
Merge pull request #247 from dtolnay/wrongspan
Browse files Browse the repository at this point in the history
Improve error message on incorrectly typed span
  • Loading branch information
dtolnay authored Mar 13, 2023
2 parents 51bb1e7 + d67f6ff commit bf9bca9
Show file tree
Hide file tree
Showing 3 changed files with 35 additions and 16 deletions.
10 changes: 5 additions & 5 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -619,28 +619,28 @@ macro_rules! quote_spanned {
#[macro_export]
macro_rules! quote_spanned {
($span:expr=>) => {{
let _ = $crate::__private::get_span($span).__into_span();
let _: $crate::__private::Span = $crate::__private::get_span($span).__into_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::get_span($span).__into_span();
let _span: $crate::__private::Span = $crate::__private::get_span($span).__into_span();
$crate::quote_token_spanned!{$tt _s _span}
_s
}};

// Special case rules for two tts, for performance.
($span:expr=> # $var:ident) => {{
let mut _s = $crate::__private::TokenStream::new();
let _ = $crate::__private::get_span($span).__into_span();
let _: $crate::__private::Span = $crate::__private::get_span($span).__into_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::get_span($span).__into_span();
let _span: $crate::__private::Span = $crate::__private::get_span($span).__into_span();
$crate::quote_token_spanned!{$tt1 _s _span}
$crate::quote_token_spanned!{$tt2 _s _span}
_s
Expand All @@ -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::get_span($span).__into_span();
let _span: $crate::__private::Span = $crate::__private::get_span($span).__into_span();
$crate::quote_each_token_spanned!{_s _span $($tt)*}
_s
}};
Expand Down
32 changes: 25 additions & 7 deletions src/runtime.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use self::get_span::{GetSpanInner, GetSpan};
use self::get_span::{GetSpan, GetSpanBase, GetSpanInner};
use crate::{IdentFragment, ToTokens, TokenStreamExt};
use core::fmt;
use core::iter;
Expand Down Expand Up @@ -168,7 +168,7 @@ impl<T: ToTokens> ToTokens for RepInterp<T> {

#[inline]
pub fn get_span<T>(span: T) -> GetSpan<T> {
GetSpan(GetSpanInner(span))
GetSpan(GetSpanInner(GetSpanBase(span)))
}

mod get_span {
Expand All @@ -178,24 +178,42 @@ mod get_span {

pub struct GetSpan<T>(pub(crate) GetSpanInner<T>);

pub struct GetSpanInner<T>(pub(crate) T);
pub struct GetSpanInner<T>(pub(crate) GetSpanBase<T>);

pub struct GetSpanBase<T>(pub(crate) T);

impl GetSpan<Span> {
#[inline]
pub fn __into_span(self) -> Span {
(self.0).0
((self.0).0).0
}
}

impl GetSpanInner<DelimSpan> {
#[inline]
pub fn __into_span(&self) -> Span {
self.0.join()
(self.0).0.join()
}
}

impl<T> GetSpanBase<T> {
#[allow(clippy::unused_self)]
pub fn __into_span(&self) -> T {
unreachable!()
}
}

impl<T> Deref for GetSpan<T> {
type Target = GetSpanInner<T>;

#[inline]
fn deref(&self) -> &Self::Target {
&self.0
}
}

impl Deref for GetSpan<DelimSpan> {
type Target = GetSpanInner<DelimSpan>;
impl<T> Deref for GetSpanInner<T> {
type Target = GetSpanBase<T>;

#[inline]
fn deref(&self) -> &Self::Target {
Expand Down
9 changes: 5 additions & 4 deletions tests/ui/wrong-type-span.stderr
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
error[E0599]: no method named `__into_span` found for struct `__private::get_span::GetSpan<&str>` in the current scope
error[E0308]: mismatched types
--> tests/ui/wrong-type-span.rs:6:5
|
6 | quote_spanned!(span=> #x);
| ^^^^^^^^^^^^^^^^^^^^^^^^^ method not found in `GetSpan<&str>`
| ^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| expected `Span`, found `&str`
| expected due to this
|
= note: the method was found for
- `__private::get_span::GetSpan<Span>`
= note: this error originates in the macro `quote_spanned` (in Nightly builds, run with -Z macro-backtrace for more info)

0 comments on commit bf9bca9

Please sign in to comment.