Expanding Rust Lifetime - rust

I have a bit of code that I'm fighting with. It's a little helper function that should return a Vec<&str> to the calling function. I can't seem to get the lifetime right, though.
Here is the code snippet:
fn take_symbol<'a>(ch: &'a str, current: &'a mut String) -> &'a mut TokenList<'a> {
let out = TokenList::<'a>::new();
out.push(current.as_str());
out.push(ch);
*current = String::new();
&mut out
}
The compiler is telling me: error: 'out' does not live long enough and that the reference must be valid for the lifetime of 'a, but it looks to me like it is defined for 'a.
I have also tried changing it to:
let out = &mut TokenList::<'a>::new();
which doesn't change any of the error messages. Or:
let out = &'a mut TokenList::<'a>::new();
which the compiler doesn't like at all.
How do I define out to have a lifetime of 'a?
For further details, here is my definition of TokenList:
pub type Token<'a> = &'a str;
pub type TokenList<'a> = Vec<Token<'a>>;

The lifetime of out is not 'a, since out is destroyed at the end of the function. Rust will not allow you to return a reference to it (it would allow accessing freed memory!).
Try changing your function to the following:
fn take_symbol<'a>(ch: &'a str, current: &'a mut String) -> TokenList<'a> {
let out = TokenList::<'a>::new();
out.push(current.as_str());
out.push(ch);
*current = String::new();
out
}
This way you will pass the ownership of out to the caller and it will live long enough.

Related

What are the differences when getting an immutable reference from a mutable reference with self-linked lifetimes?

