Skip to content

Commit 6d112d7

Browse files
Miri considers way more stuff to be raw pointer aliasing now, account for that
1 parent be465c8 commit 6d112d7

File tree

8 files changed

+72
-65
lines changed

8 files changed

+72
-65
lines changed

ci/run_linux_and_mac.sh

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,10 @@ rustup default "$MIRI_NIGHTLY"
1616
rustup component add miri
1717
# The `-Zmiri-disable-isolation` is so Miri can access the system clock
1818
# while calling `SystemTime::now()` in one of the tests.
19-
export MIRIFLAGS="-Zmiri-disable-isolation"
19+
# The `-Zmiri-permissive-provenance` is because this crate has a few
20+
# integer-to-pointer casts that are needed to avoid UB with ZST-related
21+
# stuff.
22+
export MIRIFLAGS="-Zmiri-disable-isolation -Zmiri-permissive-provenance"
2023
# We run the suite once under Miri with all functionality enabled, and then once
2124
# normally without the default features just to make sure `no_std` support has
2225
# not been broken.

src/iterators.rs

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -536,15 +536,16 @@ impl<T, const N: usize> Iterator for StaticVecIntoIter<T, N> {
536536
// Get the index in `self.data` of the item to be returned.
537537
let res_index = old_start + n;
538538
// Get a pointer to the item, using the above index.
539+
let mp = StaticVec::first_ptr_mut(&mut self.data);
539540
let res = match size_of::<T>() {
540-
0 => zst_ptr_add(StaticVec::first_ptr(&self.data), res_index),
541-
_ => StaticVec::first_ptr(&self.data).add(res_index),
541+
0 => zst_ptr_add(mp, res_index),
542+
_ => mp.add(res_index),
542543
};
543544
// Drop whatever range of values may exist in earlier positions
544545
// to avoid memory leaks.
545546
let drop_at = match size_of::<T>() {
546-
0 => zst_ptr_add_mut(StaticVec::first_ptr_mut(&mut self.data), old_start),
547-
_ => StaticVec::first_ptr_mut(&mut self.data).add(old_start),
547+
0 => zst_ptr_add_mut(mp, old_start),
548+
_ => mp.add(old_start),
548549
};
549550
ptr::drop_in_place(from_raw_parts_mut(drop_at, res_index - old_start));
550551
// Adjust our starting index.
@@ -806,9 +807,8 @@ impl<'a, T: 'a, const N: usize> Drop for StaticVecDrain<'a, T, N> {
806807
let vec_ref = &mut *self.vec;
807808
let start = vec_ref.length;
808809
let tail = self.start;
809-
vec_ref
810-
.ptr_at_unchecked(tail)
811-
.copy_to(vec_ref.mut_ptr_at_unchecked(start), total_length);
810+
let mp = vec_ref.as_mut_ptr();
811+
mp.add(tail).copy_to(mp.add(start), total_length);
812812
vec_ref.set_len(start + total_length);
813813
}
814814
}

