about summary refs log tree commit diff
path: root/library/core/src/alloc/layout.rs
diff options
context:
space:
mode:
authorScott McMurray <scottmcm@users.noreply.github.com>2022-03-27 00:06:26 -0700
committerScott McMurray <scottmcm@users.noreply.github.com>2022-04-08 20:17:38 -0700
commitfe0c08a4f24ff7e6fb03b61656436bfa5ff29ac7 (patch)
tree1d767c6d460f1fd8b6eb76f32cca54d33e445fda /library/core/src/alloc/layout.rs
parent185a3f0a112fd6439247cf15452d0c5dfb3c8c92 (diff)
downloadrust-fe0c08a4f24ff7e6fb03b61656436bfa5ff29ac7.tar.gz
rust-fe0c08a4f24ff7e6fb03b61656436bfa5ff29ac7.zip
Make non-power-of-two alignments a validity error in `Layout`
Inspired by the zulip conversation about how `Layout` should better enforce `size < isize::MAX as usize`, this uses an N-variant enum on N-bit platforms to require at the validity level that the existing invariant of "must be a power of two" is upheld.

This was MIRI can catch it, and means there's a more-specific type for `Layout` to store than just `NonZeroUsize`.
Diffstat (limited to 'library/core/src/alloc/layout.rs')
-rw-r--r--library/core/src/alloc/layout.rs11
1 files changed, 5 insertions, 6 deletions
diff --git a/library/core/src/alloc/layout.rs b/library/core/src/alloc/layout.rs
index ea639268652..4bb5e52e23a 100644
--- a/library/core/src/alloc/layout.rs
+++ b/library/core/src/alloc/layout.rs
@@ -1,7 +1,6 @@
 use crate::cmp;
 use crate::fmt;
-use crate::mem;
-use crate::num::NonZeroUsize;
+use crate::mem::{self, ValidAlign};
 use crate::ptr::NonNull;
 
 // While this function is used in one place and its implementation
@@ -40,7 +39,7 @@ pub struct Layout {
     //
     // (However, we do not analogously require `align >= sizeof(void*)`,
     //  even though that is *also* a requirement of `posix_memalign`.)
-    align_: NonZeroUsize,
+    align_: ValidAlign,
 }
 
 impl Layout {
@@ -97,8 +96,8 @@ impl Layout {
     #[must_use]
     #[inline]
     pub const unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self {
-        // SAFETY: the caller must ensure that `align` is greater than zero.
-        Layout { size_: size, align_: unsafe { NonZeroUsize::new_unchecked(align) } }
+        // SAFETY: the caller must ensure that `align` is a power of two.
+        Layout { size_: size, align_: unsafe { ValidAlign::new_unchecked(align) } }
     }
 
     /// The minimum size in bytes for a memory block of this layout.
@@ -117,7 +116,7 @@ impl Layout {
                   without modifying the layout"]
     #[inline]
     pub const fn align(&self) -> usize {
-        self.align_.get()
+        self.align_.as_nonzero().get()
     }
 
     /// Constructs a `Layout` suitable for holding a value of type `T`.