Skip to content

Commit 245357a

Browse files
committed
v0: demangle & and &mut const values.
1 parent 3cf31b9 commit 245357a

File tree

1 file changed

+64
-10
lines changed

1 file changed

+64
-10
lines changed

src/v0.rs

+64-10
Original file line numberDiff line numberDiff line change
@@ -893,7 +893,7 @@ impl<'a, 'b, 's> Printer<'a, 'b, 's> {
893893
let lt = parse!(self, integer_62);
894894
self.print_lifetime_from_index(lt)
895895
} else if self.eat(b'K') {
896-
self.print_const()
896+
self.print_const(false)
897897
} else {
898898
self.print_type()
899899
}
@@ -939,7 +939,7 @@ impl<'a, 'b, 's> Printer<'a, 'b, 's> {
939939
self.print_type()?;
940940
if tag == b'A' {
941941
self.print("; ")?;
942-
self.print_const()?;
942+
self.print_const(true)?;
943943
}
944944
self.print("]")?;
945945
}
@@ -1079,7 +1079,7 @@ impl<'a, 'b, 's> Printer<'a, 'b, 's> {
10791079
Ok(())
10801080
}
10811081

1082-
fn print_const(&mut self) -> fmt::Result {
1082+
fn print_const(&mut self, in_value: bool) -> fmt::Result {
10831083
let tag = parse!(self, next);
10841084

10851085
parse!(self, push_depth);
@@ -1091,7 +1091,12 @@ impl<'a, 'b, 's> Printer<'a, 'b, 's> {
10911091
// used (especially any special-casing), every case that needs braces
10921092
// has to call `open_brace(self)?` (and the closing brace is automatic).
10931093
let mut opened_brace = false;
1094-
let mut open_brace = |this: &mut Self| {
1094+
let mut open_brace_if_outside_expr = |this: &mut Self| {
1095+
// If this expression is nested in another, braces aren't required.
1096+
if in_value {
1097+
return Ok(());
1098+
}
1099+
10951100
opened_brace = true;
10961101
this.print("{")
10971102
};
@@ -1127,17 +1132,28 @@ impl<'a, 'b, 's> Printer<'a, 'b, 's> {
11271132
// NOTE(eddyb) a string literal `"..."` has type `&str`, so
11281133
// to get back the type `str`, `*"..."` syntax is needed
11291134
// (even if that may not be valid in Rust itself).
1130-
open_brace(self)?;
1135+
open_brace_if_outside_expr(self)?;
11311136
self.print("*")?;
11321137

1133-
match parse!(self, hex_nibbles).try_parse_str_chars() {
1134-
Some(chars) => self.print_quoted_escaped_chars('"', chars)?,
1135-
None => invalid!(self),
1136-
}
1138+
self.print_const_str_literal()?;
11371139
}
11381140

1141+
b'R' | b'Q' => {
1142+
// NOTE(eddyb) this prints `"..."` instead of `&*"..."`, which
1143+
// is what `Re..._` would imply (see comment for `str` above).
1144+
if tag == b'R' && self.eat(b'e') {
1145+
self.print_const_str_literal()?;
1146+
} else {
1147+
open_brace_if_outside_expr(self)?;
1148+
self.print("&")?;
1149+
if tag != b'R' {
1150+
self.print("mut ")?;
1151+
}
1152+
self.print_const(true)?;
1153+
}
1154+
}
11391155
b'B' => {
1140-
self.print_backref(Self::print_const)?;
1156+
self.print_backref(|this| this.print_const(in_value))?;
11411157
}
11421158
_ => invalid!(self),
11431159
}
@@ -1172,6 +1188,13 @@ impl<'a, 'b, 's> Printer<'a, 'b, 's> {
11721188

11731189
Ok(())
11741190
}
1191+
1192+
fn print_const_str_literal(&mut self) -> fmt::Result {
1193+
match parse!(self, hex_nibbles).try_parse_str_chars() {
1194+
Some(chars) => self.print_quoted_escaped_chars('"', chars),
1195+
None => invalid!(self),
1196+
}
1197+
}
11751198
}
11761199

11771200
#[cfg(test)]
@@ -1288,6 +1311,37 @@ mod tests {
12881311
);
12891312
}
12901313

1314+
// NOTE(eddyb) this uses the same strings as `demangle_const_str` and should
1315+
// be kept in sync with it - while a macro could be used to generate both
1316+
// `str` and `&str` tests, from a single list of strings, this seems clearer.
1317+
#[test]
1318+
fn demangle_const_ref_str() {
1319+
t_const!("Re616263_", "\"abc\"");
1320+
t_const!("Re27_", r#""'""#);
1321+
t_const!("Re090a_", "\"\\t\\n\"");
1322+
t_const!("Ree28882c3bc_", "\"∂ü\"");
1323+
t_const!(
1324+
"Ree183a1e18390e183ade1839be18394e1839ae18390e183935fe18392e18394e1839b\
1325+
e183a0e18398e18394e1839ae183985fe183a1e18390e18393e18398e1839ae18398_",
1326+
"\"საჭმელად_გემრიელი_სადილი\""
1327+
);
1328+
t_const!(
1329+
"Ref09f908af09fa688f09fa686f09f90ae20c2a720f09f90b6f09f9192e298\
1330+
95f09f94a520c2a720f09fa7a1f09f929bf09f929af09f9299f09f929c_",
1331+
"\"🐊🦈🦆🐮 § 🐶👒☕🔥 § 🧡💛💚💙💜\""
1332+
);
1333+
}
1334+
1335+
#[test]
1336+
fn demangle_const_ref() {
1337+
t_const!("Rp", "{&_}");
1338+
t_const!("Rh7b_", "{&123}");
1339+
t_const!("Rb0_", "{&false}");
1340+
t_const!("Rc58_", "{&'X'}");
1341+
t_const!("RRRh0_", "{&&&0}");
1342+
t_const!("RRRe_", "{&&\"\"}");
1343+
}
1344+
12911345
#[test]
12921346
fn demangle_exponential_explosion() {
12931347
// NOTE(eddyb) because of the prefix added by `t_nohash_type!` is

0 commit comments

Comments
 (0)