https://bugs.kde.org/show_bug.cgi?id=406178

            Bug ID: 406178
           Summary: Mutability of Rust objects
           Product: rust-qt-binding-generator
           Version: unspecified
          Platform: Other
                OS: Linux
            Status: REPORTED
          Severity: normal
          Priority: NOR
         Component: general
          Assignee: j...@vandenoever.info
          Reporter: kdebuac....@porcupinefactory.org
  Target Milestone: ---

This is not exactly a bug, but a discussion topic I wanted to touch upon.

SUMMARY

There can be multiple references to an object borrowed mutably when signals
come into play.

Whenever a signal handler on an object tries to access its property (e.g.
onFooChanged -> read foo), a mutable reference will be active at the same time
as an immutable one. This is becoming a problem with my branch of the bindings
generator, where objects are protected with RefCells, causing crashes. I am
writing here to summarize why this happens and try to find a way out.

STEPS TO REPRODUCE

I'll unroll how exactly the simultaneous references happen.

The object Rfoo has a property bar. There is a signal handler which wants to
read that property and do something with it. In QML terms:

Rfoo {
  id: me
  onBarChanged: console.log(me.bar)
}

When bar is written to, the following calls are made (pseudostack):

let rfoo = rfoo_qobject.get_mut() // mutable borrow begins
let emitter = rfoo.emit() // emit() takes &mut self
emitter.emit_bar_changed()
 emit onBarChanged
  QML evaluates me.bar
   let rfoo2 = rfoo_qobject.get() // second borrow begins!!!
   let bar = rfoo2.get_bar()

OBSERVED RESULT

This will pass tests in the vanilla bindgen because objects are accessed via
raw pointers, but it crashes Rust-created objects when using my branch (no
tests yet).

https://gitlab.com/rhn_mk1/rust-qt-bindings-generator

One way to get rid of this is to make Rust objects unconditionally
reference-safe (ideally thread-safe), by making calls reference &self only
immutably, and putting all data behind an Arc<Mutex> or similar. The API would
get uglier, but I'm willing to experiment, since RustGen in my branch are
already on the way there.

EXPECTED RESULT

Be able to read Foo after onFooChange without breaking Rust reference rules.
I'm not sure what that means exactly. It may be a good thing to be able to read
properties after a signal, but it's almost certainly bad to write them (and
cause multiple mutable references to data in addition to reference cycles).

The questions: is there any other design than the one I came up with that makes
sense? Is it worth bothering to fulfill Rust reference guarantees at all,
seeing as the most of the code is C++?

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to