Some confusion about inferred type signature of closures

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

Honestly, the compiler is just being kinda stupid with this issue.

See also:

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.