@@ -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+
5974impl < ' 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