https://bugs.kde.org/show_bug.cgi?id=448087
Bug ID: 448087 Summary: rust-qt-binding-generator: Undefined Behaviour: One can obtain a mutable reference to a Rust struct from an immutable reference. Product: rust-qt-binding-generator Version: unspecified Platform: Other OS: All Status: REPORTED Severity: normal Priority: NOR Component: general Assignee: j...@vandenoever.info Reporter: a...@grois.info Target Milestone: --- Created attachment 145205 --> https://bugs.kde.org/attachment.cgi?id=145205&action=edit example code ready to run cargo build SUMMARY By storing the Emitter in a RefCell one can create a mutable reference to the struct the Emitter is associated with while an arbitrary number of immutable references to the same struct may exist. If I understand the Rustonomicon correctly, such a transmutation from & to &mut violates Rust's aliasing rules and is undefined behaviour. Let's assume a minimal example (also attached in a build-ready form): ------------------- bindings.json { "cppFile": "src/Bindings.cpp", "rust": { "dir": "rust", "interfaceModule": "interface", "implementationModule": "implementation" }, "objects": { "SomeQtObject" : { "type" : "Object", "properties" : { "some_property" : { "type" : "bool", "write": true } } } } } ------------------- implementation.rs: use interface::*; pub struct SomeQtObject { emit : SomeQtObjectEmitter, emit2: std::cell::RefCell<SomeQtObjectEmitter>, some_property: bool, } impl SomeQtObjectTrait for SomeQtObject { fn new(mut emit: SomeQtObjectEmitter) -> SomeQtObject { let emit2 = emit.clone(); SomeQtObject { emit, emit2 : std::cell::RefCell::new(emit2), some_property: false, } } fn emit(&mut self) -> &mut SomeQtObjectEmitter { &mut self.emit } fn some_property(&self) -> bool { self.emit2.borrow_mut().some_property_changed(); self.some_property } fn set_some_property(&mut self, value: bool) { self.some_property = value; self.emit.some_property_changed(); } } ------------------- OBSERVED RESULT The above (and attached) example compiles fine in Rust, even though it contains an emit() statement in SomeQtObject::some_property(&self). If on the QML (or C++) side a call to SomeQtObject::set_some_property(&mut self, value: bool) is connected to this signal, undefined behaviour is invoked, as (implicitly) &self gets transmuted into &mut self. EXPECTED RESULT The safe API of the rust-qt-binding-generator should ideally make such a construct impossible. ADDITIONAL INFORMATION This might be related to https://bugs.kde.org/show_bug.cgi?id=406178, but I think it's a different issue. I've been thinking a bit on how to possibly solve this, but it's a non-trivial issue that might not be solvable without API or behaviour changes... The best option I see would be to internally create QueuedConnections on the QObject that delay the update notifications and therefore ensure that there will be no Rust -> C++ -> Rust call stacks on the same object. (That would also fix #406178.) -- You are receiving this mail because: You are watching all bug changes.