trait FnBox {
fn call_box(self: Box<Self>);
}
impl<F: FnOnce()> FnBox for F {
fn call_box(self: Box<F>) {
(*self)()
}
}
fn main() {
let job: Box<FnOnce()> = Box::new(|| {});
// versions that compile
// let job = Box::new(|| {});
// let job: Box<FnBox> = Box::new(|| {});
job.call_box();
}
job.call_box();
doesn't compile:
error[E0599]: no method named `call_box` found for type `std::boxed::Box<std::ops::FnOnce()>` in the current scope --> src/main.rs:16:9 | 16 | job.call_box(); | ^^^^^^^^ | = note: job is a function, perhaps you wish to call it = note: the method `call_box` exists but the following trait bounds were not satisfied: `std::ops::FnOnce() : FnBox` = help: items from traits can only be used if the trait is implemented and in scope = note: the following trait defines an item `call_box`, perhaps you need to implement it: candidate #1: `FnBox`
Why doesn't the compiler see the conversion to FnBox
here?
I suppose when I use let job = Box::new(|| {});
that results in a Box<closure>
type. The compiler manages to resolve job.call_box()
, which is Box<closure>
-> Box<FnOnce()>
-> Box<FnBox>
(because FnBox
is implemented for FnOnce()
, not for closure
). Why doesn't just Box<FnOnce()>
-> Box<FnBox>
work?