Skip to content

Commit 8156c2b

Browse files
committed
Add support for min_const_generics constants
1 parent c4e3ab0 commit 8156c2b

File tree

1 file changed

+102
-12
lines changed

1 file changed

+102
-12
lines changed

src/v0.rs

Lines changed: 102 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,21 @@ pub fn demangle(s: &str) -> Result<(Demangle, &str), Invalid> {
5656
Ok((Demangle { inner }, &parser.sym[parser.next..]))
5757
}
5858

59+
fn supported_const_generic_type(ty_tag: u8) -> bool {
60+
match ty_tag {
61+
// Unsigned integer types.
62+
b'h' | b't' | b'm' | b'y' | b'o' | b'j' |
63+
// Signed integer types.
64+
b'a' | b's' | b'l' | b'x' | b'n' | b'i' |
65+
// Bool.
66+
b'b' |
67+
// Char.
68+
b'c' => true,
69+
70+
_ => false,
71+
}
72+
}
73+
5974
impl<'s> Display for Demangle<'s> {
6075
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
6176
let mut printer = Printer {
@@ -532,16 +547,18 @@ impl<'s> Parser<'s> {
532547
return Ok(());
533548
}
534549

535-
match self.next()? {
536-
// Unsigned integer types.
537-
b'h' | b't' | b'm' | b'y' | b'o' | b'j' => {}
538-
539-
_ => return Err(Invalid),
550+
let ty_tag = self.next()?;
551+
if !supported_const_generic_type(ty_tag) {
552+
return Err(Invalid);
540553
}
541554

542555
if self.eat(b'p') {
543556
return Ok(());
544557
}
558+
// Negation on signed integers.
559+
if let b'a' | b's' | b'l' | b'x' | b'n' | b'i' = ty_tag {
560+
let _ = self.eat(b'n');
561+
}
545562
self.hex_nibbles()?;
546563
Ok(())
547564
}
@@ -936,21 +953,31 @@ impl<'a, 'b, 's> Printer<'a, 'b, 's> {
936953
}
937954

938955
let ty_tag = parse!(self, next);
939-
let ty = match ty_tag {
940-
// Unsigned integer types.
941-
b'h' | b't' | b'm' | b'y' | b'o' | b'j' => basic_type(ty_tag).unwrap(),
942-
943-
_ => invalid!(self),
944-
};
956+
if !supported_const_generic_type(ty_tag) {
957+
invalid!(self);
958+
}
945959

946960
if self.eat(b'p') {
947961
self.out.write_str("_")?;
948962
} else {
949-
self.print_const_uint()?;
963+
match ty_tag {
964+
// Unsigned integer types.
965+
b'h' | b't' | b'm' | b'y' | b'o' | b'j' => self.print_const_uint()?,
966+
// Signed integer types.
967+
b'a' | b's' | b'l' | b'x' | b'n' | b'i' => self.print_const_int()?,
968+
// Bool.
969+
b'b' => self.print_const_bool()?,
970+
// Char.
971+
b'c' => self.print_const_char()?,
972+
973+
// This branch ought to be unreachable.
974+
_ => invalid!(self),
975+
};
950976
}
951977

952978
if !self.out.alternate() {
953979
self.out.write_str(": ")?;
980+
let ty = basic_type(ty_tag).unwrap();
954981
self.out.write_str(ty)?;
955982
}
956983

@@ -972,6 +999,41 @@ impl<'a, 'b, 's> Printer<'a, 'b, 's> {
972999
}
9731000
v.fmt(self.out)
9741001
}
1002+
1003+
fn print_const_int(&mut self) -> fmt::Result {
1004+
if self.eat(b'n') {
1005+
self.out.write_str("-")?;
1006+
}
1007+
1008+
self.print_const_uint()
1009+
}
1010+
1011+
fn print_const_bool(&mut self) -> fmt::Result {
1012+
match parse!(self, hex_nibbles).as_bytes() {
1013+
b"0" => self.out.write_str("false"),
1014+
b"1" => self.out.write_str("true"),
1015+
_ => invalid!(self),
1016+
}
1017+
}
1018+
1019+
fn print_const_char(&mut self) -> fmt::Result {
1020+
let hex = parse!(self, hex_nibbles);
1021+
1022+
// Valid `char`s fit in `u32`.
1023+
if hex.len() > 8 {
1024+
invalid!(self);
1025+
}
1026+
1027+
let mut v = 0;
1028+
for c in hex.chars() {
1029+
v = (v << 4) | (c.to_digit(16).unwrap() as u32);
1030+
}
1031+
if let Some(c) = char::from_u32(v) {
1032+
write!(self.out, "'{}'", c)
1033+
} else {
1034+
invalid!(self)
1035+
}
1036+
}
9751037
}
9761038

9771039
#[cfg(test)]
@@ -1028,6 +1090,34 @@ mod tests {
10281090
"INtC8arrayvec8ArrayVechKj7b_E",
10291091
"arrayvec::ArrayVec<u8, 123>"
10301092
);
1093+
t_nohash!(
1094+
"_RMCs4fqI2P2rA04_13const_genericINtB0_8UnsignedKhb_E",
1095+
"<const_generic::Unsigned<11>>"
1096+
);
1097+
t_nohash!(
1098+
"_RMCs4fqI2P2rA04_13const_genericINtB0_6SignedKs98_E",
1099+
"<const_generic::Signed<152>>"
1100+
);
1101+
t_nohash!(
1102+
"_RMCs4fqI2P2rA04_13const_genericINtB0_6SignedKanb_E",
1103+
"<const_generic::Signed<-11>>"
1104+
);
1105+
t_nohash!(
1106+
"_RMCs4fqI2P2rA04_13const_genericINtB0_4BoolKb0_E",
1107+
"<const_generic::Bool<false>>"
1108+
);
1109+
t_nohash!(
1110+
"_RMCs4fqI2P2rA04_13const_genericINtB0_4BoolKb1_E",
1111+
"<const_generic::Bool<true>>"
1112+
);
1113+
t_nohash!(
1114+
"_RMCs4fqI2P2rA04_13const_genericINtB0_4CharKc76_E",
1115+
"<const_generic::Char<'v'>>"
1116+
);
1117+
t_nohash!(
1118+
"_RMCs4fqI2P2rA04_13const_genericINtB0_4CharKc2202_E",
1119+
"<const_generic::Char<'∂'>>"
1120+
);
10311121
}
10321122

10331123
#[test]

0 commit comments

Comments
 (0)