diff --git a/.travis.yml b/.travis.yml index 0285f06..42816fe 100644 --- a/.travis.yml +++ b/.travis.yml @@ -22,6 +22,8 @@ matrix: - rust: nightly env: - FEATURES='array-sizes-33-128 array-sizes-129-255' + - name: "miri" + script: sh ci/miri.sh branches: only: - master diff --git a/ci/miri.sh b/ci/miri.sh new file mode 100644 index 0000000..5528bbc --- /dev/null +++ b/ci/miri.sh @@ -0,0 +1,15 @@ +#!/usr/bin/env sh + +set -ex + +export CARGO_NET_RETRY=5 +export CARGO_NET_TIMEOUT=10 + +MIRI_NIGHTLY=nightly-$(curl -s https://rust-lang.github.io/rustup-components-history/x86_64-unknown-linux-gnu/miri) +echo "Installing latest nightly with Miri: $MIRI_NIGHTLY" +rustup default "$MIRI_NIGHTLY" + +rustup component add miri +cargo miri setup + +cargo miri test -- -- -Zunstable-options --exclude-should-panic diff --git a/src/char.rs b/src/char.rs index c9b00ca..ff060ea 100644 --- a/src/char.rs +++ b/src/char.rs @@ -63,6 +63,7 @@ pub unsafe fn encode_utf8(ch: char, ptr: *mut u8, len: usize) -> Result ArrayVec { fn drain_range(&mut self, start: usize, end: usize) -> Drain { let len = self.len(); - // bounds check happens here + + // bounds check happens here (before length is changed!) let range_slice: *const _ = &self[start..end]; + // Calling `set_len` creates a fresh and thus unique mutable references, making all + // older aliases we created invalid. So we cannot call that function. + self.len = Index::from(start); + unsafe { - // set self.vec length's to start, to be safe in case Drain is leaked - self.set_len(start); Drain { tail_start: end, tail_len: len - end, diff --git a/tests/tests.rs b/tests/tests.rs index 1cf3aad..0b2f229 100644 --- a/tests/tests.rs +++ b/tests/tests.rs @@ -165,6 +165,7 @@ fn test_drop() { } #[test] +#[cfg(not(miri))] // Miri does not support unwinding fn test_drop_panics() { use std::cell::Cell; use std::panic::catch_unwind;