Why do I get a "type annotations needed" error creating a notify watcher?

Viewed 13
let mut watcher = notify::recommended_watcher(|res: Result<_>| {
    match res {
       Ok(event) => {
            match event.kind {
                EventKind::Modify(ModifyKind::Metadata(_)) => { /* deal with metadata */ }
                EventKind::Create(CreateKind::File) => { /* deal with new files */ }
                EventKind::Other => { /* ignore meta events */ }
                _ => { /* something else changed */ }
            }
        },
        Err(e) => println!("watch error: {:?}", e)
    }
})

This code block gives me the error:

error[E0282]: type annotations needed
  --> src/main.rs:13:23
   |
13 |                 match event.kind {
   |                       ^^^^^ cannot infer type

Rust Explorer

Which doesn't make sense to me because the docs for notify use the same code without specifying a type in the match.

Can anyone help explain what is going on and where I should specify which type to get this to work?

1 Answers

There are too many layers of indirection for Rust to infer what type the _ placeholder in Result<_> refers to. It will compile if you tell it _ means Event:

use notify::Event;

let mut watcher = notify::recommended_watcher(|res: Result<Event>| {
    match res {
       Ok(event) => {
            match event.kind {
                EventKind::Modify(ModifyKind::Metadata(_)) => { /* deal with metadata */ }
                EventKind::Create(CreateKind::File) => { /* deal with new files */ }
                EventKind::Other => { /* ignore meta events */ }
                _ => { /* something else changed */ }
            }
        },
        Err(e) => println!("watch error: {:?}", e)
    }
})

Rust Explorer

The layers of indirection are:

  1. The argument to recommended_watcher must be a type that implements EventHandler:

    pub fn recommended_watcher<F>(event_handler: F) -> Result<RecommendedWatcher> 
    where
        F: EventHandler, 
    
  2. A single-argument function that takes a Result<Event> and returns nothing is an EventHandler:

    impl<F> EventHandler for F
    where
        F: FnMut(Result<Event>) + Send + 'static, 
    
  3. Therefore Result<_> must be Result<Event> to match the signature FnMut(Result<Event>).

Related