|
43 | 43 | pub mod bridge;
|
44 | 44 |
|
45 | 45 | mod diagnostic;
|
| 46 | +mod escape; |
46 | 47 |
|
47 | 48 | #[unstable(feature = "proc_macro_diagnostic", issue = "54140")]
|
48 | 49 | pub use diagnostic::{Diagnostic, Level, MultiSpan};
|
49 | 50 |
|
| 51 | +use crate::escape::{escape_bytes, EscapeOptions}; |
50 | 52 | use std::ffi::CStr;
|
51 | 53 | use std::ops::{Range, RangeBounds};
|
52 | 54 | use std::path::PathBuf;
|
@@ -1356,40 +1358,61 @@ impl Literal {
|
1356 | 1358 | /// String literal.
|
1357 | 1359 | #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
1358 | 1360 | pub fn string(string: &str) -> Literal {
|
1359 |
| - let quoted = format!("{:?}", string); |
1360 |
| - assert!(quoted.starts_with('"') && quoted.ends_with('"')); |
1361 |
| - let symbol = "ed[1..quoted.len() - 1]; |
1362 |
| - Literal::new(bridge::LitKind::Str, symbol, None) |
| 1361 | + let escape = EscapeOptions { |
| 1362 | + escape_single_quote: false, |
| 1363 | + escape_double_quote: true, |
| 1364 | + escape_nonascii: false, |
| 1365 | + }; |
| 1366 | + let repr = escape_bytes(string.as_bytes(), escape); |
| 1367 | + Literal::new(bridge::LitKind::Str, &repr, None) |
1363 | 1368 | }
|
1364 | 1369 |
|
1365 | 1370 | /// Character literal.
|
1366 | 1371 | #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
1367 | 1372 | pub fn character(ch: char) -> Literal {
|
1368 |
| - let quoted = format!("{:?}", ch); |
1369 |
| - assert!(quoted.starts_with('\'') && quoted.ends_with('\'')); |
1370 |
| - let symbol = "ed[1..quoted.len() - 1]; |
1371 |
| - Literal::new(bridge::LitKind::Char, symbol, None) |
| 1373 | + let escape = EscapeOptions { |
| 1374 | + escape_single_quote: true, |
| 1375 | + escape_double_quote: false, |
| 1376 | + escape_nonascii: false, |
| 1377 | + }; |
| 1378 | + let repr = escape_bytes(ch.encode_utf8(&mut [0u8; 4]).as_bytes(), escape); |
| 1379 | + Literal::new(bridge::LitKind::Char, &repr, None) |
1372 | 1380 | }
|
1373 | 1381 |
|
1374 | 1382 | /// Byte character literal.
|
1375 | 1383 | #[stable(feature = "proc_macro_byte_character", since = "1.79.0")]
|
1376 | 1384 | pub fn byte_character(byte: u8) -> Literal {
|
1377 |
| - let string = [byte].escape_ascii().to_string(); |
1378 |
| - Literal::new(bridge::LitKind::Byte, &string, None) |
| 1385 | + let escape = EscapeOptions { |
| 1386 | + escape_single_quote: true, |
| 1387 | + escape_double_quote: false, |
| 1388 | + escape_nonascii: true, |
| 1389 | + }; |
| 1390 | + let repr = escape_bytes(&[byte], escape); |
| 1391 | + Literal::new(bridge::LitKind::Byte, &repr, None) |
1379 | 1392 | }
|
1380 | 1393 |
|
1381 | 1394 | /// Byte string literal.
|
1382 | 1395 | #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
|
1383 | 1396 | pub fn byte_string(bytes: &[u8]) -> Literal {
|
1384 |
| - let string = bytes.escape_ascii().to_string(); |
1385 |
| - Literal::new(bridge::LitKind::ByteStr, &string, None) |
| 1397 | + let escape = EscapeOptions { |
| 1398 | + escape_single_quote: false, |
| 1399 | + escape_double_quote: true, |
| 1400 | + escape_nonascii: true, |
| 1401 | + }; |
| 1402 | + let repr = escape_bytes(bytes, escape); |
| 1403 | + Literal::new(bridge::LitKind::ByteStr, &repr, None) |
1386 | 1404 | }
|
1387 | 1405 |
|
1388 | 1406 | /// C string literal.
|
1389 | 1407 | #[stable(feature = "proc_macro_c_str_literals", since = "1.79.0")]
|
1390 | 1408 | pub fn c_string(string: &CStr) -> Literal {
|
1391 |
| - let string = string.to_bytes().escape_ascii().to_string(); |
1392 |
| - Literal::new(bridge::LitKind::CStr, &string, None) |
| 1409 | + let escape = EscapeOptions { |
| 1410 | + escape_single_quote: false, |
| 1411 | + escape_double_quote: true, |
| 1412 | + escape_nonascii: false, |
| 1413 | + }; |
| 1414 | + let repr = escape_bytes(string.to_bytes(), escape); |
| 1415 | + Literal::new(bridge::LitKind::CStr, &repr, None) |
1393 | 1416 | }
|
1394 | 1417 |
|
1395 | 1418 | /// Returns the span encompassing this literal.
|
|
0 commit comments