Repository navigation
Conversation
`Counter::new()` could not be called without a turbofish or a type
annotation. Default type parameters are only applied where a type is
written out; they are never used during inference, so the single
`impl<T, N, S> Counter<T, N, S> where S: Default` block left `S`
ambiguous:
let counter = Counter::new(); // error[E0283]
Adding a `RandomState`-pinned `new` alongside the generic one is not
possible: the two inherent impls overlap, which is `error[E0592]`.
Instead, follow the shape `std` uses for `HashMap`: pin the hasher in
the constructors which do not take one, and name the ones which do.
let mut counter = Counter::new(); // RandomState
let mut counter = Counter::with_hasher(hasher); // any BuildHasher
`Default` is deliberately left generic over `S`, matching
`impl<K, V, S: Default> Default for HashMap<K, V, S>`. Pinning it would
break `#[derive(Default)]` on types holding a custom-hasher `Counter`,
and `Counter::new()` now covers the case which needed an annotation.
BREAKING CHANGE: `new` and `with_capacity` no longer accept a custom
hasher. Replace `Counter::<T, N, S>::new()` with
`Counter::with_hasher(S::default())` and
`Counter::<T, N, S>::with_capacity(n)` with
`Counter::with_capacity_and_hasher(n, S::default())`.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
|
ⓘ Qodo reviews are paused because the subscription is no longer active. Ask your workspace admin to reactivate the subscription to resume reviews. Manage billing |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Problem
Counter::new()cannot be called without a turbofish or a type annotation:Default type parameters are only applied where a type is written out; they are never used during inference.
newlives in the singleimpl<T, N, S> Counter<T, N, S> where S: Defaultblock, soSis left ambiguous and every caller has to name a hasher they usually do not care about:HashMap::new()does not have this problem because std keeps it in a separateimpl<K, V> HashMap<K, V, RandomState>block.Approach
The same shape std uses: constructors which do not take a hasher pin
S = RandomState; constructors which do take one are named for it.Counter::new()(needs annotation)Counter::new()Counter::with_capacity(n)(needs annotation)Counter::with_capacity(n)Counter::<_, _, S>::new()Counter::with_hasher(s)Counter::<_, _, S>::with_capacity(n)Counter::with_capacity_and_hasher(n, s)with_hashertakes the hasher by value instead of requiringS: Default, which also makes seeded hashers usable.Adding a
RandomState-pinnednewalongside the generic one is not an option: the two inherent impls overlap, givingerror[E0592]: duplicate definitions with name 'new'plus anerror[E0034]at every internal call site. Moving the method is the only way to get the short form.What is deliberately unchanged
Defaultstays generic overS, matchingimpl<K, V, S: Default> Default for HashMap<K, V, S>.Counter::default()therefore still needsSpinned by context, exactly asHashMap::default()does. Restricting that impl would fix the bare call too, but it would break#[derive(Default)]on any type holding a custom-hasherCounter, andCounter::new()now covers the case which motivated this change.Breaking change
newandwith_capacityno longer accept a custom hasher. The failure is a clearerror[E0308]:Migration:
Custom hashers have only been supported since 0.7.0 (#51), so the affected surface is small. The commit is marked
feat!so git cliff picks it up as breaking.Also included
new, forwith_hasherandwith_capacity_and_hasher, and an integration test which constructs with a non-default hasher.cargo test --all-features(21 unit + 19 integration + 51 doctests),cargo clippy --all-features --all-targets, andcargo docare clean.