src/lib.rs

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1947,9 +1947,8 @@ impl<T, const N: usize> StaticVec<T, N> {
19471947
self
19481948
.ptr_at_unchecked(start)
19491949
.copy_to_nonoverlapping(Self::first_ptr_mut(&mut res), res_length);
1950-
self
1951-
.ptr_at_unchecked(end)
1952-
.copy_to(self.mut_ptr_at_unchecked(start), old_length - end);
1950+
let mp = self.as_mut_ptr();
1951+
mp.add(end).copy_to(mp.add(start), old_length - end);
19531952
self.set_len(old_length - res_length);
19541953
res
19551954
}
@@ -2048,9 +2047,8 @@ impl<T, const N: usize> StaticVec<T, N> {
20482047
.write(self.ptr_at_unchecked(i).read());
20492048
res_length += 1;
20502049
} else if res_length > 0 {
2051-
self
2052-
.ptr_at_unchecked(i)
2053-
.copy_to_nonoverlapping(self.mut_ptr_at_unchecked(i - res_length), 1);
2050+
let mp = self.as_mut_ptr();
2051+
mp.add(i).copy_to_nonoverlapping(mp.add(i - res_length), 1);
20542052
}
20552053
}
20562054
}
@@ -2470,8 +2468,9 @@ impl<T, const N: usize> StaticVec<T, N> {
24702468
/// ```
24712469
/// # use::staticvec::*;
24722470
/// let mut v = staticvec![4, 5, 6, 7];
2471+
/// let mp = v.as_mut_ptr();
24732472
/// let t = v.triple_mut();
2474-
/// assert_eq!(t, (v.as_mut_ptr(), 4, 4));
2473+
/// assert_eq!(t, (mp, 4, 4));
24752474
/// unsafe { *t.0 = 8 };
24762475
/// assert_eq!(v, [8, 5, 6, 7]);
24772476
/// ```

src/string/mod.rs

Lines changed: 15 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,8 @@ use core::str::{
77

88
pub use self::string_errors::StringError;
99
use self::string_utils::{
10-
encode_char_utf8_unchecked, is_char_boundary, is_inside_boundary, never, shift_left_unchecked,
11-
shift_right_unchecked, str_is_char_boundary, truncate_str,
10+
encode_char_utf8_unchecked, is_char_boundary, is_inside_boundary, never, str_is_char_boundary,
11+
truncate_str,
1212
};
1313
use crate::errors::CapacityError;
1414
use crate::StaticVec;
@@ -783,7 +783,7 @@ impl<const N: usize> StaticString<N> {
783783
}
784784
}
785785
unsafe {
786-
shift_left_unchecked(self, start, 0usize);
786+
shift_left_unchecked!(self, start, 0usize);
787787
self.vec.set_len(end - start)
788788
};
789789
}
@@ -811,7 +811,7 @@ impl<const N: usize> StaticString<N> {
811811
let character = character.unwrap_or_else(|| unsafe { never("Missing char") });
812812
let char_length = character.len_utf8();
813813
unsafe {
814-
shift_left_unchecked(self, index + char_length, index);
814+
shift_left_unchecked!(self, index + char_length, index);
815815
self.vec.set_len(old_length - char_length);
816816
}
817817
character
@@ -922,7 +922,7 @@ impl<const N: usize> StaticString<N> {
922922
#[inline(always)]
923923
pub unsafe fn insert_unchecked(&mut self, index: usize, character: char) {
924924
let char_length = character.len_utf8();
925-
shift_right_unchecked(self, index, index + char_length);
925+
shift_right_unchecked!(self, index, index + char_length);
926926
encode_char_utf8_unchecked(self, character, index);
927927
}
928928

@@ -1010,7 +1010,7 @@ impl<const N: usize> StaticString<N> {
10101010
let string_length = string_ref.len();
10111011
debug_assert!(string_length <= self.remaining_capacity());
10121012
let string_ptr = string_ref.as_ptr();
1013-
shift_right_unchecked(self, index, index + string_length);
1013+
shift_right_unchecked!(self, index, index + string_length);
10141014
string_ptr.copy_to_nonoverlapping(self.vec.mut_ptr_at_unchecked(index), string_length);
10151015
self.vec.set_len(self.len() + string_length);
10161016
}
@@ -1213,17 +1213,20 @@ impl<const N: usize> StaticString<N> {
12131213
);
12141214
if replace_length == 0 {
12151215
unsafe {
1216-
self
1217-
.as_ptr()
1218-
.add(end)
1219-
.copy_to(self.as_mut_ptr().add(start), old_length.saturating_sub(end));
1216+
let mp = self.vec.as_mut_ptr();
1217+
mp.add(end)
1218+
.copy_to(mp.add(start), old_length.saturating_sub(end));
12201219
self.vec.set_len(old_length.saturating_sub(replaced));
12211220
}
12221221
} else {
12231222
if start + replace_length > end {
1224-
unsafe { shift_right_unchecked(self, end, start + replace_length) };
1223+
unsafe {
1224+
shift_right_unchecked!(self, end, start + replace_length);
1225+
}
12251226
} else {
1226-
unsafe { shift_left_unchecked(self, end, start + replace_length) };
1227+
unsafe {
1228+
shift_left_unchecked!(self, end, start + replace_length);
1229+
}
12271230
}
12281231
let ptr = replace_with.as_ptr();
12291232
let dest = unsafe { self.vec.as_mut_ptr().add(start) };

src/string/string_trait_impls.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
use core::borrow::{Borrow, BorrowMut};
22
use core::cmp::Ordering;
3+
use core::convert::Infallible;
34
use core::fmt::{self, Arguments, Debug, Display, Formatter, Write};
45
use core::hash::{Hash, Hasher};
56
use core::iter::FromIterator;
@@ -211,7 +212,7 @@ impl<'a, const N: usize> FromIterator<&'a str> for StaticString<N> {
211212
}
212213

213214
impl<'a, const N: usize> FromStr for StaticString<N> {
214-
type Err = ();
215+
type Err = Infallible;
215216

216217
#[inline(always)]
217218
fn from_str(s: &str) -> Result<Self, Self::Err> {

src/string/string_utils.rs

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -76,34 +76,27 @@ pub(crate) const fn encode_utf8_raw(code: u32, len: usize) -> [u8; 4] {
7676
res
7777
}
7878

79-
/// Shifts `string` to the right.
80-
#[inline(always)]
81-
pub(crate) unsafe fn shift_right_unchecked<const N: usize>(
82-
string: &mut StaticString<N>,
83-
from: usize,
84-
to: usize,
85-
) {
86-
debug_assert!(from <= to && to + string.len() - from <= string.capacity());
87-
debug_assert!(string.as_str().is_char_boundary(from));
88-
string
89-
.as_ptr()
90-
.add(from)
91-
.copy_to(string.as_mut_ptr().add(to), string.len() - from);
79+
macro_rules! shift_right_unchecked {
80+
($self_var:expr, $from_var:expr, $to_var:expr) => {
81+
debug_assert!(
82+
$from_var as usize <= $to_var as usize
83+
&& $to_var as usize + $self_var.len() - $from_var as usize <= $self_var.capacity()
84+
);
85+
debug_assert!($self_var.as_str().is_char_boundary($from_var));
86+
let mp = $self_var.vec.as_mut_ptr();
87+
mp.add($from_var)
88+
.copy_to(mp.add($to_var), $self_var.len() - $from_var);
89+
};
9290
}
9391

94-
/// Shifts `string` to the left.
95-
#[inline(always)]
96-
pub(crate) unsafe fn shift_left_unchecked<const N: usize>(
97-
string: &mut StaticString<N>,
98-
from: usize,
99-
to: usize,
100-
) {
101-
debug_assert!(to <= from && from <= string.len());
102-
debug_assert!(string.as_str().is_char_boundary(from));
103-
string
104-
.as_ptr()
105-
.add(from)
106-
.copy_to(string.as_mut_ptr().add(to), string.len() - from);
92+
macro_rules! shift_left_unchecked {
93+
($self_var:expr, $from_var:expr, $to_var:expr) => {
94+
debug_assert!($to_var as usize <= $from_var as usize && $from_var as usize <= $self_var.len());
95+
debug_assert!($self_var.as_str().is_char_boundary($from_var));
96+
let mp = $self_var.vec.as_mut_ptr();
97+
mp.add($from_var)
98+
.copy_to(mp.add($to_var), $self_var.len() - $from_var);
99+
};
107100
}
108101

109102
/// Returns an error if `size` is greater than `limit`.
@@ -205,25 +198,33 @@ mod tests {
205198
#[test]
206199
fn shift_right() {
207200
let mut ls = StaticString::<20>::try_from_str("abcdefg").unwrap();
208-
unsafe { shift_right_unchecked(&mut ls, 0usize, 4usize) };
201+
unsafe {
202+
shift_right_unchecked!(ls, 0usize, 4usize);
203+
}
209204
unsafe { ls.vec.set_len(ls.len() + 4) };
210205
assert_eq!(ls.as_str(), "abcdabcdefg");
211206
}
212207

213208
#[test]
214209
fn shift_left() {
215210
let mut ls = StaticString::<20>::try_from_str("abcdefg").unwrap();
216-
unsafe { shift_left_unchecked(&mut ls, 1usize, 0usize) };
211+
unsafe {
212+
shift_left_unchecked!(ls, 1usize, 0usize);
213+
}
217214
unsafe { ls.vec.set_len(ls.len() - 1) };
218215
assert_eq!(ls.as_str(), "bcdefg");
219216
}
220217

221218
#[test]
222219
fn shift_nop() {
223220
let mut ls = StaticString::<20>::try_from_str("abcdefg").unwrap();
224-
unsafe { shift_right_unchecked(&mut ls, 0usize, 0usize) };
221+
unsafe {
222+
shift_right_unchecked!(ls, 0usize, 0usize);
223+
}
225224
assert_eq!(ls.as_str(), "abcdefg");
226-
unsafe { shift_left_unchecked(&mut ls, 0usize, 0usize) };
225+
unsafe {
226+
shift_left_unchecked!(ls, 0usize, 0usize);
227+
}
227228
assert_eq!(ls.as_str(), "abcdefg");
228229
}
229230

src/trait_impls.rs

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -811,9 +811,9 @@ impl<const N: usize> Read for StaticVec<u8, N> {
811811
if read_length < current_length {
812812
// Safety: we just confirmed that `read_length` is less than our current length.
813813
unsafe {
814-
self
815-
.ptr_at_unchecked(read_length)
816-
.copy_to(self.as_mut_ptr(), current_length - read_length)
814+
let mp = self.as_mut_ptr();
815+
mp.add(read_length)
816+
.copy_to(mp, current_length - read_length)
817817
};
818818
}
819819
// Safety: 0 <= `read_length` <= `current_length`.
@@ -881,9 +881,8 @@ impl<const N: usize> Read for StaticVec<u8, N> {
881881
let total_read = old_length - current_length;
882882
if current_length > 0 {
883883
unsafe {
884-
self
885-
.ptr_at_unchecked(total_read)
886-
.copy_to(self.as_mut_ptr(), current_length);
884+
let mp = self.as_mut_ptr();
885+
mp.add(total_read).copy_to(mp, current_length);
887886
}
888887
}
889888
Ok(total_read)

test/test_staticvec.rs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2554,8 +2554,9 @@ fn triple() {
25542554
#[test]
25552555
fn triple_mut() {
25562556
let mut v = staticvec![4, 5, 6, 7];
2557+
let mp = v.as_mut_ptr();
25572558
let t = v.triple_mut();
2558-
assert_eq!(t, (v.as_mut_ptr(), 4, 4));
2559+
assert_eq!(t, (mp, 4, 4));
25592560
unsafe { *t.0 = 8 };
25602561
assert_eq!(v, [8, 5, 6, 7]);
25612562
}

0 commit comments

Comments
 (0)