Auto merge of #126556 - saethlin:layout-precondition, r=joboet · patricklam/verify-rust-std@7f8bdd5 (original) (raw)

`@@ -6,7 +6,7 @@

`

6

6

``

7

7

`use crate::error::Error;

`

8

8

`use crate::ptr::{Alignment, NonNull};

`

9

``

`-

use crate::{cmp, fmt, mem};

`

``

9

`+

use crate::{assert_unsafe_precondition, cmp, fmt, mem};

`

10

10

``

11

11

`// While this function is used in one place and its implementation

`

12

12

`// could be inlined, the previous attempts to do so made rustc

`

`@@ -66,12 +66,20 @@ impl Layout {

`

66

66

`#[inline]

`

67

67

`#[rustc_allow_const_fn_unstable(ptr_alignment_type)]

`

68

68

`pub const fn from_size_align(size: usize, align: usize) -> Result<Self, LayoutError> {

`

69

``

`-

if !align.is_power_of_two() {

`

70

``

`-

return Err(LayoutError);

`

``

69

`+

if Layout::is_size_align_valid(size, align) {

`

``

70

`+

// SAFETY: Layout::is_size_align_valid checks the preconditions for this call.

`

``

71

`+

unsafe { Ok(Layout { size, align: mem::transmute(align) }) }

`

``

72

`+

} else {

`

``

73

`+

Err(LayoutError)

`

71

74

`}

`

``

75

`+

}

`

72

76

``

73

``

`-

// SAFETY: just checked that align is a power of two.

`

74

``

`-

Layout::from_size_alignment(size, unsafe { Alignment::new_unchecked(align) })

`

``

77

`+

const fn is_size_align_valid(size: usize, align: usize) -> bool {

`

``

78

`+

let Some(align) = Alignment::new(align) else { return false };

`

``

79

`+

if size > Self::max_size_for_align(align) {

`

``

80

`+

return false;

`

``

81

`+

}

`

``

82

`+

true

`

75

83

`}

`

76

84

``

77

85

`#[inline(always)]

`

`@@ -116,8 +124,17 @@ impl Layout {

`

116

124

`#[inline]

`

117

125

`#[rustc_allow_const_fn_unstable(ptr_alignment_type)]

`

118

126

`pub const unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self {

`

``

127

`+

assert_unsafe_precondition!(

`

``

128

`+

check_library_ub,

`

``

129

`+

"Layout::from_size_align_unchecked requires that align is a power of 2 \

`

``

130

`+

and the rounded-up allocation size does not exceed isize::MAX",

`

``

131

`+

(

`

``

132

`+

size: usize = size,

`

``

133

`+

align: usize = align,

`

``

134

`+

) => Layout::is_size_align_valid(size, align)

`

``

135

`+

);

`

119

136

`// SAFETY: the caller is required to uphold the preconditions.

`

120

``

`-

unsafe { Layout { size, align: Alignment::new_unchecked(align) } }

`

``

137

`+

unsafe { Layout { size, align: mem::transmute(align) } }

`

121

138

`}

`

122

139

``

123

140

`/// The minimum size in bytes for a memory block of this layout.

`