From 8931b2a8b4dc1598b61455630d41c6fd13f63394 Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Mon, 13 Mar 2023 10:57:50 -0700 Subject: [PATCH] Improve error message on incorrectly typed span --- src/lib.rs | 10 +++++----- src/runtime.rs | 31 ++++++++++++++++++++++++------- tests/ui/wrong-type-span.stderr | 9 +++++---- 3 files changed, 34 insertions(+), 16 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 54390bc..5a31606 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::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 }}; @@ -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::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 @@ -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 }}; diff --git a/src/runtime.rs b/src/runtime.rs index a0a0029..4b427be 100644 --- a/src/runtime.rs +++ b/src/runtime.rs @@ -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; @@ -168,7 +168,7 @@ impl ToTokens for RepInterp { #[inline] pub fn get_span(span: T) -> GetSpan { - GetSpan(GetSpanInner(span)) + GetSpan(GetSpanInner(GetSpanBase(span))) } mod get_span { @@ -178,24 +178,41 @@ mod get_span { pub struct GetSpan(pub(crate) GetSpanInner); - pub struct GetSpanInner(pub(crate) T); + pub struct GetSpanInner(pub(crate) GetSpanBase); + + pub struct GetSpanBase(pub(crate) T); impl GetSpan { #[inline] pub fn __into_span(self) -> Span { - (self.0).0 + ((self.0).0).0 } } impl GetSpanInner { #[inline] pub fn __into_span(&self) -> Span { - self.0.join() + (self.0).0.join() + } + } + + impl GetSpanBase { + pub fn __into_span(&self) -> T { + unreachable!() + } + } + + impl Deref for GetSpan { + type Target = GetSpanInner; + + #[inline] + fn deref(&self) -> &Self::Target { + &self.0 } } - impl Deref for GetSpan { - type Target = GetSpanInner; + impl Deref for GetSpanInner { + type Target = GetSpanBase; #[inline] fn deref(&self) -> &Self::Target { diff --git a/tests/ui/wrong-type-span.stderr b/tests/ui/wrong-type-span.stderr index bbc5abd..12ad307 100644 --- a/tests/ui/wrong-type-span.stderr +++ b/tests/ui/wrong-type-span.stderr @@ -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` = note: this error originates in the macro `quote_spanned` (in Nightly builds, run with -Z macro-backtrace for more info)