startin
startin copied to clipboard
Locating a point after garbage collection might result in panic
I'm using startin as a tool to generate meshes for terrain in runtime, and so my editor tools can both add and remove vertices. I was thinking about collecting garbage after every mutable operation to Triangulation, but it seems that it might lead to panics. The panic is semi-random, meaning in my testing it will eventually happen if I continue to add/remove vertices, but at what point exactly is unknown. The panic in the question is always:
<...>
7: core::panicking::panic_bounds_check
at /rustc/8c74a5d27c644a0f7a22bb2fa8dd3ff8257bc220/library/core/src/panicking.rs:162:5
8: startin::Triangulation::walk
9: startin::Triangulation::locate
at <...>/.cargo/registry/src/index.crates.io-6f17d22bba15001f/startin-0.7.0/src/lib.rs:874:18
10: startin::Triangulation::closest_point
at <...>/.cargo/registry/src/index.crates.io-6f17d22bba15001f/startin-0.7.0/src/lib.rs:884:18
11: project::Terrain::remove_nearest_vertex
at ./project/terrain/mod.rs:61:31
<...>
thread 'main' panicked at 'index out of bounds: the len is 26 but the index is 26', <...>/.cargo/registry/src/index.crates.io-6f17d22bba15001f/startin-0.7.0/src/lib.rs:945:18
My wild guess is that Triangulation::collect_garbage
might not update Triangulation::cur
, and so it happens to be out of bounds on the next walk
call. At first I thought it might be related to rand
, but turns out no, and I have found a repro:
//# startin = "0.7"
fn main() {
let mut pts: Vec<[f64; 3]> = Vec::new();
pts.push([10.0, 10.0, 0.0]);
pts.push([-10.0, 10.0, 0.0]);
pts.push([-10.0, -10.0, 0.0]);
pts.push([10.0, -10.0, 0.0]);
let mut dt = startin::Triangulation::new();
dt.insert(&pts, startin::InsertionStrategy::AsIs);
for i in 0..10 {
let _ = dt.insert_one_pt(-5.0 + i as f64, 0.0, 0.0).unwrap();
}
for i in 0..10 {
let idx = dt.closest_point(0.0, 0.0).unwrap();
let _point = dt.get_point(idx).unwrap();
let _ = dt.remove(idx).unwrap();
// commenting this out prevent panics
dt.collect_garbage();
}
}