Join GitHub today
GitHub is home to over 28 million developers working together to host and review code, manage projects, and build software together.
Sign up#[derive] Debug, PartialEq, Hash, etc. for any function pointers, regardless of type signature #54508
Comments
This comment has been minimized.
This comment has been minimized.
|
what's your local rustc meta info? |
This comment has been minimized.
This comment has been minimized.
|
This is certainly weird - It seems to be fixed and even if I try older compiler versions, it doesn't appear. But I did get errors that I'm closing this for now, since it doesn't seem to be an issue, but I'll reopen this once I get a verifiable example of the problem working. |
fschutt
closed this
Sep 23, 2018
This comment has been minimized.
This comment has been minimized.
|
Yeah, the example was picked poorly. The issue only appears when the callback carries a Not working: https://play.rust-lang.org/?gist=e805684b57c9992a9b1da66510c8c336&version=stable&mode=debug&edition=2015 All I changed was this: #[derive(Debug, Clone, PartialEq, Hash, Eq)]
pub struct Callback<T: Layout>(pub fn(WindowInfo<T>, usize, usize) -> Dom<T>);to this: #[derive(Debug, Clone, PartialEq, Hash, Eq)]
pub struct Callback<T: Layout>(pub fn(&mut WindowInfo<T>, usize, usize) -> Dom<T>);Notice the |
fschutt
reopened this
Sep 23, 2018
This comment has been minimized.
This comment has been minimized.
|
It seems that rust thinks that I'm still not sure where the actual bug is coming from. |
This comment has been minimized.
This comment has been minimized.
|
for<'r> fn(&'r mut WindowInfo<T>, usize, usize) -> Dom<T>
fn(WindowInfo<T>, usize, usize) -> Dom<T>
|
Havvy
added
the
C-feature-request
label
Sep 25, 2018
This comment has been minimized.
This comment has been minimized.
|
So my question then is... why isn't it implemented? Or is this the actual bug? Even after rust-lang/rfcs#387 is merged (four years ago?), this still doesn't work, so maybe it's just an issue in the standard library? But you can't impl derive for all possible function pointers: impl<Ret, A, B, C> Eq for fn(A, B, C) -> Ret
impl<Ret, A, B, C> Eq for fn<'a>(&'a A, B, C) -> Ret
impl<Ret, A, B, C> Eq for fn<'a>(&mut 'a A, B, C) -> Ret
impl<Ret, A, B, C> Eq for fn<'a, 'b>(&'a A, &'b B, C) -> Ret
impl<Ret, A, B, C> Eq for fn<'a, 'b>(&mut 'a A, &'b B, C) -> Ret
impl<Ret, A, B, C> Eq for fn<'a, 'b>(&mut 'a A, &mut 'b B, C) -> Ret
impl<Ret, A, B, C> Eq for fn<'a, 'b>(&'a A, &mut 'b B, C) -> Ret
impl<Ret, A, B, C> Eq for fn<'a, 'b>(A, &mut 'b B, C) -> Ret
impl<Ret, A, B, C> Eq for fn<'a, 'b>(A, & 'b B, C) -> Ret
impl<Ret, A, B, C> Eq for fn<'a, 'b, 'c>(&'a A, &'b B, &'c C) -> Ret
impl<Ret, A, B, C> Eq for fn<'a, 'b, 'c>(&mut 'a A, &'b B, &'c C) -> Ret
impl<Ret, A, B, C> Eq for fn<'a, 'b, 'c>(&mut 'a A, &mut 'b B, &mut 'c C) -> Ret
impl<Ret, A, B, C> Eq for fn<'a, 'b, 'c>(&mut 'a A, &'b B, &mut 'c C) -> Ret
impl<Ret, A, B, C> Eq for fn<'a, 'b, 'c>(&'a A, &'b B, &mut 'c C) -> Ret
// ... and so on.This is insane. You can't prepare for any function signature. What I don't get is that it's a function pointer - regardless of the type system, a function pointer is just a number, like a impl PartialEq for fn<*>(*) -> * {
fn eq(&self: other: &Self) -> bool { self as usize == other as usize }
}... where the * stands for "anything", i.e. any number or arguments or lifetime of types - So maybe, I thought, this should be a compiler built-in thing, that the compiler knows about function pointers and just treats them as a // instead of:
impl<A> Eq for (A) where A: Eq + ?Sized
impl<A, B> Eq for (A, B) where A: Eq, B: Eq + ?Sized
impl<A, B, C> Eq for (A, B, C) where A: Eq, B: Eq, C: Eq + ?Sized
impl<A, B, C, D> Eq for (A, B, C, D) where A: Eq, B: Eq, C: Eq, D: Eq + ?Sized
impl<A, B, C, D, E> Eq for (A, B, C, D, E) where A: Eq, B: Eq, C: Eq, D: Eq, E: Eq + ?Sized
impl<A, B, C, D, E, F> Eq for (A, B, C, D, E, F) where A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq + ?Sized
impl<A, B, C, D, E, F, G> Eq for (A, B, C, D, E, F, G) where A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq, G: Eq + ?Sized
impl<A, B, C, D, E, F, G, H> Eq for (A, B, C, D, E, F, G, H) where A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq, G: Eq, H: Eq + ?Sized
impl<A, B, C, D, E, F, G, H, I> Eq for (A, B, C, D, E, F, G, H, I) where A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq, G: Eq, H: Eq, I: Eq + ?Sized
impl<A, B, C, D, E, F, G, H, I, J> Eq for (A, B, C, D, E, F, G, H, I, J) where A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq, G: Eq, H: Eq, I: Eq, J: Eq + ?Sized
impl<A, B, C, D, E, F, G, H, I, J, K> Eq for (A, B, C, D, E, F, G, H, I, J, K) where A: Eq, B: Eq, C: Eq, D: Eq, E: Eq, F: Eq, G: Eq, H: Eq, I: Eq, J: Eq, K: Eq + ?Sized
// just:
impl<*> Eq for (*) where *: Eq + ?Sized |
fschutt commentedSep 23, 2018
•
edited
Suppose you have a situation like this:
https://play.rust-lang.org/?gist=d1bd43980abfb37197a8aaf84ed7b529&version=stable&mode=debug&edition=2015
You can implement this manually by writing something like this:
... but this is tedious to do and leads to a lot of boilerplaite code. Even worse, this is especially bad if you have a
FunctionPointer<T>used in a struct like this:... because then #[derive] doesn't work on the
Somethingstruct! This means you have to copy-paste all over again:.. and over and over and over again, for each struct that you wrap / use
Somethingin. Nevermind that this is error-prone if you add a field to theSomethingstruct, don't forget to update thehash()andfmt()functions! This leads to a whole bunch of code that I need to copy-paste because derive doesn't work.The real-world code where I encountered this problem is:
https://github.com/maps4print/azul/blob/4f2ba2e6eebdd0718d1adb15aac34c643f0f94ca/src/dom.rs#L159-L228
https://github.com/maps4print/azul/blob/4f2ba2e6eebdd0718d1adb15aac34c643f0f94ca/src/dom.rs#L358-L394
https://github.com/maps4print/azul/blob/4f2ba2e6eebdd0718d1adb15aac34c643f0f94ca/src/dom.rs#L413-L452
It's just stupid, copy-pasted code and if possible, I'd like to get rid of it with derive, but right now I sadly can't. My manual code is just a workaround for now, and I'd like this to be properly fixed somehow. Thanks in advance for any help.