diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4b8dcf189..8e2a9d66c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -54,6 +54,21 @@ jobs: - uses: dtolnay/rust-toolchain@stable - run: cargo test --all-features + miri: + runs-on: ubuntu-latest + env: + CARGO_TERM_COLOR: always + steps: + - uses: actions/checkout@v4 + - uses: dtolnay/rust-toolchain@master + with: + toolchain: nightly + components: miri + - uses: taiki-e/install-action@nextest + - run: | + cargo miri nextest run --all-features + cargo miri test --doc + check-format: name: check format runs-on: ubuntu-latest diff --git a/tests/quick.rs b/tests/quick.rs index 12b6b9d5a..672901e7c 100644 --- a/tests/quick.rs +++ b/tests/quick.rs @@ -2,7 +2,11 @@ //! and adaptors. //! //! In particular we test the tedious size_hint and exact size correctness. +//! +//! **NOTE:** Due to performance limitations, these tests are not run with miri! +//! They cannot be relied upon to discover soundness issues. +#![cfg(not(miri))] #![allow(deprecated, unstable_name_collisions)] use itertools::free::{ diff --git a/tests/specializations.rs b/tests/specializations.rs index ff3d5c19b..3e4831024 100644 --- a/tests/specializations.rs +++ b/tests/specializations.rs @@ -1,3 +1,10 @@ +//! Test specializations of methods with default impls match the behavior of the +//! default impls. +//! +//! **NOTE:** Due to performance limitations, these tests are not run with miri! +//! They cannot be relied upon to discover soundness issues. + +#![cfg(not(miri))] #![allow(unstable_name_collisions)] use itertools::Itertools; diff --git a/tests/test_std.rs b/tests/test_std.rs index 00246d506..f626a17d7 100644 --- a/tests/test_std.rs +++ b/tests/test_std.rs @@ -491,6 +491,7 @@ fn sorted_by() { it::assert_equal(v, vec![4, 3, 2, 1, 0]); } +#[cfg(not(miri))] qc::quickcheck! { fn k_smallest_range(n: i64, m: u16, k: u16) -> () { // u16 is used to constrain k and m to 0..2¹⁶, @@ -598,7 +599,9 @@ macro_rules! generic_test { }; } +#[cfg(not(miri))] generic_test!(k_smallest_sort, u8, u16, u32, u64, i8, i16, i32, i64); +#[cfg(not(miri))] generic_test!(k_smallest_by_sort, u8, u16, u32, u64, i8, i16, i32, i64); #[test] @@ -1055,8 +1058,8 @@ fn binomial(n: usize, k: usize) -> usize { #[test] fn combinations_range_count() { - for n in 0..=10 { - for k in 0..=10 { + for n in 0..=7 { + for k in 0..=7 { let len = binomial(n, k); let mut it = (0..n).combinations(k); assert_eq!(len, it.clone().count()); @@ -1077,7 +1080,7 @@ fn combinations_range_count() { #[test] fn combinations_inexact_size_hints() { - for k in 0..=10 { + for k in 0..=7 { let mut numbers = (0..18).filter(|i| i % 2 == 0); // 9 elements let mut it = numbers.clone().combinations(k); let real_n = numbers.clone().count(); @@ -1129,8 +1132,8 @@ fn permutations_zero() { #[test] fn permutations_range_count() { - for n in 0..=7 { - for k in 0..=7 { + for n in 0..=4 { + for k in 0..=4 { let len = if k <= n { (n - k + 1..=n).product() } else { 0 }; let mut it = (0..n).permutations(k); assert_eq!(len, it.clone().count()); @@ -1162,6 +1165,7 @@ fn permutations_overflowed_size_hints() { } #[test] +#[cfg(not(miri))] fn combinations_with_replacement() { // Pool smaller than n it::assert_equal((0..1).combinations_with_replacement(2), vec![vec![0, 0]]); @@ -1190,8 +1194,8 @@ fn combinations_with_replacement() { #[test] fn combinations_with_replacement_range_count() { - for n in 0..=7 { - for k in 0..=7 { + for n in 0..=4 { + for k in 0..=4 { let len = binomial(usize::saturating_sub(n + k, 1), k); let mut it = (0..n).combinations_with_replacement(k); assert_eq!(len, it.clone().count()); @@ -1236,7 +1240,7 @@ fn powerset() { assert_eq!((0..8).powerset().count(), 1 << 8); assert_eq!((0..16).powerset().count(), 1 << 16); - for n in 0..=10 { + for n in 0..=4 { let mut it = (0..n).powerset(); let len = 2_usize.pow(n); assert_eq!(len, it.clone().count());