2

I tried to run the FnBox example from the official docs but it throws an error:

error[E0432]: unresolved import `std::boxed::FnBox`
 --> src/main.rs:4:5
  |
4 | use std::boxed::FnBox;
  |     ^^^^^^^^^^^^^^^^^ no `FnBox` in `boxed`

It's easy to get this error using the rust playground, and I got the same error locally.

Actually I found some declarations from std locally:

#[rustc_paren_sugar]
#[unstable(feature = "fnbox",
           reason = "will be deprecated if and when `Box<FnOnce>` becomes usable", issue = "28796")]
pub trait FnBox<A>: FnOnce<A> {
    /// Performs the call operation.
    fn call_box(self: Box<Self>, args: A) -> Self::Output;
}

#[unstable(feature = "fnbox",
           reason = "will be deprecated if and when `Box<FnOnce>` becomes usable", issue = "28796")]
impl<A, F> FnBox<A> for F
    where F: FnOnce<A>
{
    fn call_box(self: Box<F>, args: A) -> F::Output {
        self.call_once(args)
    }
}

But there's still an error.

pretzelhammer
  • 13,874
  • 15
  • 47
  • 98
聂小涛
  • 503
  • 3
  • 16
  • 1
    `FnBox` was removed in rust 1.35. The playground's nightly (and most likely yours) runs on 1.39. Can you check your rust version using `rustc -V` and confirm it is < 1.35? – Sébastien Renauld Sep 15 '19 at 11:33
  • @SébastienRenauld actually it was removed in 1.37 and [was still present in 1.36](https://doc.rust-lang.org/1.36.0/std/boxed/trait.FnBox.html). – mcarton Sep 15 '19 at 11:42
  • Correct, it was deprecated in 1.35. I was following the commit history rather than the release notes – Sébastien Renauld Sep 15 '19 at 11:42

1 Answers1

6

FnBox was never stabilized. It was more of a hack used when you wanted a Box<dyn FnOnce()> but this type didn't used to implement FnOnce itself.

Because Box<dyn FnOnce()> implements FnOnce since Rust 1.35, FnBox has been removed in Rust 1.37.

All usages of Box<FnBox<_>> can be replaced by Box<FnOnce<_>>, for example the old documentation example:

use std::collections::HashMap;

fn make_map() -> HashMap<i32, Box<dyn FnOnce() -> i32>> {
    let mut map: HashMap<i32, Box<dyn FnOnce() -> i32>> = HashMap::new();
    map.insert(1, Box::new(|| 22));
    map.insert(2, Box::new(|| 44));
    map
}

fn main() {
    let mut map = make_map();
    for i in &[1, 2] {
        let f = map.remove(&i).unwrap();
        assert_eq!(f(), i * 22);
    }
}

(Permalink to playground)

mcarton
  • 27,633
  • 5
  • 85
  • 95