Closed
Description
The following code compiles with the 2018 edition on stable, beta and nightly, and produces this error:
Execution operation failed: Output was not valid UTF-8: invalid utf-8 sequence of 1 bytes from index 1813
Code:
use std::marker::PhantomData;
struct Scope<'env> {
invariant: PhantomData<fn(&'env ()) -> &'env ()>
}
fn scope<'env, F, T>(f: F) -> T
where
F: FnOnce(&Scope<'env>) -> T
{
f(&Scope { invariant: PhantomData })
}
impl<'env> Scope<'env> {
fn spawn<'scope, F, T>(&'scope self, f: F) -> T
where
F: FnOnce() -> T + Send + 'env,
T: Send + 'env
{
f()
}
}
fn main() {
let mut greeting = "Hello world!".to_string();
let res = scope(|s| s.spawn(|| &greeting));
greeting = "DEALLOCATED".to_string();
drop(greeting);
println!("thread result: {:?}", res);
}
And indeed there's a use-after-free here.
Interestingly, in the 2015 edition this is correctly detected as incorrect, though the error is not quite what I would have expected:
Compiling playground v0.0.1 (/playground)
error[E0597]: `*greeting` does not live long enough
--> src/main.rs:26:37
|
26 | let res = scope(|s| s.spawn(|| &greeting));
| -- ^^^^^^^^ - borrowed value only lives until here
| | |
| | borrowed value does not live long enough
| capture occurs here
...
32 | }
| - borrowed value needs to live until here
I would have expected a complaint at the re-assignment of greeting
.
(I found this while modifying an example by @stjepang and failing to reproduce some code that gets a migration warning on 2018...)