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

Compiler asks for already present bound #79629

Open
newpavlov opened this issue Dec 2, 2020 · 1 comment
Open

Compiler asks for already present bound #79629

newpavlov opened this issue Dec 2, 2020 · 1 comment
Labels
A-associated-items Area: Associated items such as associated types and consts. A-traits Area: Trait system C-bug Category: This is a bug. S-needs-repro Status: This issue has no reproduction and needs a reproduction to make progress. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@newpavlov
Copy link
Contributor

newpavlov commented Dec 2, 2020

While working on RustCrypto/stream-ciphers#195. I got roughly the following code:

use generic_array::{GenericArray, ArrayLength, typenum::{Unsigned, Quot, U16}};
use core::ops::Div;

pub trait Foo: Copy + Default {
    type Size: Unsigned;

    fn load<N>(block: &GenericArray<u8, N>) -> GenericArray<Self, Quot<N, Self::Size>>
    where
        N: ArrayLength<u8> + Div<Self::Size>,
        Quot<N, Self::Size>: ArrayLength<Self>
    {
        Default::default()
    }
}

#[derive(Copy, Clone, Default)]
#[repr(transparent)]
struct Bar(u128);

impl Foo for Bar {
    type Size = U16;
}

It compiles without issues. The default method impl will not be present in the final code, I just use it to show that the bounds are correct.

But if we are to overwrite the load method in the Bar impl by simply copying the default impl:

impl Foo for Bar {
    type Size = U16;

    fn load<N>(block: &GenericArray<u8, N>) -> GenericArray<Self, Quot<N, Self::Size>>
    where
        N: ArrayLength<u8> + Div<Self::Size>,
        Quot<N, Self::Size>: ArrayLength<Self>
    {
        Default::default()
    }
}

Playground

Compiler will return the following compilation errors:

error[E0277]: cannot divide `N` by `UInt<UInt<UInt<UInt<UInt<UTerm, B1>, B0>, B0>, B0>, B0>`
  --> src/lib.rs:23:5
   |
23 | /     fn load<N>(block: &GenericArray<u8, N>) -> GenericArray<Self, Quot<N, Self::Size>>
24 | |     where
25 | |         N: ArrayLength<u8> + Div<Self::Size>,
26 | |         Quot<N, Self::Size>: ArrayLength<Self>
   | |______________________________________________^ no implementation for `N / UInt<UInt<UInt<UInt<UInt<UTerm, B1>, B0>, B0>, B0>, B0>`
   |
help: consider further restricting this bound
   |
25 |         N: ArrayLength<u8> + Div<Self::Size> + Div<UInt<UInt<UInt<UInt<UInt<UTerm, B1>, B0>, B0>, B0>, B0>>,
   |                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0277]: cannot divide `N` by `UInt<UInt<UInt<UInt<UInt<UTerm, B1>, B0>, B0>, B0>, B0>`
  --> src/lib.rs:23:5
   |
23 | /     fn load<N>(block: &GenericArray<u8, N>) -> GenericArray<Self, Quot<N, Self::Size>>
24 | |     where
25 | |         N: ArrayLength<u8> + Div<Self::Size>,
26 | |         Quot<N, Self::Size>: ArrayLength<Self>
27 | |     {
28 | |         Default::default()
29 | |     }
   | |_____^ no implementation for `N / UInt<UInt<UInt<UInt<UInt<UTerm, B1>, B0>, B0>, B0>, B0>`
   |
help: consider further restricting this bound
   |
25 |         N: ArrayLength<u8> + Div<Self::Size> + Div<UInt<UInt<UInt<UInt<UInt<UTerm, B1>, B0>, B0>, B0>, B0>>,
   |                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error[E0277]: cannot divide `N` by `UInt<UInt<UInt<UInt<UInt<UTerm, B1>, B0>, B0>, B0>, B0>`
  --> src/lib.rs:23:8
   |
23 |     fn load<N>(block: &GenericArray<u8, N>) -> GenericArray<Self, Quot<N, Self::Size>>
   |        ^^^^ no implementation for `N / UInt<UInt<UInt<UInt<UInt<UTerm, B1>, B0>, B0>, B0>, B0>`
   |
help: consider further restricting this bound
   |
25 |         N: ArrayLength<u8> + Div<Self::Size> + Div<UInt<UInt<UInt<UInt<UInt<UTerm, B1>, B0>, B0>, B0>, B0>>,
   |                                              ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^

error: aborting due to 3 previous errors

Replacing Div<Self::Size> with Div<U16> or even with explicit Div<Uint<..>> does not fix the error.

@newpavlov newpavlov added the C-bug Category: This is a bug. label Dec 2, 2020
@ChrisDenton ChrisDenton added the needs-triage-legacy Old issue that were never triaged. Remove this label once the issue has been sufficiently triaged. label Jul 16, 2023
@fmease fmease added A-traits Area: Trait system A-associated-items Area: Associated items such as associated types and consts. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. S-needs-repro Status: This issue has no reproduction and needs a reproduction to make progress. and removed needs-triage-legacy Old issue that were never triaged. Remove this label once the issue has been sufficiently triaged. labels Jan 25, 2024
@newpavlov
Copy link
Contributor Author

I think the "needs repro" tag is wrong. The bug is reproduced in the playground link. It's not a minimal example, but it's a reproduction nevertheless.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-associated-items Area: Associated items such as associated types and consts. A-traits Area: Trait system C-bug Category: This is a bug. S-needs-repro Status: This issue has no reproduction and needs a reproduction to make progress. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

3 participants