-
-
Notifications
You must be signed in to change notification settings - Fork 192
Open
Labels
bugSomething isn't workingSomething isn't working
Description
Bug description
While adding new tests to my project, I noticed that one of them started hanging.
Interestingly, inserting a dbg!(&iter) inside the loop in iterator makes the problem disappear.
At first glance, this looks like either a bug in the iterator logic or some form of undefined behavior.
However, running the tests under Address Sanitizer and Valgrind did not report any errors.
In my project the issue appeared in debug mode, but in the minimal example (below) it only reproduces in release mode.
Code
use std::fs;
use gtk4::prelude::*;
mod tests;
fn main() {
let txt = r##"
#[gtk4::test]
fn test_list_store_iterxxxxxx() {
let columns_types: &[Type] = &[Type::STRING];
let list_store = gtk4::ListStore::new(columns_types);
let values = ["a", "b", "c"];
for v in &values {
let iter = list_store.append();
list_store.set(&iter, &[(0, &(*v))]);
}
let collected: Vec<String> = list_store.custom_iter().map(|iter| list_store.get::<String>(&iter, 0)).collect();
assert_eq!(collected, values.iter().map(|s| s.to_string()).collect::<Vec<_>>());
let empty = gtk4::ListStore::new(&[Type::STRING]);
let mut it = empty.custom_iter();
assert!(it.next().is_none());
}
"##;
let mut all = r#"
#[cfg(test)]
mod tests {
use gtk4::prelude::*;
use crate::ListStoreIterExt;
use glib::types::Type;
"#.to_string();
for i in 0..400 {
all += txt.replace("xxxxxx", &i.to_string()).as_str();
}
all += "}\n";
fs::write("src/tests.rs", all).expect("Unable to write file");
}
pub struct ListStoreIter<'a> {
list_store: &'a gtk4::ListStore,
current: Option<gtk4::TreeIter>,
}
impl<'a> ListStoreIter<'a> {
pub fn new(list_store: &'a gtk4::ListStore) -> Self {
let current = list_store.iter_first();
Self { list_store, current }
}
}
impl<'a> Iterator for ListStoreIter<'a> {
type Item = gtk4::TreeIter;
fn next(&mut self) -> Option<Self::Item> {
match &mut self.current {
None => None,
Some(iter) => {
// dbg!(&iter);
let result = Some(*iter);
let next_iter = *iter;
if self.list_store.iter_next(&next_iter) {
self.current = Some(next_iter);
} else {
self.current = None;
}
result
}
}
}
}
pub trait ListStoreIterExt {
fn custom_iter(&self) -> ListStoreIter;
}
impl ListStoreIterExt for gtk4::ListStore {
fn custom_iter(&self) -> ListStoreIter {
ListStoreIter::new(self)
}
}
Project - t.zip
Metadata
Metadata
Assignees
Labels
bugSomething isn't workingSomething isn't working