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

Relax trait bounds #21

Merged
merged 5 commits into from
May 5, 2022
Merged

Conversation

clint-white
Copy link
Contributor

These are some proposed changes that collectively relax some of the trait bounds in the crate. They are split into several commits so that each one can be coherent and focussed on one kind of change and in that way, hopefully, easier to review. In some cases existing bounds can be relaxed without modifying code in the implementations; in others a minor amount of refactoring allows us to relax the bounds.

This builds on similar work in prior PRs such as #7, #17, #19.

The first `impl` block contained several methods which really have
different needs as far as trait bounds on `N` are concerned, forcing the
block to have the union of all of those requirements.  By breaking this
`impl` block up we can better limit the bounds for each method to what
is strictly necessary.  This has downstream benefits in relaxing the
bounds on other trait implementations further down in the crate.

For example, `Counter::update()` does not require `N: PartialOrd` or `N:
SubAssign`, `Counter::subtract()` does not require `N: AddAssign`, and
`Counter::new()` requires neither the `PartialOrd` nor `AddAssign` nor
`SubAssign` nor `One` bounds on `N`.

This also eliminates the counter-intuitive bound `N: SubAssign` on the
implementation of `AddAssign` for `Counter<T, N>`, as well as the bound
`N: AddAssign` on the implementation of `SubAssign` for `Counter<T, N>`,
etc.
The implementations of `Deref` and `DerefMut` do not clone `N` and hence
do not need the bound `N: Clone`.  It looks like the bound was added in
commit cb24e7f because it was required by the bound `N: Clone` on the
struct itself.  The bound on the struct was later removed in 8180199,
but it looks like the bound on these `impl`s remained.

The current implementation of `Sub<I: IntoIterator<Item = T>>` does not
clone either `T` or `N` and hence does not need either bound `T: Clone`
or `N: Clone`.  It looks like the original implementation did clone
`self`, but that was changed in cdaad73fs at which point the bound `T:
Clone` and `N: Clone` could have been removed.
This builds on commit c2d7198, which refactored the iteration to take
ownership of the keys and values of `rhs.map` instead of references.
Not only is `value` owned and hence does not need to be cloned, but also
`key` is owned and thus there is no need to clone it to look up the
entry.
Since we are taking ownership of both the `self` and `rhs` Counters, we
really do not have to clone either keys or values to produce new
Counters with the correct semantics for these traits.

This commit refactors these implementations to void cloning and
removes the bounds `T: Clone` and `N: Clone`.
Elsewhere in the crate when we have a borrow but need ownership, we
clone instead of copy.  It seems it would be more consistent to do the
same here.
@coriolinus
Copy link
Owner

At first glance this looks plausible, but I'm busy at the moment and don't have time to give this a proper review. I intend to come back to this within a week. If next Sunday I haven't actually properly reviewed this, please ping me.

Copy link
Owner

@coriolinus coriolinus left a comment

Choose a reason for hiding this comment

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

Thank, you, this is great! I really appreciate the work you've put into this.

@coriolinus coriolinus merged commit b253d08 into coriolinus:master May 5, 2022
@clint-white clint-white deleted the relax-trait-bounds branch May 7, 2022 15:46
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.

None yet

2 participants