Skip to content

Commit a7f35c4

Browse files
committed
Add StrStyle to ast::LitKind::ByteStr.
This is required to distinguish between cooked and raw byte string literals in an `ast::LitKind`, without referring to an adjacent `token::Lit`. It's a prerequisite for the next commit.
1 parent e658144 commit a7f35c4

File tree

18 files changed

+39
-28
lines changed

18 files changed

+39
-28
lines changed

compiler/rustc_ast/src/ast.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1796,8 +1796,9 @@ pub enum LitKind {
17961796
/// A string literal (`"foo"`). The symbol is unescaped, and so may differ
17971797
/// from the original token's symbol.
17981798
Str(Symbol, StrStyle),
1799-
/// A byte string (`b"foo"`).
1800-
ByteStr(Lrc<[u8]>),
1799+
/// A byte string (`b"foo"`). Not stored as a symbol because it might be
1800+
/// non-utf8, and symbols only allow utf8 strings.
1801+
ByteStr(Lrc<[u8]>, StrStyle),
18011802
/// A byte char (`b'f'`).
18021803
Byte(u8),
18031804
/// A character literal (`'a'`).
@@ -1822,7 +1823,7 @@ impl LitKind {
18221823

18231824
/// Returns `true` if this literal is byte literal string.
18241825
pub fn is_bytestr(&self) -> bool {
1825-
matches!(self, LitKind::ByteStr(_))
1826+
matches!(self, LitKind::ByteStr(..))
18261827
}
18271828

18281829
/// Returns `true` if this is a numeric literal.

compiler/rustc_ast/src/util/literal.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
//! Code related to parsing literals.
22
3-
use crate::ast::{self, LitKind, MetaItemLit};
3+
use crate::ast::{self, LitKind, MetaItemLit, StrStyle};
44
use crate::token::{self, Token};
55
use rustc_lexer::unescape::{byte_from_char, unescape_byte, unescape_char, unescape_literal, Mode};
66
use rustc_span::symbol::{kw, sym, Symbol};
77
use rustc_span::Span;
88
use std::ascii;
9+
use std::str;
910

1011
#[derive(Debug)]
1112
pub enum LitError {
@@ -115,9 +116,9 @@ impl LitKind {
115116
}
116117
});
117118
error?;
118-
LitKind::ByteStr(buf.into())
119+
LitKind::ByteStr(buf.into(), StrStyle::Cooked)
119120
}
120-
token::ByteStrRaw(_) => {
121+
token::ByteStrRaw(n) => {
121122
let s = symbol.as_str();
122123
let bytes = if s.contains('\r') {
123124
let mut buf = Vec::with_capacity(s.len());
@@ -136,7 +137,7 @@ impl LitKind {
136137
symbol.to_string().into_bytes()
137138
};
138139

139-
LitKind::ByteStr(bytes.into())
140+
LitKind::ByteStr(bytes.into(), StrStyle::Raw(n))
140141
}
141142
token::Err => LitKind::Err,
142143
})
@@ -155,10 +156,15 @@ impl LitKind {
155156
(token::Str, symbol, None)
156157
}
157158
LitKind::Str(symbol, ast::StrStyle::Raw(n)) => (token::StrRaw(n), symbol, None),
158-
LitKind::ByteStr(ref bytes) => {
159+
LitKind::ByteStr(ref bytes, ast::StrStyle::Cooked) => {
159160
let string = bytes.escape_ascii().to_string();
160161
(token::ByteStr, Symbol::intern(&string), None)
161162
}
163+
LitKind::ByteStr(ref bytes, ast::StrStyle::Raw(n)) => {
164+
// Unwrap because raw byte string literals can only contain ASCII.
165+
let string = str::from_utf8(bytes).unwrap();
166+
(token::ByteStrRaw(n), Symbol::intern(&string), None)
167+
}
162168
LitKind::Byte(byte) => {
163169
let string: String = ascii::escape_default(byte).map(Into::<char>::into).collect();
164170
(token::Byte, Symbol::intern(&string), None)

compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
9797
}
9898
ExprKind::IncludedBytes(bytes) => hir::ExprKind::Lit(respan(
9999
self.lower_span(e.span),
100-
LitKind::ByteStr(bytes.clone()),
100+
LitKind::ByteStr(bytes.clone(), StrStyle::Cooked),
101101
)),
102102
ExprKind::Cast(expr, ty) => {
103103
let expr = self.lower_expr(expr);

compiler/rustc_ast_pretty/src/pprust/state/expr.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -323,7 +323,8 @@ impl<'a> State<'a> {
323323
self.print_token_literal(*token_lit, expr.span);
324324
}
325325
ast::ExprKind::IncludedBytes(bytes) => {
326-
let lit = ast::LitKind::ByteStr(bytes.clone()).synthesize_token_lit();
326+
let lit = ast::LitKind::ByteStr(bytes.clone(), ast::StrStyle::Cooked)
327+
.synthesize_token_lit();
327328
self.print_token_literal(lit, expr.span)
328329
}
329330
ast::ExprKind::Cast(expr, ty) => {

compiler/rustc_builtin_macros/src/concat_bytes.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,7 +69,7 @@ fn invalid_type_err(
6969
Ok(ast::LitKind::Int(_, _)) => {
7070
cx.span_err(span, "numeric literal is not a `u8`");
7171
}
72-
Ok(ast::LitKind::ByteStr(_) | ast::LitKind::Byte(_)) => unreachable!(),
72+
Ok(ast::LitKind::ByteStr(..) | ast::LitKind::Byte(_)) => unreachable!(),
7373
Err(err) => {
7474
report_lit_error(&cx.sess.parse_sess, err, token_lit, span);
7575
}
@@ -97,7 +97,7 @@ fn handle_array_element(
9797
)) if val <= u8::MAX.into() => Some(val as u8),
9898

9999
Ok(ast::LitKind::Byte(val)) => Some(val),
100-
Ok(ast::LitKind::ByteStr(_)) => {
100+
Ok(ast::LitKind::ByteStr(..)) => {
101101
if !*has_errors {
102102
cx.struct_span_err(expr.span, "cannot concatenate doubly nested array")
103103
.note("byte strings are treated as arrays of bytes")
@@ -174,7 +174,7 @@ pub fn expand_concat_bytes(
174174
Ok(ast::LitKind::Byte(val)) => {
175175
accumulator.push(val);
176176
}
177-
Ok(ast::LitKind::ByteStr(ref bytes)) => {
177+
Ok(ast::LitKind::ByteStr(ref bytes, _)) => {
178178
accumulator.extend_from_slice(&bytes);
179179
}
180180
_ => {

compiler/rustc_expand/src/base.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1234,7 +1234,7 @@ pub fn expr_to_spanned_string<'a>(
12341234
Err(match expr.kind {
12351235
ast::ExprKind::Lit(token_lit) => match ast::LitKind::from_token_lit(token_lit) {
12361236
Ok(ast::LitKind::Str(s, style)) => return Ok((s, style, expr.span)),
1237-
Ok(ast::LitKind::ByteStr(_)) => {
1237+
Ok(ast::LitKind::ByteStr(..)) => {
12381238
let mut err = cx.struct_span_err(expr.span, err_msg);
12391239
let span = expr.span.shrink_to_lo();
12401240
err.span_suggestion(

compiler/rustc_expand/src/build.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -361,7 +361,7 @@ impl<'a> ExtCtxt<'a> {
361361
}
362362

363363
pub fn expr_byte_str(&self, sp: Span, bytes: Vec<u8>) -> P<ast::Expr> {
364-
self.expr_lit(sp, ast::LitKind::ByteStr(Lrc::from(bytes)))
364+
self.expr_lit(sp, ast::LitKind::ByteStr(Lrc::from(bytes), ast::StrStyle::Cooked))
365365
}
366366

367367
/// `[expr1, expr2, ...]`

compiler/rustc_expand/src/proc_macro_server.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -526,7 +526,8 @@ impl server::TokenStream for Rustc<'_, '_> {
526526
Ok(tokenstream::TokenStream::token_alone(token::Literal(*token_lit), expr.span))
527527
}
528528
ast::ExprKind::IncludedBytes(bytes) => {
529-
let lit = ast::LitKind::ByteStr(bytes.clone()).synthesize_token_lit();
529+
let lit = ast::LitKind::ByteStr(bytes.clone(), ast::StrStyle::Cooked)
530+
.synthesize_token_lit();
530531
Ok(tokenstream::TokenStream::token_alone(token::TokenKind::Literal(lit), expr.span))
531532
}
532533
ast::ExprKind::Unary(ast::UnOp::Neg, e) => match &e.kind {

compiler/rustc_hir_typeck/src/fn_ctxt/checks.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1169,7 +1169,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
11691169

11701170
match lit.node {
11711171
ast::LitKind::Str(..) => tcx.mk_static_str(),
1172-
ast::LitKind::ByteStr(ref v) => {
1172+
ast::LitKind::ByteStr(ref v, _) => {
11731173
tcx.mk_imm_ref(tcx.lifetimes.re_static, tcx.mk_array(tcx.types.u8, v.len() as u64))
11741174
}
11751175
ast::LitKind::Byte(_) => tcx.types.u8,

compiler/rustc_hir_typeck/src/pat.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -386,7 +386,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
386386
// Byte string patterns behave the same way as array patterns
387387
// They can denote both statically and dynamically-sized byte arrays.
388388
let mut pat_ty = ty;
389-
if let hir::ExprKind::Lit(Spanned { node: ast::LitKind::ByteStr(_), .. }) = lt.kind {
389+
if let hir::ExprKind::Lit(Spanned { node: ast::LitKind::ByteStr(..), .. }) = lt.kind {
390390
let expected = self.structurally_resolved_type(span, expected);
391391
if let ty::Ref(_, inner_ty, _) = expected.kind()
392392
&& matches!(inner_ty.kind(), ty::Slice(_))

0 commit comments

Comments
 (0)