From abb181dfd9b9df22908ab08d7cfb46509295e2e6 Mon Sep 17 00:00:00 2001 From: Deadbeef Date: Fri, 10 Mar 2023 14:18:58 +0000 Subject: [PATCH] make it semantic error --- compiler/rustc_ast/src/util/literal.rs | 2 ++ compiler/rustc_ast_passes/src/feature_gate.rs | 1 + compiler/rustc_parse/src/lexer/mod.rs | 3 +++ compiler/rustc_session/messages.ftl | 2 ++ compiler/rustc_session/src/errors.rs | 15 ++++++++++++++- .../rfcs/rfc-3348-c-string-literals/no-nuls.rs | Bin 322 -> 570 bytes .../rfc-3348-c-string-literals/no-nuls.stderr | Bin 670 -> 674 bytes 7 files changed, 22 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_ast/src/util/literal.rs b/compiler/rustc_ast/src/util/literal.rs index cd3b163e3ac..15a54fe13d0 100644 --- a/compiler/rustc_ast/src/util/literal.rs +++ b/compiler/rustc_ast/src/util/literal.rs @@ -8,6 +8,7 @@ use rustc_lexer::unescape::{ }; use rustc_span::symbol::{kw, sym, Symbol}; use rustc_span::Span; +use std::ops::Range; use std::{ascii, fmt, str}; // Escapes a string, represented as a symbol. Reuses the original symbol, @@ -38,6 +39,7 @@ pub enum LitError { InvalidFloatSuffix, NonDecimalFloat(u32), IntTooLarge(u32), + NulInCStr(Range), } impl LitKind { diff --git a/compiler/rustc_ast_passes/src/feature_gate.rs b/compiler/rustc_ast_passes/src/feature_gate.rs index 17bcd24ee39..c4578ec4af1 100644 --- a/compiler/rustc_ast_passes/src/feature_gate.rs +++ b/compiler/rustc_ast_passes/src/feature_gate.rs @@ -572,6 +572,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) { } }; } + gate_all!(c_str_literals, "`c\"..\"` literals are experimental"); gate_all!( if_let_guard, "`if let` guards are experimental", diff --git a/compiler/rustc_parse/src/lexer/mod.rs b/compiler/rustc_parse/src/lexer/mod.rs index b2050780309..050f1898615 100644 --- a/compiler/rustc_parse/src/lexer/mod.rs +++ b/compiler/rustc_parse/src/lexer/mod.rs @@ -204,6 +204,9 @@ impl<'a> StringReader<'a> { rustc_lexer::TokenKind::Literal { kind, suffix_start } => { let suffix_start = start + BytePos(suffix_start); 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 string = self.str_from(suffix_start); if string == "_" { diff --git a/compiler/rustc_session/messages.ftl b/compiler/rustc_session/messages.ftl index ff53f22d43f..2420857e739 100644 --- a/compiler/rustc_session/messages.ftl +++ b/compiler/rustc_session/messages.ftl @@ -93,3 +93,5 @@ session_invalid_int_literal_width = invalid width `{$width}` for integer literal .help = valid widths are 8, 16, 32, 64 and 128 session_optimization_fuel_exhausted = optimization-fuel-exhausted: {$msg} + +session_nul_in_c_str = null characters in C string literals are not supported diff --git a/compiler/rustc_session/src/errors.rs b/compiler/rustc_session/src/errors.rs index bd32adbbdbb..22af74eb1d9 100644 --- a/compiler/rustc_session/src/errors.rs +++ b/compiler/rustc_session/src/errors.rs @@ -6,7 +6,7 @@ use rustc_ast::token; use rustc_ast::util::literal::LitError; use rustc_errors::{error_code, DiagnosticMessage, EmissionGuarantee, IntoDiagnostic, MultiSpan}; use rustc_macros::Diagnostic; -use rustc_span::{Span, Symbol}; +use rustc_span::{BytePos, Span, Symbol}; use rustc_target::spec::{SplitDebuginfo, StackProtector, TargetTriple}; #[derive(Diagnostic)] @@ -307,6 +307,13 @@ pub(crate) struct BinaryFloatLiteralNotSupported { pub span: Span, } +#[derive(Diagnostic)] +#[diag(session_nul_in_c_str)] +pub(crate) struct NulInCStr { + #[primary_span] + pub span: Span, +} + pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span: Span) { // Checks if `s` looks like i32 or u1234 etc. fn looks_like_width_suffix(first_chars: &[char], s: &str) -> bool { @@ -385,6 +392,12 @@ pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span: }; sess.emit_err(IntLiteralTooLarge { span, limit }); } + LitError::NulInCStr(range) => { + let lo = BytePos(span.lo().0 + range.start as u32 + 2); + let hi = BytePos(span.lo().0 + range.end as u32 + 2); + let span = span.with_lo(lo).with_hi(hi); + sess.emit_err(NulInCStr { span }); + } } } diff --git a/tests/ui/rfcs/rfc-3348-c-string-literals/no-nuls.rs b/tests/ui/rfcs/rfc-3348-c-string-literals/no-nuls.rs index f6c86a1ba8762358537827376cbffc5c3f4508e9..e66519f294cd08f751f03b725967b5cd60dcee1d 100644 GIT binary patch literal 570 zcmbV}F>Avx5QRPKSDYOWQkQs6Xd#4jDiqw&PK^+9YLJy6ouS3JzdaYZZGy>C-z1*& z?w-C|#6_(oc209ud32R&P&;Y7*fUmJXk}x$fSv)BO3Ex*hvRbj{SLc4f6Z55J7Yk7 zNGBC}Jv0`!K)o7!V86bu&$3~jH=1WFKeKsZUGm?F17odJ?pV3bXdi=aPx$r2jHf(B zTp@}F0gq464{Jv67lo=1{CV^8wjoT$jeCafw@y%Qo3Q zPSCPEM;jBMN(!DFx@K1cWyzSFfW04Mhd1Y+KEI4HjfNE;5i#rWCql1B(8Y@nzCYRR fyP*I|{vI!G(MUg&)j`5rY|)T>DjOU+cR0qrx?#zt literal 670 zcmcJNI}5@v5XYVKDgG4KYQ#q+f{QLfC+AYAHE5wEa!Ew6es@F0SVV;0bT96AFG-|H zK)JR>eXXdftt2!GI~Yrix-cM3w;1ma$Enh(Pc#!UVj(ggLC5kOomYT5DR{C8&R_#& z`K>OKf1}P$Lfcgd?nWL;VFqm$4^_YPMWO$ VFr1x))mY+2^4@4?5MIMD_6Dmm#F_vA