What does & actually do? - rust

I am trying to understand Rust's reference.
fn main() {
let x: i32 = 0;
println!("{}", x+1); // this works
println!("{}", (&x)+1); // this works
//println!("{}", (&(&x))+1); // but this failed
}
What I get:
1
1
What does & actually do? Why can &x be added like it is an integer but not &(&x)?

& takes the reference of the operand. This can be thought of as finding the memory address that the value is stored at.
Your example works because + is implemented using the Add trait, which has the following variants:
impl Add<i32> for i32
impl<'a> Add<i32> for &'a i32
impl<'a> Add<&'a i32> for i32
impl<'a, 'b> Add<&'a i32> for &'b i32
That is, you can add any pair of references and non-references. However, your second example would have two levels of indirection (&&i32), and the Add trait isn't implemented for that many levels of reference.

Related

Lifetime parameters in a trait

I'm having difficulties understanding lifetime parameters in the following code snippet.
struct C {
data: Vec<u32>,
cols: usize
}
trait M<'s> {
fn get(&'s self, r: usize, c: usize) -> u32;
fn get_mut(&'s mut self, r: usize, c: usize) -> &'s mut u32;
}
impl<'s> M<'s> for C {
fn get(&'s self, r: usize, c: usize) -> u32 {
return self.data[self.cols*r+c];
}
fn get_mut(&'s mut self, r: usize, c: usize) -> &'s mut u32 {
return &mut self.data[self.cols*r+c];
}
}
#[cfg(test)]
mod tests {
use super::*;
fn create() -> C {
let data = vec![0u32,1u32,2u32,3u32,4u32,5u32];
return C{data, cols: 3};
}
fn select<'s, 'r: 's>(data: &'r mut dyn M<'s>) {
let mut _val: u32 = 0;
for r in 0..2 {
for c in 0..3 {
_val += *data.get_mut(r,c);
}
}
}
#[test]
fn test_select() {
let mut data = create();
select(&mut data);
}
}
The code snippet does not compile, because it complains that *data is borrowed multiple times in the function fn select<'s, 'r: 's>(data: &'r mut dyn M<'s>) {} when calling get_mut (once in every loop iteration). Even safeguarding the questionable line with curly braces (and thus creating a new context) does not help. My expectation (in both cases) would be, that the mutable borrow of &mut data should end right after the execution of that line.
On the other hand, when I remove all lifetime parameters, everything works as expected.
Can anyone explain what's the difference between the two versions (with and without explicit lifetimes)?
I've also tried to find information about additional lifetime parameters for traits, in particular specifying their meaning, but I have found none. So I assume, that they are just a declaration of the used labels inside the trait. But if that is so, then I would assume that leaving out the lifetime parameters completely and applying the eliding rules would lead to the same result.
There are two things to consider. The first is when you use a generic lifetime for a function, that lifetime must be larger than the life of the function call simply by construction. And the second is since the lifetime self is tied to the lifetime parameter of the trait, when you call .get_mut(), data is borrowed for the lifetime of 's. Combining those two principles, data is borrowed for longer than the function call so you can't call it again (its already mutably borrowed).
On the other hand, when I remove all lifetime parameters, everything works as expected. Can anyone explain what's the difference between the two versions (with and without explicit lifetimes)?
Without a generic lifetime on M, the methods will behave as if defined as so:
impl M for C {
fn get<'a>(&'a self, r: usize, c: usize) -> u32 {
return self.data[self.cols * r + c];
}
fn get_mut<'a>(&'a mut self, r: usize, c: usize) -> &'a mut u32 {
return &mut self.data[self.cols * r + c];
}
}
Thus there is no lifetime associated with the trait; the lifetimes given and returned from the function are generic only to those method calls. And since the compiler can choose a new lifetime 'a for each call and it will always pick the shorted lifetime to satisfy its usage, you can then call data.get_mut() multiple times without worry. And I'll be honest, having the lifetime on the trait didn't make much sense with the original code; as mentioned, the code works with all lifetime annotations removed: playground.

