diff options
| author | Dylan DPC <99973273+Dylan-DPC@users.noreply.github.com> | 2022-04-04 20:41:30 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-04-04 20:41:30 +0200 |
| commit | 2d1496a8f62afb3ff3b7e4233c2eb65593d89780 (patch) | |
| tree | bf97266ddece38bd6f7f9f1778664c1e9407e6bd | |
| parent | 98168925f6570a8d0292abd493cf20bde89c7663 (diff) | |
| parent | f383134acc48c97bbf2389aa62d51b9a51535482 (diff) | |
| download | rust-2d1496a8f62afb3ff3b7e4233c2eb65593d89780.tar.gz rust-2d1496a8f62afb3ff3b7e4233c2eb65593d89780.zip | |
Rollup merge of #95343 - dtolnay:literals, r=petrochenkov
Reduce unnecessary escaping in proc_macro::Literal::character/string
I noticed that https://doc.rust-lang.org/proc_macro/struct.Literal.html#method.character is producing unreadable literals that make macro-expanded code unnecessarily hard to read. Since the proc macro server was using `escape_unicode()`, every char is escaped using `\u{…}` regardless of whether there is any need to do so. For example `Literal::character('=')` would previously produce `'\u{3d}'` which unnecessarily obscures the meaning when reading the macro-expanded code.
I've changed Literal::string also in this PR because `str`'s `Debug` impl is also smarter than just calling `escape_debug` on every char. For example `Literal::string("ferris's")` would previously produce `"ferris\'s"` but will now produce `"ferris's"`.
| -rw-r--r-- | compiler/rustc_expand/src/proc_macro_server.rs | 16 | ||||
| -rw-r--r-- | src/test/ui/proc-macro/auxiliary/api/parse.rs | 11 | ||||
| -rw-r--r-- | src/test/ui/proc-macro/quote-debug.stdout | 4 |
3 files changed, 21 insertions, 10 deletions
diff --git a/compiler/rustc_expand/src/proc_macro_server.rs b/compiler/rustc_expand/src/proc_macro_server.rs index bfdf99762f5..20351070f71 100644 --- a/compiler/rustc_expand/src/proc_macro_server.rs +++ b/compiler/rustc_expand/src/proc_macro_server.rs @@ -658,16 +658,16 @@ impl server::Literal for Rustc<'_, '_> { self.lit(token::Float, Symbol::intern(n), Some(sym::f64)) } fn string(&mut self, string: &str) -> Self::Literal { - let mut escaped = String::new(); - for ch in string.chars() { - escaped.extend(ch.escape_debug()); - } - self.lit(token::Str, Symbol::intern(&escaped), None) + let quoted = format!("{:?}", string); + assert!(quoted.starts_with('"') && quoted.ends_with('"')); + let symbol = "ed[1..quoted.len() - 1]; + self.lit(token::Str, Symbol::intern(symbol), None) } fn character(&mut self, ch: char) -> Self::Literal { - let mut escaped = String::new(); - escaped.extend(ch.escape_unicode()); - self.lit(token::Char, Symbol::intern(&escaped), None) + let quoted = format!("{:?}", ch); + assert!(quoted.starts_with('\'') && quoted.ends_with('\'')); + let symbol = "ed[1..quoted.len() - 1]; + self.lit(token::Char, Symbol::intern(symbol), None) } fn byte_string(&mut self, bytes: &[u8]) -> Self::Literal { let string = bytes diff --git a/src/test/ui/proc-macro/auxiliary/api/parse.rs b/src/test/ui/proc-macro/auxiliary/api/parse.rs index 6186b941ef6..27391f83111 100644 --- a/src/test/ui/proc-macro/auxiliary/api/parse.rs +++ b/src/test/ui/proc-macro/auxiliary/api/parse.rs @@ -18,6 +18,17 @@ fn test_display_literal() { Literal::f64_unsuffixed(1e100).to_string(), "10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0", ); + + assert_eq!( + Literal::string("a \t ❤ ' \" \u{1}").to_string(), + "\"a \\t ❤ ' \\\" \\u{1}\"", + ); + assert_eq!(Literal::character('a').to_string(), "'a'"); + assert_eq!(Literal::character('\t').to_string(), "'\\t'"); + assert_eq!(Literal::character('❤').to_string(), "'❤'"); + assert_eq!(Literal::character('\'').to_string(), "'\\''"); + assert_eq!(Literal::character('"').to_string(), "'\"'"); + assert_eq!(Literal::character('\u{1}').to_string(), "'\\u{1}'"); } fn test_parse_literal() { diff --git a/src/test/ui/proc-macro/quote-debug.stdout b/src/test/ui/proc-macro/quote-debug.stdout index ec54851fcf9..d2cc5c6e2a3 100644 --- a/src/test/ui/proc-macro/quote-debug.stdout +++ b/src/test/ui/proc-macro/quote-debug.stdout @@ -22,7 +22,7 @@ fn main() { crate::Span::recover_proc_macro_span(0)))), crate::TokenStream::from(crate::TokenTree::Ident(crate::Ident::new("hello", crate::Span::recover_proc_macro_span(1)))), - crate::TokenStream::from(crate::TokenTree::Punct(crate::Punct::new('\u{3d}', + crate::TokenStream::from(crate::TokenTree::Punct(crate::Punct::new('=', crate::Spacing::Alone))), crate::TokenStream::from(crate::TokenTree::Literal({ let mut iter = @@ -35,7 +35,7 @@ fn main() { ::core::panicking::panic("internal error: entered unreachable code") } })), - crate::TokenStream::from(crate::TokenTree::Punct(crate::Punct::new('\u{3b}', + crate::TokenStream::from(crate::TokenTree::Punct(crate::Punct::new(';', crate::Spacing::Alone)))].iter().cloned().collect::<crate::TokenStream>() } const _: () = |
