@@ -56,6 +56,21 @@ pub fn demangle(s: &str) -> Result<(Demangle, &str), Invalid> {
56
56
Ok ( ( Demangle { inner } , & parser. sym [ parser. next ..] ) )
57
57
}
58
58
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
+
59
74
impl < ' s > Display for Demangle < ' s > {
60
75
fn fmt ( & self , f : & mut fmt:: Formatter ) -> fmt:: Result {
61
76
let mut printer = Printer {
@@ -532,16 +547,18 @@ impl<'s> Parser<'s> {
532
547
return Ok ( ( ) ) ;
533
548
}
534
549
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 ) ;
540
553
}
541
554
542
555
if self . eat ( b'p' ) {
543
556
return Ok ( ( ) ) ;
544
557
}
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
+ }
545
562
self . hex_nibbles ( ) ?;
546
563
Ok ( ( ) )
547
564
}
@@ -936,21 +953,31 @@ impl<'a, 'b, 's> Printer<'a, 'b, 's> {
936
953
}
937
954
938
955
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
+ }
945
959
946
960
if self . eat ( b'p' ) {
947
961
self . out . write_str ( "_" ) ?;
948
962
} 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
+ } ;
950
976
}
951
977
952
978
if !self . out . alternate ( ) {
953
979
self . out . write_str ( ": " ) ?;
980
+ let ty = basic_type ( ty_tag) . unwrap ( ) ;
954
981
self . out . write_str ( ty) ?;
955
982
}
956
983
@@ -972,6 +999,41 @@ impl<'a, 'b, 's> Printer<'a, 'b, 's> {
972
999
}
973
1000
v. fmt ( self . out )
974
1001
}
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
+ }
975
1037
}
976
1038
977
1039
#[ cfg( test) ]
@@ -1028,6 +1090,34 @@ mod tests {
1028
1090
"INtC8arrayvec8ArrayVechKj7b_E" ,
1029
1091
"arrayvec::ArrayVec<u8, 123>"
1030
1092
) ;
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
+ ) ;
1031
1121
}
1032
1122
1033
1123
#[ test]
0 commit comments