about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEduard-Mihai Burtescu <edy.burt@gmail.com>2016-11-12 10:38:44 +0200
committerGitHub <noreply@github.com>2016-11-12 10:38:44 +0200
commit69717bbdedbc9cecb3b8e133d1e1a4813e34b4e1 (patch)
tree95e8548cc054d803aee12bdd39bfda57e1d28b21 /src
parentafbb675f2ec243358933f9fa16175fd8db83a3ae (diff)
parent323c20c8a4747aa96285c90005a00aa43228af8e (diff)
downloadrust-69717bbdedbc9cecb3b8e133d1e1a4813e34b4e1.tar.gz
rust-69717bbdedbc9cecb3b8e133d1e1a4813e34b4e1.zip
Rollup merge of #37708 - oli-obk:box_free, r=eddyb
change the `box_free` lang item to accept pointers to unsized types

in miri we use the `box_free` lang item as the destructor for `Box` objects, since the function's api matches that of an `fn drop(&mut self)` in a hypothetical `impl<T: ?Sized> Drop for Box<T>` exactly.

This works fine except if we insert a check in the `size_of` intrinsic to ensure that it is only called with sized types, since the `box_free` lang item calls that intrinsic.

cc @eddyb

no clue who to r? here, probably lang team?
Diffstat (limited to 'src')
-rw-r--r--src/doc/book/lang-items.md4
-rw-r--r--src/liballoc/heap.rs9
2 files changed, 7 insertions, 6 deletions
diff --git a/src/doc/book/lang-items.md b/src/doc/book/lang-items.md
index de7dbab3f12..9fb130845fb 100644
--- a/src/doc/book/lang-items.md
+++ b/src/doc/book/lang-items.md
@@ -46,8 +46,8 @@ unsafe fn deallocate(ptr: *mut u8, _size: usize, _align: usize) {
 }
 
 #[lang = "box_free"]
-unsafe fn box_free<T>(ptr: *mut T) {
-    deallocate(ptr as *mut u8, ::core::mem::size_of::<T>(), ::core::mem::align_of::<T>());
+unsafe fn box_free<T: ?Sized>(ptr: *mut T) {
+    deallocate(ptr as *mut u8, ::core::mem::size_of_val(&*ptr), ::core::mem::align_of_val(&*ptr));
 }
 
 #[start]
diff --git a/src/liballoc/heap.rs b/src/liballoc/heap.rs
index bfed8a8e83a..12809171b74 100644
--- a/src/liballoc/heap.rs
+++ b/src/liballoc/heap.rs
@@ -17,7 +17,7 @@
 
 use core::{isize, usize};
 #[cfg(not(test))]
-use core::intrinsics::{min_align_of, size_of};
+use core::intrinsics::{min_align_of_val, size_of_val};
 
 #[allow(improper_ctypes)]
 extern "C" {
@@ -152,11 +152,12 @@ unsafe fn exchange_free(ptr: *mut u8, old_size: usize, align: usize) {
 #[cfg(not(test))]
 #[lang = "box_free"]
 #[inline]
-unsafe fn box_free<T>(ptr: *mut T) {
-    let size = size_of::<T>();
+unsafe fn box_free<T: ?Sized>(ptr: *mut T) {
+    let size = size_of_val(&*ptr);
+    let align = min_align_of_val(&*ptr);
     // We do not allocate for Box<T> when T is ZST, so deallocation is also not necessary.
     if size != 0 {
-        deallocate(ptr as *mut u8, size, min_align_of::<T>());
+        deallocate(ptr as *mut u8, size, align);
     }
 }