let colon = || char::<_, nom::error::Error<_>>(',');
let int = || map_res(is_not(","), |f: &str| f.parse::<i32>());
let (s, (x, _, y, _)) = tuple((int(), colon(), int(), colon()))(s).unwrap();
To give some background on this: closures aren't just functions. They're combinations of functions and data they can access. The captured data could be something non-copyable (e.g. an exclusive reference, which can't be copied, because it would stop being exclusive), so the compiler can't automatically assume closures are copyable.
Additionally, in generic code it doesn't matter what the code actually does, it only matters what the generic bounds say the code could do. In case of nom, it says closures could have non-copyable data (they're not marked as Copy), so all of them, generically, are treated as such.