Coercion of argument references in function pointer type

While trying to use drain_filter I was a bit surprised to get the following error:

expected signature of `for<'r> fn(&'r mut Foo) -> _
found signature of `for<'r> fn(&'r Foo) -> _

Since &mut T coerces to &T, is there a reason why the second function pointer doesn't coerce to the first?

&mut T is an unique pointer, &T is a shared pointer. First can has only one owner, second — many, i.e. first contract is more strict. If we wants to convert a shared pointer to an unique pointer then we will must leave only one data owner, and the rest of owners will be has dangling references.

I believe you've got it backwards. They're asking why you can't coerce a function pointer that takes a &T into a function pointer that takes a &mut T. That is, how is it wrong to pass a &mut T to a function? &T?

Yes. I felt there should be nothing wrong with that, so was wondering if I was mistaken or if it's just not implemented, or if there's some arcane compiler reason why that's not the case.

I suspect this is a case where a coercion is simply missing - I don't think there's any soundness issue with allowing such a thing. Afterall, you can force the (reference weakening) coercion by using a closure:

vec.drain_filter(|x| fn_taking_shared_borrow(x));

Yeah, that's what I did. It's trivial, really. Hence my surprise. I wanted to check if it was a known issue before opening a bug report or something. I looked in the tracker but didn't find any previous issue.

Yeah, I thought I've seen this come up in the bugtracker before but failed to find an issue as well. It won't hurt to file one, and if someone feels it's a dupe, they'll link/close it against the original one.

I'll just go ahead and do that then, thank you!