Skip to content

Conversation

kayabaNerve
Copy link

Resolves #131. I did maintain the From<&[u8]> references, which still offers a way to achieve the removed functionality (albeit not with the existing traits). I cannot comment this should be merged, solely lodge my issue and note this resolves my issue. I'll accept being told I'm the one who's misusing things and this is intended behavior 😅

This doesn't break sha2 0.11.0-rc.0, blake2 0.11.0-rc.0 as used in my tree so hopefully it wouldn't actually be problematic to move forward with.

@tarcieri
Copy link
Member

tarcieri commented Aug 30, 2025

Let's talk about this on #131 first. This is a very, very big breaking change which will impact a large part of the RustCrypto codebase.

If you really want to see it through, I would suggest opening PRs against all of the repos to see the impact.

@kayabaNerve
Copy link
Author

Of course, it has to be discussed first. I solely opened it so if we agree on the idea, this is available. I can make other PRs as well to prove lack of or minimal impact :)

@tarcieri
Copy link
Member

tarcieri commented Aug 30, 2025

I can make other PRs as well to prove lack of or minimal impact :)

@kayabaNerve I specifically replaced all of the occurrences of .as_ref().into() throughout all of the RustCrypto repos with as_ref when doing the generic-array => hybrid-array migration, so I am expecting there to be several dozen places that this will cause breakage.

I'm asking you to do this not to "prove lack of or minimal impact", but to address the actual downstream breakages I know this is going to cause. This is a feature we are actively using which you are asking us to remove.

@kayabaNerve
Copy link
Author

I apologize if I was too optimistic due to my experience, and if I haven't realized how impactful this would be. I've tried to be clear this isn't my place to comment on if it should occur, solely to raise the annoyance I observed. If you don't believe this is justified, please close both the issue and the PR and I'll have no issue, solely an annoyance I'll tolerate. I apologize if this has been too much of a bother.

I'll make the PRs now to discover and realize the impact otherwise.

@tarcieri
Copy link
Member

The real issue is that this is a useful feature which we are using which doesn't have a good replacement which you are asking to remove. The alternative reference conversion looks a bit like (&arr).into() or &arr.into() which is both a bit ugly and also difficult for people to figure out.

That said, the usefulness of the feature does need to be balanced against the kind of problems you're encountering in #131, which is why I'm trying to figure out in that thread what exactly is going on in your code which is leading to the ambiguity in the first place.

@kayabaNerve
Copy link
Author

For each of the following repositories, I added the following block to their root-level Cargo.tomls:

[patch.crates-io]
hybrid-array = { git = "https://github.com/kayabaNerve/hybrid-array", branch = "remove-as-ref" }

I then ran cargo update -p hybrid-array && cargo check --all-features --all-targets.

Repository Changes Required Comments
https://github.com/RustCrypto/AEADs Yes ocb3 alone was affected
https://github.com/RustCrypto/block-modes None
https://github.com/RustCrypto/block-ciphers None
https://github.com/RustCrypto/crypto-bigint None
https://github.com/RustCrypto/elliptic-curves Yes check passes without --all-targets
https://github.com/RustCrypto/formats None
https://github.com/RustCrypto/hashes None check required +nightly due to using the unstable test feature
https://github.com/RustCrypto/JOSE None hybrid-array not in-tree
https://github.com/RustCrypto/KDFs None
https://github.com/RustCrypto/KEMs None
https://github.com/RustCrypto/key-wraps None
https://github.com/RustCrypto/MACs None
https://github.com/RustCrypto/nacl-compat None hybrid-array not in-tree
https://github.com/RustCrypto/PAKEs None hybrid-array not in-tree
https://github.com/RustCrypto/password-hashes None
https://github.com/RustCrypto/RSA None
https://github.com/RustCrypto/signatures Yes check passes without --all-targets
https://github.com/RustCrypto/sponges None hybrid-array not in-tree
https://github.com/RustCrypto/SSH None
https://github.com/RustCrypto/stream-ciphers None
https://github.com/RustCrypto/traits None
https://github.com/RustCrypto/universal-hashes None
https://github.com/RustCrypto/utils None

This is comprehensive to every RustCrypto repository updated this year, unless I missed one, except the archived asm-hashes repository.

So the ocb3 crate and the tests/benches for signatures, elliptic-curves. I'll open the complimentary PRs now. I can also open PRs to every single repository just to prove the CI passes even with this patch applied, even though no changes are required.

@tarcieri
Copy link
Member

tarcieri commented Aug 30, 2025

That's surprising. I would've expected more breakages.

cargo check --all-features --all-targets.

Err, you need to run cargo build at least I would think? hmm, or not

@kayabaNerve
Copy link
Author

I'm pleasantly surprised by it given your recent comment, yet it lines up with my initial optimistic view. My guess is because I left Array<T, U { N }>: AsRef<[T; N]> in place. I'm not surprised people turn &Array<T, U { N }> -> &[T; N] more often than they turn &[T; N] -> &Array<T, U { N }>.

