Generic functions and their pointer uniquness

Playing around with generics, I noticed that generic functions always generate unique pointers for each instantiation:

fn test_trait<T>() {
}

fn main() {
    let first: fn () = test_trait::<usize>;
    let second: fn () = test_trait::<String>;
    let third: fn () = test_trait::<usize>;
    println!("{:?} | {:?} | {:?}", first, second, third);
    assert_eq!(first, third);
    assert_ne!(first, second);
}

But I don't think the behavior is documented anywhere so that I could rely on it.
Is anyone aware if the behavior is documented when it comes to function address?

I don't think that you can rely on this, because when I tried it on release mode they all had the same address

https://play.rust-lang.org/?version=stable&mode=release&edition=2018&gist=e2071df4a89c372b9638366ae797e796

Damn, you're right.
I guess it is up to compiler so that it would be possible to optimize.
This is unfortunate

It's interesting that, if the function really does something depending on the type, the addresses will be different even in release: https://play.rust-lang.org/?version=stable&mode=release&edition=2018&gist=fb78eb2ac763e6989200b9f36ac62f9d This is understandable, since compiler must generate code for every of them, so maybe in this case the difference might be reliable.

LLVM doesn't even know that they come from the same generic source when it deduplicates them... which means even completely distinct functions can end up sharing the same code location if the optimizer chooses.

1 Like

Yeah, but it is completely unreliable because it is up to compiler to decide.
So you cannot really rely on it.

Pointer uniqueness of function is non-deterministic actually.

In my opinion, PartialEq and Hash shouldn't be implemented for function pointers, but it's here, and it cannot be removed now. Also, because those are implementations, you cannot even deprecate those (see https://github.com/rust-lang/rust/issues/39935). That said, most programs don't compare function pointers (I think?), so this isn't that big of a deal.

2 Likes