Skip to content
This repository has been archived by the owner on Nov 30, 2022. It is now read-only.

Remove Index trait bound from Hash #168

Closed
wants to merge 4 commits into from

Conversation

tcharding
Copy link
Member

@tcharding tcharding commented Aug 9, 2022

The Index trait is not required if we provide the AsRef trait. Users
can just call as_ref()[0] to get access to the 0th element of a Hash.

For times when we take a reference to the whole slice [..] using
as_ref() is capable and arguably more ergonomic.

From the Hash trait remove the trait bound on Index and its
associated traits, instead use the trait bound AsRef (we already have
a trait bound of Borrow).

The first patch removes Deref implementations, I did this because
the docs say so - not sure if that is enough justification or if I'm
missing something.

https://doc.rust-lang.org/std/ops/trait.Deref.html

This work was inspired by rust-bitcoin/rust-miniscript#450 (comment)

Verification

This PR is verified to not break usage of the lib by patching rust-secp256k1 and rust-bitcoin.

@tcharding
Copy link
Member Author

hmm, the CI fail appears to be on master right now. Will investigate more.

@apoelstra
Copy link
Member

Yeah, I can get behind this. When I added Index I think it [..] was the fashionale way to convert slice-like objects to slices. Or maybe I just saw it done this way once and copied it.

I do think that .as_ref is more explicit about what's going on, and a bit less less likely to happen by accident/confusingly.

@tcharding
Copy link
Member Author

CI needs #167 to go green

@apoelstra
Copy link
Member

Ok, merged #167. Can you rebase this?

@tcharding
Copy link
Member Author

Rebased!

@Kixunil
Copy link
Collaborator

Kixunil commented Aug 9, 2022

I meant removing bound not impl. But since indexing into hash is kinda weird, I'm not against removing impl. Could be done in two steps.

@apoelstra
Copy link
Member

cc @TheBlueMatt are you opposed to this? It's a reduction in the API surface which arguably needlessly breaks people (in a mechanically fixable way, but still annoying). But OTOH it makes the separation between hashes and byteslices a little cleaner.

@sanket1729
Copy link
Member

ACK removing the bound.

According to the Rust docs [0] on the `Deref` trait, it should only be
implemented for smart pointers.

Remove the implementation of `Deref`.

[0] https://doc.rust-lang.org/std/ops/trait.Deref.html
The `Index` trait is not required if we provide the `AsRef` trait. Users
can just call `as_ref()[0]` to get access to the 0th element of a `Hash`.

For times when we take a reference to the whole slice `[..]` using
`as_ref()` is capable and arguably more ergonomic.

From the `Hash` trait remove the trait bound on `Index` and its
associated traits, instead use the trait bound `AsRef` (we already have
a trait bound of `Borrow`).

Fix all uses of `foo[..]` -> `foo.as_ref()`.
@tcharding
Copy link
Member Author

Rebase only, no other changes.

Copy link
Member

@apoelstra apoelstra left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK b13b06a

@apoelstra
Copy link
Member

I've ACKed but I would still like a (concept) ACK from @TheBlueMatt since we're removing API functions that are fairly widely used.

@Kixunil
Copy link
Collaborator

Kixunil commented Sep 7, 2022

For consideration: some of these methods to avoid inference issues and possibly get better clarity than with as_ref:

  • as_bytes(&self) -> &[u8; LEN]
  • as_byte_array(&self) -> &[u8; LEN]
  • as_bytes(&self) -> &[u8]
  • as_byte_slice(&self) -> &[u8]
  • as_mut_*

@tcharding
Copy link
Member Author

I've added as_bytes(&self) -> &[u8; LEN] for all hash types as well as for types created by hash_newtype!.

We now implement `AsRef` for hash types, sometimes usage of `as_ref` may
required type annotations. For such cases we can provide an alternate
way to get the underlying bytes to make the API more ergonomic.

Add a method `as_bytes` for getting a reference to the inner byte array.
Add for new types created by `hash_newtype` also.
We implement `as_bytes` on hash types; in order to be able to modify a
hash it would be useful to iterate the inner byte array mutable.

Add a `as_mut_bytes` method to all hash types and also to any hash
created with `hash_newtype`.
@tcharding
Copy link
Member Author

I've added as_mut_bytes as well, as a separate patch. I'm not understanding the utility of this method though - why would one want to modify a hash making the preimage unknown? If we want a hash with an unknown pre-image we can just use Hash::all_zeros.

@Kixunil
Copy link
Collaborator

Kixunil commented Sep 8, 2022

@tcharding the only utility I can think of is consistency and I think three more lines are fine just for consistency.

@tcharding
Copy link
Member Author

Cool, cheers.

@tcharding
Copy link
Member Author

Closing in preparation for archiving this repo. See rust-bitcoin/rust-bitcoin#1284

@tcharding tcharding closed this Nov 8, 2022
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants