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

Deranged 0.4.1 breaks build of other crates (PartialEq with empty slices) #21

Closed
chifflier opened this issue Mar 31, 2025 · 10 comments
Closed

Comments

@chifflier
Copy link

chifflier commented Mar 31, 2025

Hi,

After a cargo update from 0.4.0 to 0.4.1, building unit tests breaks in unrelated parts of my crate (asn1-rs) due to a conflicting implementation of PartialEq. Building with 0.4.0 works fine

I know this has already been reported, however I think this is not a duplicate:

  • I have updated all dependencies using a global cargo update (including time and deranged), problem is still here
  • cargo outdated shows to crate to upgrade
  • this seems to happen only with empty slices
  • this happens in code not importing time nor deranged

I tried to pin the problem to a minimal test case
The errors are related to comparisons of empty &[u8] (non-empty comparison work). For ex, the following fails:

fn build_failure() {
    let b1 = &[0_u8, 1];
    assert_eq!(b1, &[]);
}

Edit: the minimal crate I created to show the problem fails for another reason
Edit 2:
I have tried to isolate the problem in a minimal crate here
Adding use time::OffsetDateTime is enough to trigger the problem:
The first function build_ok builds, while the second fails with error:

error[E0283]: type annotations needed
  --> src/lib.rs:10:5
   |
10 |     assert_eq!(b1, &[]);
   |     ^^^^^^^^^^^^^^^^^^^ cannot infer type
   |
   = note: multiple `impl`s satisfying `u8: PartialEq<_>` found in the following crates: `core`, `deranged`:
           - impl PartialEq for u8;
           - impl<MIN, MAX> PartialEq<deranged::RangedU8<MIN, MAX>> for u8
             where the constant `MIN` has type `u8`, the constant `MAX` has type `u8`;
   = note: required for `[u8]` to implement `PartialEq<[_; 0]>`
   = note: 1 redundant requirement hidden
   = note: required for `&[u8]` to implement `PartialEq<&[_; 0]>`
   = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info)
@ggwpez
Copy link

ggwpez commented Apr 1, 2025

This breaks our code base for downstream users who do not use --locked to compile: paritytech/polkadot-sdk#8121

cargo update -p deranged --precise 0.4.0 for anybody wondering what to do.

tshepang added a commit to ferrocene/ferrocene that referenced this issue Apr 1, 2025
This avoids jhpratt/deranged#21,
which broke these commands:

    x test tests/ui-fulldeps/stable-mir/check_abi.rs
    x dist clippy
    x test rust-analyzer
@tdkt
Copy link

tdkt commented Apr 3, 2025

Please release 0.5.0 and then yank 0.4.1. It also messes with From<u16> for usize.

@jhpratt
Copy link
Owner

jhpratt commented Apr 3, 2025

Unfortunately there isn't really anything that can be done on my end. The impl is considered acceptable breakage per RFC 1105, and even if it happened in a breaking release the same issue would arise due to it being an indirect (and not publicly exposed) dependency.

@jhpratt jhpratt closed this as not planned Won't fix, can't repro, duplicate, stale Apr 3, 2025
AMDmi3 added a commit to repology/repology-rs that referenced this issue Apr 3, 2025
This fixed compile error described in [1]

Also use expect instead of unwrap.

[1] jhpratt/deranged#21
@RalfJung
Copy link

RalfJung commented Apr 3, 2025

Something seems off if a crate introduces breakage to entirely unrelated code that isn't even close to any of the types involved in the crate -- maybe this is formally acceptable, but it's not something I encountered before with another crate, and it is not nice to have invasive changes on unrelated code paths in this way.

@chifflier
Copy link
Author

Unfortunately there isn't really anything that can be done on my end.

I tend to disagree - there are other solutions than adding a trait that leaks on other crates. Implementing PartialEq for all T might be nice for you own use, but I'm sure this could be implemented another way. Besides, this wasn't present in the previous version.

The impl is considered acceptable breakage per RFC 1105, and even if it happened in a breaking release the same issue would arise due to it being an indirect (and not publicly exposed) dependency.

This RFC covers semver and version numbering. I do not think breaking a default trait implementation for all other crates can be described as an "API change"

I understand the changes you pushed might be nice, but I kindly ask you to reconsider the "wontfix". Maybe this trait can be used only internally (or when imported), or maybe using PartialEq is not possible without leaking.

@jhpratt
Copy link
Owner

jhpratt commented Apr 3, 2025

Something seems off if a crate introduces breakage to entirely unrelated code that isn't even close to any of the types involved in the crate

imo this is on Rust — type inference errors are far too easy to cause.

impl<T, U> PartialEq<[U]> for [T]
where
    T: PartialEq<U>

If this were impl<T, U=T>, this should work. I don't know if that's currently possible in Rust or not.

Maybe this trait can be used only internally (or when imported)

That's simply not possible. The orphan rule prevents doing this in a downstream crate, which is precisely what the impl is intended for.


Not directed at anyone in particular, but I will restate this. Yanking and releasing as 0.5 accomplishes nothing, unless you are relying on deranged directly (which is rarely the case).

@tdkt
Copy link

tdkt commented Apr 3, 2025

Fair enough that a version bump doesn't help as the conflicting code is in downstreams. It does mean this is no longer possible in any crate that has deranged somewhere in the dependency graph:

// just so the crate actually gets included.
use deranged::OptionRangedI8 as _;

fn main() {
    let a = 3usize;
    let b = 3u16;

    if a == b.into() {
        println!("Hello, world!");
    }
}

Causes:

error[E0283]: type annotations needed
 --> src/main.rs:8:15
  |
8 |     if a == b.into() {
  |          --   ^^^^
  |          |
  |          type must be known at this point
  |
  = note: multiple `impl`s satisfying `usize: PartialEq<_>` found in the following crates: `core`, `deranged`:
          - impl PartialEq for usize;
          - impl<MIN, MAX> PartialEq<RangedUsize<MIN, MAX>> for usize
            where the constant `MIN` has type `usize`, the constant `MAX` has type `usize`;
help: try using a fully qualified path to specify the expected types
  |
8 |     if a == <u16 as Into<T>>::into(b) {
  |             +++++++++++++++++++++++ ~

For more information about this error, try `rustc --explain E0283`.

Should this be reported on rust issue tracker or is this working as intended?

@jhpratt
Copy link
Owner

jhpratt commented Apr 3, 2025

While I still believe this can and should be handled better by the language, the reality is that it isn't and caused breakage in more ways than I thought would happen, including code that cannot easily be adjusted. For that reason, I am reconsidering whether to yank the release. If I do, there will not be a 0.5 release with the same. It would be removed entirely unless and until it is handled better on the language side (which I advocate for regardless).

Expect a final decision in the next day or two at the latest. I will announce it here regardless of outcome. The reason for the delay is that I'm currently busy and abroad, which is not a good combination for making OSS decisions.

@jhpratt
Copy link
Owner

jhpratt commented Apr 5, 2025

Alright, it's yanked. Hopefully this improves things!

@RalfJung
Copy link

RalfJung commented Apr 5, 2025 via email

zydou pushed a commit to zydou/arti that referenced this issue Apr 7, 2025
The issues were in:

deranged 0.4.1:
 - yanked
 - (Issue was a compatibility-break, not security:
   jhpratt/deranged#21)

tokio 1.44.1:
 - RUSTSEC-2025-0023
 - (I believe we're okay, since we don't use tokio's
   broadcast channel)

openssl 0.10.71
 - RUSTSEC-2025-0022
 - (We do not appear to use the affected APIs.)
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

No branches or pull requests

5 participants