How to get `&mut T` of a Box<Rc<RefCell<T>>>? - rust

I got a Box<Rc<RefCell<T>>> from FFI. How can I get the &mut T based on it?
I can not compile it. Compiler tells me:
47 | let mut r: &mut Server = server.borrow_mut();
| ^^^^^^^^^^ the trait BorrowMut<Server> is not implemented for Box<Rc<RefCell<Server>>>
|
= help: the trait BorrowMut<T> is implemented for Box<T, A>
For more information about this error, try rustc --explain E0277.
#[derive(Debug)]
struct Server {
id: i32,
}
impl Server {
pub fn change_id(&mut self) {
self.id = self.id + 1;
}
}
#[no_mangle]
pub extern "C" fn server_change_id(server: *mut Rc<RefCell<Server>>) -> isize {
let server: Box<Rc<RefCell<Server>>> = unsafe { Box::from_raw(server) };
let mut r: &mut Server = server.borrow_mut();
r.change_id();
return 0;
}

Auto-deref will make borrow_mut() directly accessible.
use std::{cell::RefCell, cell::RefMut, ops::DerefMut, rc::Rc};
fn main() {
let a = Box::new(Rc::new(RefCell::new("aaa".to_owned())));
//
println!("{:?}", a);
{
let mut r: RefMut<String> = a.borrow_mut();
r.push_str("bbb"); // via RefMut
let r2: &mut String = r.deref_mut();
r2.push_str("ccc"); // via exclusive-reference
}
println!("{:?}", a);
}
/*
RefCell { value: "aaa" }
RefCell { value: "aaabbbccc" }
*/
In your code, let mut r = server.borrow_mut(); should be enough to invoke r.change_id().
let mut r = server.borrow_mut();
r.change_id();
If you absolutely want a &mut, then use let r2 = r.deref_mut() and invoke r2.change_id().
let mut r = server.borrow_mut();
let r2 = r.deref_mut();
r2.change_id();

T gets wrapped inside the RefCell<T> must implement the Deref or DerefMut trait in order to be borrowed mutably or reference borrowed. In your case, Server must implement a deref method.
use std::ops::DerefMut;
impl DerefMut for Server {
fn deref_mut(&mut self) -> &mut Self {
*self // this assumes your server has more than just one i32 field.
}
}
After this implementation, you should be able to call server.borrow_mut() should work perfectly and return you a mutable server object.

Related

Returning References from Struct Method with Lifetimes