Specifying lifetime causing immutable/mutable borrow conflict

Small example to illustrate the problem. The following compiles:
fn main() {
let value: u32 = 15;
let mut ref_to_value: &u32 = &0;
fill_object(&mut ref_to_value, &value);
println!("referring to value {}", ref_to_value);
}
fn fill_object<'a>(m: &mut &'a u32, v: &'a u32) {
*m = v;
}
Now, the following gives a compile time error about mutable borrow followed by immutable borrow:
fn fill_object<'a>(m: &'a mut &'a u32, v: &'a u32) {
*m = v;
}
fill_object(&mut ref_to_value, &value);
| ----------------- mutable borrow occurs here
5 | println!("referring to value {}", ref_to_value);
| ^^^^^^^^^^^^
| |
| immutable borrow occurs here
| mutable borrow later used here
Why? I'm presuming that because I have now specified a lifetime of 'a for the reference to ref_to_value, that mutable reference is now over the entire scope (ie. main). Whereas before, without the 'a lifetime reference, the mutable reference was limited?
I'm looking for clarity on how to think about this.
Your intuition is spot on. With one lifetime,
fn fill_object<'a>(m: &'a mut &'a u32, v: &'a u32) {
*m = v;
}
All three references are required to live for the same length, so if v lives a long time then the mutable reference must as well. This is not intuitive behavior, so it's generally a bad idea to tie together lifetimes like this. If you don't specify any lifetimes, Rust gives each reference a different one implicitly. So the following are equivalent.
fn fill_object(m: &mut &u32, v: &u32)
fn fill_object<'a, 'b, 'c>(m: &'a mut &'b u32, v: &'c u32)
(Note: The inferred lifetime of returned values is a bit more complicated but isn't in play here)
So, your partially-specified lifetimes are equivalent to
fn fill_object<'a>(m: &mut &'a u32, v: &'a u32);
fn fill_object<'a, 'b>(m: &'b mut &'a u32, v: &'a u32);
As a side note, &mut &u32 is a weird type for multiple reasons. Putting aside the fact that u32 is copy (and hence, outside of generics, useless to take immutable references of), a mutable reference to an immutable reference is just confusing. I'm not sure what you're real use case is. If this was just a test example, then sure. But if this is your real program, I recommend considering if you can get off with fill_object(&mut u32, u32), and if you really need the nested reference, you might consider making it a bit easier to swallow with a structure.
struct MyIntegerCell<'a>(&'a u32);
Plus some documentation as to why this is necessary. And then you would have fill_object(&mut MyIntegerCell, u32) or something like that.

Building structs dynamically with lifetime parameters

Trying to build a tree structure from another tree structure in Rust - where the the built tree structure are dependent on lifetimes parameters.
The traits below represents a simplified version of my search tree structure (the one I wish for to be build dynamically):
trait SPart {
fn search<'b>(&'b self, queue: &mut Vec<Box<dyn SPart + 'b>>);
}
trait SubSPart<PP: SPart> {
fn promote_search<'b>(&'b self, parent: &'b PP, queue: &mut Vec<Box<dyn SPart + 'b>>);
}
struct SP<'a>(pub Vec<Box<dyn SubSPart<Self> + 'a>>);
struct SSP(pub i32);
impl<'a> SPart for SP<'a> {
fn search<'b>(&'b self, queue: &mut Vec<Box<dyn SPart + 'b>>) {
for c in &self.0 {
c.promote_search(self, queue);
}
}
}
impl<'a> SubSPart<SP<'a>> for SSP {
fn promote_search<'b>(&'b self, parent: &'b SP, queue: &mut Vec<Box<dyn SPart + 'b>>) {
queue.push(Box::new(SP(vec![])));
}
}
The parts and subparts can contain references to data, hence I think the lifetime-parameter is necessary.
These parts are usually also short-lived in a recursive function, and can be created dynamically referring back to data from earlier frames in the recursive call.
This all works with flying colors, so now I'm interested in building this initial tree structure dynamically from a separate tree structure:
trait BPart {
fn build<'b>(&'b self, v: &mut Vec<Box<dyn SPart + 'b>>);
}
trait SubBPart<P, PP: SPart> {
fn build<'b>(&'b self, parent: &'b P, v: &mut Vec<Box<dyn SubSPart<PP> + 'b>>);
}
struct BP<'a>(pub Vec<Box<dyn SubBPart<Self, SP<'a>>>>, pub i32);
struct SBP(pub i32);
impl<'a> BPart for BP<'a> {
fn build<'b>(&'b self, v: &mut Vec<Box<dyn SPart + 'b>>) {
let mut sv = vec![];
for sp in &self.0 {
sp.build(self, &mut sv);
}
let sp = SP(sv);
v.push(Box::new(sp));
}
}
impl<'a> SubBPart<BP<'a>, SP<'a>> for SBP {
fn build<'b>(&'b self, parent: &'b BP<'a>, v: &mut Vec<Box<dyn SubSPart<SP> + 'b>>) {
v.push(Box::new(SSP(self.0 + parent.1)));
}
}
fn main() {
let bp = BP(vec![Box::new(SBP(42))], 21);
let mut v = vec![];
bp.build(&mut v);
}
However, this fails with:
error[E0495]: cannot infer an appropriate lifetime for borrow expression due to conflicting requirements
It seems like the lifetime is tied to the BPart ('a) where I wish for the lifetime to be valid for any lifetime ('b) at the time of creation of the SPart and SubSPart, but I'm unaware of how to express this in Rust.
Link to rust playground
Edit:
Added trait methods and examples, and main method.
This is quite the spaghetti of lifetime constraints so I'll try to break down the limitations:
The lifetime 'b is invariant due to its use in &mut Vec<Box<dyn SPart + 'b>>. Most lifetime annotations are covariant, meaning it can be shortened as necessary to align with other constraints. But the compiler cannot do so here because, if shortened, the value could be mutated or assigned to a value that lives shorter than it needs to.
The lifetime 'a is invariant due to its use in Vec<Box<dyn SubBPart<Self, SP<'a>>>>. An implementor of Trait<'a> can use inner mutability and thus, for the same reasons above, cannot be covariant.
'a: 'b - The use of &'b self implies BP<'a>: 'b and thus implies 'a: 'b meaning that the lifetime of 'b cannot outlive the life of 'a.
'b: 'a - The use of dyn SubSPart<PP> + 'b normally means that the trait object is allowed to borrow from 'b but because PP is SP<'a> it is also allowed to borrow from 'a. This means that in order for 'b from SubBPart::build to line up with BPart::build, then 'a cannot outlive 'b.
To satisfy the above constraints, it must be that 'a == 'b. But 'b is part of a trait's function signature as a generic parameter, so it must be allowed to be anything.
I don't have a good recommendation for you for how to fix it since your code is very obfuscated as to what these lifetimes and trait abstractions are for.
This is indeed a case where a higher kinded lifetime is needed. Instead of locking in on a specific lifetime, giving 'a as a generic parameter in the struct BP, the use of a higher kinded lifetime can be specified as follows:
struct BP(pub Vec<Box<dyn for<'a> SubBPart<Self, SP<'a>>>>, pub i32);
To complete the answer: In my case, a SPart or SubSPart can contain references to data from its builder BPart or SubBPart. This required changes to the traits:
trait BPart<'a> {
fn build(&'a self, v: &mut Vec<Box<dyn SPart + 'a>>);
}
trait SubBPart<'a, P, PP: SPart> {
fn build(&'a self, parent: &'a P, v: &mut Vec<Box<dyn SubSPart<PP> + 'a>>);
}
and then adjusting the impls accordingly.

