@@ -570,12 +570,7 @@ pub struct Case {
570570
571571impl Variant {
572572 pub fn tag ( & self ) -> Int {
573- match self . cases . len ( ) {
574- n if n <= u8:: max_value ( ) as usize => Int :: U8 ,
575- n if n <= u16:: max_value ( ) as usize => Int :: U16 ,
576- n if n <= u32:: max_value ( ) as usize => Int :: U32 ,
577- _ => panic ! ( "too many cases to fit in a repr" ) ,
578- }
573+ discriminant_type ( self . cases . len ( ) )
579574 }
580575}
581576
@@ -595,12 +590,18 @@ pub struct EnumCase {
595590
596591impl Enum {
597592 pub fn tag ( & self ) -> Int {
598- match self . cases . len ( ) {
599- n if n <= u8:: max_value ( ) as usize => Int :: U8 ,
600- n if n <= u16:: max_value ( ) as usize => Int :: U16 ,
601- n if n <= u32:: max_value ( ) as usize => Int :: U32 ,
602- _ => panic ! ( "too many cases to fit in a repr" ) ,
603- }
593+ discriminant_type ( self . cases . len ( ) )
594+ }
595+ }
596+
597+ /// This corresponds to the `discriminant_type` function in the Canonical ABI.
598+ fn discriminant_type ( num_cases : usize ) -> Int {
599+ match num_cases. checked_sub ( 1 ) {
600+ None => Int :: U8 ,
601+ Some ( n) if n <= u8:: max_value ( ) as usize => Int :: U8 ,
602+ Some ( n) if n <= u16:: max_value ( ) as usize => Int :: U16 ,
603+ Some ( n) if n <= u32:: max_value ( ) as usize => Int :: U32 ,
604+ _ => panic ! ( "too many cases to fit in a repr" ) ,
604605 }
605606}
606607
@@ -745,3 +746,20 @@ impl Function {
745746 }
746747 }
747748}
749+
750+ #[ cfg( test) ]
751+ mod test {
752+ use super :: * ;
753+
754+ #[ test]
755+ fn test_discriminant_type ( ) {
756+ assert_eq ! ( discriminant_type( 1 ) , Int :: U8 ) ;
757+ assert_eq ! ( discriminant_type( 0x100 ) , Int :: U8 ) ;
758+ assert_eq ! ( discriminant_type( 0x101 ) , Int :: U16 ) ;
759+ assert_eq ! ( discriminant_type( 0x10000 ) , Int :: U16 ) ;
760+ assert_eq ! ( discriminant_type( 0x10001 ) , Int :: U32 ) ;
761+ if let Ok ( num_cases) = usize:: try_from ( 0x100000000_u64 ) {
762+ assert_eq ! ( discriminant_type( num_cases) , Int :: U32 ) ;
763+ }
764+ }
765+ }
0 commit comments