-
-
Notifications
You must be signed in to change notification settings - Fork 110
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Union, Clone and Copy #527
Conversation
General idea is to ensure that once postprocessing phase is completed, the types themselves describe exactly which types will be generated. This would allow to make sys code generation to be completely unconditional, but this still remains to be done.
There is manually written code that uses their fields.
Seems blocked by gtk-rs/gir-files#13 as attempt to generate |
@EPashkin thanks for pointing that out. I am running this with PangoCairo fixed |
Generate empty lines in gdk-sys @@ -3210,6 +3229,7 @@ impl ::std::fmt::Debug for GdkEventGrabBroken {
}
#[repr(C)]
+
pub struct GdkEventKey {
pub type_: GdkEventType,
pub window: *mut GdkWindow,
@@ -3354,6 +3381,7 @@ impl ::std::fmt::Debug for GdkEventProximity {
}
#[repr(C)]
+
pub struct GdkEventScroll {
pub type_: GdkEventType,
pub window: *mut GdkWindow, Examples builds fine but there warning about
and
|
I pushed commit with codegen cleanup mentioned earlier. |
@tmiasko Thanks, I check it tomorrow. |
src/codegen/sys/fields.rs
Outdated
|
||
fn analyze_fields(env: &Env, unsafe_access: bool, fields: &[Field]) -> (Vec<FieldInfo>, Option<String>) { | ||
let mut truncated = None; | ||
let mut infos = Vec::new(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe use Vec::with_capacity(fields.len)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done.
* Reuse is incomplete check from analysis phase. The Library::fix_field establishes all invariants required for analysis::types::IsIncomplete, so we can just use it in Library::make_unrepresentable_types_opaque. As a minor drawback we no longer have information why type is considered incomplete. * Preallocate memory for fields in analyze_fields. * Fix condition checking number of parameters for which Rust still derives traits. It should be inclusive. * Remove unnecessary whitespace in sys code generation.
|
||
fn field_ffi_type(env: &Env, field: &Field) -> Result { | ||
if field.is_incomplete(&env.library) { | ||
return Err(TypeError::Ignored(format!("field {} has incomplete type", &field.name))); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
IMHO better also show type here (not insist, as do it troublesome at first glance).
#[repr(C)]
pub struct GtkAboutDialogClass {
_truncated_record_marker: c_void,
// /*Ignored*/field parent_class has incomplete type
}
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It will be serious problem to show right type, as bit field also reason for incompleteness
and /*Ignored*/field null_fold_if_empty has incomplete type u32
looks strange.
So ignore this proposal
src/analysis/types.rs
Outdated
impl IsPtr for Field { | ||
fn is_ptr(&self) -> bool { | ||
if let Some(ref c_type) = self.c_type { | ||
return c_type.contains("*") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Clippy nags about this and others contains("*")
:
warning: single-character string constant used as pattern
--> src\analysis\types.rs:16:36
|
16 | return c_type.contains("*")
| ----------------^^^- help: try using a char instead: `c_type.contains('*')`
|
= note: #[warn(single_char_pattern)] on by default
= help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.183/index.html#single_char_pattern
src/library_postprocessing.rs
Outdated
continue; | ||
} | ||
let field_type = self.type_(field.typ); | ||
if let Some(_) = field_type.maybe_ref_as::<Function>() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
warning: redundant pattern matching, consider using `is_some()`
--> src\library_postprocessing.rs:303:36
|
303 | if let Some(_) = field_type.maybe_ref_as::<Function>() {
| -------^^^^^^^---------------------------------------- help: try this: `if field_type.maybe_ref_as::<Function>().is_some()`
|
= note: #[warn(if_let_redundant_pattern_matching)] on by default
= help: for further information visit https://rust-lang-nursery.github.io/rust-clippy/v0.0.183/index.html#if_let_redundant_pattern_matching
src/library_postprocessing.rs
Outdated
Type::Union(Union { ref name, ref fields, ..}) => { | ||
for (fid, field) in fields.iter().enumerate() { | ||
if nameutil::needs_mangling(&field.name) { | ||
let new_name = nameutil::mangle_keywords(&*field.name).to_string(); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe .into_owned()
instead?
src/library_postprocessing.rs
Outdated
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unneeded line
src/parser.rs
Outdated
{ | ||
Type::union(self, u, ns_id) | ||
} | ||
Type::union(self, u, ns_id) | ||
}; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just let type_id = Type::union(self, u, ns_id)
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Or move into fields.push
src/parser.rs
Outdated
{ | ||
Type::union(self, u, ns_id) | ||
} | ||
Type::union(self, u, ns_id) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Same
src/parser.rs
Outdated
@@ -591,7 +583,7 @@ impl Library { | |||
s.push('_'); | |||
s | |||
}) | |||
.unwrap_or_else(String::new), | |||
.unwrap_or("".into()), |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please change it back, and next too
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
.. as clippy nags
src/codegen/sys/statics.rs
Outdated
@@ -52,7 +47,7 @@ pub fn only_for_glib(w: &mut Write) -> Result<()> { | |||
"pub type gpointer = *mut c_void;", | |||
"", | |||
"#[repr(C)]", | |||
"#[derive(Debug)]", | |||
"#[derive(Copy,Clone,Debug)]", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
#[derive(Copy, Clone, Debug)]
?
src/analysis/types.rs
Outdated
} | ||
} | ||
} | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unneeded line
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This still actual
@tmiasko, @sdroege, @GuillaumeGomez There will be no problem with union Debug implementation? #[repr(C)]
#[derive(Copy, Clone)]
pub union GtkBindingArg_d {
pub long_data: c_long,
pub double_data: c_double,
pub string_data: *mut c_char,
}
impl ::std::fmt::Debug for GtkBindingArg_d {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
f.debug_struct(&format!("GtkBindingArg_d @ {:?}", self as *const _))
.field("long_data", unsafe { &self.long_data })
.field("double_data", unsafe { &self.double_data })
.field("string_data", unsafe { &self.string_data })
.finish()
}
} |
Also we need print #[repr(C)]
#[derive(Copy, Clone)]
pub union GtkTextAttributes_u1 {
pub font_features: *mut c_char,
pub padding: [c_uint; 2],
}
impl ::std::fmt::Debug for GtkTextAttributes_u1 {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
f.debug_struct(&format!("GtkTextAttributes_u1 @ {:?}", self as *const _))
.field("font_features", unsafe { &self.font_features })
.field("padding", unsafe { &self.padding })
.finish()
}
} |
Note: almost all GUI "xxClass" now incomplete due bit field in GtkContainerClass @@ -3083,20 +3494,24 @@ pub struct GtkContainerClass {
pub get_child_property: Option<unsafe extern "C" fn(*mut GtkContainer, *mut GtkWidget, c_uint, *mut gobject::GValue, *mut gobject::GParamSpec)>,
pub get_path_for_child: Option<unsafe extern "C" fn(*mut GtkContainer, *mut GtkWidget) -> *mut GtkWidgetPath>,
_truncated_record_marker: c_void,
- //_handle_border_width: unsigned: 1,
- //_gtk_reserved1: fn,
- //_gtk_reserved2: fn,
- //_gtk_reserved3: fn,
- //_gtk_reserved4: fn,
- //_gtk_reserved5: fn,
- //_gtk_reserved6: fn,
- //_gtk_reserved7: fn,
- //_gtk_reserved8: fn,
+ // /*Ignored*/field _handle_border_width has incomplete type
} |
My thoughts about issues raised by @EPashkin, and some of my own:
Thanks for review @EPashkin. |
I pushed two commits. First addresses @EPashkin review comments. It did help to some degree with printing padding fields, |
The best way to check if |
@GuillaumeGomez I forgot that we can test it ;)
|
src/codegen/sys/statics.rs
Outdated
@@ -52,7 +47,7 @@ pub fn only_for_glib(w: &mut Write) -> Result<()> { | |||
"pub type gpointer = *mut c_void;", | |||
"", | |||
"#[repr(C)]", | |||
"#[derive(Debug)]", | |||
"#[derive(Copy,Clone)]", |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
"#[derive(Copy, Clone)]",
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Union containing volatile field need to be copyable as well.
Alternatively we could stop generating unions with volatile fields.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry that it was unclear: You just forgot space between.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please make 2 last fixes change current commits.
Changes from last 2 commits: @@ -1261,11 +1258,9 @@ pub struct GApplicationCommandLineClass {
impl ::std::fmt::Debug for GApplicationCommandLineClass {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
f.debug_struct(&format!("GApplicationCommandLineClass @ {:?}", self as *const _))
- .field("parent_class", &self.parent_class)
.field("print_literal", &self.print_literal)
.field("printerr_literal", &self.printerr_literal)
.field("get_stdin", &self.get_stdin)
- .field("padding", &self.padding)
.finish()
}
}
@@ -1554,7 +1549,6 @@ pub struct GDBusAnnotationInfo {
impl ::std::fmt::Debug for GDBusAnnotationInfo {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
f.debug_struct(&format!("GDBusAnnotationInfo @ {:?}", self as *const _))
- .field("ref_count", &self.ref_count)
.field("key", &self.key)
.field("value", &self.value)
.field("annotations", &self.annotations)
@@ -4168,8 +4145,6 @@ pub struct GSimpleActionGroupClass {
impl ::std::fmt::Debug for GSimpleActionGroupClass {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
f.debug_struct(&format!("GSimpleActionGroupClass @ {:?}", self as *const _))
- .field("parent_class", &self.parent_class)
- .field("padding", &self.padding)
.finish()
}
}
@@ -1144,8 +1144,6 @@ pub union GMutex {
impl ::std::fmt::Debug for GMutex {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
f.debug_struct(&format!("GMutex @ {:?}", self as *const _))
- .field("p", unsafe { &self.p })
- .field("i", unsafe { &self.i })
.finish()
}
}
@@ -833,15 +830,6 @@ pub struct PangoFontMetrics {
impl ::std::fmt::Debug for PangoFontMetrics {
fn fmt(&self, f: &mut ::std::fmt::Formatter) -> ::std::fmt::Result {
f.debug_struct(&format!("PangoFontMetrics @ {:?}", self as *const _))
- .field("ref_count", &self.ref_count)
- .field("ascent", &self.ascent)
- .field("descent", &self.descent)
- .field("approximate_char_width", &self.approximate_char_width)
- .field("approximate_digit_width", &self.approximate_digit_width)
- .field("underline_position", &self.underline_position)
- .field("underline_thickness", &self.underline_thickness)
- .field("strikethrough_position", &self.strikethrough_position)
- .field("strikethrough_thickness", &self.strikethrough_thickness)
.finish()
}
} |
Done. I also included hack for GHookList so that gstreamer bindings remain more or less working. |
Thanks |
Ok, no one against PR, so I will merge it. |
Union, Clone and Copy
Functionally wise this PR introduces support for unions and derives Clone and
Copy traits for ffi types (based on @Luke-Nukem work from #415).
It also temporarily removes support for structs with partially generated
fields. In particular types with bitfields are not generated, with exception of
GdkEventKey and GdkEventScroll. Exception is made because there is manual code
that uses those.
From implementation perspective this change tries to migrate most logic to
phases that occur before code generation, so that codegen is only concerned
with joining some string together, so to say. At this point this may not be
readily visible, as codegen cleanup will follow in a later PR.
Tested with all crates hosted under gtk-rs (regenerated ffi and api crates).
soup-sys-rs requires manual tweak to import sockaddr from libc.
This PR incorporates both #415 and #526.