Skip to content

rustc unable to interact with trait bound required by other required trait #63251

Open
@vadixidav

Description

@vadixidav

This bug happens on nightly-2019-08-01-x86_64-unknown-linux-gnu and also a nightly I had from a month ago.

rustc 1.38.0-nightly (8a58268b5 2019-07-31)

I minimized my issue to the following (playground link):

use generic_array::{GenericArray, ArrayLength};

pub struct HNSW<M: ArrayLength<u32>> {
    zero: Vec<ZeroNode<M>>,
}

struct ZeroNode<N: ArrayLength<u32>> {
    neighbors: GenericArray<u32, N>,
}

impl<M: ArrayLength<u32>> HNSW<M> {
    pub fn insert(&mut self) {
        self.zero.push(ZeroNode {
            neighbors: [!0; M::USIZE].into(),
        });
    }
}

ArrayLength has a required bound Unsigned from typenum which has an associated const USIZE. Therefore, the ArrayLength trait bound should work. The compiler adds this comment:

   Compiling playground v0.0.1 (/playground)
error[E0599]: no associated item named `USIZE` found for type `M` in the current scope
  --> src/lib.rs:14:32
   |
14 |             neighbors: [!0; M::USIZE].into(),
   |                                ^^^^^ associated item not found in `M`
   |
   = help: items from traits can only be used if the trait is implemented and in scope
   = note: the following trait defines an item `USIZE`, perhaps you need to implement it:
           candidate #1: `typenum::marker_traits::Unsigned`

If I do what it says, it gives the exact same issue (playground link).

I then attempted to be clever and force the compiler to do the right thing (playground link):

<M as typenum::marker_traits::Unsigned>::USIZE:

error[E0277]: the trait bound `M: typenum::marker_traits::Unsigned` is not satisfied
  --> src/lib.rs:15:29
   |
15 |             neighbors: [!0; <M as typenum::marker_traits::Unsigned>::USIZE].into(),
   |                             ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `typenum::marker_traits::Unsigned` is not implemented for `M`
   |
   = help: consider adding a `where M: typenum::marker_traits::Unsigned` bound
   = note: required by `typenum::marker_traits::Unsigned::USIZE`

It seems that, even when the trait is specifically required to be implemented, it still isn't implemented. This behavior is highly erroneous.

In the meantime, if anyone knows temporary workarounds for this issue, I would appreciate that. I am using this in this crate.

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-lazy-normalizationArea: Lazy normalization (tracking issue: #60471)T-compilerRelevant to the compiler team, which will review and decide on the PR/issue.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions