use std::fmt::Display;
fn box_displayable<'a, T: Display + 'a>(t: T) -> Box<dyn Display + 'a>
{
Box::new(t)
}
fn main() {
let s = String::from("ss");
let _b = box_displayable(&s);
// drop(_b); // fails without this
drop(s);
}
Why drop(s) is not allowed? _b does not used any more after all.
I found this can be compiled:
fn main() {
let s = String::from("ss");
let _b = Box::new(&s);
//drop(_b);
drop(s);
}
Seems the signature tell NLL _b has 'a directly, and 'a lasts until the end of block.
When NLL see a expression, there is no lifetime in signature, it has to do more work by itself and find a more proper lifetime...
While, the following can't be compiled, and 'b can't be told directly.
use std::fmt::Display;
fn box_displayable<'b, 'a : 'b, T: Display + 'a>(t: T) -> Box<dyn Display + 'b>
{
Box::new(t)
}
fn main() {
let s = String::from("ss");
let _b = box_displayable(&s);
//drop(_b);
drop(s);
}
NLL doesn't affect drop order. In fact, nothing about lifetime analysis has any impact on drop order. Borrow checking and drop checking are pass/fail; the compiler doesn't use them to figure out when to drop things, only to figure out whether the predetermined drop order leads to valid code.
It's not allowed to drop *_b after s because *_b borrows s and may have drop glue that uses that borrow. The compiler has to account for this possibility because *_b is of type dyn Display + 'a, which could be implemented by a type that has drop glue that uses the borrow.
In the compilable example, *_b is of type &String, which the compiler knows does not have drop glue, so it doesn't have to take the dropping of _b into account when checking whether s is borrowed or can be moved into drop.
Note that in the above explanation, I sometimes used *_b (the referent of _b) and sometimes _b itself. This is deliberate because when it comes to most types (including any types you could write without using experimental features) only the dropness of _b would matter. But Box<T> is special because the compiler knows that dropping it doesn't involve accessing the T (except to call the drop glue for T itself, if any exists).