From cebf2d8220f7f713ebb757c6c1a19d18c7dd81e6 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 15 Nov 2017 10:22:31 +0200 Subject: [PATCH 1/4] glib: Don't implement DerefMut on TypedValue It allows replacing the underlying Value inside the TypedValue with one of a different type and breaks type-safety: let mut meh: TypedValue = (&123i32).into(); let meh2: Value = (&1u8).to_value(); *meh = meh2; Fixes https://github.com/gtk-rs/glib/issues/254 --- src/value.rs | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-) diff --git a/src/value.rs b/src/value.rs index c9cd0015f0b2..c344b7f78bfc 100644 --- a/src/value.rs +++ b/src/value.rs @@ -74,7 +74,7 @@ use std::borrow::Borrow; use std::fmt; use std::marker::PhantomData; use std::mem; -use std::ops::{Deref, DerefMut}; +use std::ops::Deref; use std::ffi::CStr; use std::ptr; use libc::c_void; @@ -439,19 +439,19 @@ impl<'a, T: FromValueOptional<'a> + SetValue> TypedValue { /// /// This method is only available for types that support a `None` value. pub fn set(&mut self, value: Option<&U>) where T: Borrow { - unsafe { SetValueOptional::set_value_optional(self, value) } + unsafe { SetValueOptional::set_value_optional(&mut self.0, value) } } /// Sets the value to `None`. /// /// This method is only available for types that support a `None` value. pub fn set_none(&mut self) where T: SetValueOptional { - unsafe { T::set_value_optional(self, None) } + unsafe { T::set_value_optional(&mut self.0, None) } } /// Sets the value. pub fn set_some(&mut self, value: &U) where T: Borrow { - unsafe { SetValue::set_value(self, value) } + unsafe { SetValue::set_value(&mut self.0, value) } } } @@ -475,12 +475,6 @@ impl Deref for TypedValue { } } -impl DerefMut for TypedValue { - fn deref_mut(&mut self) -> &mut Value { - &mut self.0 - } -} - impl<'a, T: FromValueOptional<'a> + SetValueOptional> From> for TypedValue { fn from(value: Option<&'a T>) -> Self { TypedValue(Value::from(value), PhantomData) From 892123df0ca3ad1e204add2312a43e3a34058313 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 15 Nov 2017 10:28:13 +0200 Subject: [PATCH 2/4] glib: Derive Clone for TypedValue instead of manually implementing it --- src/value.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/value.rs b/src/value.rs index c344b7f78bfc..bfa34f102c83 100644 --- a/src/value.rs +++ b/src/value.rs @@ -416,6 +416,7 @@ impl Drop for ValueArray { /// accepted. /// /// See the [module documentation](index.html) for more details. +#[derive(Clone)] pub struct TypedValue(Value, PhantomData<*const T>); impl<'a, T: FromValueOptional<'a> + SetValue> TypedValue { @@ -455,11 +456,6 @@ impl<'a, T: FromValueOptional<'a> + SetValue> TypedValue { } } -impl Clone for TypedValue { - fn clone(&self) -> Self { - TypedValue(self.0.clone(), PhantomData) - } -} impl fmt::Debug for TypedValue { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { From d3d5754b1d6fc6e18f4c448ad41ce24573a117f7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 15 Nov 2017 10:28:46 +0200 Subject: [PATCH 3/4] glib: Implement fmt::Debug for Value/TypedValue by using Formatter::debug_tuple() This takes into account all formatting parameters as needed. --- src/value.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/value.rs b/src/value.rs index bfa34f102c83..93a1e9e9df37 100644 --- a/src/value.rs +++ b/src/value.rs @@ -185,7 +185,10 @@ impl fmt::Debug for Value { unsafe { let s: String = from_glib_full( gobject_ffi::g_strdup_value_contents(self.to_glib_none().0)); - write!(f, "Value({})", s) + + f.debug_tuple("Value") + .field(&s) + .finish() } } } @@ -456,10 +459,11 @@ impl<'a, T: FromValueOptional<'a> + SetValue> TypedValue { } } - impl fmt::Debug for TypedValue { fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> { - write!(f, "TypedValue({:?})", self.0) + f.debug_tuple("TypedValue") + .field(&self.0) + .finish() } } From 2bb5d2d169fee574c07d7a93bf9e02f60bdbb38e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Sebastian=20Dr=C3=B6ge?= Date: Wed, 15 Nov 2017 10:39:58 +0200 Subject: [PATCH 4/4] glib: Make TypedValue #[repr(C)] This allows to use them directly wherever a GValue is used in FFI by transmuting --- src/value.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/value.rs b/src/value.rs index 93a1e9e9df37..529a974d2647 100644 --- a/src/value.rs +++ b/src/value.rs @@ -420,6 +420,7 @@ impl Drop for ValueArray { /// /// See the [module documentation](index.html) for more details. #[derive(Clone)] +#[repr(C)] pub struct TypedValue(Value, PhantomData<*const T>); impl<'a, T: FromValueOptional<'a> + SetValue> TypedValue {