about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/libcore/intrinsics.rs33
-rw-r--r--src/libcore/ptr.rs75
-rw-r--r--src/libcore/str/mod.rs3
-rw-r--r--src/libstd/lib.rs1
-rw-r--r--src/libstd/sys_common/memchr.rs9
5 files changed, 80 insertions, 41 deletions
diff --git a/src/libcore/intrinsics.rs b/src/libcore/intrinsics.rs
index f7f1dd12d28..bc82f0230e5 100644
--- a/src/libcore/intrinsics.rs
+++ b/src/libcore/intrinsics.rs
@@ -1381,38 +1381,7 @@ extern "rust-intrinsic" {
 }
 
 #[cfg(stage0)]
-/// Computes the byte offset that needs to be applied to `ptr` in order to
-/// make it aligned to `align`.
-/// If it is not possible to align `ptr`, the implementation returns
-/// `usize::max_value()`.
-///
-/// There are no guarantees whatsover that offsetting the pointer will not
-/// overflow or go beyond the allocation that `ptr` points into.
-/// It is up to the caller to ensure that the returned offset is correct
-/// in all terms other than alignment.
-///
-/// # Examples
-///
-/// Accessing adjacent `u8` as `u16`
-///
-/// ```
-/// # #![feature(core_intrinsics)]
-/// # fn foo(n: usize) {
-/// # use std::intrinsics::align_offset;
-/// # use std::mem::align_of;
-/// # unsafe {
-/// let x = [5u8, 6u8, 7u8, 8u8, 9u8];
-/// let ptr = &x[n] as *const u8;
-/// let offset = align_offset(ptr as *const (), align_of::<u16>());
-/// if offset < x.len() - n - 1 {
-///     let u16_ptr = ptr.offset(offset as isize) as *const u16;
-///     assert_ne!(*u16_ptr, 500);
-/// } else {
-///     // while the pointer can be aligned via `offset`, it would point
-///     // outside the allocation
-/// }
-/// # } }
-/// ```
+/// remove me after the next release
 pub unsafe fn align_offset(ptr: *const (), align: usize) -> usize {
     let offset = ptr as usize % align;
     if offset == 0 {
diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs
index dd01534ec02..4041a3760e5 100644
--- a/src/libcore/ptr.rs
+++ b/src/libcore/ptr.rs
@@ -1064,7 +1064,43 @@ impl<T: ?Sized> *const T {
         copy_nonoverlapping(self, dest, count)
     }
 
-
+    /// Computes the byte offset that needs to be applied in order to
+    /// make the pointer aligned to `align`.
+    /// If it is not possible to align the pointer, the implementation returns
+    /// `usize::max_value()`.
+    ///
+    /// There are no guarantees whatsover that offsetting the pointer will not
+    /// overflow or go beyond the allocation that the pointer points into.
+    /// It is up to the caller to ensure that the returned offset is correct
+    /// in all terms other than alignment.
+    ///
+    /// # Examples
+    ///
+    /// Accessing adjacent `u8` as `u16`
+    ///
+    /// ```
+    /// # #![feature(align_offset)]
+    /// # fn foo(n: usize) {
+    /// # use std::mem::align_of;
+    /// # unsafe {
+    /// let x = [5u8, 6u8, 7u8, 8u8, 9u8];
+    /// let ptr = &x[n] as *const u8;
+    /// let offset = ptr.align_offset(align_of::<u16>());
+    /// if offset < x.len() - n - 1 {
+    ///     let u16_ptr = ptr.offset(offset as isize) as *const u16;
+    ///     assert_ne!(*u16_ptr, 500);
+    /// } else {
+    ///     // while the pointer can be aligned via `offset`, it would point
+    ///     // outside the allocation
+    /// }
+    /// # } }
+    /// ```
+    #[unstable(feature = "align_offset", issue = "44488")]
+    pub fn align_offset(self, align: usize) -> usize {
+        unsafe {
+            intrinsics::align_offset(self as *const _, align)
+        }
+    }
 }
 
 #[lang = "mut_ptr"]
@@ -1284,6 +1320,43 @@ impl<T: ?Sized> *mut T {
         }
     }
 
+    /// Computes the byte offset that needs to be applied in order to
+    /// make the pointer aligned to `align`.
+    /// If it is not possible to align the pointer, the implementation returns
+    /// `usize::max_value()`.
+    ///
+    /// There are no guarantees whatsover that offsetting the pointer will not
+    /// overflow or go beyond the allocation that the pointer points into.
+    /// It is up to the caller to ensure that the returned offset is correct
+    /// in all terms other than alignment.
+    ///
+    /// # Examples
+    ///
+    /// Accessing adjacent `u8` as `u16`
+    ///
+    /// ```
+    /// # #![feature(align_offset)]
+    /// # fn foo(n: usize) {
+    /// # use std::mem::align_of;
+    /// # unsafe {
+    /// let x = [5u8, 6u8, 7u8, 8u8, 9u8];
+    /// let ptr = &x[n] as *const u8;
+    /// let offset = ptr.align_offset(align_of::<u16>());
+    /// if offset < x.len() - n - 1 {
+    ///     let u16_ptr = ptr.offset(offset as isize) as *const u16;
+    ///     assert_ne!(*u16_ptr, 500);
+    /// } else {
+    ///     // while the pointer can be aligned via `offset`, it would point
+    ///     // outside the allocation
+    /// }
+    /// # } }
+    /// ```
+    #[unstable(feature = "align_offset", issue = "44488")]
+    pub fn align_offset(self, align: usize) -> usize {
+        unsafe {
+            intrinsics::align_offset(self as *const _, align)
+        }
+    }
 
     /// Calculates the offset from a pointer (convenience for `.offset(count as isize)`).
     ///
diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs
index d4fef45ae4e..0d907d11cfb 100644
--- a/src/libcore/str/mod.rs
+++ b/src/libcore/str/mod.rs
@@ -23,7 +23,6 @@ use fmt;
 use iter::{Map, Cloned, FusedIterator};
 use slice::{self, SliceIndex};
 use mem;
-use intrinsics::align_offset;
 
 pub mod pattern;
 
@@ -1515,7 +1514,7 @@ fn run_utf8_validation(v: &[u8]) -> Result<(), Utf8Error> {
             let ptr = v.as_ptr();
             let align = unsafe {
                 // the offset is safe, because `index` is guaranteed inbounds
-                align_offset(ptr.offset(index as isize) as *const (), usize_bytes)
+                ptr.offset(index as isize).align_offset(usize_bytes)
             };
             if align == 0 {
                 while index < blocks_end {
diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs
index 1a0f8b8d217..a3eecd46e90 100644
--- a/src/libstd/lib.rs
+++ b/src/libstd/lib.rs
@@ -242,6 +242,7 @@
 #![feature(allocator_internals)]
 #![feature(allow_internal_unsafe)]
 #![feature(allow_internal_unstable)]
+#![feature(align_offset)]
 #![feature(asm)]
 #![feature(box_syntax)]
 #![feature(cfg_target_has_atomic)]
diff --git a/src/libstd/sys_common/memchr.rs b/src/libstd/sys_common/memchr.rs
index 3824a5fb528..50f998eb486 100644
--- a/src/libstd/sys_common/memchr.rs
+++ b/src/libstd/sys_common/memchr.rs
@@ -65,15 +65,12 @@ pub mod fallback {
         let usize_bytes = mem::size_of::<usize>();
 
         // search up to an aligned boundary
-        let align = (ptr as usize) & (usize_bytes- 1);
-        let mut offset;
-        if align > 0 {
-            offset = cmp::min(usize_bytes - align, len);
+        let mut offset = ptr.align_offset(usize_bytes);
+        if offset > 0 {
+            offset = cmp::min(offset, len);
             if let Some(index) = text[..offset].iter().position(|elt| *elt == x) {
                 return Some(index);
             }
-        } else {
-            offset = 0;
         }
 
         // search the body of the text