@@ -1476,6 +1476,7 @@ impl Numeric {
14761476#[ derive( Copy , Clone , PartialEq , Eq , Hash ) ]
14771477#[ cfg_attr( feature = "nightly" , derive( StableHash ) ) ]
14781478pub enum Primitive {
1479+ Bool ,
14791480 /// The `bool` is the signedness of the `Integer` type.
14801481 ///
14811482 /// One would think we would not care about such details this low down,
@@ -1491,6 +1492,7 @@ pub enum Primitive {
14911492impl fmt:: Debug for Primitive {
14921493 fn fmt ( & self , f : & mut fmt:: Formatter < ' _ > ) -> fmt:: Result {
14931494 let name = match * self {
1495+ Primitive :: Bool => "bool" ,
14941496 Primitive :: Int ( integer, is_signed) => {
14951497 if is_signed {
14961498 integer. int_ty_str ( )
@@ -1517,6 +1519,7 @@ impl Primitive {
15171519 let dl = cx. data_layout ( ) ;
15181520
15191521 match self {
1522+ Bool => Size :: from_bits ( 1 ) ,
15201523 Int ( i, _) => i. size ( ) ,
15211524 Float ( f) => f. size ( ) ,
15221525 Pointer ( a) => dl. pointer_size_in ( a) ,
@@ -1532,6 +1535,7 @@ impl Primitive {
15321535 let dl = cx. data_layout ( ) ;
15331536
15341537 match self {
1538+ Bool => dl. i1_align ,
15351539 Int ( i, _) => i. align ( dl) ,
15361540 Float ( f) => f. align ( dl) ,
15371541 Pointer ( a) => dl. pointer_align_in ( a) ,
@@ -1566,6 +1570,7 @@ impl fmt::Debug for Scalar {
15661570 match self {
15671571 Scalar :: Initialized { value, valid_range } => {
15681572 let ( size, is_signed) = match * value {
1573+ Primitive :: Bool => ( Size :: from_bits ( 1 ) , false ) ,
15691574 Primitive :: Int ( integer, is_signed) => ( integer. size ( ) , is_signed) ,
15701575 Primitive :: Float ( float) => ( float. size ( ) , false ) ,
15711576 Primitive :: Pointer ( _) => ( Size :: from_bits ( 128 ) , false ) ,
@@ -1582,11 +1587,10 @@ impl fmt::Debug for Scalar {
15821587impl Scalar {
15831588 #[ inline]
15841589 pub fn is_bool ( & self ) -> bool {
1585- use Integer :: * ;
15861590 matches ! (
15871591 self ,
15881592 Scalar :: Initialized {
1589- value: Primitive :: Int ( I8 , false ) ,
1593+ value: Primitive :: Bool ,
15901594 valid_range: WrappingRange { start: 0 , end: 1 }
15911595 }
15921596 )
@@ -2132,14 +2136,33 @@ impl Niche {
21322136 // In practice this means that enums with `count > 1` are unlikely to claim niche zero,
21332137 // since they have to fit perfectly. If niche zero is already reserved, the selection of
21342138 // bounds are of little interest.
2139+ //
2140+ // Because bools still have a size of 1 byte, we may need to potentially adjust the scalar
2141+ // here to compensate for reserving more space than the single bit. Niche reservation will
2142+ // never try to go larger than the in-memory size though, so it's always an adjustment
2143+ // bool -> u8.
21352144 let move_start = |v : WrappingRange | {
21362145 let start = v. start . wrapping_sub ( count) & max_value;
2137- Some ( ( start, Scalar :: Initialized { value, valid_range : v. with_start ( start) } ) )
2146+ let valid_range = v. with_start ( start) ;
2147+ let mut value = value;
2148+ if let Primitive :: Bool = value
2149+ && valid_range. end . wrapping_sub ( valid_range. start ) >= 2
2150+ {
2151+ value = Primitive :: Int ( Integer :: I8 , false ) ;
2152+ }
2153+ Some ( ( start, Scalar :: Initialized { value, valid_range } ) )
21382154 } ;
21392155 let move_end = |v : WrappingRange | {
21402156 let start = v. end . wrapping_add ( 1 ) & max_value;
21412157 let end = v. end . wrapping_add ( count) & max_value;
2142- Some ( ( start, Scalar :: Initialized { value, valid_range : v. with_end ( end) } ) )
2158+ let valid_range = v. with_end ( end) ;
2159+ let mut value = value;
2160+ if let Primitive :: Bool = value
2161+ && valid_range. end . wrapping_sub ( valid_range. start ) >= 2
2162+ {
2163+ value = Primitive :: Int ( Integer :: I8 , false ) ;
2164+ }
2165+ Some ( ( start, Scalar :: Initialized { value, valid_range } ) )
21432166 } ;
21442167 let distance_end_zero = max_value - v. end ;
21452168 // FIXME: this ought to work for `bool` too, but that seems to be hitting a miscompilation
0 commit comments