Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

"Expected fn item, found a different fn item" when working with function pointers

Tags:

I have the following code (Playground):

// Two dummy functions, both with the signature `fn(u32) -> bool` fn foo(x: u32) -> bool {     x % 2 == 0 } fn bar(x: u32) -> bool {     x == 27 }   fn call_both<F>(a: F, b: F) where     F: Fn(u32) -> bool, {     a(5);     b(5); }  fn main() {     call_both(foo, bar);  // <-- error } 

To me, it seems like this should compile as foo and bar have the same signature: fn(u32) -> bool. Yet, I get the following error:

error[E0308]: mismatched types   --> src/main.rs:20:20    | 20 |     call_both(foo, bar);    |                    ^^^ expected fn item, found a different fn item    |    = note: expected type `fn(u32) -> bool {foo}`               found type `fn(u32) -> bool {bar}` 

The same error can be triggered with this code:

let mut x = foo; x = bar;  // <-- error 

I also tried to cast bar to the function pointer type again:

let mut x = foo; x = bar as fn(u32) -> bool;  // <-- error 

This resulted in a slightly different error:

error[E0308]: mismatched types   --> src/main.rs:20:9    | 20 |     x = bar as fn(u32) -> bool;    |         ^^^^^^^^^^^^^^^^^^^^^^ expected fn item, found fn pointer    |    = note: expected type `fn(u32) -> bool {foo}`               found type `fn(u32) -> bool` 

I don't understand these errors at all. What are fn items vs. fn pointers and why are foo and bar different fn items?

like image 457
JONNALAGADDA Srinivas Avatar asked Jan 12 '15 05:01

JONNALAGADDA Srinivas


People also ask

What are the differences between function pointers and normal pointers?

Typically a function pointer stores the start of executable code. 2) Unlike normal pointers, we do not allocate de-allocate memory using function pointers. 3) A function’s name can also be used to get functions’ address. For example, in the below program, we have removed address operator ‘&’ in assignment.

How do you infer the type of a function pointer?

Much like the auto keyword can be used to infer the type of normal variables, the auto keyword can also infer the type of a function pointer. This works exactly like you’d expect, and the syntax is very clean.

Can a function pointer print a value other than 1?

On the author’s machine, this printed: …but it may print some other value (e.g. 1) on your machine, depending on how your compiler decides to convert the function pointer to another type for printing.

How many function pointers are there in an array of functions?

Also, we declare an array of four function pointer. Each function pointer of array element takes two integers parameters and returns an integer value. We assign and initialize each array element with the function already declared.


1 Answers

Each named function has a distinct type since Rust PR #19891 was merged. You can, however, cast the functions to the corresponding function pointer type with the as operator.

call_both(foo as fn(u32) -> bool, bar as fn(u32) -> bool); 

It's also valid to cast only the first of the functions: the cast will be inferred on the second, because both functions must have the same type.

call_both(foo as fn(u32) -> bool, bar); 
like image 104
Francis Gagné Avatar answered Oct 02 '22 03:10

Francis Gagné