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

Derive convenience traits for PSO components and a few other types #1249

Merged
merged 1 commit into from
May 4, 2017
Merged

Derive convenience traits for PSO components and a few other types #1249

merged 1 commit into from
May 4, 2017

Conversation

ebkalderon
Copy link
Contributor

@ebkalderon ebkalderon commented May 2, 2017

Changed

  • Derived Clone, Copy, Debug, Eq, Hash, and/or PartialEq for a bunch of structs, mostly within the gfx::pso::* module.
  • Updated the gfx_pipeline! macro to automatically derive Clone, Debug, and PartialEq for the resulting Data, Meta, and Init structs.
  • Updated the gfx_impl_struct_meta! macro to automatically derive Clone, Copy, Debug, and PartialEq for the resulting struct.
  • Minor reformatting.

Fixed

  • Eliminated TODOs for manually implementing Eq, Hash, and PartialEq on several structs which contain PhantomData<T> as data members.

CC @kvark @msiglreith

@kvark
Copy link
Member

kvark commented May 2, 2017 via email

@ebkalderon
Copy link
Contributor Author

ebkalderon commented May 2, 2017

@kvark Good idea! I can add such a macro, if you want, but in what crate/module would you like me to store it? Using a macro certainly sounds appealing in the long-term, but the effort of wiring it up and exporting it between crates might outweigh the advantages. I don't mind fixing each of the #[derive] statements by hand. grep and vim are my best friends right now. 😂

EDIT: Looking at the source of the std::cmp::Eq trait, it appears that deriving it doesn't make a difference at all from implementing it manually since it has no methods and depends on PartialEq. As such, I think it's okay to keep #[derive(..., Eq, ...)].

@kvark
Copy link
Member

kvark commented May 2, 2017

I can add such a macro, if you want, but in what crate/module would you like me to store it?

gfx_core

but the effort of wiring it up and exporting it between crates might outweigh the advantages

It's just a few lines of code, and the only crate that would need to use it from the core is gfx itself. I don't see the effort concern here, it would save a lot of lines and make it more consistent.

As such, I think it's okay to keep #[derive(..., Eq, ...)]

Yep.

@ebkalderon
Copy link
Contributor Author

ebkalderon commented May 2, 2017

Heh, interesting timing! Just as you commented this message, I pushed my manual fixes to my branch.

Fair enough, I'll revise it once more and add the macro then. Would lib.rs be good place or would you prefer I create a new macros.rs file instead?

@kvark
Copy link
Member

kvark commented May 2, 2017

I think the macros is small enough so that it can live in lib.rs itself.

@torkleyy
Copy link
Contributor

torkleyy commented May 3, 2017

There is a lot of structs with PhantomData that you added derives to. This is not perfect.

I don't understand, what is the problem of deriving for a struct with PhantomData?

@kvark
Copy link
Member

kvark commented May 3, 2017

@torkleyy it's not perfect in a way that these structs look very similar, and we end up with tons of code duplication. Nothing is wrong about PhantomData in particular.

@msiglreith
Copy link
Contributor

As followup to @torkleyy 's question:
What was the original reason for these TODOs
// TODO: manual Eq & Hash impl because PhantomData

The Eq implementation of PhantomData returns always true and the hashing is a no-op.
Therefore #[derive(..., Eq, Hash, ...) looks fine to me instead of manually implementing them. I assumed there was some issue with these based on the TODO above.

@ebkalderon
Copy link
Contributor Author

ebkalderon commented May 3, 2017

@msiglreith I'm pretty sure that the original commenter was mistaken about Eq in particular; I mentioned that already a few posts up and revised my PR to just derive Eq like normal.

@kvark Just curious, but if the structs in question contained a PhantomData field, doesn't that mean that it's meant to be type checked at compile time? If so, why are we skirting around type checking the phantom fields rather than deriving PartialEq and Hash? Is it for ensuring that Texture<R, T> and RawTexture<R> result in the same equality and hash?

@kvark
Copy link
Member

kvark commented May 3, 2017

Therefore #[derive(..., Eq, Hash, ...) looks fine to me instead of manually implementing them. I assumed there was some issue with these based on the TODO above.

It would be safest to look at the code that #derive produces, to make sure no extra bounds are put.
We could also have simple unit tests that just try to use the derived traits with T type that doesn't implement anything.

@kvark
Copy link
Member

kvark commented May 3, 2017

@ebkalderon

If so, why are we skirting around type checking the phantom fields rather than deriving PartialEq and Hash?

We aren't cheating here. The limitation of #derive, AFAIK, is that it automatically requires the generic type parameters to implement the traits you specify, while the actual implementation may not even care. So we should be smarter than #derive by macroing it manually.

@torkleyy
Copy link
Contributor

torkleyy commented May 3, 2017

@kvark Indeed (https://is.gd/7fse6V), but why is that? It could just do a where PhantomData<T>: Hash, right?

@kvark
Copy link
Member

kvark commented May 3, 2017

@torkleyy surely it could be better... the answer lies somewhere within the #derive implementation. And I have a feeling that fixing that would break rust-1.0 promise.

@torkleyy
Copy link
Contributor

torkleyy commented May 3, 2017

Yeah, it does:

use std::marker::PhantomData;

struct Foo;

#[derive(Clone, Copy, Hash, PartialEq, Eq)]
struct Bar<T> {
    value: u32,
    phantom: PhantomData<T>,
}

impl Hash for Bar<Foo> { // Conflicting impls if #derive did the right thing
    ...
}

@ebkalderon
Copy link
Contributor Author

Relevant issue: rust-lang/rust#26925

@kvark
Copy link
Member

kvark commented May 4, 2017

Happy to see this coming to a success!
@homu r+

@homu
Copy link
Contributor

homu commented May 4, 2017

📌 Commit b31869a has been approved by kvark

homu added a commit that referenced this pull request May 4, 2017
Derive convenience traits for PSO components and a few other types

### Changed

* Derived `Clone`, `Copy`, `Debug`, `Eq`, `Hash`, and/or `PartialEq` for a bunch of structs, mostly within the `gfx::pso::*` module.
* Updated the `gfx_pipeline!` macro to automatically derive `Clone`, `Debug`, and `PartialEq` for the resulting `Data`, `Meta`, and `Init` structs.
* Updated the `gfx_impl_struct_meta!` macro to automatically derive `Clone`, `Copy`, `Debug`, and `PartialEq` for the resulting struct.
* Minor reformatting.

### Fixed

* Eliminated TODOs for manually implementing `Eq`, `Hash`, and `PartialEq` on several structs which contain `PhantomData<T>` as data members.

CC @kvark @msiglreith
@homu
Copy link
Contributor

homu commented May 4, 2017

⌛ Testing commit b31869a with merge 162221c...

@homu
Copy link
Contributor

homu commented May 4, 2017

☀️ Test successful - status

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

Successfully merging this pull request may close these issues.

5 participants