Reputation: 13616
Here is an example:
use std::iter::Filter;
use std::slice::Iter;
fn test(xs: &[i32]) -> Filter<Iter<i32>, fn(&&i32) -> bool> {
fn nothing(_: &&i32) -> bool { false }
let ys = xs.iter().filter(nothing);
ys
}
fn main () {
}
Compilation fails with:
src/main.rs:8:5: 8:7 error: mismatched types:
expected `core::iter::Filter<core::slice::Iter<'_, i32>, fn(&&i32) -> bool>`,
found `core::iter::Filter<core::slice::Iter<'_, i32>, fn(&&i32) -> bool {test1::nothing}>`
(expected fn pointer,
found fn item) [E0308]
src/main.rs:8 ys
^~
This is because the inferred type of ys
has the type of a specific function item in it. In this particular case the issue is easy to fix: one can either explicitly specify the type without the function item in the binding, or avoid the let
altogether.
Both of these work:
fn test(xs: &[i32]) -> Filter<Iter<i32>, fn(&&i32) -> bool> {
fn nothing(_: &&i32) -> bool { false }
let ys: Filter<Iter<i32>, fn(&&i32) -> bool> = xs.iter().filter(nothing);
ys
}
fn test(xs: &[i32]) -> Filter<Iter<i32>, fn(&&i32) -> bool> {
fn nothing(_: &&i32) -> bool { false }
xs.iter().filter(nothing)
}
Therefore, as the Reference says, indeed Rust is capable of performing this coercion itself. But what if the code was more complex and I had to perform this cast manually? How would I do this?
In this case as
won’t work, and transmute
seems to be an overkill, although, I believe, it would do the job.
Upvotes: 2
Views: 319
Reputation: 299810
You can actually cast using as
:
fn test(xs: &[i32]) -> Filter<Iter<i32>, fn(&&i32) -> bool> {
fn nothing(_: &&i32) -> bool { false }
let ys = xs.iter().filter(nothing as fn(&&i32) -> bool);
^~~~~~~~~~~~~~~~~~~~
ys
}
However you need to use as
to change the function's type, not the Filter
type, as as
is not allowed to change arbitrary types.
Personally, I consider the necessity of the cast a short-coming and hope that type inference will improve to the point it becomes unnecessary. The fact that it works for a direct return is a red-herring, it should probably work with an intermediate value too.
Upvotes: 3