Closed
Description
Found in this SO question.
This code compiles:
struct Test;
impl Test {
fn method1(&mut self, arg: &str) -> Result<usize, &str> {
unreachable!()
}
fn method2(self: &mut Test, arg: &str) -> Result<usize, &str> {
unreachable!()
}
fn test(self: &mut Test) -> Result<usize, &str> {
let s = format!("abcde");
let data = match self.method1(&*s) {
Ok(r) => r,
Err(e) => return Err(e)
};
unreachable!()
}
}
fn main() {
}
But if you change self.method1(&*s)
to self.method2(&*s)
it will stop compiling:
test7.rs:14:41: 14:42 error: `s` does not live long enough
test7.rs:14 let data = match self.method2(&*s) {
^
test7.rs:12:53: 19:6 note: reference must be valid for the anonymous lifetime #1 defined on the block at 12:52...
test7.rs:12 fn test(self: &mut Test) -> Result<usize, &str> {
test7.rs:13 let s = format!("abcde");
test7.rs:14 let data = match self.method2(&*s) {
test7.rs:15 Ok(r) => r,
test7.rs:16 Err(e) => return Err(e)
test7.rs:17 };
...
test7.rs:12:53: 19:6 note: ...but borrowed value is only valid for the block at 12:52
test7.rs:12 fn test(self: &mut Test) -> Result<usize, &str> {
test7.rs:13 let s = format!("abcde");
test7.rs:14 let data = match self.method2(&*s) {
test7.rs:15 Ok(r) => r,
test7.rs:16 Err(e) => return Err(e)
test7.rs:17 };
...
According to the lifetime elision rules this signature:
fn method2(self: &mut Test, arg: &str) -> Result<usize, &str>
should be equivalent to this one:
fn method2<'a, 'b>(self: &'a mut Test, arg: &'b str) -> Result<usize, &'a str>
However, it seems that currently it is equivalent to this one:
fn method2<'a>(self: &'a mut Test, arg: &'a str) -> Result<usize, &'a str>
which gives exactly the same error as the elided version.
Another funny thing is that if I remove match
and write just
let data = self.method2(&*s);
It compiles again.