struct Foo01<'a> {
val: u32,
str: &'a String,
}
fn mutate_and_share_01<'a>(foo: &'a mut Foo01<'a>) -> &'a Foo01<'a> {
foo
}
fn mutate_and_share_02<'a>(foo: &'a mut Foo01<'a>) -> &'a Foo01 {
foo
}
fn mutate_and_share_03<'a>(foo: &'a mut Foo01) -> &'a Foo01<'a> {
foo
}
fn main() {
let mut foo = Foo01 { val: 16, str: &String::from("Hello ") };
let foo_mut = &mut foo;
//let loan = mutate_and_share_01(foo_mut);
//let loan2 = mutate_and_share_01(foo_mut); //error
//let loan = mutate_and_share_02(foo_mut);
//let loan2 = mutate_and_share_02(foo_mut); //error
let loan = mutate_and_share_03(foo_mut);
let loan2 = mutate_and_share_03(foo_mut); //good
}
What are differences between these mutate_and_share versions?
In cases 1 and 2, you're saying that the function borrows the structure for as long as the structure borrows its parameter:
foo: &'a mut Foo01<'a>
this says "foo is borrowed from 'a" (&'a mut) and "foo borrows its parameter for 'a" (Foo01<'a>).
Meaning as far as rustc is concerned a call to this function will necessarily borrow the input forever, as the structure necessarily borrows its input for the entirety of its own lifetime, and thus you get locked out: you can't "unborrow" the input by dropping it so the second call can't work ever.
In case 3 you're relating the parameter of the output to the internal borrow which isn't really true but works well enough at least for this case. The reality is that the two lifetimes are unrelated:
fn mutate_and_share<'a, 'b>(foo: &'a mut Foo01<'b>) -> &'a Foo01<'b> {
foo
}
Also do note that your third case only works because you're never using loan, so it's immediately dropped before the second line executes. If you do this:
let loan = mutate_and_share_03(foo_mut);
let loan2 = mutate_and_share_03(foo_mut); //good
print("{}", loan.val)
then it's not going to compile because the mutable borrows are overlapping.
Oh, and &String is generally useless. There are use cases for &mut String, but any time you see an immutable reference to a String you'd be better off with an &str. Same with &Vec<T>, not useful, should be &[T].

Why does borrow checker need life time tags for output when the inputs are very clear?

Why does the borrow checker gets confused about the lifetimes in the below code
fn main() {
let ss = "abc"; // lets say 'a scope
let tt = "def"; // lets say 'b scope
let result = func(ss, tt);
}
fn func(s: &str, t: &str) -> &str {
t
}
| fn func(s: &str, t: &str) -> &str {
| ^ expected lifetime parameter
|
= help: this function's return type contains a borrowed value, but the signature does not say whether it is borrowed from `s` or `t`
Why does it even matter what is going out in this code? Am I missing something very important edge case?
but when I annotate them with life time tags it works.
fn func<'a>(s: &'a str, t: &'a str) -> &'a str {
t
}
I read that each variable binding (let) creates an Implicit scope, then how come 2 input variables have same scope. Correct me If I'm worng. In the function call 'func' stack, "s" will be pushed first and then "t", So "s" and "t" have different lifetimes. First "t" is dropped and then "s".
You haven’t told the compiler whether the return value may borrow from s, from t, from both, or from neither:
fn from_s<'a, 'b>(s: &'a str, t: &'b str) -> &'a str {
// can be abbreviated: fn from_s<'a>(s: &'a str, t: &str) -> &'a str
s
}
fn from_t<'a, 'b>(s: &'a str, t: &'b str) -> &'b str {
// can be abbreviated: fn from_t<'a>(s: &str, t: &'a str) -> &'a str
t
}
fn from_both<'a>(s: &'a str, t: &'a str) -> &'a str {
if s < t {
s
} else {
t
}
}
fn from_neither<'a, 'b>(s: &'a str, t: &'b str) -> &'static str {
// can be abbreviated: fn func(s: &str, t: &str) -> &'static str
"foo"
}
The compiler can assume the last one isn’t what you wanted if you didn’t write 'static. But you still need to disambiguate between the first three.
To see why the difference would matter, consider a caller like
fn main() {
let s = String::from("s");
let r;
{
let t = String::from("t");
r = from_s(&s, &t);
// t goes out of scope
}
println!("{}", r);
}
If the compiler allowed you to call from_t instead of from_s, you’d be printing a string that had already been freed.
If I understand correctly, the question is "why both arguments may have the same lifetime?" The short answer is that the lifetime annotations are not concrete values, but rather bounds - it states that "this value must live no more/no less then this lifetime".
When you're writing your code as you do in question: fn func<'a>(s: &'a str, t: &'a str) -> &'a str, you're saying literally the following:
there is some lifetime - let's name it 'a, which can be different on every call site.
arguments s and t must both live no less then 'a (for string literals, this is always the case, since they are 'static, but this may not hold for &String coerced to &str) - that is, function type is contravariant over arguments types (and the lifetime is part of a type).
return value must live no more then 'a - function type is covariant over the return type.
(for more information on variance see the Rustonomicon)
Simplified, this means that both arguments must outlive the return value. This is not always what you want - consider the following case (note that I'm returning s now, so that the initialization order doesn't change):
fn main() {
let ss = "abc";
let mut result = "";
{
let tt = "def".to_string();
result = func(ss, &tt);
}
println!("{}", result);
}
fn func<'a>(s: &'a str, t: &'a str) -> &'a str {
s
}
(playground)
This code won't compile, although it is logically correct, since the lifetime annotations don't agree with logic: second argument, t, is in no way connected to the return value, and yet it limits its lifetime, according to function annotations. But when we change function to the following:
fn func<'a, 'b>(s: &'a str, t: &'b str) -> &'a str {
s
}
...it compiles and return the desired result (although with some warnings), since now the lifetime 'b isn't connected with 'a and, in fact, can be removed at all - lifetime elision will do its work well.

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.

Need help on lifetime issue

