rust


error: cannot move out of borrowed content on &mut self


I was trying to make a Disjoint-Set data structure in Rust. The relevant code is:
pub struct Set<'a, T: 'a> {
rank: u32,
value: T,
parent: Option<&'a mut Set<'a, T>>
}
impl<'a, T> Set<'a, T> {
pub fn find(&'a mut self) -> &'a mut Set<'a, T> {
match self.parent {
None => self,
Some(mut p) => {
self.parent = Some( p.find() );
self.parent.unwrap()
}
}
}
}
The errors I get are:
lib.rs:69:15: 69:19 error: cannot move out of borrowed content
lib.rs:69 match self.parent {
^~~~
lib.rs:73:17: 73:21 error: cannot move out of borrowed content
lib.rs:73 self.parent.unwrap()
^~~~
I'm fairly new to Rust and I'm not sure I understand the borrow checker fully, but I am using references to avoid taking ownership of structs themselves so that they can be pointed to and reassigned similar to how you would in other languages.
I can avoid these errors by removing the mut from the references in the struct, but then I cannot change the parent of each set because they are immutable.
I have read through similar questions such as:
Rust: “cannot move out of self because it is borrowed” error
Can't borrow File from &mut self (error msg: cannot move out of borrowed content)
But these aren't helping me work out how to solve this issue. I have also tried restructuring the function find as well as the struct itself to use Rc<RefCell<Set>> and Box<Set> but I always end up at the same error.
Can anyone help me understand this error and how to fix it?
I am using rustc 1.0.0-nightly (44a287e6e 2015-01-08)
By default, a match arm is going to take the enum variant components by value. Since your type isn't copyable, that would mean that the component would be moved out of the original place. This would make your original struct partially undefined - a big no-no in Rust.
To fix that, take a reference instead, as the compiler instructs.
Next up, instead of storing the result in an Option and then immediately taking it back out, try to keep the reference in a variable, put it in the Option and return it:
let z = p.find();
self.parent = Some(z);
z
This leads to the core problem with the whole idea:
error: cannot borrow `*z` as mutable more than once at a time
You are trying to store a mutable reference and return it. This would mean that there would be multiple concurrent mutable references to the same item (also known as aliasing). Preventing this is another core tenet of Rust's safety systems, because then it's harder for the compiler to guarantee when and where things are being changed.

Related Links

Anonymous enum in Rust
Lifetime of references in closures
Why can't the Option.expect() message be downcast as a &'static str when a panic is handled with catch_unwind?
Why does the Rust documentation say that sharing a reference to a vector would create an invalid vector even though the vector is on the heap?
Polymorphism in Rust and trait references (trait objects?)
Setting the include path with bindgen
In Rust, how can a reference be a pointer to a pointer-to-a-pointer?
How to join thread in drop function? [duplicate]
Blanket implementation of core traits constrained by locally-defined public trait
Why does this Rust program ignore immutability
Pointer dereferencing in Rust
Cannot borrow data mutably in a `&` reference in array
How to cleanly break tokio-core event loop and futures::Stream in Rust
Kcov is reporting 100% for Rust lib even though some methods are not covered
How to write a panic! like macro in Rust?
Detecting the end of DMA transfer in the Ethernet card.

Categories

HOME
google-chrome
opengl
oracle
libgdx
clearcase
angular-ui-grid
eclipse-plugin
d3.js
mongoid
google-play-services
nsis
material-components
sentry
fedora
angular2-template
migrate
xamarin-zebble
game-maker
documentum
orc
outlook-restapi
jpa-2.0
corona
synthesis
phonegap-build
google-tasks-api
reselect
checkout
xsl-fo
bluemix-mobile-services
workday
neo4j.rb
gollum-wiki
ava
eclipse-emf
perfino
managed-c++
annotation-processing
ninject
polyml
textmate2
runtimeexception
djcelery
forms-authentication
ng-repeat
mars-simulator
jacoco-maven-plugin
robust
type-inference
code-push
viewmodel
sonicmq
lightning-workbench
phppgadmin
android-mediarecorder
ptvs
sesame
lvalue
apache-modules
swiperefreshlayout
zend-server
qtextedit
pjax
libharu
okio
openquery
nunit-console
django-testing
callouts
android-sdcard
qpixmap
strpos
simian
gulp-uglify
teamviewer
gravatar
jnlp
libz
vdm-sl
artisan
phpredis
camus
ssmtp
htmltidy
maven-shade-plugin
nanomsg
operands
quantify
webmethod
xcode6.3.1
redpitaya
refit
map
profiles
assetic
ctp
compiler-flags
vlab
rautomation
yii-booster
quickgraph
indesign-server
bcdedit
jquery-lazyload
chefspec
handshake
idispatch
msinfo32
gamesalad
wiktionary
navigationcontroller
boost-foreach
filelock
database-deadlocks
bll
aspbutton
.net-services
html-components
rawcontacts
spring-modules
fxruby
subtext
autobench

Resources

Database Users
RDBMS discuss
Database Dev&Adm
javascript
java
csharp
php
android
javascript
java
csharp
php
python
android
jquery
ruby
ios
html
Mobile App
Mobile App
Mobile App