@@ -401,6 +401,8 @@ macro_rules! make_bitflags {
401401 $(
402402 n |= $enum:: $variant as <$enum as $crate:: _internal:: RawBitFlags >:: Numeric ;
403403 ) *
404+ // SAFETY: The value has been created from numeric values of the underlying
405+ // enum, so only valid bits are set.
404406 unsafe { $crate:: BitFlags :: <$enum>:: from_bits_unchecked_c(
405407 n, $crate:: BitFlags :: CONST_TOKEN ) }
406408 }
@@ -460,6 +462,8 @@ where
460462 #[ must_use]
461463 #[ inline( always) ]
462464 pub fn from_bits_truncate ( bits : T :: Numeric ) -> Self {
465+ // SAFETY: We're truncating out all the invalid bits, so the remaining
466+ // ones must be valid.
463467 unsafe { BitFlags :: from_bits_unchecked ( bits & T :: ALL_BITS ) }
464468 }
465469
@@ -486,6 +490,7 @@ where
486490 #[ must_use]
487491 #[ inline( always) ]
488492 pub fn from_flag ( flag : T ) -> Self {
493+ // SAFETY: A value of the underlying enum is valid by definition.
489494 unsafe { Self :: from_bits_unchecked ( flag. bits ( ) ) }
490495 }
491496
@@ -586,6 +591,8 @@ where
586591 #[ inline( always) ]
587592 pub fn exactly_one ( self ) -> Option < T > {
588593 if self . val . is_power_of_two ( ) {
594+ // SAFETY: By the invariant of the BitFlags type, all bits are valid
595+ // in isolation for the underlying enum.
589596 Some ( unsafe { core:: mem:: transmute_copy ( & self . val ) } )
590597 } else {
591598 None
@@ -677,6 +684,10 @@ where
677684 if self . rest . is_empty ( ) {
678685 None
679686 } else {
687+ // SAFETY: `flag` will be a single bit, because
688+ // x & -x = x & (~x + 1), and the increment causes only one 0 -> 1 transition.
689+ // The invariant of `from_bits_unchecked` is satisfied, because bits & x
690+ // is a subset of bits, which we know are the valid bits.
680691 unsafe {
681692 let bits = self . rest . bits ( ) ;
682693 let flag: T :: Numeric = bits & bits. wrapping_neg ( ) ;
@@ -867,6 +878,8 @@ where
867878 type Output = BitFlags < T > ;
868879 #[ inline( always) ]
869880 fn bitor ( self , other : B ) -> BitFlags < T > {
881+ // SAFETY: The two operands are known to be composed of valid bits,
882+ // and 0 | 0 = 0 in the columns of the invalid bits.
870883 unsafe { BitFlags :: from_bits_unchecked ( self . bits ( ) | other. into ( ) . bits ( ) ) }
871884 }
872885}
@@ -879,6 +892,8 @@ where
879892 type Output = BitFlags < T > ;
880893 #[ inline( always) ]
881894 fn bitand ( self , other : B ) -> BitFlags < T > {
895+ // SAFETY: The two operands are known to be composed of valid bits,
896+ // and 0 & 0 = 0 in the columns of the invalid bits.
882897 unsafe { BitFlags :: from_bits_unchecked ( self . bits ( ) & other. into ( ) . bits ( ) ) }
883898 }
884899}
@@ -891,6 +906,8 @@ where
891906 type Output = BitFlags < T > ;
892907 #[ inline( always) ]
893908 fn bitxor ( self , other : B ) -> BitFlags < T > {
909+ // SAFETY: The two operands are known to be composed of valid bits,
910+ // and 0 ^ 0 = 0 in the columns of the invalid bits.
894911 unsafe { BitFlags :: from_bits_unchecked ( self . bits ( ) ^ other. into ( ) . bits ( ) ) }
895912 }
896913}
@@ -934,7 +951,7 @@ where
934951 type Output = BitFlags < T > ;
935952 #[ inline( always) ]
936953 fn not ( self ) -> BitFlags < T > {
937- unsafe { BitFlags :: from_bits_unchecked ( !self . bits ( ) & T :: ALL_BITS ) }
954+ BitFlags :: from_bits_truncate ( !self . bits ( ) )
938955 }
939956}
940957
0 commit comments