Backport official GLib iterator safety fix for Linux desktop

This commit is contained in:
karl committed 2026-10-13 10:35:50 +02:00
1 parent 43c43ebdc9
commit 8ef874c609
133 files changed
+55342 -2

No files matched your search

@@ -0,0 +1,33 @@
mod imp {
use glib::subclass::prelude::*;
#[derive(Default)]
pub struct TestObject {
s: String,
}
#[glib::object_subclass]
impl ObjectSubclass for TestObject {
const NAME: &'static str = "TestObject";
type Type = super::TestObject;
}
impl ObjectImpl for TestObject {}
}
glib::wrapper! {
pub struct TestObject(ObjectSubclass<imp::TestObject>);
}
impl Default for TestObject {
fn default() -> Self {
glib::Object::new()
}
}
fn main() {
fn check<T: Send + Sync>(_obj: &T) {}
let obj = TestObject::default();
check(&obj);
}
@@ -0,0 +1,34 @@
mod imp {
use glib::subclass::prelude::*;
use std::cell::RefCell;
#[derive(Default)]
pub struct TestObject {
s: RefCell<String>,
}
#[glib::object_subclass]
impl ObjectSubclass for TestObject {
const NAME: &'static str = "TestObject";
type Type = super::TestObject;
}
impl ObjectImpl for TestObject {}
}
glib::wrapper! {
pub struct TestObject(ObjectSubclass<imp::TestObject>);
}
impl Default for TestObject {
fn default() -> Self {
glib::Object::new()
}
}
fn main() {
fn check<T: Send>(_obj: &T) {}
let obj = TestObject::default();
check(&obj);
}
@@ -0,0 +1,26 @@
error[E0277]: `RefCell<std::string::String>` cannot be shared between threads safely
--> tests/subclass_compiletest/02-no-auto-send-sync.rs:33:11
|
33 | check(&obj);
| ----- ^^^^ `RefCell<std::string::String>` cannot be shared between threads safely
| |
| required by a bound introduced by this call
|
= help: within `imp::TestObject`, the trait `Sync` is not implemented for `RefCell<std::string::String>`
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
note: required because it appears within the type `TestObject`
--> tests/subclass_compiletest/02-no-auto-send-sync.rs:6:16
|
6 | pub struct TestObject {
| ^^^^^^^^^^
= note: required for `TypedObjectRef<imp::TestObject, ()>` to implement `Send`
note: required because it appears within the type `TestObject`
--> tests/subclass_compiletest/02-no-auto-send-sync.rs:20:16
|
20 | pub struct TestObject(ObjectSubclass<imp::TestObject>);
| ^^^^^^^^^^
note: required by a bound in `main::check`
--> tests/subclass_compiletest/02-no-auto-send-sync.rs:30:17
|
30 | fn check<T: Send>(_obj: &T) {}
| ^^^^ required by this bound in `check`
@@ -0,0 +1,6 @@
fn main() {
fn check<T: Send + Sync>(_obj: &T) {}
let obj = glib::Object::new::<glib::Object>();
check(&obj);
}
@@ -0,0 +1,41 @@
error[E0277]: `*mut c_void` cannot be sent between threads safely
--> tests/subclass_compiletest/03-object-no-auto-send-sync.rs:5:11
|
5 | check(&obj);
| ----- ^^^^ `*mut c_void` cannot be sent between threads safely
| |
| required by a bound introduced by this call
|
= help: the trait `Send` is not implemented for `*mut c_void`
= note: required for `TypedObjectRef<*mut c_void, ()>` to implement `Send`
note: required because it appears within the type `Object`
--> src/object.rs
|
| pub Object, *mut std::os::raw::c_void, (), gobject_ffi::GObject, @ffi_class gobject_ffi::GObjectClass, @type_ gobject_ffi::g_object_g...
| ^^^^^^
note: required by a bound in `main::check`
--> tests/subclass_compiletest/03-object-no-auto-send-sync.rs:2:17
|
2 | fn check<T: Send + Sync>(_obj: &T) {}
| ^^^^ required by this bound in `check`
error[E0277]: `*mut c_void` cannot be shared between threads safely
--> tests/subclass_compiletest/03-object-no-auto-send-sync.rs:5:11
|
5 | check(&obj);
| ----- ^^^^ `*mut c_void` cannot be shared between threads safely
| |
| required by a bound introduced by this call
|
= help: the trait `Sync` is not implemented for `*mut c_void`
= note: required for `TypedObjectRef<*mut c_void, ()>` to implement `Send`
note: required because it appears within the type `Object`
--> src/object.rs
|
| pub Object, *mut std::os::raw::c_void, (), gobject_ffi::GObject, @ffi_class gobject_ffi::GObjectClass, @type_ gobject_ffi::g_object_g...
| ^^^^^^
note: required by a bound in `main::check`
--> tests/subclass_compiletest/03-object-no-auto-send-sync.rs:2:17
|
2 | fn check<T: Send + Sync>(_obj: &T) {}
| ^^^^ required by this bound in `check`
@@ -0,0 +1,69 @@
mod imp_parent {
use glib::subclass::prelude::*;
#[derive(Default)]
pub struct TestParent {
s: String,
}
#[glib::object_subclass]
impl ObjectSubclass for TestParent {
const NAME: &'static str = "TestParent";
type Type = super::TestParent;
}
impl ObjectImpl for TestParent {}
}
glib::wrapper! {
pub struct TestParent(ObjectSubclass<imp_parent::TestParent>);
}
pub trait TestParentImpl: glib::subclass::prelude::ObjectImpl + Send + Sync {}
unsafe impl<T: TestParentImpl> glib::subclass::prelude::IsSubclassable<T> for TestParent {}
impl Default for TestParent {
fn default() -> Self {
glib::Object::new()
}
}
mod imp_object {
use glib::subclass::prelude::*;
#[derive(Default)]
pub struct TestObject {
s: String,
}
#[glib::object_subclass]
impl ObjectSubclass for TestObject {
const NAME: &'static str = "TestObject";
type Type = super::TestObject;
type ParentType = super::TestParent;
}
impl ObjectImpl for TestObject {}
impl super::TestParentImpl for TestObject {}
}
glib::wrapper! {
pub struct TestObject(ObjectSubclass<imp_object::TestObject>) @extends TestParent;
}
impl Default for TestObject {
fn default() -> Self {
glib::Object::new()
}
}
fn main() {
fn check<T: Send + Sync>(_obj: &T) {}
let obj = TestParent::default();
check(&obj);
let obj = TestObject::default();
check(&obj);
}
@@ -0,0 +1,67 @@
mod imp_parent {
use glib::subclass::prelude::*;
use std::cell::RefCell;
#[derive(Default)]
pub struct TestParent {
s: RefCell<String>,
}
#[glib::object_subclass]
impl ObjectSubclass for TestParent {
const NAME: &'static str = "TestParent";
type Type = super::TestParent;
}
impl ObjectImpl for TestParent {}
}
glib::wrapper! {
pub struct TestParent(ObjectSubclass<imp_parent::TestParent>);
}
pub trait TestParentImpl: glib::subclass::prelude::ObjectImpl {}
unsafe impl<T: TestParentImpl> glib::subclass::prelude::IsSubclassable<T> for TestParent {}
impl Default for TestParent {
fn default() -> Self {
glib::Object::new()
}
}
mod imp_object {
use glib::subclass::prelude::*;
#[derive(Default)]
pub struct TestObject {
s: String,
}
#[glib::object_subclass]
impl ObjectSubclass for TestObject {
const NAME: &'static str = "TestObject";
type Type = super::TestObject;
type ParentType = super::TestParent;
}
impl ObjectImpl for TestObject {}
impl super::TestParentImpl for TestObject {}
}
glib::wrapper! {
pub struct TestObject(ObjectSubclass<imp_object::TestObject>) @extends TestParent;
}
impl Default for TestObject {
fn default() -> Self {
glib::Object::new()
}
}
fn main() {
fn check<T: Send + Sync>(_obj: &T) {}
let obj = TestObject::default();
check(&obj);
}
@@ -0,0 +1,32 @@
error[E0277]: `RefCell<std::string::String>` cannot be shared between threads safely
--> tests/subclass_compiletest/05-no-auto-send-sync-with-non-send-sync-parent.rs:66:11
|
66 | check(&obj);
| ----- ^^^^ `RefCell<std::string::String>` cannot be shared between threads safely
| |
| required by a bound introduced by this call
|
= help: within `imp_parent::TestParent`, the trait `Sync` is not implemented for `RefCell<std::string::String>`
= note: if you want to do aliasing and mutation between multiple threads, use `std::sync::RwLock` instead
note: required because it appears within the type `TestParent`
--> tests/subclass_compiletest/05-no-auto-send-sync-with-non-send-sync-parent.rs:6:16
|
6 | pub struct TestParent {
| ^^^^^^^^^^
= note: required for `TypedObjectRef<imp_parent::TestParent, ()>` to implement `Send`
note: required because it appears within the type `TestParent`
--> tests/subclass_compiletest/05-no-auto-send-sync-with-non-send-sync-parent.rs:20:16
|
20 | pub struct TestParent(ObjectSubclass<imp_parent::TestParent>);
| ^^^^^^^^^^
= note: required for `TypedObjectRef<imp_object::TestObject, TestParent>` to implement `Send`
note: required because it appears within the type `TestObject`
--> tests/subclass_compiletest/05-no-auto-send-sync-with-non-send-sync-parent.rs:53:16
|
53 | pub struct TestObject(ObjectSubclass<imp_object::TestObject>) @extends TestParent;
| ^^^^^^^^^^
note: required by a bound in `main::check`
--> tests/subclass_compiletest/05-no-auto-send-sync-with-non-send-sync-parent.rs:63:17
|
63 | fn check<T: Send + Sync>(_obj: &T) {}
| ^^^^ required by this bound in `check`
@@ -0,0 +1,51 @@
glib::wrapper! {
#[doc(alias = "GInitiallyUnowned")]
pub struct InitiallyUnowned(Object<glib::gobject_ffi::GInitiallyUnowned, glib::gobject_ffi::GInitiallyUnownedClass>);
match fn {
type_ => || glib::gobject_ffi::g_initially_unowned_get_type(),
}
}
pub trait InitiallyUnownedImpl: glib::subclass::prelude::ObjectImpl {}
unsafe impl<T: InitiallyUnownedImpl> glib::subclass::prelude::IsSubclassable<T>
for InitiallyUnowned
{
}
mod imp_object {
use glib::subclass::prelude::*;
#[derive(Default)]
pub struct TestObject {
s: String,
}
#[glib::object_subclass]
impl ObjectSubclass for TestObject {
const NAME: &'static str = "TestObject";
type Type = super::TestObject;
type ParentType = super::InitiallyUnowned;
}
impl ObjectImpl for TestObject {}
impl super::InitiallyUnownedImpl for TestObject {}
}
glib::wrapper! {
pub struct TestObject(ObjectSubclass<imp_object::TestObject>) @extends InitiallyUnowned;
}
impl Default for TestObject {
fn default() -> Self {
glib::Object::new()
}
}
fn main() {
fn check<T: Send + Sync>(_obj: &T) {}
let obj = TestObject::default();
check(&obj);
}
@@ -0,0 +1,53 @@
error[E0277]: `*mut c_void` cannot be sent between threads safely
--> tests/subclass_compiletest/06-no-auto-send-sync-with-non-send-sync-ffi-parent.rs:50:11
|
50 | check(&obj);
| ----- ^^^^ `*mut c_void` cannot be sent between threads safely
| |
| required by a bound introduced by this call
|
= help: the trait `Send` is not implemented for `*mut c_void`
= note: required for `TypedObjectRef<*mut c_void, ()>` to implement `Send`
note: required because it appears within the type `InitiallyUnowned`
--> tests/subclass_compiletest/06-no-auto-send-sync-with-non-send-sync-ffi-parent.rs:3:16
|
3 | pub struct InitiallyUnowned(Object<glib::gobject_ffi::GInitiallyUnowned, glib::gobject_ffi::GInitiallyUnownedClass>);
| ^^^^^^^^^^^^^^^^
= note: required for `TypedObjectRef<imp_object::TestObject, InitiallyUnowned>` to implement `Send`
note: required because it appears within the type `TestObject`
--> tests/subclass_compiletest/06-no-auto-send-sync-with-non-send-sync-ffi-parent.rs:37:16
|
37 | pub struct TestObject(ObjectSubclass<imp_object::TestObject>) @extends InitiallyUnowned;
| ^^^^^^^^^^
note: required by a bound in `main::check`
--> tests/subclass_compiletest/06-no-auto-send-sync-with-non-send-sync-ffi-parent.rs:47:17
|
47 | fn check<T: Send + Sync>(_obj: &T) {}
| ^^^^ required by this bound in `check`
error[E0277]: `*mut c_void` cannot be shared between threads safely
--> tests/subclass_compiletest/06-no-auto-send-sync-with-non-send-sync-ffi-parent.rs:50:11
|
50 | check(&obj);
| ----- ^^^^ `*mut c_void` cannot be shared between threads safely
| |
| required by a bound introduced by this call
|
= help: the trait `Sync` is not implemented for `*mut c_void`
= note: required for `TypedObjectRef<*mut c_void, ()>` to implement `Send`
note: required because it appears within the type `InitiallyUnowned`
--> tests/subclass_compiletest/06-no-auto-send-sync-with-non-send-sync-ffi-parent.rs:3:16
|
3 | pub struct InitiallyUnowned(Object<glib::gobject_ffi::GInitiallyUnowned, glib::gobject_ffi::GInitiallyUnownedClass>);
| ^^^^^^^^^^^^^^^^
= note: required for `TypedObjectRef<imp_object::TestObject, InitiallyUnowned>` to implement `Send`
note: required because it appears within the type `TestObject`
--> tests/subclass_compiletest/06-no-auto-send-sync-with-non-send-sync-ffi-parent.rs:37:16
|
37 | pub struct TestObject(ObjectSubclass<imp_object::TestObject>) @extends InitiallyUnowned;
| ^^^^^^^^^^
note: required by a bound in `main::check`
--> tests/subclass_compiletest/06-no-auto-send-sync-with-non-send-sync-ffi-parent.rs:47:17
|
47 | fn check<T: Send + Sync>(_obj: &T) {}
| ^^^^ required by this bound in `check`