Auto merge of #117472 - jmillikin:stable-c-str-literals, r=Nilstrieb
Stabilize C string literals RFC: https://rust-lang.github.io/rfcs/3348-c-str-literal.html Tracking issue: https://github.com/rust-lang/rust/issues/105723 Documentation PR (reference manual): https://github.com/rust-lang/reference/pull/1423 # Stabilization report Stabilizes C string and raw C string literals (`c"..."` and `cr#"..."#`), which are expressions of type [`&CStr`](https://doc.rust-lang.org/stable/core/ffi/struct.CStr.html). Both new literals require Rust edition 2021 or later. ```rust const HELLO: &core::ffi::CStr = c"Hello, world!"; ``` C strings may contain any byte other than `NUL` (`b'\x00'`), and their in-memory representation is guaranteed to end with `NUL`. ## Implementation Originally implemented by PR https://github.com/rust-lang/rust/pull/108801, which was reverted due to unintentional changes to lexer behavior in Rust editions < 2021. The current implementation landed in PR https://github.com/rust-lang/rust/pull/113476, which restricts C string literals to Rust edition >= 2021. ## Resolutions to open questions from the RFC * Adding C character literals (`c'.'`) of type `c_char` is not part of this feature. * Support for `c"..."` literals does not prevent `c'.'` literals from being added in the future. * C string literals should not be blocked on making `&CStr` a thin pointer. * It's possible to declare constant expressions of type `&'static CStr` in stable Rust (as of v1.59), so C string literals are not adding additional coupling on the internal representation of `CStr`. * The unstable `concat_bytes!` macro should not accept `c"..."` literals. * C strings have two equally valid `&[u8]` representations (with or without terminal `NUL`), so allowing them to be used in `concat_bytes!` would be ambiguous. * Adding a type to represent C strings containing valid UTF-8 is not part of this feature. * Support for a hypothetical `&Utf8CStr` may be explored in the future, should such a type be added to Rust.
This commit is contained in:
commit
63d16b5a98
19 changed files with 41 additions and 90 deletions
|
@ -515,7 +515,6 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
gate_all!(c_str_literals, "`c\"..\"` literals are experimental");
|
|
||||||
gate_all!(
|
gate_all!(
|
||||||
if_let_guard,
|
if_let_guard,
|
||||||
"`if let` guards are experimental",
|
"`if let` guards are experimental",
|
||||||
|
|
|
@ -19,8 +19,8 @@ fn invalid_type_err(
|
||||||
let snippet = cx.sess.source_map().span_to_snippet(span).ok();
|
let snippet = cx.sess.source_map().span_to_snippet(span).ok();
|
||||||
match ast::LitKind::from_token_lit(token_lit) {
|
match ast::LitKind::from_token_lit(token_lit) {
|
||||||
Ok(ast::LitKind::CStr(_, _)) => {
|
Ok(ast::LitKind::CStr(_, _)) => {
|
||||||
// FIXME(c_str_literals): should concatenation of C string literals
|
// Avoid ambiguity in handling of terminal `NUL` by refusing to
|
||||||
// include the null bytes in the end?
|
// concatenate C string literals as bytes.
|
||||||
cx.emit_err(errors::ConcatCStrLit { span: span });
|
cx.emit_err(errors::ConcatCStrLit { span: span });
|
||||||
}
|
}
|
||||||
Ok(ast::LitKind::Char(_)) => {
|
Ok(ast::LitKind::Char(_)) => {
|
||||||
|
|
|
@ -77,6 +77,8 @@ declare_features! (
|
||||||
(accepted, bindings_after_at, "1.56.0", Some(65490), None),
|
(accepted, bindings_after_at, "1.56.0", Some(65490), None),
|
||||||
/// Allows empty structs and enum variants with braces.
|
/// Allows empty structs and enum variants with braces.
|
||||||
(accepted, braced_empty_structs, "1.8.0", Some(29720), None),
|
(accepted, braced_empty_structs, "1.8.0", Some(29720), None),
|
||||||
|
/// Allows `c"foo"` literals.
|
||||||
|
(accepted, c_str_literals, "CURRENT_RUSTC_VERSION", Some(105723), None),
|
||||||
/// Allows `#[cfg_attr(predicate, multiple, attributes, here)]`.
|
/// Allows `#[cfg_attr(predicate, multiple, attributes, here)]`.
|
||||||
(accepted, cfg_attr_multi, "1.33.0", Some(54881), None),
|
(accepted, cfg_attr_multi, "1.33.0", Some(54881), None),
|
||||||
/// Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests.
|
/// Allows the use of `#[cfg(doctest)]`, set when rustdoc is collecting doctests.
|
||||||
|
|
|
@ -354,8 +354,6 @@ declare_features! (
|
||||||
(unstable, async_fn_track_caller, "1.73.0", Some(110011), None),
|
(unstable, async_fn_track_caller, "1.73.0", Some(110011), None),
|
||||||
/// Allows builtin # foo() syntax
|
/// Allows builtin # foo() syntax
|
||||||
(unstable, builtin_syntax, "1.71.0", Some(110680), None),
|
(unstable, builtin_syntax, "1.71.0", Some(110680), None),
|
||||||
/// Allows `c"foo"` literals.
|
|
||||||
(unstable, c_str_literals, "1.71.0", Some(105723), None),
|
|
||||||
/// Treat `extern "C"` function as nounwind.
|
/// Treat `extern "C"` function as nounwind.
|
||||||
(unstable, c_unwind, "1.52.0", Some(74990), None),
|
(unstable, c_unwind, "1.52.0", Some(74990), None),
|
||||||
/// Allows using C-variadics.
|
/// Allows using C-variadics.
|
||||||
|
|
|
@ -223,9 +223,6 @@ impl<'a> StringReader<'a> {
|
||||||
rustc_lexer::TokenKind::Literal { kind, suffix_start } => {
|
rustc_lexer::TokenKind::Literal { kind, suffix_start } => {
|
||||||
let suffix_start = start + BytePos(suffix_start);
|
let suffix_start = start + BytePos(suffix_start);
|
||||||
let (kind, symbol) = self.cook_lexer_literal(start, suffix_start, kind);
|
let (kind, symbol) = self.cook_lexer_literal(start, suffix_start, kind);
|
||||||
if let token::LitKind::CStr | token::LitKind::CStrRaw(_) = kind {
|
|
||||||
self.sess.gated_spans.gate(sym::c_str_literals, self.mk_sp(start, self.pos));
|
|
||||||
}
|
|
||||||
let suffix = if suffix_start < self.pos {
|
let suffix = if suffix_start < self.pos {
|
||||||
let string = self.str_from(suffix_start);
|
let string = self.str_from(suffix_start);
|
||||||
if string == "_" {
|
if string == "_" {
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#![allow(clippy::needless_raw_string_hashes, clippy::no_effect, unused)]
|
#![allow(clippy::needless_raw_string_hashes, clippy::no_effect, unused)]
|
||||||
#![warn(clippy::needless_raw_strings)]
|
#![warn(clippy::needless_raw_strings)]
|
||||||
#![feature(c_str_literals)]
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
"aaa";
|
"aaa";
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#![allow(clippy::needless_raw_string_hashes, clippy::no_effect, unused)]
|
#![allow(clippy::needless_raw_string_hashes, clippy::no_effect, unused)]
|
||||||
#![warn(clippy::needless_raw_strings)]
|
#![warn(clippy::needless_raw_strings)]
|
||||||
#![feature(c_str_literals)]
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
r#"aaa"#;
|
r#"aaa"#;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: unnecessary raw string literal
|
error: unnecessary raw string literal
|
||||||
--> $DIR/needless_raw_string.rs:6:5
|
--> $DIR/needless_raw_string.rs:5:5
|
||||||
|
|
|
|
||||||
LL | r#"aaa"#;
|
LL | r#"aaa"#;
|
||||||
| ^^^^^^^^
|
| ^^^^^^^^
|
||||||
|
@ -13,7 +13,7 @@ LL + "aaa";
|
||||||
|
|
|
|
||||||
|
|
||||||
error: unnecessary raw string literal
|
error: unnecessary raw string literal
|
||||||
--> $DIR/needless_raw_string.rs:9:5
|
--> $DIR/needless_raw_string.rs:8:5
|
||||||
|
|
|
|
||||||
LL | br#"aaa"#;
|
LL | br#"aaa"#;
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
@ -25,7 +25,7 @@ LL + b"aaa";
|
||||||
|
|
|
|
||||||
|
|
||||||
error: unnecessary raw string literal
|
error: unnecessary raw string literal
|
||||||
--> $DIR/needless_raw_string.rs:12:5
|
--> $DIR/needless_raw_string.rs:11:5
|
||||||
|
|
|
|
||||||
LL | cr#"aaa"#;
|
LL | cr#"aaa"#;
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
@ -37,7 +37,7 @@ LL + c"aaa";
|
||||||
|
|
|
|
||||||
|
|
||||||
error: unnecessary raw string literal
|
error: unnecessary raw string literal
|
||||||
--> $DIR/needless_raw_string.rs:16:5
|
--> $DIR/needless_raw_string.rs:15:5
|
||||||
|
|
|
|
||||||
LL | / r#"
|
LL | / r#"
|
||||||
LL | | a
|
LL | | a
|
||||||
|
@ -56,7 +56,7 @@ LL ~ ";
|
||||||
|
|
|
|
||||||
|
|
||||||
error: unnecessary raw string literal
|
error: unnecessary raw string literal
|
||||||
--> $DIR/needless_raw_string.rs:22:5
|
--> $DIR/needless_raw_string.rs:21:5
|
||||||
|
|
|
|
||||||
LL | r"no hashes";
|
LL | r"no hashes";
|
||||||
| ^^^^^^^^^^^^
|
| ^^^^^^^^^^^^
|
||||||
|
@ -68,7 +68,7 @@ LL + "no hashes";
|
||||||
|
|
|
|
||||||
|
|
||||||
error: unnecessary raw string literal
|
error: unnecessary raw string literal
|
||||||
--> $DIR/needless_raw_string.rs:23:5
|
--> $DIR/needless_raw_string.rs:22:5
|
||||||
|
|
|
|
||||||
LL | br"no hashes";
|
LL | br"no hashes";
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
@ -80,7 +80,7 @@ LL + b"no hashes";
|
||||||
|
|
|
|
||||||
|
|
||||||
error: unnecessary raw string literal
|
error: unnecessary raw string literal
|
||||||
--> $DIR/needless_raw_string.rs:24:5
|
--> $DIR/needless_raw_string.rs:23:5
|
||||||
|
|
|
|
||||||
LL | cr"no hashes";
|
LL | cr"no hashes";
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#![allow(clippy::no_effect, unused)]
|
#![allow(clippy::no_effect, unused)]
|
||||||
#![warn(clippy::needless_raw_string_hashes)]
|
#![warn(clippy::needless_raw_string_hashes)]
|
||||||
#![feature(c_str_literals)]
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
r"\aaa";
|
r"\aaa";
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
#![allow(clippy::no_effect, unused)]
|
#![allow(clippy::no_effect, unused)]
|
||||||
#![warn(clippy::needless_raw_string_hashes)]
|
#![warn(clippy::needless_raw_string_hashes)]
|
||||||
#![feature(c_str_literals)]
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
r#"\aaa"#;
|
r#"\aaa"#;
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
error: unnecessary hashes around raw string literal
|
error: unnecessary hashes around raw string literal
|
||||||
--> $DIR/needless_raw_string_hashes.rs:6:5
|
--> $DIR/needless_raw_string_hashes.rs:5:5
|
||||||
|
|
|
|
||||||
LL | r#"\aaa"#;
|
LL | r#"\aaa"#;
|
||||||
| ^^^^^^^^^
|
| ^^^^^^^^^
|
||||||
|
@ -13,7 +13,7 @@ LL + r"\aaa";
|
||||||
|
|
|
|
||||||
|
|
||||||
error: unnecessary hashes around raw string literal
|
error: unnecessary hashes around raw string literal
|
||||||
--> $DIR/needless_raw_string_hashes.rs:7:5
|
--> $DIR/needless_raw_string_hashes.rs:6:5
|
||||||
|
|
|
|
||||||
LL | r##"Hello "world"!"##;
|
LL | r##"Hello "world"!"##;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -25,7 +25,7 @@ LL + r#"Hello "world"!"#;
|
||||||
|
|
|
|
||||||
|
|
||||||
error: unnecessary hashes around raw string literal
|
error: unnecessary hashes around raw string literal
|
||||||
--> $DIR/needless_raw_string_hashes.rs:8:5
|
--> $DIR/needless_raw_string_hashes.rs:7:5
|
||||||
|
|
|
|
||||||
LL | r######" "### "## "# "######;
|
LL | r######" "### "## "# "######;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -37,7 +37,7 @@ LL + r####" "### "## "# "####;
|
||||||
|
|
|
|
||||||
|
|
||||||
error: unnecessary hashes around raw string literal
|
error: unnecessary hashes around raw string literal
|
||||||
--> $DIR/needless_raw_string_hashes.rs:9:5
|
--> $DIR/needless_raw_string_hashes.rs:8:5
|
||||||
|
|
|
|
||||||
LL | r######" "aa" "# "## "######;
|
LL | r######" "aa" "# "## "######;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -49,7 +49,7 @@ LL + r###" "aa" "# "## "###;
|
||||||
|
|
|
|
||||||
|
|
||||||
error: unnecessary hashes around raw string literal
|
error: unnecessary hashes around raw string literal
|
||||||
--> $DIR/needless_raw_string_hashes.rs:10:5
|
--> $DIR/needless_raw_string_hashes.rs:9:5
|
||||||
|
|
|
|
||||||
LL | br#"\aaa"#;
|
LL | br#"\aaa"#;
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
@ -61,7 +61,7 @@ LL + br"\aaa";
|
||||||
|
|
|
|
||||||
|
|
||||||
error: unnecessary hashes around raw string literal
|
error: unnecessary hashes around raw string literal
|
||||||
--> $DIR/needless_raw_string_hashes.rs:11:5
|
--> $DIR/needless_raw_string_hashes.rs:10:5
|
||||||
|
|
|
|
||||||
LL | br##"Hello "world"!"##;
|
LL | br##"Hello "world"!"##;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -73,7 +73,7 @@ LL + br#"Hello "world"!"#;
|
||||||
|
|
|
|
||||||
|
|
||||||
error: unnecessary hashes around raw string literal
|
error: unnecessary hashes around raw string literal
|
||||||
--> $DIR/needless_raw_string_hashes.rs:12:5
|
--> $DIR/needless_raw_string_hashes.rs:11:5
|
||||||
|
|
|
|
||||||
LL | br######" "### "## "# "######;
|
LL | br######" "### "## "# "######;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -85,7 +85,7 @@ LL + br####" "### "## "# "####;
|
||||||
|
|
|
|
||||||
|
|
||||||
error: unnecessary hashes around raw string literal
|
error: unnecessary hashes around raw string literal
|
||||||
--> $DIR/needless_raw_string_hashes.rs:13:5
|
--> $DIR/needless_raw_string_hashes.rs:12:5
|
||||||
|
|
|
|
||||||
LL | br######" "aa" "# "## "######;
|
LL | br######" "aa" "# "## "######;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -97,7 +97,7 @@ LL + br###" "aa" "# "## "###;
|
||||||
|
|
|
|
||||||
|
|
||||||
error: unnecessary hashes around raw string literal
|
error: unnecessary hashes around raw string literal
|
||||||
--> $DIR/needless_raw_string_hashes.rs:14:5
|
--> $DIR/needless_raw_string_hashes.rs:13:5
|
||||||
|
|
|
|
||||||
LL | cr#"\aaa"#;
|
LL | cr#"\aaa"#;
|
||||||
| ^^^^^^^^^^
|
| ^^^^^^^^^^
|
||||||
|
@ -109,7 +109,7 @@ LL + cr"\aaa";
|
||||||
|
|
|
|
||||||
|
|
||||||
error: unnecessary hashes around raw string literal
|
error: unnecessary hashes around raw string literal
|
||||||
--> $DIR/needless_raw_string_hashes.rs:15:5
|
--> $DIR/needless_raw_string_hashes.rs:14:5
|
||||||
|
|
|
|
||||||
LL | cr##"Hello "world"!"##;
|
LL | cr##"Hello "world"!"##;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -121,7 +121,7 @@ LL + cr#"Hello "world"!"#;
|
||||||
|
|
|
|
||||||
|
|
||||||
error: unnecessary hashes around raw string literal
|
error: unnecessary hashes around raw string literal
|
||||||
--> $DIR/needless_raw_string_hashes.rs:16:5
|
--> $DIR/needless_raw_string_hashes.rs:15:5
|
||||||
|
|
|
|
||||||
LL | cr######" "### "## "# "######;
|
LL | cr######" "### "## "# "######;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -133,7 +133,7 @@ LL + cr####" "### "## "# "####;
|
||||||
|
|
|
|
||||||
|
|
||||||
error: unnecessary hashes around raw string literal
|
error: unnecessary hashes around raw string literal
|
||||||
--> $DIR/needless_raw_string_hashes.rs:17:5
|
--> $DIR/needless_raw_string_hashes.rs:16:5
|
||||||
|
|
|
|
||||||
LL | cr######" "aa" "# "## "######;
|
LL | cr######" "aa" "# "## "######;
|
||||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
@ -145,7 +145,7 @@ LL + cr###" "aa" "# "## "###;
|
||||||
|
|
|
|
||||||
|
|
||||||
error: unnecessary hashes around raw string literal
|
error: unnecessary hashes around raw string literal
|
||||||
--> $DIR/needless_raw_string_hashes.rs:19:5
|
--> $DIR/needless_raw_string_hashes.rs:18:5
|
||||||
|
|
|
|
||||||
LL | / r#"
|
LL | / r#"
|
||||||
LL | | \a
|
LL | | \a
|
||||||
|
@ -164,7 +164,7 @@ LL ~ ";
|
||||||
|
|
|
|
||||||
|
|
||||||
error: unnecessary hashes around raw string literal
|
error: unnecessary hashes around raw string literal
|
||||||
--> $DIR/needless_raw_string_hashes.rs:25:5
|
--> $DIR/needless_raw_string_hashes.rs:24:5
|
||||||
|
|
|
|
||||||
LL | r###"rust"###;
|
LL | r###"rust"###;
|
||||||
| ^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^
|
||||||
|
@ -176,7 +176,7 @@ LL + r"rust";
|
||||||
|
|
|
|
||||||
|
|
||||||
error: unnecessary hashes around raw string literal
|
error: unnecessary hashes around raw string literal
|
||||||
--> $DIR/needless_raw_string_hashes.rs:26:5
|
--> $DIR/needless_raw_string_hashes.rs:25:5
|
||||||
|
|
|
|
||||||
LL | r#"hello world"#;
|
LL | r#"hello world"#;
|
||||||
| ^^^^^^^^^^^^^^^^
|
| ^^^^^^^^^^^^^^^^
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
// check-pass
|
// check-pass
|
||||||
// edition: 2021
|
// edition: 2021
|
||||||
#![feature(c_str_literals)]
|
|
||||||
|
|
||||||
// aux-build: print-tokens.rs
|
// aux-build: print-tokens.rs
|
||||||
extern crate print_tokens;
|
extern crate print_tokens;
|
||||||
|
|
|
@ -3,91 +3,91 @@ TokenStream [
|
||||||
kind: Integer,
|
kind: Integer,
|
||||||
symbol: "1",
|
symbol: "1",
|
||||||
suffix: None,
|
suffix: None,
|
||||||
span: #0 bytes(172..173),
|
span: #0 bytes(144..145),
|
||||||
},
|
},
|
||||||
Literal {
|
Literal {
|
||||||
kind: Integer,
|
kind: Integer,
|
||||||
symbol: "17",
|
symbol: "17",
|
||||||
suffix: Some("u8"),
|
suffix: Some("u8"),
|
||||||
span: #0 bytes(182..186),
|
span: #0 bytes(154..158),
|
||||||
},
|
},
|
||||||
Literal {
|
Literal {
|
||||||
kind: Float,
|
kind: Float,
|
||||||
symbol: "42.",
|
symbol: "42.",
|
||||||
suffix: None,
|
suffix: None,
|
||||||
span: #0 bytes(195..198),
|
span: #0 bytes(167..170),
|
||||||
},
|
},
|
||||||
Literal {
|
Literal {
|
||||||
kind: Float,
|
kind: Float,
|
||||||
symbol: "3.14",
|
symbol: "3.14",
|
||||||
suffix: Some("f32"),
|
suffix: Some("f32"),
|
||||||
span: #0 bytes(207..214),
|
span: #0 bytes(179..186),
|
||||||
},
|
},
|
||||||
Literal {
|
Literal {
|
||||||
kind: Byte,
|
kind: Byte,
|
||||||
symbol: "a",
|
symbol: "a",
|
||||||
suffix: None,
|
suffix: None,
|
||||||
span: #0 bytes(223..227),
|
span: #0 bytes(195..199),
|
||||||
},
|
},
|
||||||
Literal {
|
Literal {
|
||||||
kind: Byte,
|
kind: Byte,
|
||||||
symbol: "\xFF",
|
symbol: "\xFF",
|
||||||
suffix: None,
|
suffix: None,
|
||||||
span: #0 bytes(236..243),
|
span: #0 bytes(208..215),
|
||||||
},
|
},
|
||||||
Literal {
|
Literal {
|
||||||
kind: Char,
|
kind: Char,
|
||||||
symbol: "c",
|
symbol: "c",
|
||||||
suffix: None,
|
suffix: None,
|
||||||
span: #0 bytes(252..255),
|
span: #0 bytes(224..227),
|
||||||
},
|
},
|
||||||
Literal {
|
Literal {
|
||||||
kind: Char,
|
kind: Char,
|
||||||
symbol: "\x32",
|
symbol: "\x32",
|
||||||
suffix: None,
|
suffix: None,
|
||||||
span: #0 bytes(264..270),
|
span: #0 bytes(236..242),
|
||||||
},
|
},
|
||||||
Literal {
|
Literal {
|
||||||
kind: Str,
|
kind: Str,
|
||||||
symbol: "\\"str\\"",
|
symbol: "\\"str\\"",
|
||||||
suffix: None,
|
suffix: None,
|
||||||
span: #0 bytes(279..288),
|
span: #0 bytes(251..260),
|
||||||
},
|
},
|
||||||
Literal {
|
Literal {
|
||||||
kind: StrRaw(1),
|
kind: StrRaw(1),
|
||||||
symbol: "\"raw\" str",
|
symbol: "\"raw\" str",
|
||||||
suffix: None,
|
suffix: None,
|
||||||
span: #0 bytes(297..311),
|
span: #0 bytes(269..283),
|
||||||
},
|
},
|
||||||
Literal {
|
Literal {
|
||||||
kind: StrRaw(3),
|
kind: StrRaw(3),
|
||||||
symbol: "very ##\"raw\"## str",
|
symbol: "very ##\"raw\"## str",
|
||||||
suffix: None,
|
suffix: None,
|
||||||
span: #0 bytes(320..347),
|
span: #0 bytes(292..319),
|
||||||
},
|
},
|
||||||
Literal {
|
Literal {
|
||||||
kind: ByteStr,
|
kind: ByteStr,
|
||||||
symbol: "\\"byte\\" str",
|
symbol: "\\"byte\\" str",
|
||||||
suffix: None,
|
suffix: None,
|
||||||
span: #0 bytes(356..371),
|
span: #0 bytes(328..343),
|
||||||
},
|
},
|
||||||
Literal {
|
Literal {
|
||||||
kind: ByteStrRaw(1),
|
kind: ByteStrRaw(1),
|
||||||
symbol: "\"raw\" \"byte\" str",
|
symbol: "\"raw\" \"byte\" str",
|
||||||
suffix: None,
|
suffix: None,
|
||||||
span: #0 bytes(380..402),
|
span: #0 bytes(352..374),
|
||||||
},
|
},
|
||||||
Literal {
|
Literal {
|
||||||
kind: CStr,
|
kind: CStr,
|
||||||
symbol: "\\"c\\" str",
|
symbol: "\\"c\\" str",
|
||||||
suffix: None,
|
suffix: None,
|
||||||
span: #0 bytes(411..423),
|
span: #0 bytes(383..395),
|
||||||
},
|
},
|
||||||
Literal {
|
Literal {
|
||||||
kind: CStrRaw(1),
|
kind: CStrRaw(1),
|
||||||
symbol: "\"raw\" \"c\" str",
|
symbol: "\"raw\" \"c\" str",
|
||||||
suffix: None,
|
suffix: None,
|
||||||
span: #0 bytes(432..451),
|
span: #0 bytes(404..423),
|
||||||
},
|
},
|
||||||
]
|
]
|
||||||
1
|
1
|
||||||
|
|
|
@ -1,8 +1,6 @@
|
||||||
// run-pass
|
// run-pass
|
||||||
// edition: 2021
|
// edition: 2021
|
||||||
|
|
||||||
#![feature(c_str_literals)]
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
assert_eq!(b"test\0", c"test".to_bytes_with_nul());
|
assert_eq!(b"test\0", c"test".to_bytes_with_nul());
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,15 +0,0 @@
|
||||||
// gate-test-c_str_literals
|
|
||||||
// known-bug: #113333
|
|
||||||
// edition: 2021
|
|
||||||
|
|
||||||
macro_rules! m {
|
|
||||||
($t:tt) => {}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() {
|
|
||||||
c"foo";
|
|
||||||
// FIXME(c_str_literals): This should be ``c".."` literals are experimental`
|
|
||||||
|
|
||||||
m!(c"test");
|
|
||||||
// FIXME(c_str_literals): This should be ``c".."` literals are experimental`
|
|
||||||
}
|
|
|
@ -1,21 +0,0 @@
|
||||||
error[E0658]: `c".."` literals are experimental
|
|
||||||
--> $DIR/gate.rs:10:5
|
|
||||||
|
|
|
||||||
LL | c"foo";
|
|
||||||
| ^^^^^^
|
|
||||||
|
|
|
||||||
= note: see issue #105723 <https://github.com/rust-lang/rust/issues/105723> for more information
|
|
||||||
= help: add `#![feature(c_str_literals)]` to the crate attributes to enable
|
|
||||||
|
|
||||||
error[E0658]: `c".."` literals are experimental
|
|
||||||
--> $DIR/gate.rs:13:8
|
|
||||||
|
|
|
||||||
LL | m!(c"test");
|
|
||||||
| ^^^^^^^
|
|
||||||
|
|
|
||||||
= note: see issue #105723 <https://github.com/rust-lang/rust/issues/105723> for more information
|
|
||||||
= help: add `#![feature(c_str_literals)]` to the crate attributes to enable
|
|
||||||
|
|
||||||
error: aborting due to 2 previous errors
|
|
||||||
|
|
||||||
For more information about this error, try `rustc --explain E0658`.
|
|
Binary file not shown.
Binary file not shown.
|
@ -1,8 +1,6 @@
|
||||||
// run-pass
|
// run-pass
|
||||||
// edition: 2021
|
// edition: 2021
|
||||||
|
|
||||||
#![feature(c_str_literals)]
|
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
c"\xEF\x80🦀\u{1F980}".to_bytes_with_nul(),
|
c"\xEF\x80🦀\u{1F980}".to_bytes_with_nul(),
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue