diff --git a/.cargo/config b/.cargo/config.toml similarity index 100% rename from .cargo/config rename to .cargo/config.toml diff --git a/.github/workflows/safety.yml b/.github/workflows/safety.yml index f4bf8218..3d9455ac 100644 --- a/.github/workflows/safety.yml +++ b/.github/workflows/safety.yml @@ -54,3 +54,26 @@ jobs: env: LSAN_OPTIONS: "suppressions=lsan-suppressions.txt" RUSTFLAGS: "-Z sanitizer=leak" + miri: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + with: + submodules: true + - run: | + echo "NIGHTLY=nightly-$(curl -s https://rust-lang.github.io/rustup-components-history/x86_64-unknown-linux-gnu/miri)" >> $GITHUB_ENV + - name: Install ${{ env.NIGHTLY }} + uses: dtolnay/rust-toolchain@master + with: + toolchain: ${{ env.NIGHTLY }} + components: miri + - name: Install cargo-nextest + uses: baptiste0928/cargo-install@v1 + with: + crate: cargo-nextest + locked: true + - name: cargo miri test + timeout-minutes: 120 + run: cargo miri nextest run --no-default-features --features=image/default + env: + MIRIFLAGS: "" diff --git a/src/binary_descriptors/brief.rs b/src/binary_descriptors/brief.rs index 0256026c..1ebafdaa 100644 --- a/src/binary_descriptors/brief.rs +++ b/src/binary_descriptors/brief.rs @@ -269,13 +269,11 @@ pub fn brief( #[cfg(test)] mod tests { + use super::*; + use crate::utils::gray_bench_image; use rand::Rng; use test::{black_box, Bencher}; - use crate::utils::gray_bench_image; - - use super::*; - #[test] fn test_compute_hamming_distance() { let d1 = BriefDescriptor { @@ -326,8 +324,16 @@ mod tests { let integral_image: ImageBuffer, Vec> = integral_image(&image); assert_eq!(local_pixel_average(&integral_image, 3, 3, 2), 117); } +} + +#[cfg(not(miri))] +#[cfg(test)] +mod benches { + use super::*; + use crate::utils::gray_bench_image; + use rand::Rng; + use test::{black_box, Bencher}; - #[cfg_attr(miri, ignore)] #[bench] #[ignore] fn bench_brief_random_test_pairs_1000_keypoints(b: &mut Bencher) { @@ -346,7 +352,6 @@ mod tests { }) } - #[cfg_attr(miri, ignore)] #[bench] #[ignore] fn bench_brief_fixed_test_pairs_1000_keypoints(b: &mut Bencher) { diff --git a/src/binary_descriptors/mod.rs b/src/binary_descriptors/mod.rs index 47526dfa..f695bc14 100644 --- a/src/binary_descriptors/mod.rs +++ b/src/binary_descriptors/mod.rs @@ -133,7 +133,7 @@ pub fn match_binary_descriptors<'a, T: BinaryDescriptor>( matches } -#[cfg_attr(miri, ignore)] +#[cfg(not(miri))] #[cfg(test)] mod benches { use super::*; diff --git a/src/distance_transform.rs b/src/distance_transform.rs index a044f3ae..4eccf4ed 100644 --- a/src/distance_transform.rs +++ b/src/distance_transform.rs @@ -582,7 +582,7 @@ mod tests { } } -#[cfg_attr(miri, ignore)] +#[cfg(not(miri))] #[cfg(test)] mod benches { use super::*; diff --git a/src/drawing/bezier.rs b/src/drawing/bezier.rs index 1107a32f..ea4ee1f9 100644 --- a/src/drawing/bezier.rs +++ b/src/drawing/bezier.rs @@ -81,7 +81,7 @@ pub fn draw_cubic_bezier_curve_mut( } } -#[cfg_attr(miri, ignore)] +#[cfg(not(miri))] #[cfg(test)] mod benches { use image::{GrayImage, Luma}; diff --git a/src/drawing/conics.rs b/src/drawing/conics.rs index 8715a0c1..11b07ea2 100644 --- a/src/drawing/conics.rs +++ b/src/drawing/conics.rs @@ -356,6 +356,7 @@ mod tests { } } + #[cfg_attr(miri, ignore = "slow [>1480s]")] #[test] fn test_draw_filled_ellipse() { let ellipse = Ellipse { @@ -378,7 +379,7 @@ mod tests { } } -#[cfg_attr(miri, ignore)] +#[cfg(not(miri))] #[cfg(test)] mod benches { use super::*; diff --git a/src/drawing/line.rs b/src/drawing/line.rs index 337fd3f2..26bef92e 100644 --- a/src/drawing/line.rs +++ b/src/drawing/line.rs @@ -593,7 +593,7 @@ mod tests { } } -#[cfg_attr(miri, ignore)] +#[cfg(not(miri))] #[cfg(test)] mod benches { use super::*; diff --git a/src/edges.rs b/src/edges.rs index ce690b7a..14bc5161 100644 --- a/src/edges.rs +++ b/src/edges.rs @@ -156,7 +156,7 @@ fn hysteresis( out } -#[cfg_attr(miri, ignore)] +#[cfg(not(miri))] #[cfg(test)] mod benches { use super::canny; diff --git a/src/filter/median.rs b/src/filter/median.rs index f830a4cd..dabc956f 100644 --- a/src/filter/median.rs +++ b/src/filter/median.rs @@ -325,7 +325,7 @@ impl HistSet { } } -#[cfg_attr(miri, ignore)] +#[cfg(not(miri))] #[cfg(test)] mod benches { use super::*; diff --git a/src/filter/mod.rs b/src/filter/mod.rs index 867bea4c..7dd38d48 100644 --- a/src/filter/mod.rs +++ b/src/filter/mod.rs @@ -957,7 +957,6 @@ mod tests { blur(image, stdev) } - #[cfg_attr(miri, ignore)] #[bench] #[ignore] // Gives a baseline performance using code from another library fn bench_baseline_gaussian_stdev_1(b: &mut Bencher) { @@ -968,7 +967,6 @@ mod tests { }); } - #[cfg_attr(miri, ignore)] #[bench] #[ignore] // Gives a baseline performance using code from another library fn bench_baseline_gaussian_stdev_3(b: &mut Bencher) { @@ -979,7 +977,6 @@ mod tests { }); } - #[cfg_attr(miri, ignore)] #[bench] #[ignore] // Gives a baseline performance using code from another library fn bench_baseline_gaussian_stdev_10(b: &mut Bencher) { diff --git a/src/geometric_transformations.rs b/src/geometric_transformations.rs index cc2c72a9..a9399a5d 100644 --- a/src/geometric_transformations.rs +++ b/src/geometric_transformations.rs @@ -1108,6 +1108,7 @@ mod tests { }); } + #[cfg_attr(miri, ignore = "Miri detected UB in nalgebra")] #[test] fn test_from_control_points_translate() { let from = [(0f32, 0.0), (50.0, 50.0), (50.0, 0.0), (0.0, 50.0)]; @@ -1122,6 +1123,7 @@ mod tests { assert_approx_eq!(out.1, 5.0, 1e-10); } + #[cfg_attr(miri, ignore = "Miri detected UB in dependencies")] #[test] fn test_from_control_points() { let from = [(0f32, 0.0), (50.0, 50.0), (50.0, 0.0), (0.0, 50.0)]; @@ -1136,6 +1138,7 @@ mod tests { assert_approx_eq!(out.1, 20.0, 1e-10); } + #[cfg_attr(miri, ignore = "Miri detected UB in nalgebra")] #[test] fn test_from_control_points_2() { let from = [ @@ -1150,6 +1153,7 @@ mod tests { assert!(p.is_some()); } + #[cfg_attr(miri, ignore = "Miri detected UB in nalgebra")] #[test] /// Test case from https://github.com/image-rs/imageproc/issues/412 fn test_from_control_points_nofreeze() { @@ -1164,6 +1168,7 @@ mod tests { Projection::from_control_points(from, to); } + #[cfg_attr(miri, ignore = "Miri detected UB in nalgebra")] #[test] fn test_from_control_points_known_transform() { let t = Projection::translate(10f32, 10f32); @@ -1185,6 +1190,7 @@ mod tests { } } + #[cfg_attr(miri, ignore = "Miri detected UB in nalgebra")] #[test] fn test_from_control_points_colinear() { let from = [(0f32, 0.0), (50.0, 50.0), (50.0, 0.0), (0.0, 50.0)]; @@ -1195,6 +1201,7 @@ mod tests { assert!(p.is_none()); } + #[cfg_attr(miri, ignore = "Miri detected UB in nalgebra")] #[test] fn test_from_control_points_translation() { let p = Projection::translate(10f32, 15f32); @@ -1213,6 +1220,7 @@ mod tests { } } + #[cfg_attr(miri, ignore = "Miri detected UB in nalgebra")] #[test] fn test_from_control_points_underdetermined() { let from = [ diff --git a/src/gradients.rs b/src/gradients.rs index fc94ba29..f1e7fbb2 100644 --- a/src/gradients.rs +++ b/src/gradients.rs @@ -253,7 +253,6 @@ mod tests { use super::*; use crate::utils::gray_bench_image; use image::{ImageBuffer, Luma}; - use test::{black_box, Bencher}; #[rustfmt::skip::macros(gray_image)] #[test] @@ -365,7 +364,7 @@ mod tests { } } -#[cfg_attr(miri, ignore)] +#[cfg(not(miri))] #[cfg(test)] mod benches { use super::*; diff --git a/src/haar.rs b/src/haar.rs index 59c64daa..be8efce5 100644 --- a/src/haar.rs +++ b/src/haar.rs @@ -736,7 +736,7 @@ mod tests { } } -#[cfg_attr(miri, ignore)] +#[cfg(not(miri))] #[cfg(test)] mod benches { use super::*; diff --git a/src/hog.rs b/src/hog.rs index f655b15b..24cf773d 100644 --- a/src/hog.rs +++ b/src/hog.rs @@ -686,7 +686,7 @@ mod tests { } } -#[cfg_attr(miri, ignore)] +#[cfg(not(miri))] #[cfg(test)] mod benches { use super::*; diff --git a/src/hough.rs b/src/hough.rs index 564225e1..812b44ef 100644 --- a/src/hough.rs +++ b/src/hough.rs @@ -539,7 +539,7 @@ mod tests { test_detect_line!(detect_line_neg10_120, -10.0, 120); } -#[cfg_attr(miri, ignore)] +#[cfg(not(miri))] #[cfg(test)] mod benches { use super::*; diff --git a/src/local_binary_patterns.rs b/src/local_binary_patterns.rs index e8f7fcfb..e93d6fbd 100644 --- a/src/local_binary_patterns.rs +++ b/src/local_binary_patterns.rs @@ -663,7 +663,7 @@ mod tests { } } -#[cfg_attr(miri, ignore)] +#[cfg(not(miri))] #[cfg(test)] mod benches { use super::*; diff --git a/src/morphology.rs b/src/morphology.rs index 197f8feb..e250f37d 100644 --- a/src/morphology.rs +++ b/src/morphology.rs @@ -459,7 +459,7 @@ mod tests { } } -#[cfg_attr(miri, ignore)] +#[cfg(not(miri))] #[cfg(test)] mod benches { use super::*; diff --git a/src/noise.rs b/src/noise.rs index c7889934..b691d88c 100644 --- a/src/noise.rs +++ b/src/noise.rs @@ -64,7 +64,7 @@ where } } -#[cfg_attr(miri, ignore)] +#[cfg(not(miri))] #[cfg(test)] mod benches { use super::*; diff --git a/src/pixelops.rs b/src/pixelops.rs index bea0da22..ef7542c7 100644 --- a/src/pixelops.rs +++ b/src/pixelops.rs @@ -76,7 +76,7 @@ mod tests { } } -#[cfg_attr(miri, ignore)] +#[cfg(not(miri))] #[cfg(test)] mod benches { use super::*; diff --git a/src/region_labelling.rs b/src/region_labelling.rs index 432a0a10..5d22574e 100644 --- a/src/region_labelling.rs +++ b/src/region_labelling.rs @@ -275,7 +275,7 @@ mod tests { // One huge component with eight-way connectivity, loads of // isolated components with four-way connectivity. - pub(in super::benches) fn chessboard(width: u32, height: u32) -> GrayImage { + pub(super) fn chessboard(width: u32, height: u32) -> GrayImage { ImageBuffer::from_fn(width, height, |x, y| { if (x + y) % 2 == 0 { Luma([255u8]) @@ -304,7 +304,7 @@ mod tests { } } -#[cfg_attr(miri, ignore)] +#[cfg(not(miri))] #[cfg(test)] mod benches { use super::connected_components; diff --git a/src/seam_carving.rs b/src/seam_carving.rs index 91a1786c..f2a39446 100644 --- a/src/seam_carving.rs +++ b/src/seam_carving.rs @@ -181,7 +181,7 @@ pub fn draw_vertical_seams(image: &GrayImage, seams: &[VerticalSeam]) -> Image