Skip to content

Can't compare FFI function pointers #38848

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

Closed
YaLTeR opened this issue Jan 5, 2017 · 2 comments
Closed

Can't compare FFI function pointers #38848

YaLTeR opened this issue Jan 5, 2017 · 2 comments
Labels
I-needs-decision Issue: In need of a decision. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.

Comments

@YaLTeR
Copy link
Contributor

YaLTeR commented Jan 5, 2017

extern "fastcall", "system", "cdecl" and some others function pointers cannot be compared.

I tried this code:

https://is.gd/5JBZee

extern "fastcall" fn test() {}

fn main() {
    let fastcall_ptr: extern "fastcall" fn() = test;
    
    let check = fastcall_ptr == test;
}

I expected to see this happen: the code compiles fine.

Instead, this happened:

error[E0369]: binary operation `==` cannot be applied to type `extern "fastcall" fn()`
note: an implementation of `std::cmp::PartialEq` might be missing for `extern "fastcall" fn()`
error[E0308]: mismatched types
    expected fn pointer, found fn item

Replacing fastcall with C in this example, or getting rid of extern "fastcall" entirely results in code that compiles fine:

https://is.gd/JI89Zs

fn test() {}
extern "C" fn c_test() {}

fn main() {
    let ptr: fn() = test;
    let c_ptr: extern "C" fn() = c_test;
    
    let check = ptr == test;
    let c_check = c_ptr == c_test;
}

rustc 1.16.0-nightly (4682271 2017-01-03)

@petrochenkov
Copy link
Contributor

A bit of history: several traits were originally implemented for fn pointers for all ABIs, but that caused serious metadata bloat, so implementations for "rare" ABIs were dropped.
Unfortunately, the only way to generalize over ABIs is macros, so this bloat is unavoidable currently.
However, metadata format changed few times since #28268 so it may make sense to try to add these impls and re-measure the size of libcore.

Workaround:

// Cast to `usize` and compare
fn main() {
    let a: extern "fastcall" fn() = panic!();
    let b: extern "fastcall" fn() = panic!();
    a as usize == b as usize;
}

@brson brson added T-libs-api Relevant to the library API team, which will review and decide on the PR/issue. I-wrong I-needs-decision Issue: In need of a decision. labels Jan 11, 2017
@petrochenkov
Copy link
Contributor

I'll close this in favor of more general #40710.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
I-needs-decision Issue: In need of a decision. T-libs-api Relevant to the library API team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants