Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Weird and inconsistent function pointer comparison behaviour #33879

Closed
simias opened this issue May 26, 2016 · 7 comments
Closed

Weird and inconsistent function pointer comparison behaviour #33879

simias opened this issue May 26, 2016 · 7 comments

Comments

@simias
Copy link

simias commented May 26, 2016

Long story short:

fn main() {
    let f = foo;

    // error: binary operation `==` cannot be applied to type `fn(u32) {foo}` [E0369]
    let _ = f == foo;

    // error: binary operation `==` cannot be applied to type `fn(u32) {foo}` [E0369]
    let _ = foo == f;

    // error: binary operation `==` cannot be applied to type `fn(u32) {foo}` [E0369]
    let _ = foo as fn(&u32) == f;

    // Compiles, even though as far as I can tell it should be
    // equivalent to the previous one
    let _ = foo as fn(_) == f;

    // error: binary operation `==` cannot be applied to type `fn(u32) {foo}` [E0369]
    let _ = f == foo as fn(_);
}

fn foo(param: &u32) {
    println!("{}", param);
}

I don't understand why the compiler is so picky about comparing function pointers, in particular I don't understand why it accepts the cast as fn(_) but not as fn(u32). And even when it works it's not commutative, which for the == operator is rather unexpected.

@petrochenkov
Copy link
Contributor

as fn(_) and as fn(u32) behave identically on playpen's stable/beta/nightly. What version of rustc do you use?

Other examples involve function item types fn(u32) {foo}, they are not function pointers (fn(u32)) and, unfortunately, library traits like PartialEq cannot be implemented for them.

@simias
Copy link
Author

simias commented May 26, 2016

A few more weirdnesses:

fn main() {
    let f = foo;

    // Compiles, even though the single-argument version doesn't with
    // explicit parameter types
    let _ = foo as fn(u32, u32) == f;
}

fn foo(param: u32, param2: u32) {
    println!("{} {}", param, param2);
}

But then

fn main() {
    let f = foo;
    // error: binary operation `==` cannot be applied to type `fn(&u32, u32)` [E0369]
    let _ = foo as fn(&u32, u32) == f;

    // Compiles
    let _ = foo as fn(_, u32) == f;

}

fn foo(param: &u32, param2: u32) {
    println!("{} {}", *param, param2);
}

So it seems that the number of parameters and whether or not they're references changes whether the compiler accepts the comparison or not

@simias
Copy link
Author

simias commented May 26, 2016

Ah good point @petrochenkov, it seems the behaviour changed, I was testing with rustc 1.8.0 (db2939409 2016-04-11). I'm going to update.

It still leaves the problem of non-commutative comparisons and the error in my 2nd post still happens on the playpen.

@simias
Copy link
Author

simias commented May 26, 2016

I've edited the original comment to use &u32 as parameter type to have the same behaviour with the current -stable.

@petrochenkov
Copy link
Contributor

A few more weirdnesses:

It's a known bug, it affects function pointers with references in arguments.
#24000 is related and probably something else

It still leaves the problem of non-commutative comparisons

It's a problem, but it's not a problem specific to function pointers, traits for binary operators like == need to be implemented for the first operand, and in this case it can't be implemented for the first operand, because it's an anonymous function item type.

@simias
Copy link
Author

simias commented May 26, 2016

Fair enough. Should I close this issue as a duplicate of #24000 then?

@petrochenkov
Copy link
Contributor

Closing as a duplicate.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants