diff --git a/src/libcore/slice/mod.rs b/src/libcore/slice/mod.rs index eeb171ebb9b46..f9de78c6cdfea 100644 --- a/src/libcore/slice/mod.rs +++ b/src/libcore/slice/mod.rs @@ -1785,6 +1785,7 @@ impl [T] { return (self, &[], &[]); } else { let (left, rest) = self.split_at(offset); + // now `rest` is definitely aligned, so `from_raw_parts_mut` below is okay let (us_len, ts_len) = rest.align_to_offsets::(); return (left, from_raw_parts(rest.as_ptr() as *const U, us_len), @@ -1837,6 +1838,7 @@ impl [T] { return (self, &mut [], &mut []); } else { let (left, rest) = self.split_at_mut(offset); + // now `rest` is definitely aligned, so `from_raw_parts_mut` below is okay let (us_len, ts_len) = rest.align_to_offsets::(); let mut_ptr = rest.as_mut_ptr(); return (left, diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index 7968521f7b461..b087ec81f59c6 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -986,3 +986,17 @@ fn test_align_to_non_trivial() { assert_eq!(aligned.len(), 4); assert_eq!(prefix.len() + suffix.len(), 2); } + +#[test] +fn test_align_to_empty_mid() { + use core::mem; + + // Make sure that we do not create empty unaligned slices for the mid part, even when the + // overall slice is too short to contain an aligned address. + let bytes = [1, 2, 3, 4, 5, 6, 7]; + type Chunk = u32; + for offset in 0..4 { + let (_, mid, _) = unsafe { bytes[offset..offset+1].align_to::() }; + assert_eq!(mid.as_ptr() as usize % mem::align_of::(), 0); + } +}