about summary refs log tree commit diff
diff options
context:
space:
mode:
authornovafacing <rowanbhart@gmail.com>2024-01-16 13:27:58 -0800
committernovafacing <rowanbhart@gmail.com>2024-01-16 13:27:58 -0800
commitee007ab187dc3eb9587a787d1029c539d54710b0 (patch)
tree2c83c3b9b63d2018c13177c187616eaa25a76ef0
parente64f8495e73fbc3653b4bcb73268c58b9c4a0a0d (diff)
downloadrust-ee007ab187dc3eb9587a787d1029c539d54710b0.tar.gz
rust-ee007ab187dc3eb9587a787d1029c539d54710b0.zip
proc_macro_c_str_literals: Implement Literal::c_string constructor
-rw-r--r--library/proc_macro/src/lib.rs8
-rw-r--r--tests/ui/feature-gates/feature-gate-proc_macro_c_str_literals.rs11
-rw-r--r--tests/ui/feature-gates/feature-gate-proc_macro_c_str_literals.stderr13
-rw-r--r--tests/ui/proc-macro/auxiliary/api/mod.rs2
-rw-r--r--tests/ui/proc-macro/auxiliary/api/parse.rs7
-rw-r--r--tests/ui/proc-macro/test.rs1
6 files changed, 38 insertions, 4 deletions
diff --git a/library/proc_macro/src/lib.rs b/library/proc_macro/src/lib.rs
index 6e664a162df..ca83e2be5c1 100644
--- a/library/proc_macro/src/lib.rs
+++ b/library/proc_macro/src/lib.rs
@@ -45,6 +45,7 @@ mod diagnostic;
 #[unstable(feature = "proc_macro_diagnostic", issue = "54140")]
 pub use diagnostic::{Diagnostic, Level, MultiSpan};
 
+use std::ffi::CStr;
 use std::ops::{Range, RangeBounds};
 use std::path::PathBuf;
 use std::str::FromStr;
@@ -1351,6 +1352,13 @@ impl Literal {
         Literal::new(bridge::LitKind::ByteStr, &string, None)
     }
 
+    /// C string literal.
+    #[unstable(feature = "proc_macro_c_str_literals", issue = "119750")]
+    pub fn c_string(string: &CStr) -> Literal {
+        let string = string.to_bytes().escape_ascii().to_string();
+        Literal::new(bridge::LitKind::CStr, &string, None)
+    }
+
     /// Returns the span encompassing this literal.
     #[stable(feature = "proc_macro_lib2", since = "1.29.0")]
     pub fn span(&self) -> Span {
diff --git a/tests/ui/feature-gates/feature-gate-proc_macro_c_str_literals.rs b/tests/ui/feature-gates/feature-gate-proc_macro_c_str_literals.rs
new file mode 100644
index 00000000000..5554c813925
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-proc_macro_c_str_literals.rs
@@ -0,0 +1,11 @@
+// edition: 2021
+// force-host
+#![crate_type = "proc-macro"]
+
+extern crate proc_macro;
+
+use proc_macro::Literal;
+
+fn test() {
+    Literal::c_string(c"a"); //~ ERROR use of unstable library feature 'proc_macro_c_str_literals'
+}
diff --git a/tests/ui/feature-gates/feature-gate-proc_macro_c_str_literals.stderr b/tests/ui/feature-gates/feature-gate-proc_macro_c_str_literals.stderr
new file mode 100644
index 00000000000..9bba1d50ce3
--- /dev/null
+++ b/tests/ui/feature-gates/feature-gate-proc_macro_c_str_literals.stderr
@@ -0,0 +1,13 @@
+error[E0658]: use of unstable library feature 'proc_macro_c_str_literals'
+  --> $DIR/feature-gate-proc_macro_c_str_literals.rs:10:5
+   |
+LL |     Literal::c_string(c"a");
+   |     ^^^^^^^^^^^^^^^^^
+   |
+   = note: see issue #119750 <https://github.com/rust-lang/rust/issues/119750> for more information
+   = help: add `#![feature(proc_macro_c_str_literals)]` to the crate attributes to enable
+   = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
+
+error: aborting due to 1 previous error
+
+For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/proc-macro/auxiliary/api/mod.rs b/tests/ui/proc-macro/auxiliary/api/mod.rs
index 3bea5d75779..5a533b9e17e 100644
--- a/tests/ui/proc-macro/auxiliary/api/mod.rs
+++ b/tests/ui/proc-macro/auxiliary/api/mod.rs
@@ -1,10 +1,12 @@
 // force-host
 // no-prefer-dynamic
+// edition: 2021
 
 #![crate_type = "proc-macro"]
 #![crate_name = "proc_macro_api_tests"]
 #![feature(proc_macro_span)]
 #![feature(proc_macro_byte_character)]
+#![feature(proc_macro_c_str_literals)]
 #![deny(dead_code)] // catch if a test function is never called
 
 extern crate proc_macro;
diff --git a/tests/ui/proc-macro/auxiliary/api/parse.rs b/tests/ui/proc-macro/auxiliary/api/parse.rs
index 07c9f464961..801c616c804 100644
--- a/tests/ui/proc-macro/auxiliary/api/parse.rs
+++ b/tests/ui/proc-macro/auxiliary/api/parse.rs
@@ -19,10 +19,8 @@ fn test_display_literal() {
         "10000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000.0",
     );
 
-    assert_eq!(
-        Literal::string("a \t ❤ ' \" \u{1}").to_string(),
-        "\"a \\t ❤ ' \\\" \\u{1}\"",
-    );
+    assert_eq!(Literal::string("a \t ❤ ' \" \u{1}").to_string(), "\"a \\t ❤ ' \\\" \\u{1}\"",);
+    assert_eq!(Literal::c_string(c"\'\"\x7f\u{7fff}").to_string(), r#"c"\'\"\x7f\xe7\xbf\xbf""#);
     assert_eq!(Literal::character('a').to_string(), "'a'");
     assert_eq!(Literal::character('\t').to_string(), "'\\t'");
     assert_eq!(Literal::character('❤').to_string(), "'❤'");
@@ -41,6 +39,7 @@ fn test_parse_literal() {
     assert_eq!("b'a'".parse::<Literal>().unwrap().to_string(), "b'a'");
     assert_eq!("\"\n\"".parse::<Literal>().unwrap().to_string(), "\"\n\"");
     assert_eq!("b\"\"".parse::<Literal>().unwrap().to_string(), "b\"\"");
+    assert_eq!("c\"\"".parse::<Literal>().unwrap().to_string(), "c\"\"");
     assert_eq!("r##\"\"##".parse::<Literal>().unwrap().to_string(), "r##\"\"##");
     assert_eq!("10ulong".parse::<Literal>().unwrap().to_string(), "10ulong");
     assert_eq!("-10ulong".parse::<Literal>().unwrap().to_string(), "-10ulong");
diff --git a/tests/ui/proc-macro/test.rs b/tests/ui/proc-macro/test.rs
index c96aa73175f..2ec62072020 100644
--- a/tests/ui/proc-macro/test.rs
+++ b/tests/ui/proc-macro/test.rs
@@ -1,5 +1,6 @@
 // check-pass
 // aux-build:api/mod.rs
+// edition: 2021
 
 //! This is for everything that *would* be a #[test] inside of libproc_macro,
 //! except for the fact that proc_macro objects are not capable of existing