pub struct Decoder<'a> {
reader: &'a mut io::Reader+'a,
}
impl<'a> Decoder<'a> {
pub fn from_reader(r: &'a mut io::Reader) -> Decoder<'a> {
Decoder {
reader: r,
}
}
}
// shortcut method to accept bytes to decode
pub fn decode<'a, T: Decodable<Decoder<'a>, IoError>>(data: Vec<u8>) -> DecodeResult<T> {
let mut r = MemReader::new(data);
let mut decoder = Decoder::from_reader(&mut r); // error: `r` does not live long enough
Decodable::decode(&mut decoder)
}
I have two question here.
How do you read this declaration(what it means) reader: &'a mut io::Reader+'a. Which I was referencing the code from the std json encoder.
I write a shortcut method to wrap Vec<u8> with MemReader, so that I can just interfacing io::Reader. But the compiler complains error:rdoes not live long. How to make it right.
Update: I upload the code to github.
The first 'a means that the Reader object itself has lifetime 'a. The second 'a means that the Reader object doesn't contain references that outlive 'a. Since Reader is a trait, it could be implemented by a struct that has lifetime parameters. This bound applies to those potential lifetime parameters.
The problem is with the bound on T: Decodable<Decoder<'a>, IoError> references the lifetime parameter 'a. However, the Decoder you're creating references a local variable, whereas 'a refers to a lifetime that lives longer than the function call (because it's an input parameter specified implicitly at the call site).
I think there's no way to make this function compile successfully without unsafe code for the moment. In fact, Encoder::buffer_encode seems to be having the same issue (#14302) and uses a similar workaround. transmute allows us to coerce the local lifetime to 'a.
pub fn decode<'a, T: Decodable<Decoder<'a>, IoError>>(data: Vec<u8>) -> DecodeResult<T> {
let mut r = MemReader::new(data);
let mut decoder = unsafe { mem::transmute(Decoder::from_reader(&mut r)) };
Decodable::decode(&mut decoder)
}

Rust lifetimes - returning value from vector in RWLock in Arc

I'm having a lot of trouble with lifetimes in relation to Arcs and RWLocks.
struct ComponentContainer<T>{
id_to_component: HashMap<uint, uint>,
components: Arc<RWLock<~Vec<T>>>
}
id_to_component is a map of component ids to an index into the Vec inside components.
I've tried everything from the intuitive:
impl<T: Component> ComponentContainer<T>{
fn get<'a>(&'a self, id: uint) -> &'a T {
let idx = self.id_to_component.get(&id);
self.components.read().get(*idx)
}
}
To the extremely verbose (manually storing each reference):
impl<T: Component> ComponentContainer<T> {
fn get<'a>(&'a self, id: uint) -> &'a T {
let idx = self.id_to_component.get(&id);
let components: &'a RWLock<~Vec<T>> = &'a *self.components;
let c: &'a RWLock<~Vec<T>> = &'a *components;
let tmp: &'a RWLockReadGuard<'a, ~Vec<T>> = &'a c.read();
let v: &'a ~Vec<T> = &'a **tmp;
v.get(*idx)
}
}
With the verbose one, I end up getting the error:
error: borrowed value does not live long enough
let tmp: &'a RWLockReadGuard<'a, ~Vec<T>> = &'a c.read();
^~~~~~~~~~~~
According to the source for RWLock.read(), the returned reference should have the specified lifetime, unless I'm reading it incorrectly.
Edit: full rustc output for short version
test.rs:18:9: 18:31 error: borrowed value does not live long enough
test.rs:18 self.components.read().get(*idx)
^~~~~~~~~~~~~~~~~~~~~~
test.rs:16:45: 19:6 note: reference must be valid for the lifetime &'a as defined on the block at 16:44...
test.rs:16 fn get<'a>(&'a self, id: uint) -> &'a T {
test.rs:17 let idx = self.id_to_component.get(&id);
test.rs:18 self.components.read().get(*idx)
test.rs:19 }
test.rs:16:45: 19:6 note: ...but borrowed value is only valid for the block at 16:44
test.rs:16 fn get<'a>(&'a self, id: uint) -> &'a T {
test.rs:17 let idx = self.id_to_component.get(&id);
test.rs:18 self.components.read().get(*idx)
test.rs:19 }
error: aborting due to previous error
Let's look at the signature of read():
fn read<'a>(&'a self) -> RWLockReadGuard<'a>
It returns a RWLockReadGuard<'a>. That's not a reference to a RWLockReadGuard, it's a RWLockReadGuard, containing inside it references of lifetime 'a.
Now your line:
let tmp: &'a RWLockReadGuard<'a, ~Vec<T>> = &'a c.read();
You are taking a reference to the RWLockReadGuard. That means that the referenced object must live for at least as long as the reference. But this is not the case: the value is the value returned by c.read(), which is not stored anywhere. Because it is not stored anywhere, it is discarded at the end of the statement, and so the borrow is invalid, because the required 'a is longer than the statement and so cannot be satisfied.
What you should do instead is simply drop the &'a part, using the object directly:
let tmp: RWLockReadGuard<'a, ~Vec<T>> = c.read();
I'm not sure what's wrong with your short version at first glance, and I don't have rustc handy. Please post the full rustc stderr.

Resources