update and add a few tests

This commit is contained in:
Deadbeef 2023-03-06 07:10:23 +00:00
parent 8ff3903643
commit 76d1f93896
11 changed files with 48 additions and 3 deletions

View File

@ -1814,7 +1814,7 @@ pub enum LitKind {
/// A byte string (`b"foo"`). Not stored as a symbol because it might be
/// non-utf8, and symbols only allow utf8 strings.
ByteStr(Lrc<[u8]>, StrStyle),
/// A C String (`c"foo"`).
/// A C String (`c"foo"`). Guaranteed only have `\0` in the end.
CStr(Lrc<[u8]>, StrStyle),
/// A byte char (`b'f'`).
Byte(u8),

View File

@ -181,7 +181,7 @@ impl LitKind {
}
});
error?;
buf.push(b'\0');
buf.push(0);
LitKind::CStr(buf.into(), StrStyle::Cooked)
}
token::CStrRaw(n) => {
@ -204,7 +204,7 @@ impl LitKind {
}
});
error?;
buf.push(b'\0');
buf.push(0);
LitKind::CStr(buf.into(), StrStyle::Raw(n))
}
token::Err => LitKind::Err,

View File

@ -1,3 +1,4 @@
use ast::token;
use rustc_ast as ast;
use rustc_ast::visit::{self, AssocCtxt, FnCtxt, FnKind, Visitor};
use rustc_ast::{attr, AssocConstraint, AssocConstraintKind, NodeId};

View File

@ -313,6 +313,8 @@ declare_features! (
(active, async_fn_in_trait, "1.66.0", Some(91611), None),
/// Treat `extern "C"` function as nounwind.
(active, c_unwind, "1.52.0", Some(74990), None),
/// Allows `c"foo"` literals.
(active, c_str_literals, "CURRENT_RUSTC_VERSION", Some(105723), None),
/// Allows using C-variadics.
(active, c_variadic, "1.34.0", Some(44930), None),
/// Allows the use of `#[cfg(sanitize = "option")]`; set when -Zsanitizer is used.

View File

@ -146,6 +146,12 @@ pub(crate) fn lit_to_mir_constant<'tcx>(
let id = tcx.allocate_bytes(data);
ConstValue::Scalar(Scalar::from_pointer(id.into(), &tcx))
}
(ast::LitKind::CStr(data, _), ty::Ref(_, inner_ty, _)) if matches!(inner_ty.kind(), ty::Adt(def, _) if Some(def.did()) == tcx.lang_items().c_str()) =>
{
let allocation = Allocation::from_bytes_byte_aligned_immutable(data as &[u8]);
let allocation = tcx.mk_const_alloc(allocation);
ConstValue::Slice { data: allocation, start: 0, end: data.len() }
}
(ast::LitKind::Byte(n), ty::Uint(ty::UintTy::U8)) => {
ConstValue::Scalar(Scalar::from_uint(*n, Size::from_bytes(1)))
}

View File

@ -441,6 +441,7 @@ symbols! {
bridge,
bswap,
c_str,
c_str_literals,
c_unwind,
c_variadic,
call,

View File

@ -0,0 +1,7 @@
// run-pass
#![feature(c_str_literals)]
fn main() {
assert_eq!(b"test\0", c"test".to_bytes_with_nul());
}

View File

@ -0,0 +1,7 @@
fn main() {
c"foo";
//~^ ERROR: `c".."` literals are experimental
m!(c"test");
//~^ ERROR: `c".."` literals are experimental
}

View File

@ -0,0 +1,21 @@
error[E0658]: `c".."` literals are experimental
--> $DIR/gate.rs:8: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:11: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.