about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-05-19 02:31:32 +0200
committerGitHub <noreply@github.com>2019-05-19 02:31:32 +0200
commit7885dfc62385b722e04067b2d5c26aeea429fb02 (patch)
tree0e2763a862c5adba15a38f940376f81ac71e92fd /src
parent963184bbb670c1ffa97fc28a98cd5e8473118859 (diff)
parentc0b6d3c975915e740548f0ec7bcf5963e7a3b218 (diff)
downloadrust-7885dfc62385b722e04067b2d5c26aeea429fb02.tar.gz
rust-7885dfc62385b722e04067b2d5c26aeea429fb02.zip
Rollup merge of #60370 - Richard-W:const-layout-construction, r=sfackler
Mark core::alloc::Layout::from_size_align_unchecked const

Makes it possible (pending stabilization of #57563 (`const_fn`)) to rewrite code like

```rust
const BUFFER_SIZE: usize = 0x2000;
const BUFFER_ALIGN: usize = 0x1000;

fn foo() {
  let layout = std::alloc::Layout::from_size_align(BUFFER_SIZE, BUFFER_ALIGN)
    .unwrap();
  let buffer = std::alloc::alloc(layout);
}
```
to
```rust
const BUFFER_LAYOUT: std::alloc::Layout = unsafe {
  std::alloc::Layout::from_size_align_unchecked(0x2000, 0x1000)
};

fn foo() {
  let buffer = std::alloc::alloc(BUFFER_LAYOUT);
}
```

which (although `unsafe` is used) looks somewhat cleaner and is easier to read.
Diffstat (limited to 'src')
-rw-r--r--src/libcore/alloc.rs2
-rw-r--r--src/libcore/tests/alloc.rs10
-rw-r--r--src/libcore/tests/lib.rs2
-rw-r--r--src/test/ui/consts/std/alloc.rs10
-rw-r--r--src/test/ui/consts/std/alloc.stderr11
5 files changed, 34 insertions, 1 deletions
diff --git a/src/libcore/alloc.rs b/src/libcore/alloc.rs
index c124457118c..302a9d89e58 100644
--- a/src/libcore/alloc.rs
+++ b/src/libcore/alloc.rs
@@ -99,7 +99,7 @@ impl Layout {
     /// [`Layout::from_size_align`](#method.from_size_align).
     #[stable(feature = "alloc_layout", since = "1.28.0")]
     #[inline]
-    pub unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self {
+    pub const unsafe fn from_size_align_unchecked(size: usize, align: usize) -> Self {
         Layout { size_: size, align_: NonZeroUsize::new_unchecked(align) }
     }
 
diff --git a/src/libcore/tests/alloc.rs b/src/libcore/tests/alloc.rs
new file mode 100644
index 00000000000..63537ba23d8
--- /dev/null
+++ b/src/libcore/tests/alloc.rs
@@ -0,0 +1,10 @@
+use core::alloc::Layout;
+
+#[test]
+fn const_unchecked_layout() {
+    const SIZE: usize = 0x2000;
+    const ALIGN: usize = 0x1000;
+    const LAYOUT: Layout = unsafe { Layout::from_size_align_unchecked(SIZE, ALIGN) };
+    assert_eq!(LAYOUT.size(), SIZE);
+    assert_eq!(LAYOUT.align(), ALIGN);
+}
diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs
index b8075ef2942..c617596aba8 100644
--- a/src/libcore/tests/lib.rs
+++ b/src/libcore/tests/lib.rs
@@ -31,10 +31,12 @@
 #![feature(slice_partition_dedup)]
 #![feature(copy_within)]
 #![feature(int_error_matching)]
+#![feature(const_fn)]
 #![warn(rust_2018_idioms)]
 
 extern crate test;
 
+mod alloc;
 mod any;
 mod array;
 mod ascii;
diff --git a/src/test/ui/consts/std/alloc.rs b/src/test/ui/consts/std/alloc.rs
new file mode 100644
index 00000000000..65ac7e44926
--- /dev/null
+++ b/src/test/ui/consts/std/alloc.rs
@@ -0,0 +1,10 @@
+use std::alloc::Layout;
+
+// ok
+const LAYOUT_VALID: Layout = unsafe { Layout::from_size_align_unchecked(0x1000, 0x08) };
+
+// not ok, since alignment needs to be non-zero.
+const LAYOUT_INVALID: Layout = unsafe { Layout::from_size_align_unchecked(0x1000, 0x00) };
+//~^ ERROR it is undefined behavior to use this value
+
+fn main() {}
diff --git a/src/test/ui/consts/std/alloc.stderr b/src/test/ui/consts/std/alloc.stderr
new file mode 100644
index 00000000000..74a8f3daf6a
--- /dev/null
+++ b/src/test/ui/consts/std/alloc.stderr
@@ -0,0 +1,11 @@
+error[E0080]: it is undefined behavior to use this value
+  --> $DIR/alloc.rs:7:1
+   |
+LL | const LAYOUT_INVALID: Layout = unsafe { Layout::from_size_align_unchecked(0x1000, 0x00) };
+   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0 at .align_, but expected something greater or equal to 1
+   |
+   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior
+
+error: aborting due to previous error
+
+For more information about this error, try `rustc --explain E0080`.