diff --git a/macros/src/lib.rs b/macros/src/lib.rs index a3bb2ff6..e7f2eb5d 100644 --- a/macros/src/lib.rs +++ b/macros/src/lib.rs @@ -12,7 +12,7 @@ use proc_macro::TokenStream; use proc_macro2::TokenStream as TokenStream2; use quote::{quote, quote_spanned}; use std::fmt; -use syn::spanned::Spanned; +use syn::{LitStr, spanned::Spanned}; mod error; mod parser; @@ -22,10 +22,9 @@ mod parser; pub fn parse_lit(input: TokenStream) -> TokenStream { build_uuid(input.clone()).unwrap_or_else(|e| { let msg = e.to_string(); - let ts = TokenStream2::from(input); let span = match e { - Error::UuidParse(error::Error(error::ErrorKind::Char { + Error::UuidParse(lit, error::Error(error::ErrorKind::Char { character, index, })) => { @@ -36,19 +35,20 @@ pub fn parse_lit(input: TokenStream) -> TokenStream { width += 1; } let mut s = proc_macro2::Literal::string(""); - s.set_span(ts.span()); + s.set_span(lit.span()); s.subspan(index..index + width - 1) } - Error::UuidParse(error::Error( + Error::UuidParse(lit, error::Error( error::ErrorKind::GroupLength { index, len, .. }, )) => { let mut s = proc_macro2::Literal::string(""); - s.set_span(ts.span()); + s.set_span(lit.span()); s.subspan(index..index + len) } _ => None, } - .unwrap_or_else(|| ts.span()); + .unwrap_or_else(|| TokenStream2::from(input).span()); + TokenStream::from(quote_spanned! {span=> compile_error!(#msg) }) @@ -57,26 +57,26 @@ pub fn parse_lit(input: TokenStream) -> TokenStream { enum Error { NonStringLiteral, - UuidParse(error::Error), + UuidParse(LitStr, error::Error), } impl fmt::Display for Error { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { match *self { Error::NonStringLiteral => f.write_str("expected string literal"), - Error::UuidParse(ref e) => write!(f, "{}", e), + Error::UuidParse(_, ref e) => write!(f, "{}", e), } } } fn build_uuid(input: TokenStream) -> Result { - let string = match syn::parse::(input) { - Ok(syn::Lit::Str(literal)) => literal.value(), + let str_lit = match syn::parse::(input) { + Ok(syn::Lit::Str(literal)) => literal, _ => return Err(Error::NonStringLiteral), }; - let bytes = parser::try_parse(&string) - .map_err(|e| Error::UuidParse(e.into_err()))?; + let bytes = parser::try_parse(&str_lit.value()) + .map_err(|e| Error::UuidParse(str_lit, e.into_err()))?; let tokens = bytes .iter() diff --git a/tests/ui/compile_fail/invalid_parse.stderr b/tests/ui/compile_fail/invalid_parse.stderr index 7fd8a0a7..b6304949 100644 --- a/tests/ui/compile_fail/invalid_parse.stderr +++ b/tests/ui/compile_fail/invalid_parse.stderr @@ -1,8 +1,10 @@ error: invalid length: expected length 32 for simple format, found 0 - --> tests/ui/compile_fail/invalid_parse.rs:3:23 + --> tests/ui/compile_fail/invalid_parse.rs:3:17 | 3 | const _: Uuid = uuid!(""); - | ^^ + | ^^^^^^^^^ + | + = note: this error originates in the macro `uuid` (in Nightly builds, run with -Z macro-backtrace for more info) error: invalid character: expected an optional prefix of `urn:uuid:` followed by [0-9a-zA-Z], found `!` at 1 --> tests/ui/compile_fail/invalid_parse.rs:4:24 @@ -29,16 +31,20 @@ error: invalid character: expected an optional prefix of `urn:uuid:` followed by | ^ error: invalid group count: expected 5, found 4 - --> tests/ui/compile_fail/invalid_parse.rs:8:23 + --> tests/ui/compile_fail/invalid_parse.rs:8:17 | 8 | const _: Uuid = uuid!("F9168C5E-CEB2-4faa-B6BFF329BF39FA1E4"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the macro `uuid` (in Nightly builds, run with -Z macro-backtrace for more info) error: invalid group count: expected 5, found 3 - --> tests/ui/compile_fail/invalid_parse.rs:9:23 + --> tests/ui/compile_fail/invalid_parse.rs:9:17 | 9 | const _: Uuid = uuid!("F9168C5E-CEB2-4faa"); - | ^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the macro `uuid` (in Nightly builds, run with -Z macro-backtrace for more info) error: invalid character: expected an optional prefix of `urn:uuid:` followed by [0-9a-zA-Z], found `X` at 19 --> tests/ui/compile_fail/invalid_parse.rs:10:42 @@ -59,10 +65,12 @@ error: invalid group length in group 4: expected 12, found 8 | ^^^^^^^^ error: invalid length: expected length 32 for simple format, found 33 - --> tests/ui/compile_fail/invalid_parse.rs:13:23 + --> tests/ui/compile_fail/invalid_parse.rs:13:17 | 13 | const _: Uuid = uuid!("67e5504410b1426f9247bb680e5fe0c88"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the macro `uuid` (in Nightly builds, run with -Z macro-backtrace for more info) error: invalid character: expected an optional prefix of `urn:uuid:` followed by [0-9a-zA-Z], found `g` at 32 --> tests/ui/compile_fail/invalid_parse.rs:14:55 @@ -71,10 +79,12 @@ error: invalid character: expected an optional prefix of `urn:uuid:` followed by | ^ error: invalid length: expected length 32 for simple format, found 31 - --> tests/ui/compile_fail/invalid_parse.rs:18:23 + --> tests/ui/compile_fail/invalid_parse.rs:18:17 | 18 | const _: Uuid = uuid!("67e5504410b1426f9247bb680e5fe0c"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the macro `uuid` (in Nightly builds, run with -Z macro-backtrace for more info) error: invalid character: expected an optional prefix of `urn:uuid:` followed by [0-9a-zA-Z], found `X` at 7 --> tests/ui/compile_fail/invalid_parse.rs:19:30 @@ -83,10 +93,12 @@ error: invalid character: expected an optional prefix of `urn:uuid:` followed by | ^ error: invalid group count: expected 5, found 2 - --> tests/ui/compile_fail/invalid_parse.rs:20:23 + --> tests/ui/compile_fail/invalid_parse.rs:20:17 | 20 | const _: Uuid = uuid!("67e550-4105b1426f9247bb680e5fe0c"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the macro `uuid` (in Nightly builds, run with -Z macro-backtrace for more info) error: invalid group length in group 3: expected 4, found 5 --> tests/ui/compile_fail/invalid_parse.rs:21:43 @@ -113,10 +125,12 @@ error: invalid group length in group 4: expected 12, found 8 | ^^^^^^^^ error: invalid group count: expected 5, found 4 - --> tests/ui/compile_fail/invalid_parse.rs:27:23 + --> tests/ui/compile_fail/invalid_parse.rs:27:17 | 27 | const _: Uuid = uuid!("F9168C5E-CEB2-4faa-B6BFF329BF39FA1E4"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the macro `uuid` (in Nightly builds, run with -Z macro-backtrace for more info) error: invalid character: expected an optional prefix of `urn:uuid:` followed by [0-9a-zA-Z], found `G` at 30 --> tests/ui/compile_fail/invalid_parse.rs:28:53 @@ -143,10 +157,12 @@ error: invalid character: expected an optional prefix of `urn:uuid:` followed by | ^ error: invalid group count: expected 5, found 2 - --> tests/ui/compile_fail/invalid_parse.rs:35:23 + --> tests/ui/compile_fail/invalid_parse.rs:35:17 | 35 | const _: Uuid = uuid!("67e550-4105b1426f9247bb680e5fe0c"); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: this error originates in the macro `uuid` (in Nightly builds, run with -Z macro-backtrace for more info) error: invalid character: expected an optional prefix of `urn:uuid:` followed by [0-9a-zA-Z], found `岡` at 7 --> tests/ui/compile_fail/invalid_parse.rs:37:30 @@ -167,10 +183,12 @@ error: invalid character: expected an optional prefix of `urn:uuid:` followed by | ^^ error: invalid length: expected length 32 for simple format, found 4 - --> tests/ui/compile_fail/invalid_parse.rs:42:23 + --> tests/ui/compile_fail/invalid_parse.rs:42:17 | 42 | const _: Uuid = uuid!("F916"); - | ^^^^^^ + | ^^^^^^^^^^^^^ + | + = note: this error originates in the macro `uuid` (in Nightly builds, run with -Z macro-backtrace for more info) error: invalid character: expected an optional prefix of `urn:uuid:` followed by [0-9a-zA-Z], found `x` at 5 --> tests/ui/compile_fail/invalid_parse.rs:43:28