@@ -45,6 +45,8 @@ impl Alignment {
45
45
#[ unstable( feature = "ptr_alignment_type" , issue = "102070" ) ]
46
46
#[ inline]
47
47
#[ must_use]
48
+ #[ rustc_allow_const_fn_unstable( contracts) ]
49
+ #[ core:: contracts:: ensures( |result: & Alignment | result. as_usize( ) . is_power_of_two( ) ) ]
48
50
pub const fn of < T > ( ) -> Self {
49
51
// This can't actually panic since type alignment is always a power of two.
50
52
const { Alignment :: new ( align_of :: < T > ( ) ) . unwrap ( ) }
@@ -56,6 +58,11 @@ impl Alignment {
56
58
/// Note that `0` is not a power of two, nor a valid alignment.
57
59
#[ unstable( feature = "ptr_alignment_type" , issue = "102070" ) ]
58
60
#[ inline]
61
+ #[ rustc_allow_const_fn_unstable( contracts) ]
62
+ #[ core:: contracts:: ensures(
63
+ move |result: & Option <Alignment >|
64
+ align. is_power_of_two( ) == result. is_some( ) &&
65
+ ( result. is_none( ) || result. unwrap( ) . as_usize( ) == align) ) ]
59
66
pub const fn new ( align : usize ) -> Option < Self > {
60
67
if align. is_power_of_two ( ) {
61
68
// SAFETY: Just checked it only has one bit set
@@ -76,6 +83,12 @@ impl Alignment {
76
83
#[ unstable( feature = "ptr_alignment_type" , issue = "102070" ) ]
77
84
#[ inline]
78
85
#[ track_caller]
86
+ #[ rustc_allow_const_fn_unstable( contracts) ]
87
+ #[ allow( unused_parens) ]
88
+ #[ core:: contracts:: requires( align. is_power_of_two( ) ) ]
89
+ #[ core:: contracts:: ensures(
90
+ move |result: & Alignment |
91
+ result. as_usize( ) == align && result. as_usize( ) . is_power_of_two( ) ) ]
79
92
pub const unsafe fn new_unchecked ( align : usize ) -> Self {
80
93
assert_unsafe_precondition ! (
81
94
check_language_ub,
@@ -91,13 +104,19 @@ impl Alignment {
91
104
/// Returns the alignment as a [`usize`].
92
105
#[ unstable( feature = "ptr_alignment_type" , issue = "102070" ) ]
93
106
#[ inline]
107
+ #[ rustc_allow_const_fn_unstable( contracts) ]
108
+ #[ core:: contracts:: ensures( |result: & usize | result. is_power_of_two( ) ) ]
94
109
pub const fn as_usize ( self ) -> usize {
95
110
self . 0 as usize
96
111
}
97
112
98
113
/// Returns the alignment as a <code>[NonZero]<[usize]></code>.
99
114
#[ unstable( feature = "ptr_alignment_type" , issue = "102070" ) ]
100
115
#[ inline]
116
+ #[ rustc_allow_const_fn_unstable( contracts) ]
117
+ #[ core:: contracts:: ensures(
118
+ move |result: & NonZero <usize >|
119
+ result. get( ) . is_power_of_two( ) && result. get( ) == self . as_usize( ) ) ]
101
120
pub const fn as_nonzero ( self ) -> NonZero < usize > {
102
121
// This transmutes directly to avoid the UbCheck in `NonZero::new_unchecked`
103
122
// since there's no way for the user to trip that check anyway -- the
@@ -123,6 +142,12 @@ impl Alignment {
123
142
/// ```
124
143
#[ unstable( feature = "ptr_alignment_type" , issue = "102070" ) ]
125
144
#[ inline]
145
+ #[ rustc_const_unstable( feature = "contracts" , issue = "128044" ) ]
146
+ #[ allow( unused_parens) ]
147
+ #[ core:: contracts:: requires( self . as_usize( ) . is_power_of_two( ) ) ]
148
+ #[ core:: contracts:: ensures(
149
+ move |result: & u32 |
150
+ * result < usize :: BITS && ( 1usize << * result) == self . as_usize( ) ) ]
126
151
pub const fn log2 ( self ) -> u32 {
127
152
self . as_nonzero ( ) . trailing_zeros ( )
128
153
}
@@ -152,6 +177,11 @@ impl Alignment {
152
177
/// ```
153
178
#[ unstable( feature = "ptr_alignment_type" , issue = "102070" ) ]
154
179
#[ inline]
180
+ #[ rustc_const_unstable( feature = "contracts" , issue = "128044" ) ]
181
+ #[ core:: contracts:: ensures(
182
+ move |result: & usize |
183
+ * result > 0 && * result == !( self . as_usize( ) -1 ) &&
184
+ self . as_usize( ) & * result == self . as_usize( ) ) ]
155
185
pub const fn mask ( self ) -> usize {
156
186
// SAFETY: The alignment is always nonzero, and therefore decrementing won't overflow.
157
187
!( unsafe { self . as_usize ( ) . unchecked_sub ( 1 ) } )
0 commit comments