-
Notifications
You must be signed in to change notification settings - Fork 13.6k
Closed
Labels
A-NLLArea: Non-lexical lifetimes (NLL)Area: Non-lexical lifetimes (NLL)A-borrow-checkerArea: The borrow checkerArea: The borrow checkerA-closuresArea: Closures (`|…| { … }`)Area: Closures (`|…| { … }`)C-bugCategory: This is a bug.Category: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundnessfixed-by-NLLBugs fixed, but only when NLL is enabled.Bugs fixed, but only when NLL is enabled.
Description
extern crate futures;
extern crate tokio_core;
use futures::{future, Future};
use tokio_core::reactor::Core;
pub trait Action {
type Output: Future<Item = (), Error = ()>;
fn run(self) -> Self::Output;
}
impl<T: Future<Item=(), Error=()>, F: FnOnce() -> T> Action for F {
type Output = T;
fn run(self) -> Self::Output {
self()
}
}
fn retry<A: Action>(action: A) -> impl Future<Item = (), Error = ()> {
action.run()
}
/*
The `lazy` closure avoids the check of its lifetime here, if:
- the `lazy` closure is nested into the `action` closure, and
- the `action` closure is passed into the `retry` function, and
- the `retry` function take a generic by the `Action` trait argument, and
- the `Action` trait is implemented for an `Fn*` trait.
As a result, we get arbitrary values in variables and at best SIGSEGV.
*/
fn main() {
let mut core = Core::new().unwrap();
let handle = core.handle();
for i in &[1, 2, 3, 4, 5] {
println!("outer: {}", i);
let f = move || {
println!("inner: {}", i);
future::ok::<(), ()>(())
};
let action = move || {
future::lazy(|| { // The `lazy` closure
f()
})
};
handle.spawn(retry(action))
}
core.run(future::empty::<(), ()>()).expect("Core::run");
}
Output:
outer: 1
outer: 2
outer: 3
outer: 4
outer: 5
inner: 1027752016
inner: 1027752016
inner: 1027752016
inner: 1027752016
inner: 1027752016
Errors:
Compiling playground v0.0.1 (file:///playground)
Finished dev [unoptimized + debuginfo] target(s) in 2.29s
Running `target/debug/playground`
/root/entrypoint.sh: line 8: 8 Killed timeout --signal=KILL ${timeout} "$@"
This emits a warning in the 2018 edition mode, but silently accepts code leading to UB in the 2015 edition.
hellow554
Metadata
Metadata
Assignees
Labels
A-NLLArea: Non-lexical lifetimes (NLL)Area: Non-lexical lifetimes (NLL)A-borrow-checkerArea: The borrow checkerArea: The borrow checkerA-closuresArea: Closures (`|…| { … }`)Area: Closures (`|…| { … }`)C-bugCategory: This is a bug.Category: This is a bug.I-unsoundIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/SoundnessIssue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundnessfixed-by-NLLBugs fixed, but only when NLL is enabled.Bugs fixed, but only when NLL is enabled.