I am trying this code:
struct ByteIter<'a> {
remainder: &'a mut [u8],
index: usize,
}
impl<'a> ByteIter<'a> {
fn new(remainder: &'a mut [u8]) -> ByteIter<'a> {
ByteIter{remainder, index: 0}
}
fn next(&'a mut self) -> Option<&'a mut u8> {
if self.index >= self.remainder.len() {
None
} else {
let mut byte = &mut self.remainder[self.index];
self.index += 1;
Some(byte)
}
}
}
fn main() {
let mut a = [ 0x51, 0x52, 0x53, 0x54];
let mut bytes = ByteIter::new(&mut a);
{
let byte_1 = bytes.next();
}
let byte_2 = bytes.next();
}
Now, as I understand, the byte_1 was borrowed from bytes. But it's lifetime has already expired. Still when I compile this, I see the following error:
29 | let byte_2 = bytes.next();
| ^^^^^
| |
| second mutable borrow occurs here
| first borrow later used here
What is the first mutable borrow here? Shouldn't it be released when byte_1 goes out of scope?
Importantly, what should I do to fix this?
With impl<'a> ByteIter<'a>, you declare that 'a is the lifetime used in the structure, ie, it's the lifetime of the underlying slice.
Now, when you say fn next(&'a mut self) -> Option<&'a mut u8> {, you're reusing the same 'a, and you say it's the same than the returned mutable reference. You're saying that the returned lifetime is the same than the ByteIter struct content.
Remove the additional lifetime constraint and the compiler will be free to compute the appropriate lifetime:
fn next(& mut self) -> Option<& mut u8> {
if self.index >= self.remainder.len() {
None
} else {
let mut byte = &mut self.remainder[self.index];
self.index += 1;
Some(byte)
}
}

Why Rust can't coerce mutable reference to immutable reference in a type constructor?

It is possible to coerce &mut T into &T but it doesn't work if the type mismatch happens within a type constructor.
playground
use ndarray::*; // 0.13.0
fn print(a: &ArrayView1<i32>) {
println!("{:?}", a);
}
pub fn test() {
let mut x = array![1i32, 2, 3];
print(&x.view_mut());
}
For the above code I get following error:
|
9 | print(&x.view_mut());
| ^^^^^^^^^^^^^ types differ in mutability
|
= note: expected reference `&ndarray::ArrayBase<ndarray::ViewRepr<&i32>, ndarray::dimension::dim::Dim<[usize; 1]>>`
found reference `&ndarray::ArrayBase<ndarray::ViewRepr<&mut i32>, ndarray::dimension::dim::Dim<[usize; 1]>>`
It is safe to coerce &mut i32 to &i32 so why it is not applied in this situation? Could you provide some examples on how could it possibly backfire?
In general, it's not safe to coerce Type<&mut T> into Type<&T>.
For example, consider this wrapper type, which is implemented without any unsafe code and is therefore sound:
#[derive(Copy, Clone)]
struct Wrapper<T>(T);
impl<T: Deref> Deref for Wrapper<T> {
type Target = T::Target;
fn deref(&self) -> &T::Target { &self.0 }
}
impl<T: DerefMut> DerefMut for Wrapper<T> {
fn deref_mut(&mut self) -> &mut T::Target { &mut self.0 }
}
This type has the property that &Wrapper<&T> automatically dereferences to &T, and &mut Wrapper<&mut T> automatically dereferences to &mut T. In addition, Wrapper<T> is copyable if T is.
Assume that there exists a function that can take a &Wrapper<&mut T> and coerce it into a &Wrapper<&T>:
fn downgrade_wrapper_ref<'a, 'b, T: ?Sized>(w: &'a Wrapper<&'b mut T>) -> &'a Wrapper<&'b T> {
unsafe {
// the internals of this function is not important
}
}
By using this function, it is possible to get a mutable and immutable reference to the same value at the same time:
fn main() {
let mut value: i32 = 0;
let mut x: Wrapper<&mut i32> = Wrapper(&mut value);
let x_ref: &Wrapper<&mut i32> = &x;
let y_ref: &Wrapper<&i32> = downgrade_wrapper_ref(x_ref);
let y: Wrapper<&i32> = *y_ref;
let a: &mut i32 = &mut *x;
let b: &i32 = &*y;
// these two lines will print the same addresses
// meaning the references point to the same value!
println!("a = {:p}", a as &mut i32); // "a = 0x7ffe56ca6ba4"
println!("b = {:p}", b as &i32); // "b = 0x7ffe56ca6ba4"
}
Full playground example
This is not allowed in Rust, leads to undefined behavior and means that the function downgrade_wrapper_ref is unsound in this case. There may be other specific cases where you, as the programmer, can guarantee that this won't happen, but it still requires you to implement it specifically for those case, using unsafe code, to ensure that you take the responsibility of making those guarantees.
Consider this check for an empty string that relies on content staying unchanged for the runtime of the is_empty function (for illustration purposes only, don't use this in production code):
struct Container<T> {
content: T
}
impl<T> Container<T> {
fn new(content: T) -> Self
{
Self { content }
}
}
impl<'a> Container<&'a String> {
fn is_empty(&self, s: &str) -> bool
{
let str = format!("{}{}", self.content, s);
&str == s
}
}
fn main() {
let mut foo : String = "foo".to_owned();
let container : Container<&mut String> = Container::new(&mut foo);
std::thread::spawn(|| {
container.content.replace_range(1..2, "");
});
println!("an empty str is actually empty: {}", container.is_empty(""))
}
(Playground)
This code does not compile since &mut String does not coerce into &String. If it did, however, it would be possible that the newly created thread changed the content after the format! call but before the equal comparison in the is_empty function, thereby invalidating the assumption that the container's content was immutable, which is required for the empty check.
It seems type coercions don't apply to array elements when array is the function parameter type.
playground

How do I modify the content of a `RefCell<Option<T>>`?

I have an Option<T> that is shared by several structures and that must be mutable. I'm using a RefCell since, as I understand, it is the tool for that job. How do I access (and alter) the content of that Option<T> ?
I tried the following:
use std::cell::RefCell;
#[derive(Debug)]
struct S {
val: i32
}
fn main() {
let rc: RefCell<Option<S>> = RefCell::new(Some(S{val: 0}));
if let Some(ref mut s2) = rc.borrow_mut() {
s2.val += 1;
}
println!("{:?}", rc);
}
But the compiler won't let me do it:
error[E0308]: mismatched types
--> <anon>:10:12
|
10 | if let Some(ref mut s2) = rc.borrow_mut() {
| ^^^^^^^^^^^^^^^^ expected struct `std::cell::RefMut`, found enum `std::option::Option`
|
= note: expected type `std::cell::RefMut<'_, std::option::Option<S>, >`
found type `std::option::Option<_>`
When you borrow_mut the RefCell, you get a RefMut, as the compiler says. To get the value inside it, just use the operator deref_mut:
use std::cell::RefCell;
#[derive(Debug)]
struct S {
val: i32
}
fn main() {
let rc: RefCell<Option<S>> = RefCell::new(Some(S{val: 0}));
if let Some(ref mut s2) = *rc.borrow_mut() { // deref_mut
s2.val += 1;
}
println!("{:?}", rc);
}

Reference lifetime conflicts with same lifetime range

I am trying to store and use an optional callback handle in Rust which works like a method to the structure I am storing it in. It works as long as I do not pass a reference to itself to the callback. But doing so gives me a lifetime error for the used object references (E0312). The lifetime seems to be the same and I cannot figure out what to change to get this working.
type Callback<'a> = Fn(&'a mut Func, i32) -> i32;
struct Func<'a> {
val: i32,
func: Option<Box<Callback<'a>>>,
}
impl<'a, 'b> Func<'b> {
fn exec(&'a mut self, val: i32) -> i32 {
if let Some(ref f) = self.func {
return f(self, val);
};
0i32
}
}
fn main() {
let mut a32 = Func{
val: 10i32,
func: Some(Box::new(|ref mut s, val: i32| -> i32 {
let v = s.val;
s.val += 1;
val * 32 + v
}))
};
println!("a32(4) = {}", a32.exec(4i32));
println!("a32(4) = {}", a32.exec(4i32));
}
Is there a way to fix this or did I come across a compiler bug?
Using rustc 1.15.0 (10893a9a3 2017-01-19).
See also on Rust playground.
I also tried the same without explicit lifetimes but then I run into the problem that I cannot alias references in Rust (E0502).
I know that Rust tries to prevent this to avoid data races but would this mean that I always need to create a copy of my object in these cases?
The following does not work either giving me an error, that borrowed content cannot be moved out (E0507).
impl Func {
fn exec(&mut self, val: i32) -> i32 {
if self.func.is_some() {
return self.func.unwrap()(self, val);
};
0i32
}
}
But I could not find a way to clone the boxed function...
You have a borrow issue here:
You are borrowing self.func immutably
You are attempting to borrow self mutably at the same time
This is not allowed, because it could allow you to change func while using it, which heralds troubles.
You could attempt to change Callback to only pass in &mut i32 instead, but then you would hit lifetime unification issues:
if you specify that exec takes &'a mut self, then you anchor the object, borrowing it for the rest of its lifetime,
on the other hand, if you specify a fresh lifetime, then by definition it's less than 'a, and you required 'a in the signature of Callback.
Neither situation works.
The solution, thus, is to avoid the lifetime in the first place.
It's also easier (on borrowing) NOT to pass an instance of self but just to pass a reference to self.val so I present that first:
type Callback = Fn(&mut i32, i32) -> i32;
struct Func {
val: i32,
func: Option<Box<Callback>>,
}
impl Func {
fn exec(&mut self, val: i32) -> i32 {
if let Some(ref f) = self.func {
return f(&mut self.val, val);
};
0i32
}
}
fn main() {
let mut a32 = Func{
val: 10i32,
func: Some(Box::new(|s: &mut i32, val: i32| -> i32 {
let v = *s;
*s += 1;
val * 32 + v
}))
};
println!("a32(4) = {}", a32.exec(4i32));
println!("a32(4) = {}", a32.exec(4i32));
}
If you want to really pass Func, you need to "option dance":
impl Func {
fn exec(&mut self, val: i32) -> i32 {
let func = self.func.take();
let res = if let Some(ref f) = func {
f(self, val)
} else {
0i32
};
self.func = func;
res
}
}
And be aware that self.func is empty in the callback.

How to return a reference to a sub-value of a value that is under a mutex?

I have a structure that looks somewhat like this:
pub struct MyStruct {
data: Arc<Mutex<HashMap<i32, Vec<i32>>>>,
}
I can easily get a lock on the mutex and query the underlying HashMap:
let d = s.data.lock().unwrap();
let v = d.get(&1).unwrap();
println!("{:?}", v);
Now I want to make a method to encapsulate the querying, so I write something like this:
impl MyStruct {
pub fn get_data_for(&self, i: &i32) -> &Vec<i32> {
let d = self.data.lock().unwrap();
d.get(i).unwrap()
}
}
This fails to compile because I'm trying to return a reference to the data under a Mutex:
error: `d` does not live long enough
--> <anon>:30:9
|
30 | d.get(i).unwrap()
| ^
|
note: reference must be valid for the anonymous lifetime #1 defined on the block at 28:53...
--> <anon>:28:54
|
28 | pub fn get_data_for(&self, i: &i32) -> &Vec<i32> {
| ^
note: ...but borrowed value is only valid for the block suffix following statement 0 at 29:42
--> <anon>:29:43
|
29 | let d = self.data.lock().unwrap();
| ^
I can fix it by wrapping the HashMap values in an Arc, but it looks ugly (Arc in Arc) and complicates the code:
pub struct MyStruct {
data: Arc<Mutex<HashMap<i32, Arc<Vec<i32>>>>>,
}
What is the best way to approach this? Is it possible to make a method that does what I want, without modifying the data structure?
Full example code.
The parking_lot crate provides an implementation of Mutexes that's better on many accounts than the one in std. Among the goodies is MutexGuard::map, which implements an interface similar to owning_ref's.
use std::sync::Arc;
use parking_lot::{Mutex, MutexGuard, MappedMutexGuard};
use std::collections::HashMap;
pub struct MyStruct {
data: Arc<Mutex<HashMap<i32, Vec<i32>>>>,
}
impl MyStruct {
pub fn get_data_for(&self, i: &i32) -> MappedMutexGuard<Vec<i32>> {
MutexGuard::map(self.data.lock(), |d| d.get_mut(i).unwrap())
}
}
You can try it on the playground here.
This solution is similar to #Neikos's, but using owning_ref to do hold the MutexGuard and a reference to the Vec:
extern crate owning_ref;
use std::sync::Arc;
use std::sync::{Mutex,MutexGuard};
use std::collections::HashMap;
use std::vec::Vec;
use owning_ref::MutexGuardRef;
type HM = HashMap<i32, Vec<i32>>;
pub struct MyStruct {
data: Arc<Mutex<HM>>,
}
impl MyStruct {
pub fn new() -> MyStruct {
let mut hm = HashMap::new();
hm.insert(3, vec![2,3,5,7]);
MyStruct{
data: Arc::new(Mutex::new(hm)),
}
}
pub fn get_data_for<'ret, 'me:'ret, 'c>(&'me self, i: &'c i32) -> MutexGuardRef<'ret, HM, Vec<i32>> {
MutexGuardRef::new(self.data.lock().unwrap())
.map(|mg| mg.get(i).unwrap())
}
}
fn main() {
let s: MyStruct = MyStruct::new();
let vref = s.get_data_for(&3);
for x in vref.iter() {
println!("{}", x);
}
}
This has the advantage that it's easy (through the map method on owning_ref) to get a similar reference to anything else reachable from the Mutex (an individual item in a Vec, etc.) without having to re-implement the returned type.
This can be made possible by using a secondary struct that implements Deref and holds the MutexGuard.
Example:
use std::sync::{Arc, Mutex, MutexGuard};
use std::collections::HashMap;
use std::ops::Deref;
pub struct Inner<'a>(MutexGuard<'a, HashMap<i32, Vec<i32>>>, i32);
impl<'a> Deref for Inner<'a> {
type Target = Vec<i32>;
fn deref(&self) -> &Self::Target {
self.0.get(&self.1).unwrap()
}
}
pub struct MyStruct {
data: Arc<Mutex<HashMap<i32, Vec<i32>>>>,
}
impl MyStruct {
pub fn get_data_for<'a>(&'a self, i: i32) -> Inner<'a> {
let d = self.data.lock().unwrap();
Inner(d, i)
}
}
fn main() {
let mut hm = HashMap::new();
hm.insert(1, vec![1,2,3]);
let s = MyStruct {
data: Arc::new(Mutex::new(hm))
};
{
let v = s.get_data_for(1);
println!("{:?}", *v);
let x : Vec<_> = v.iter().map(|x| x * 2).collect();
println!("{:?}", x); // Just an example to see that it works
}
}
As described in Why can't I store a value and a reference to that value in the same struct?, the Rental crate allows for self-referential structs in certain cases. Here, we bundle the Arc, the MutexGuard, and the value all into a struct that Derefs to the value:
#[macro_use]
extern crate rental;
use std::{
collections::HashMap, sync::{Arc, Mutex},
};
use owning_mutex_guard_value::OwningMutexGuardValue;
pub struct MyStruct {
data: Arc<Mutex<HashMap<i32, Vec<i32>>>>,
}
impl MyStruct {
pub fn get_data_for(&self, i: &i32) -> OwningMutexGuardValue<HashMap<i32, Vec<i32>>, Vec<i32>> {
OwningMutexGuardValue::new(
self.data.clone(),
|d| Box::new(d.lock().unwrap()),
|g, _| g.get(i).unwrap(),
)
}
}
rental! {
mod owning_mutex_guard_value {
use std::sync::{Arc, Mutex, MutexGuard};
#[rental(deref_suffix)]
pub struct OwningMutexGuardValue<T, U>
where
T: 'static,
U: 'static,
{
lock: Arc<Mutex<T>>,
guard: Box<MutexGuard<'lock, T>>,
value: &'guard U,
}
}
}
fn main() {
let mut data = HashMap::new();
data.insert(1, vec![1, 2, 3]);
let s = MyStruct {
data: Arc::new(Mutex::new(data)),
};
let locked_data = s.get_data_for(&1);
let total: i32 = locked_data.iter().map(|x| x * 2).sum();
println!("{}", total);
assert!(s.data.try_lock().is_err());
drop(locked_data);
assert!(s.data.try_lock().is_ok());
}
Here's an implementation of the closure-passing approach mentioned in the comments:
impl MyStruct {
pub fn with_data_for<T>(&self, i: &i32, f: impl FnOnce(&Vec<i32>) -> T) -> Option<T> {
let map_guard = &self.data.lock().ok()?;
let vec = &map_guard.get(i)?;
Some(f(vec))
}
}
Rust Playground
Example usage:
s.with_data_for(&1, |v| {
println!("{:?}", v);
});
let sum: i32 = s.with_data_for(&1, |v| v.iter().sum()).unwrap();
println!("{}", sum);

Resources