Unsoundness due to closure return value not being checked for WF
Open
@ShoyuVanilla is already working on this.
Since Feb 20, 2026.
A-borrow-checker
A-closures
A-lifetimes
A-NLL
C-bug
I-unsound
P-high
T-compiler
T-types
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
Description
This unsoundness is an exploitation of the weirdness in #123312. See also #148854 for a similar unsoundness.
The below code causes a use-after-free (segfault in my testing).
type Payload = Box<i32>;
trait StaticToStatic {
fn static_to_static(self) -> &'static Payload where Self: 'static;
}
impl<'a> StaticToStatic for &'a Payload {
fn static_to_static(self) -> &'static Payload where Self: 'static {
self // Legal. 'a must be 'static due to Self: 'static
}
}
struct Wrap<T: StaticToStatic + 'static>(T);
trait ToStatic {
fn to_static(self) -> &'static Payload;
}
impl<T: StaticToStatic> ToStatic for Wrap<T> {
fn to_static(self) -> &'static Payload {
self.0.static_to_static() // Legal. T: 'static is implied by Wrap<T>
}
}
// Trait to allow mentioning FnOnce without mentioning the return type directly
trait MyFnOnce {
type MyOutput;
fn my_call_once(self) -> Self::MyOutput;
}
impl<F: FnOnce() -> T, T> MyFnOnce for F {
type MyOutput = T;
fn my_call_once(self) -> T {
self()
}
}
fn call<F: MyFnOnce<MyOutput: ToStatic>>(f: F) -> &'static Payload {
f.my_call_once().to_static()
}
fn extend<T: StaticToStatic>(x: T) -> &'static Payload {
let c = move || {
// Probably should be illegal, since Wrap requires T: 'static
Wrap(x)
};
call(c)
}
fn main() {
let x = Box::new(Box::new(1));
let y = extend(&*x);
drop(x);
println!("{y}"); // segfaults
}
cc @lcnr @ShoyuVanilla
Meta
Reproducible on the playground with version 1.95.0-nightly (2026-01-24 f134bbc78dac04a17324)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Assessment
This issue has not been assessed yet.