-
-
Notifications
You must be signed in to change notification settings - Fork 20
Conversation
Normally we redefine enums in rust part (https://github.com/gtk-rs/gdk/blob/master/src/auto/enums.rs#L9-L66). It also prevent direct conversion from/to ints for more safety. Not sure if that needed for #[doc(hidden)]
impl ToGlib for Content {
type GlibType = Content;
fn to_glib(&self) -> Content {
*self
}
} |
I saw that and was wondering why? And the stranger part is the docs for
How is that? I'm getting an error when doing this: #[repr(C)]
enum X {
Hello = 0,
World = 1,
}
fn main() {
let x: X = 0 as X;
}
|
Before #144 gdk reexported sys enums. Strange, before it normally converted and gtk-rs/gir@2941754 need to fix that, |
That's the other way round -- EDIT: Corrected typo ( I cannot |
I think reexporting sys enums is the right thing to do, if there are no structural difference between them. |
You right about |
Since there are no extra safety achieved by this, wouldn't it be better to remove the whole enum redefining thingy? (Note: there was a typo in my previous comment) |
For now, it's a common base to gave |
I not remember why we redefine enum in non-sys crate but by https://github.com/gtk-rs/gdk/blob/master/src/auto/enums.rs#L9-L66 example maybe it to get normal names for cases |
But https://github.com/gtk-rs/sys/blob/master/gdk-sys/src/lib.rs#L28-L42 also seems normal enum |
Those constants are just referencing camel cased enum variants. |
It should probably be done at the gir-for-rust level. Refer to the |
Yes, we can change https://github.com/gtk-rs/gir/blob/master/src/analysis/conversion_type.rs#L58 to remove to_glib/from_glib and https://github.com/gtk-rs/gir/blob/master/src/codegen/enums.rs to generate reexports but IMHO better wait some time before do this massive change. |
I think it was mostly to have it implemented on every object so we could call |
@GuillaumeGomez IMHO not, we have ConversionType::Direct at moment when gtk-rs/gir#229 and gtk-rs/gtk#310 landed year ago. |
Sure, meanwhile here is a PR for it. 😄 |
Seems main reason to redefine is checking returned value |
That seems like a good idea at first, but when I think about it, that doesn't make a lot of sense. Additional "safety" provided by doing that seems to be in "preventing gtk from returning bad enumerations due to bugs in it." But gtk-rs is just a wrapper, as such it may not be worth checking for upstream bugs, from a performance point-of-view. As of now, it just transmutes an |
"Checks" done when converting FFI-enum to rust-enum not when converting from i32 to FFI-enum |
But when you |
As I understand this match will panic on not listed values. |
No, there's no built-in runtime panic behavior for |
@johncf you right. Match not panic on wrong values but go to one branch ("B" in my test case). #[repr(C)]
pub enum Test {
A = 0,
B = 1,
}
let v: Test = unsafe { std::mem::transmute(2) } ;
match v {
Test::A => println!("A"),
Test::B => println!("B"),
} |
That's what I said, we should write a full |
Let's ditch it! 😄 Tons of lines of code will be saved! (-1.6kloc just for this repo!!) And also result in lot more simplified code!
No, performance overheads!! 😢 |
Well, it doesn't like a good idea to just transmute any value. :-/ |
@GuillaumeGomez what you mean about full match?
|
@GuillaumeGomez Using Rust, people like to do strong compile-time checks so as to avoid certain runtime checks thereby gaining performance. But in our case, since we are in the ffi boundary, there's a limit to what compile-time checks can accomplish. I'm very much against sacrificing runtime performance for doing upstream bug-checks. ( |
Hum... The comparison should work normally... Strange. |
That's my main concern: the day we have a bug, debugging this will be terrible. Can we at least add a check before transmuting? |
What type of check? IMHO we can't check that i32 not present in enum in general |
This is what I'm thinking he's referring to: #[repr(C)]
pub enum Test {
A = 0,
B = 1,
}
fn toTest(v) -> Test {
match v {
0 => Test::A,
1 => Test::B,
_ => panic!("Bad!"),
}
} |
@johncf: Exactly. |
|
and still print "B" |
The comparison is another issue from my point of view. |
@johncf By way, wrong i32 may be not from bug in upstream, but also when upstream add new case to enum |
This is everyday! 😄 In my opinion, what gtk-rs should strive to accomplish is:
Those two goals are hard enough to achieve. Once they are achieved 🤞 , perhaps we can think about preventing upstream bugs too. |
They are essentially API changes, which means versions change. |
Don't only take the parts you want. 😝 The last part was the important one: don't make bug tracking harder.
In |
IMHO it impossible in case of check enum values |
Sorry, if I sounded argument-y... And yeah, bugs beyond ffi boundary will be harder to track. But do you agree with those two goals? Oh, and also:
|
Maybe I wasn't clear enough: I agree with the transmute change, it's a good idea. My main concern is principally: if an user gets an invalid converted value, then Rust safety is just gone. And it seems quite simple for it to happen: you use the crate of someone targetting 3.8 and you have a superior version which inserted a value inside the enum. You got the jackpot. |
From my point of view, much of your concerns should not be taken care of from a wrapper (even if the wrapper is written in a language which promises safety). Those safety guarantees must be built ground up -- the underlying library should be so designed that languages with the highest safety guarantees will be able to withhold those guarantees. A C-library written without that in mind can only be so much safe... (To be honest, I'm quite happy that most gtk libraries come with those gir files describing a lot more than what the language could, though still far from complete. And I'm very happy that using Rust, we can actually make the compiler do many of the checks written in those gir files!)
Version? Of course the wrapper should be very much concerned about version differences, and provide correct behavior across them. This is a very different topic, though. |
If we still prefer checked
|
After some long careful considerations, I've come to the conclusion that I'll be a lot more productive if I shifted the GUI development to Vala, and form a feature-specific FFI interface between Vala and Rust, which should be very easy. Vala, being specifically designed for GObject, simply provides a lot of convenience when it comes to Gtk development. The convenience and maturity of Vala ecosystem far outweighed all arguments raised by the Rust-fanboy in me. Anyway, I'll see to the conclusion of this PR. So feel free to suggest changes or close this, after the maintainers have reached a decision. |
I was thinking about a way to make everyone happy: adding an unchecked method which uses |
Updated to reflect changes from gtk-rs/gir#354 |
I think adding |
Note: does not compile
Make it compile
WIP: Do not merge!
Why is
.to_glib()
generated? I saw this, but I could not understand the purpose of it. It looks like an unnecessary indirection. What changes should be made incairo
(since there's only one type involved)?Should I simply do: