Skip to content

Error reporting bug with const_generics and const_evaluatable_checked #82959

@AuroransSolis

Description

@AuroransSolis

Issue three of three I'll be filing tonight.

This is the code that causes the bug:

#![feature(const_generics, const_evaluatable_checked, array_map)]

pub struct ConstCheck<const CHECK: bool>;

pub trait True {}
impl True for ConstCheck<true> {}

pub trait OrdesDec {
    type Newlen;
    type Output;

    fn pop(self) -> (Self::Newlen, Self::Output);
}

impl<T, const N: usize> OrdesDec for [T; N]
where
    ConstCheck<{N > 1}>: True,
    ConstCheck<{N - 1 != 0}>: True,
{
    type Newlen = [T; N - 1];
    type Output = T;

    fn pop(self) -> (Self::Newlen, Self::Output) {
        let mut iter = IntoIter::new(self);
        let end = iter.next_back().unwrap();
        let new = [(); N - 1].map(move |()| iter.next().unwrap());
        (new, end)
    }
}

I don't remember why I tried this, but I did. And the error messages I got on it were wild:

error[E0283]: type annotations needed
  --> src/nightly_arr.rs:24:28
   |
6  | pub trait True {}
   | -------------- required by this bound in `True`
...
24 |     ConstCheck<{ N > 1 }>: True,
   |                            ^^^^ cannot infer type for struct `ConstCheck<{ N > 1 }>`
   |
   = note: cannot satisfy `ConstCheck<{ N > 1 }>: True`

error[E0283]: type annotations needed
  --> src/nightly_arr.rs:28:5
   |
24 |     ConstCheck<{ N > 1 }>: True,
   |                            ---- required by this bound in `nightly_arr::<impl OrdesDec for [T; N]>`
...
28 |     type Newlen = [T; N - 1];
   |     ^^^^^^^^^^^^^^^^^^^^^^^^^ cannot infer type for struct `ConstCheck<{ N > 1 }>`
   |
   = note: cannot satisfy `ConstCheck<{ N > 1 }>: True`
help: consider specifying the type arguments in the function call
   |
28 |     type Newlen = [T; N - 1];::<T, N>
   |                              ^^^^^^^^

error[E0283]: type annotations needed
  --> src/nightly_arr.rs:31:5
   |
31 | /     fn pop(self) -> (Self::Newlen, Self::Output) {
32 | |         let mut iter = IntoIter::new(self);
33 | |         let end = iter.next_back().unwrap();
34 | |         let new = [(); N - 1].map(move |()| iter.next().unwrap());
35 | |         (new, end)
36 | |     }
   | |_____^ cannot infer type for struct `ConstCheck<{ N > 1 }>`
   |
   = note: cannot satisfy `ConstCheck<{ N > 1 }>: True`
   = note: required because of the requirements on the impl of `OrdesDec` for `[T; N]`

error: aborting due to 3 previous errors

Now you're probably thinking to yourself, "Hey Auro, isn't that exactly the same code as in #82956? Oh, and #82957? And isn't it silly to pull the same dumb gag twice?" To answer the last question: yes, definitely. To answer the other two: no, not quite. Check out the constraints on the OrdesDec impl: [T; N - 1]: Sized has been swapped out for ConstCheck<{N - 1 != 0}>: True. I don't even know what's going on in those error messages, if I'm honest. They confuse me.

Meta

rustc --version --verbose:

rustc 1.52.0-nightly (35dbef235 2021-03-02)
binary: rustc
commit-hash: 35dbef235048f9a2939dc20effe083ca483c37ff
commit-date: 2021-03-02
host: x86_64-unknown-linux-gnu
release: 1.52.0-nightly
LLVM version: 11.0.1

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-const-genericsArea: const generics (parameters and arguments)C-bugCategory: This is a bug.F-generic_const_exprs`#![feature(generic_const_exprs)]`

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions