Skip to content

Commit abb181d

Browse files
committed
make it semantic error
1 parent bf3ca59 commit abb181d

File tree

7 files changed

+22
-1
lines changed

7 files changed

+22
-1
lines changed

compiler/rustc_ast/src/util/literal.rs

+2
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use rustc_lexer::unescape::{
88
};
99
use rustc_span::symbol::{kw, sym, Symbol};
1010
use rustc_span::Span;
11+
use std::ops::Range;
1112
use std::{ascii, fmt, str};
1213

1314
// Escapes a string, represented as a symbol. Reuses the original symbol,
@@ -38,6 +39,7 @@ pub enum LitError {
3839
InvalidFloatSuffix,
3940
NonDecimalFloat(u32),
4041
IntTooLarge(u32),
42+
NulInCStr(Range<usize>),
4143
}
4244

4345
impl LitKind {

compiler/rustc_ast_passes/src/feature_gate.rs

+1
Original file line numberDiff line numberDiff line change
@@ -572,6 +572,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session) {
572572
}
573573
};
574574
}
575+
gate_all!(c_str_literals, "`c\"..\"` literals are experimental");
575576
gate_all!(
576577
if_let_guard,
577578
"`if let` guards are experimental",

compiler/rustc_parse/src/lexer/mod.rs

+3
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,9 @@ impl<'a> StringReader<'a> {
204204
rustc_lexer::TokenKind::Literal { kind, suffix_start } => {
205205
let suffix_start = start + BytePos(suffix_start);
206206
let (kind, symbol) = self.cook_lexer_literal(start, suffix_start, kind);
207+
if let token::LitKind::CStr | token::LitKind::CStrRaw(_) = kind {
208+
self.sess.gated_spans.gate(sym::c_str_literals, self.mk_sp(start, self.pos));
209+
}
207210
let suffix = if suffix_start < self.pos {
208211
let string = self.str_from(suffix_start);
209212
if string == "_" {

compiler/rustc_session/messages.ftl

+2
Original file line numberDiff line numberDiff line change
@@ -93,3 +93,5 @@ session_invalid_int_literal_width = invalid width `{$width}` for integer literal
9393
.help = valid widths are 8, 16, 32, 64 and 128
9494
9595
session_optimization_fuel_exhausted = optimization-fuel-exhausted: {$msg}
96+
97+
session_nul_in_c_str = null characters in C string literals are not supported

compiler/rustc_session/src/errors.rs

+14-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use rustc_ast::token;
66
use rustc_ast::util::literal::LitError;
77
use rustc_errors::{error_code, DiagnosticMessage, EmissionGuarantee, IntoDiagnostic, MultiSpan};
88
use rustc_macros::Diagnostic;
9-
use rustc_span::{Span, Symbol};
9+
use rustc_span::{BytePos, Span, Symbol};
1010
use rustc_target::spec::{SplitDebuginfo, StackProtector, TargetTriple};
1111

1212
#[derive(Diagnostic)]
@@ -307,6 +307,13 @@ pub(crate) struct BinaryFloatLiteralNotSupported {
307307
pub span: Span,
308308
}
309309

310+
#[derive(Diagnostic)]
311+
#[diag(session_nul_in_c_str)]
312+
pub(crate) struct NulInCStr {
313+
#[primary_span]
314+
pub span: Span,
315+
}
316+
310317
pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span: Span) {
311318
// Checks if `s` looks like i32 or u1234 etc.
312319
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:
385392
};
386393
sess.emit_err(IntLiteralTooLarge { span, limit });
387394
}
395+
LitError::NulInCStr(range) => {
396+
let lo = BytePos(span.lo().0 + range.start as u32 + 2);
397+
let hi = BytePos(span.lo().0 + range.end as u32 + 2);
398+
let span = span.with_lo(lo).with_hi(hi);
399+
sess.emit_err(NulInCStr { span });
400+
}
388401
}
389402
}
390403

248 Bytes
Binary file not shown.
Binary file not shown.

0 commit comments

Comments
 (0)