`cannot infer an appropriate lifetime for autoref due to conflicting requirements` but can't change anything due to trait definition constraints

I was implementing linked lists by following along too many linked lists. When trying to implement iter_mut(), I did it myself and made the following code:
type Link<T> = Option<Box<Node<T>>>;
pub struct List<T> {
head: Link<T>,
}
struct Node<T> {
elem: T,
next: Link<T>,
}
impl<T> List<T> {
pub fn iter_mut(&mut self) -> IterMut<T> {
IterMut::<T>(&mut self.head)
}
}
pub struct IterMut<'a, T>(&'a mut Link<T>);
impl<'a, T> Iterator for IterMut<'a, T> {
type Item = &'a mut T;
fn next<'b>(&'b mut self) -> Option<&'a mut T> {
self.0.as_mut().map(|node| {
self.0 = &mut (**node).next;
&mut (**node).elem
})
}
}
I am to avoiding coersions and elisions because being explicit lets me understand more.
Error:
error[E0495]: cannot infer an appropriate lifetime for autoref due to conflicting requirements
--> src/third.rs:24:16
|
24 | self.0.as_mut().map(|node| {
| ^^^^^^
|
note: first, the lifetime cannot outlive the lifetime `'b` as defined on the method body at 23:13...
--> src/third.rs:23:13
|
23 | fn next<'b>(&'b mut self) -> Option<&'a mut T> {
| ^^
note: ...so that reference does not outlive borrowed content
--> src/third.rs:24:9
|
24 | self.0.as_mut().map(|node| {
| ^^^^^^
note: but, the lifetime must be valid for the lifetime `'a` as defined on the impl at 20:6...
--> src/third.rs:20:6
|
20 | impl<'a, T> Iterator for IterMut<'a, T> {
| ^^
note: ...so that reference does not outlive borrowed content
--> src/third.rs:25:22
|
25 | self.0 = &mut (**node).next;
| ^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0495`.
I have looked at Cannot infer an appropriate lifetime for autoref due to conflicting requirements.
I understand a bit but not much. The problem that I am facing here is that if I try to change anything, an error pops saying that can't match the trait definition.
My thought was that basically I need to state somehow that lifetime 'b outlives 'a i.e <'b : 'a> but I can't figure out how to do it. Also, I have similar functions to implement iter() which works fine. It confuses me why iter_mut() produces such errors.
Iter
type Link<T> = Option<Box<Node<T>>>;
pub struct Iter<'a, T>(&'a Link<T>);
impl<'a, T> Iterator for Iter<'a, T> {
type Item = &'a T;
fn next(&mut self) -> Option<Self::Item> {
self.0.as_ref().map(|node| {
self.0 = &((**node).next);
&((**node).elem)
})
}
}
impl<T> List<T> {
pub fn iter(&self) -> Iter<T> {
Iter::<T>(&self.head)
}
}
☝️This works.
The key thing is that you need to be able to somehow extract an Option<&'a mut T> from a &'b mut IterMut<'a, T>.
To understand why IterMut<'a, T> := &'a mut Link<T> can't work, you need to understand what exactly you can do with a mutable reference. The answer, of course, is almost everything. You can copy data out of it, change its value, and lots of other things. The one thing you can't do is invalidate it. If you want to move the data under the mutable reference out, it has to be replaced with something of the same type (including lifetimes).
Inside the body of next, self is (essentially) &'b mut &'a mut Link<T>. Unless we know something about T (and we can't in this context), there's simply no way to produce something of type &'a mut Link<T> from this. For example, if this were possible in general, we'd be able to do
fn bad<'a, 'b, T>(_x: &'b mut &'a mut T) -> &'a mut T {
todo!()
}
fn do_stuff<'a>(x: &'a mut i32, y: &'a mut i32) {
// lots of stuff that only works if x and y don't alias
*x = 13;
*y = 42;
}
fn main() {
let mut x: &mut i32 = &mut 0;
let y: &mut i32 = {
let z: &mut &mut i32 = &mut x;
bad(z)
};
// `x` and `y` are aliasing mutable references
// and we can use both at once!
do_stuff(x, y);
}
(playground link)
The point is that if we were able to borrow something for a short (generic) lifetime 'b and return something that allowed modification during the longer lifetime 'a, we'd be able to use multiple short lifetimes (shorter than 'a and non-overlapping) to get multiple mutable references with the same lifetime 'a.
This also explains why the immutable version works. With immutable references, it's trivial to go from &'b &'a T to &'a T: just deference and copy the immutable reference. By contrast, mutable references don't implement Copy.
So if we can't produce a &'a mut Link<T> from a &'b mut &'a mut Link<T>, we certainly can't get an Option<&'a mut T out of it either (other than None). (Note that we can produce a &'b mut Link<T> and hence an Option<'b mut T>. That's what your code does right now.)
So what does work? Remember our goal is to be able to produce an Option<&'a mut T> from a &'b mut IterMut<'a, T>.
If we were able to produce a IterMut<'a, T> unconditionally, we'd be able to (temporarily) replace self with it and hence be able to directly access the IterMut<'a, T> associated to our list.
// This actually type-checks!
fn next<'b>(&'b mut self) -> Option<&'a mut T> {
let mut temp: IterMut<'a, T> = todo!(); // obviously this won't work
std::mem::swap(&mut self.0, &mut temp.0);
temp.0.as_mut().map(|node| {
self.0 = &mut node.next;
&mut node.elem
})
}
(playground link)
The easiest way to set things up so that this all works is by transposing IterMut<'a, T> a bit. Rather than having the mutable reference outside the option, make it inside! Now you'll always be able to produce an IterMut<'a, T> with None!
struct IterMut<'a, T>(Option<&mut Box<Node<T>>>);
Translating next, we get
fn next<'b>(&'b mut self) -> Option<&'a mut T> {
let mut temp: IterMut<'a, T> = IterMut(None);
std::mem::swap(&mut self.0, &mut temp.0);
temp.0.map(|node| {
self.0 = node.next.as_mut();
&mut node.elem
})
}
More idiomatically, we can use Option::take rather than std::mem::swap (This is mentioned earlier in Too Many Linked Lists).
fn next<'b>(&'b mut self) -> Option<&'a mut T> {
self.0.take().map(|node| {
self.0 = node.next.as_mut();
&mut node.elem
})
}
(playground link)
This actually ends up being slightly different than the implementation in Too Many Linked Lists. That implementation removes the double indirection of &mut Box<Node<T>> and replaces it with simply &mut Node<T>. However, I'm not sure how much you gain since that implementation still has a double deref in List::iter_mut and Iterator::next.
Rust is trying to say that you have a dangling reference.
self.0.as_mut() // value borrowed
self.0 = <> // underlying value changed here.
The problem is the following definition:
pub struct IterMut<'a, T>(&'a mut Link<T>)
This can't encapsulate that you will have a "empty" node meaning reached the end of the node.
Use the structure as mentioned in the book like:
pub struct IterMut<'a, T>(Option<&'a mut Node<T>>);
This ensures that you can leave None in its place when you run end of list and use take to modify the IterMut content behind the scenes.

Turning a Vec<Rc<RefCell<T>>> into a &[&mut T]

I've got a vector of reference-counted RefCells and want to pass a Vec of (mut) references into the RefCells into a function. The references shouldn't need to outlive the function call.
It seems like it should be possible (with just one, something like &*x.borrow_mut() is ok). I tried to keep intermediate vectors of RefMut and &mut to control the lifetimes, but I haven't yet worked out a way to get it to work:
use std::cell::{RefCell,RefMut};
use std::vec::Vec;
use std::rc::Rc;
trait SomeTrait {}
struct Wrapper<'a> {
pub r: &'a mut SomeTrait,
}
fn foo(_: &[Wrapper]) {}
fn main() {
let mut v1: Vec<Rc<RefCell<SomeTrait>>> = unimplemented!();
let mut v_rm: Vec<RefMut<_>> = v1.iter_mut().map(|r| r.borrow_mut()).collect();
let mut v_wrapper: Vec<Wrapper> = v_rm.iter_mut().map(|ref mut rm| Wrapper{ r: &mut ***rm }).collect();
foo(&v_wrapper[..]);
}
(playground)
There's clearly a lifetime issue:
rustc 1.11.0 (9b21dcd6a 2016-08-15)
error: borrowed value does not live long enough
--> <anon>:17:60
|>
17 |> let mut v_wrapper: Vec<Wrapper> = v_rm.iter_mut().map(|ref mut rm| Wrapper{ r: &mut ***rm }).collect();
|> ^^^^^^^^^^
note: reference must be valid for the block suffix following statement 2 at 17:107...
--> <anon>:17:108
|>
17 |> let mut v_wrapper: Vec<Wrapper> = v_rm.iter_mut().map(|ref mut rm| Wrapper{ r: &mut ***rm }).collect();
|> ^
note: ...but borrowed value is only valid for the block at 17:71
--> <anon>:17:72
|>
17 |> let mut v_wrapper: Vec<Wrapper> = v_rm.iter_mut().map(|ref mut rm| Wrapper{ r: &mut ***rm }).collect();
|> ^^^^^^^^^^^^^^^^^^^^^^^^
error: aborting due to previous error
I do control foo so can alter its API to make things easier, but it's in a different module/crate and I don't really want it to need to know that I keep my SomeTrait objects in an Rc<RefCell<_>>.
While it is certainly possible to write code that starts with a Vec<RefMut<T>> and creates a Vec<&mut T> from that (generic example), I would suggest that you change the signature of foo. Many algorithms do not need the random access provided by slices, and if the function could accept an iterator instead of a slice, you wouldn't need to create two whole additional Vecs, aside from the calling function becoming simpler. I'm thinking of a signature like this
fn foo<I, R>(widgets: I)
where I: IntoIterator<Item=R>,
R: DerefMut<Target=SomeTrait>
{
for widget in widgets {
// ...
}
}
Then all you need is producing an iterator that yields RefMut's, which is easily accomplished with v1.iter_mut().map(|x| x.borrow_mut()). Here's an example.
First, I agree with #delnan that you should switch to an iterator-based interface if you can.
Most of this code is just fine, and after changing foo and Wrapper to be a bit more flexible, I was able to tweak the rest and get it to compile:
use std::cell::{RefCell,RefMut};
use std::vec::Vec;
use std::rc::Rc;
trait SomeTrait {}
struct Wrapper<'a, 'b> where 'b: 'a {
pub r: &'a mut (SomeTrait + 'b),
}
fn foo<'a, 'b>(_: &'a mut [Wrapper<'a, 'b>]) where 'b: 'a {}
fn main() {
let mut v1: Vec<Rc<RefCell<SomeTrait>>> = unimplemented!();
let mut v_rm: Vec<RefMut<_>> = v1.iter_mut().map(|r| r.borrow_mut()).collect();
let mut v_wrapper: Vec<Wrapper> = v_rm.iter_mut().map(|mut rm| Wrapper{ r: &mut **rm }).collect();
foo(&mut v_wrapper[..]);
}
The key thing to understand here is that every trait object type has an implicit lifetime stapled to it, because an impl may contain references. There's no such type as SomeTrait, only SomeTrait + 'a or SomeTrait + 'b or SomeTrait + 'static.
The problem in your code was a mismatch between two things Rust inferred.
Where you wrote Rc<RefCell<SomeTrait>>, Rust assumed you meant Rc<RefCell<SomeTrait + 'static>>.
Where you wrote fn foo(_: &[Wrapper]) {}, different rules applied, and Rust assumed you meant fn foo<'a>(_: &'a [Wrapper<'a> + 'a]).
D'oh. Under those assumptions, the puzzle indeed has no solutions, and that's why I had to loosen things up.
If you don't want that 'b lifetime parameter, you can ditch it and just change 'b to 'static in the one place where it's used (on the type of Wrapper::r). That's less flexible: you'll be limited to SomeTrait impls that have static lifetime.

Resources