Closed
Description
The following code shows inconsistent behavior in lifetime checking:
use std::convert::AsMut;
use std::borrow::BorrowMut;
trait T {}
impl T for u8 {}
fn main() {
// A (AsMut and Primitive Type):
{
let mut r: Box<u8> = Box::new(23u8);
let _: &mut u8 = r.as_mut();
}
// B (AsMut and Trait Objects):
{
let mut r: Box<T> = Box::new(23u8);
let _: &mut T = r.as_mut();
}
// C (BorrowMut and Primitive Type):
{
let mut r: Box<u8> = Box::new(23u8);
let _: &mut u8 = r.borrow_mut();
}
// D (BorrowMut and Trait Object):
{
let mut r: Box<T> = Box::new(23u8);
let _: &mut T = r.borrow_mut();
}
}
Using the stable compiler 1.14.0, case B and D yield a lifetime error:
$ rustc --version
rustc 1.14.0 (e8a012324 2016-12-16)
$ rustc test.rs
error: `r` does not live long enough
--> test.rs:19:5
|
18 | let _: &mut T = r.as_mut();
| - borrow occurs here
19 | }
| ^ `r` dropped here while still borrowed
|
= note: values in a scope are dropped in the opposite order they are created
error: `r` does not live long enough
--> test.rs:31:5
|
30 | let _: &mut T = r.borrow_mut();
| - borrow occurs here
31 | }
| ^ `r` dropped here while still borrowed
|
= note: values in a scope are dropped in the opposite order they are created
error: aborting due to 2 previous errors
return code: 101
A nightly rustc from last week shows only an error in case D.
$ rustc --version
rustc 1.15.0-nightly (71c06a56a 2016-12-18)
$ rustc test.rs
error: `r` does not live long enough
--> test.rs:31:5
|
30 | let _: &mut T = r.borrow_mut();
| - borrow occurs here
31 | }
| ^ `r` dropped here while still borrowed
|
= note: values in a scope are dropped in the opposite order they are created
error: aborting due to previous error
return code: 101
This is strange, as BorrowMut::borrow_mut()
and AsMut::as_mut()
have the same type signature. So cases B and D should give the same result.
Furthermore, I am not sure why case A and B (or, for that matter, case C and D) behave differently. The only difference is that they use trait objects instead of primitive types, and as far as I understand, this should have no influence on the lifetime behavior.