-
-
Notifications
You must be signed in to change notification settings - Fork 14.2k
Open
Labels
C-external-bugCategory: issue that is caused by bugs in software beyond our controlCategory: issue that is caused by bugs in software beyond our controlE-needs-mcveCall for participation: This issue has a repro, but needs a Minimal Complete and Verifiable ExampleCall for participation: This issue has a repro, but needs a Minimal Complete and Verifiable Example
Description
Code
Cargo toml
[package]
name = "t"
version = "0.1.0"
edition = "2021"
[dependencies]
gtk4 = "0.10.0"
glib = "0.21.1"
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); // Uncommenting this line, fixes issue
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)
}
}Rust 1.86.0 executes the tests correctly. Running:
cargo +1.86.0 test --release
finishes as expected:
test tests::tests::test_list_store_iter98 ... ok
test tests::tests::test_list_store_iter99 ... ok
test result: ok. 400 passed; 0 failed; 0 ignored; 0 measured; 0 filtered out; finished in 0.02s
However, Rust 1.87.0 and later freeze during execution and consume an excessive amount of RAM over time when running:
cargo +1.87.0 test --release
Related gtk4-rs issue - gtk-rs/gtk4-rs#2140
This may be caused either by a change in Rust optimizations or by invalid behavior in gtk4-rs that only manifests with newer compiler versions.
I ran the code under AddressSanitizer and Valgrind and found no memory errors, which suggests this is more likely an optimization-related issue rather than a direct memory safety problem.
dianqk
Metadata
Metadata
Assignees
Labels
C-external-bugCategory: issue that is caused by bugs in software beyond our controlCategory: issue that is caused by bugs in software beyond our controlE-needs-mcveCall for participation: This issue has a repro, but needs a Minimal Complete and Verifiable ExampleCall for participation: This issue has a repro, but needs a Minimal Complete and Verifiable Example