If this did cause a notable amount of breakage, I'd concede the issue as obviously, this would be a used feature. My entire issue is premised on how this feature may not offer sufficient benefit to justify the unfortunate annoyance it may cause. It's not to say this isn't a feature itself.

I'll open the three corresponding PRs. I trust you to decide if it's better to have this feature or more pleasant to remove it. I won't hold any 'grudge' either way. I understand that while digest 0.11 has yet to be realized, this is still later into the release cycle for such a change and don't want to derail it in any way. I do appreciate the work of hybrid-array and look forward to using it, outside of pre/rc :)

@tarcieri
Copy link
Member

My guess is because I left Array<T, U { N }>: AsRef<[T; N]> in place. I'm not surprised people turn &Array<T, U { N }> -> &[T; N] more often than they turn &[T; N] -> &Array<T, U { N }>.

That may very well be it.

That said, it could still be a useful tool for people who want to write code in terms of core arrays rather than the Array type, especially when only working with a single concrete size. Our goal is to eventually get rid of hybrid-array and replace it with sufficiently advanced future const generics.

@kayabaNerve
Copy link
Author

In that case, there is still From<&[T; N]> for &Array<T, U { N }>. It's making those use-cases slightly less intuitive to avoid the fallout from introducing another impl AsRef on a type defined in core. Again though, up to you which path is optimal.

I do understand why generic-array exists, how hybrid-array improves, and would love to see it removed entirely when the time happens. Of course, I extensively use and love crypto-bigint, which I've found incredibly powerful. I'm not here to stand in the way of anything, nor to disagree. Solely to raise this concern and have it considered.

@kayabaNerve
Copy link
Author

kayabaNerve commented Aug 30, 2025

Three required PRs have been opened. +28, -22 in total, including the patch statements which would be removed before being merged 😅

@tarcieri
Copy link
Member

tarcieri commented Sep 1, 2025

I might do a slightly different take on this PR that accomplishes the same result

Comment on lines -171 to -176
/// pub fn get_third_item_const_generic<T, const N: usize>(arr_ref: &[T; N]) -> &T
/// where
/// [T; N]: AssocArraySize + AsRef<ArrayN<T, N>>
/// {
/// get_third_item_hybrid_array(arr_ref.as_ref())
/// }
Copy link
Member

Choose a reason for hiding this comment

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

This is the really sad thing to lose, BTW. It made it possible to write APIs using const generics that hid the use of Array behind the scenes, so the callers didn't have to care about Array at all

tarcieri added a commit that referenced this pull request Sep 1, 2025
See #131, #132

Notably these impls even existing can break code which would otherwise
compile when `hybrid-array` is included as a dependency, due to some
complex interactions between type inference and the sized-to-unsized
coercion, something I previously knew little about prior to #131:

https://rustc-dev-guide.rust-lang.org/traits/unsize.html

Notably the existence of overlapping `AsRef` impls can break inference
in cases where code is depending on the sized-to-unsized coercion, since
the compiler can infer the desired type is `[T]` and coerce the other
arguments from `[T; N]` into `[T]` to match.

When this is no longer possible, it can fail in some pretty
counterintuitive ways. See #131 for examples.

This is all unfortunate because it's removing functionality which made
it possible to expose `[T; N]` in public APIs so the caller didn't have
to worry about `Array` at all. Perhaps we can lean on the `From` impls
for doing such conversions instead.
@tarcieri
Copy link
Member

tarcieri commented Sep 1, 2025

I opened #133 which ended up being more similar to this PR than I was hoping and I guess I could've just told you to do those changes @kayabaNerve, mea culpa.

I'd like to see if I can add back the documentation example at least, using From to do reference conversions, or failing that perhaps Borrow could work as a replacement for AsRef

tarcieri added a commit that referenced this pull request Sep 1, 2025
Closes #131, #132

Notably these impls even existing can break code which would otherwise
compile when `hybrid-array` is included as a dependency, due to some
complex interactions between type inference and the sized-to-unsized
coercion, something I previously knew little about prior to #131:

https://rustc-dev-guide.rust-lang.org/traits/unsize.html

Notably the existence of overlapping `AsRef` impls can break inference
in cases where code is depending on the sized-to-unsized coercion, since
the compiler can infer the desired type is `[T]` and coerce the other
arguments from `[T; N]` into `[T]` to match.

When this is no longer possible, it can fail in some pretty
counterintuitive ways. See #131 for examples.

This is all unfortunate because it's removing functionality which made
it possible to expose `[T; N]` in public APIs so the caller didn't have
to worry about `Array` at all. Perhaps we can lean on the `From` impls
for doing such conversions instead.
@tarcieri
Copy link
Member

tarcieri commented Sep 1, 2025

Equivalent outcome accomplished in #133

@tarcieri tarcieri closed this Sep 1, 2025
@kayabaNerve
Copy link
Author

kayabaNerve commented Sep 1, 2025

No worries! I'm not offended and knew when I deleted the documentation, this probably wasn't optimal. Thanks for making the changes yourself!

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.

AsRef<Array<_, _>> for [T; N] is poisonous
2 participants