1

I have some code like this:

type MyFn = Box<Fn(usize) -> bool>;

fn main() {
    let my_fn: MyFn = Box::new(|x: usize| x > 10);
    dbg!(my_fn);
}

This doesn't compile because MyFn doesn't implement std::fmt::Debug. That's reasonable, so what if I try to implement it for MyFn?

It fails saying:

conflicting implementations of trait std::fmt::Debug for type std::boxed::Box<(dyn std::ops::Fn(usize) -> bool + 'static)>

As well as:

only traits defined in the current crate can be implemented for arbitrary types

How can I implement Debug and other traits for MyFn?

maxcountryman
  • 1,562
  • 1
  • 24
  • 51
  • You can't MyFn is just an alias. Do something like https://play.integer32.com/?version=stable&mode=debug&edition=2018&gist=06b9086f9dff4485180f349f3aee1e09 – Stargateur Jun 24 '19 at 02:14

1 Answers1

4

Creating a type alias does not create an entirely new type, it just allows you to refer to the existing type via a different name. Therefore, trying to implement Debug for MyFn is exactly the same as trying to implement it for Box<Fn(usize) -> bool> - which is not allowed, since your crate doesn't own the type or the trait. Rust's 'orphan rules' require your crate to have defined one or both for the implementation to be valid.

A common pattern to get around this is to create a 'newtype' struct, which wraps the type:

struct MyFn(Box<Fn(usize) -> bool>);

You can implement Debug for this struct, as the struct comes from your crate.

Joe Clay
  • 33,401
  • 4
  • 85
  • 85
  • 1
    While this technically works, it makes calling the closure pretty awkward: `MyFn.0(...)`; this is a bummer. – maxcountryman Jun 24 '19 at 13:25
  • 1
    @maxcountryman: It is possible to [implement `Deref`](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=6f7c164064905c2bd6533c1de66fdee3) to make this a bit cleaner, but [it's considered a bit of a bad practice](https://stackoverflow.com/questions/45086595/is-it-considered-a-bad-practice-to-implement-deref-for-newtypes). Fingers crossed a nicer syntax for delegation gets added some day! – Joe Clay Jun 24 '19 at 15:02