Skip to content

Commit 359a397

Browse files
committed
Preserve byte string literal raw-ness in AST
1 parent eda0699 commit 359a397

File tree

10 files changed

+41
-19
lines changed

10 files changed

+41
-19
lines changed

src/librustc/ich/impls_syntax.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,7 @@ impl_stable_hash_for_spanned!(::syntax::ast::LitKind);
166166
impl_stable_hash_for!(enum ::syntax::ast::LitKind {
167167
Str(value, style),
168168
Err(value),
169-
ByteStr(value),
169+
ByteStr(value, style),
170170
Byte(value),
171171
Char(value),
172172
Int(value, lit_int_type),

src/librustc_mir/hair/constant.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ crate fn lit_to_const<'a, 'gcx, 'tcx>(
4444
ty: tcx.types.err,
4545
});
4646
},
47-
LitKind::ByteStr(ref data) => {
47+
LitKind::ByteStr(ref data, _) => {
4848
let id = tcx.allocate_bytes(data);
4949
ConstValue::Scalar(Scalar::Ptr(id.into()))
5050
},

src/librustc_typeck/check/_match.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -153,7 +153,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
153153
// They can denote both statically and dynamically sized byte arrays
154154
let mut pat_ty = ty;
155155
if let hir::ExprKind::Lit(ref lt) = lt.node {
156-
if let ast::LitKind::ByteStr(_) = lt.node {
156+
if let ast::LitKind::ByteStr(..) = lt.node {
157157
let expected_ty = self.structurally_resolved_type(pat.span, expected);
158158
if let ty::Ref(_, r_ty, _) = expected_ty.sty {
159159
if let ty::Slice(_) = r_ty.sty {

src/librustc_typeck/check/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -3092,7 +3092,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
30923092

30933093
match lit.node {
30943094
ast::LitKind::Str(..) => tcx.mk_static_str(),
3095-
ast::LitKind::ByteStr(ref v) => {
3095+
ast::LitKind::ByteStr(ref v, _) => {
30963096
tcx.mk_imm_ref(tcx.lifetimes.re_static,
30973097
tcx.mk_array(tcx.types.u8, v.len() as u64))
30983098
}

src/libsyntax/ast.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1355,7 +1355,7 @@ pub enum LitKind {
13551355
/// A string literal (`"foo"`).
13561356
Str(Symbol, StrStyle),
13571357
/// A byte string (`b"foo"`).
1358-
ByteStr(Lrc<Vec<u8>>),
1358+
ByteStr(Lrc<Vec<u8>>, StrStyle),
13591359
/// A byte char (`b'f'`).
13601360
Byte(u8),
13611361
/// A character literal (`'a'`).
@@ -1384,7 +1384,7 @@ impl LitKind {
13841384
/// Returns `true` if this literal is byte literal string.
13851385
pub fn is_bytestr(&self) -> bool {
13861386
match self {
1387-
LitKind::ByteStr(_) => true,
1387+
LitKind::ByteStr(..) => true,
13881388
_ => false,
13891389
}
13901390
}

src/libsyntax/attr/mod.rs

+6-1
Original file line numberDiff line numberDiff line change
@@ -635,11 +635,16 @@ impl LitKind {
635635
LitKind::Str(string, ast::StrStyle::Raw(n)) => {
636636
Token::Literal(token::Lit::StrRaw(string, n), None)
637637
}
638-
LitKind::ByteStr(ref bytes) => {
638+
LitKind::ByteStr(ref bytes, ast::StrStyle::Cooked) => {
639639
let string = bytes.iter().cloned().flat_map(ascii::escape_default)
640640
.map(Into::<char>::into).collect::<String>();
641641
Token::Literal(token::Lit::ByteStr(Symbol::intern(&string)), None)
642642
}
643+
LitKind::ByteStr(ref bytes, ast::StrStyle::Raw(n)) => {
644+
let string = String::from_utf8(bytes.to_vec())
645+
.expect("broken UTF-8 in a raw byte string literal");
646+
Token::Literal(token::Lit::ByteStrRaw(Symbol::intern(&string), n), None)
647+
}
643648
LitKind::Byte(byte) => {
644649
let string: String = ascii::escape_default(byte).map(Into::<char>::into).collect();
645650
Token::Literal(token::Lit::Byte(Symbol::intern(&string)), None)

src/libsyntax/ext/source_util.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,8 @@ pub fn expand_include_bytes(cx: &mut ExtCtxt<'_>, sp: Span, tts: &[tokenstream::
166166
};
167167
cx.source_map().new_source_file(file.into(), contents);
168168

169-
base::MacEager::expr(cx.expr_lit(sp, ast::LitKind::ByteStr(Lrc::new(bytes))))
169+
let lit_kind = ast::LitKind::ByteStr(Lrc::new(bytes), ast::StrStyle::Raw(0));
170+
base::MacEager::expr(cx.expr_lit(sp, lit_kind))
170171
},
171172
Err(e) => {
172173
cx.span_err(sp, &format!("couldn't read {}: {}", file.display(), e));

src/libsyntax/parse/mod.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -419,10 +419,11 @@ crate fn lit_token(lit: token::Lit, suf: Option<Symbol>, diag: Option<(Span, &Ha
419419
return (true, Some(LitKind::Err(i)));
420420
}
421421
buf.shrink_to_fit();
422-
(true, Some(LitKind::ByteStr(Lrc::new(buf))))
422+
(true, Some(LitKind::ByteStr(Lrc::new(buf), ast::StrStyle::Cooked)))
423423
}
424-
token::ByteStrRaw(i, _) => {
425-
(true, Some(LitKind::ByteStr(Lrc::new(i.to_string().into_bytes()))))
424+
token::ByteStrRaw(i, n) => {
425+
let bytes = Lrc::new(i.to_string().into_bytes());
426+
(true, Some(LitKind::ByteStr(bytes, ast::StrStyle::Raw(n))))
426427
}
427428
}
428429
}

src/libsyntax/print/pprust.rs

+19-8
Original file line numberDiff line numberDiff line change
@@ -611,6 +611,7 @@ pub trait PrintState<'a> {
611611
}
612612
match lit.node {
613613
ast::LitKind::Str(st, style) => self.print_string(&st.as_str(), style),
614+
ast::LitKind::ByteStr(ref st, style) => self.print_byte_string(st, style),
614615
ast::LitKind::Err(st) => {
615616
let st = st.as_str().escape_debug().to_string();
616617
let mut res = String::with_capacity(st.len() + 2);
@@ -651,14 +652,6 @@ pub trait PrintState<'a> {
651652
ast::LitKind::Bool(val) => {
652653
if val { self.writer().word("true") } else { self.writer().word("false") }
653654
}
654-
ast::LitKind::ByteStr(ref v) => {
655-
let mut escaped: String = String::new();
656-
for &ch in v.iter() {
657-
escaped.extend(ascii::escape_default(ch)
658-
.map(|c| c as char));
659-
}
660-
self.writer().word(format!("b\"{}\"", escaped))
661-
}
662655
}
663656
}
664657

@@ -677,6 +670,24 @@ pub trait PrintState<'a> {
677670
self.writer().word(st)
678671
}
679672

673+
fn print_byte_string(&mut self, st: &[u8], style: ast::StrStyle) -> io::Result<()> {
674+
let st = match style {
675+
ast::StrStyle::Cooked => {
676+
let mut escaped = String::with_capacity(st.len());
677+
for &c in st {
678+
escaped.extend(ascii::escape_default(c).map(|c| c as char));
679+
}
680+
format!("b\"{}\"", escaped)
681+
}
682+
ast::StrStyle::Raw(n) => {
683+
let st = String::from_utf8(st.to_owned())
684+
.expect("broken UTF-8 in a raw byte string literal");
685+
format!("br{delim}\"{string}\"{delim}", delim="#".repeat(n as usize), string=st)
686+
}
687+
};
688+
self.writer().word(st)
689+
}
690+
680691
fn print_inner_attributes(&mut self,
681692
attrs: &[ast::Attribute]) -> io::Result<()> {
682693
self.print_either_attributes(attrs, ast::AttrStyle::Inner, false, true)

src/test/pretty/raw-byte-str.rs

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// pp-exact
2+
3+
fn main() { let x = br#"byt
4+
es"#; }

0 commit comments

Comments
 (0)