While doing AoC today I ran into something kind of strange/interesting today
I have a dijkstras algorithm helper function that takes a function with these bounds to get the neighbours of any node
NeighboursFn: FnMut(&T) -> SearchIter,
SearchIter: IntoIterator<Item = T>,
At first I wrote this function:
|&t| {
// Implementation ...
}
and got this error:
error: implementation of `FnOnce` is not general enough
--> src/day15.rs:83:6
|
83 | .check();
| ^^^^^ implementation of `FnOnce` is not general enough
|
= note: closure with signature `fn(&'2 Tile) -> arrayvec::ArrayVec<Tile, 4_usize>` must implement `FnOnce<(&'1 Tile,)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&'2 Tile,)>`, for some specific lifetime `'2`
This error message confused me quite a bit, for one it mentions FnOnce when I required FnMut, but I know they are related so I brushed over that. The main thing is that while I sort of understood what it meant in terms of the lifetimes, I had no idea how to fix it, the types/lifetimes are inferred. Why is the compiler not inferring a general enough lifetime, especially when I had other code that looked very similar and was compiling fine.
Spent a good 10 minutes. In fact, I wonder how many of you guys already know the problem/fix necessary.
.
.
.
.
.
.
.
.
.
.
The way I fixed it was by changing it to
|&t: &Tile| {
// ...
}
Adding the explicit type annotation for the argument fixed it for some reason. That was it, I spent a long time wondering if I am accidentally capturing something that was somehow affecting the lifetimes in the closure but it doesnt work even for something as simple as |&t| [t]
, but |&t: Tile| [t]
is fine
I guess I am not sure what I am asking, maybe some more details about the problem I ran into, or a more motivated solution than 'just add type annotations for some reason.' Or something to read about how closure type signatures are inferred