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

unsatisfied trait bound uses _ for unevaluated constants #82934

Closed
shepmaster opened this issue Mar 9, 2021 · 3 comments
Closed

unsatisfied trait bound uses _ for unevaluated constants #82934

shepmaster opened this issue Mar 9, 2021 · 3 comments
Labels
A-const-generics Area: const generics (parameters and arguments) A-diagnostics Area: Messages for errors, warnings, and lints const-generics-bad-diagnostics An error is correctly emitted, but is confusing, for `min_const_generics`. F-generic_const_exprs `#![feature(generic_const_exprs)]` T-compiler Relevant to the compiler team, which will review and decide on the PR/issue.

Comments

@shepmaster
Copy link
Member

Given the following code:

#![allow(incomplete_features)]
#![feature(const_generics, const_evaluatable_checked)]

use arrayvec::ArrayVec; // 0.5.2

fn append<T, const N: usize>(start: [T; N], v: T) -> [T; N + 1] {
    let xs = ArrayVec::new();
    for _ in 0..N {
        xs.push(v);
    }
    xs.push(v);
    match xs.into_inner() {
        Ok(xs) => xs,
        _ => unreachable!()
    }
}

The current output is:

error[E0283]: type annotations needed for `ArrayVec<[T; _]>`
 --> src/lib.rs:7:14
  |
7 |     let xs = ArrayVec::new();
  |         --   ^^^^^^^^^^^^^ cannot infer type for array `[T; _]`
  |         |
  |         consider giving `xs` the explicit type `ArrayVec<[T; _]>`, where the type parameter `[T; _]` is specified
  |
  = note: cannot satisfy `[T; _]: Array`
  = note: required by `ArrayVec::<A>::new`

Ideally the output should:

  1. Not tell me to add a type when that's not the real problem.
  2. Not tell me to add a type after I add one and it doesn't solve the problem.
  3. Focus on the fact that the trait bound isn't satisfied for arbitrary N.
  • 1.52.0-nightly (2021-03-07 234781a)
@shepmaster shepmaster added A-diagnostics Area: Messages for errors, warnings, and lints T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. A-const-generics Area: const generics (parameters and arguments) F-const_generics `#![feature(const_generics)]` F-generic_const_exprs `#![feature(generic_const_exprs)]` const-generics-bad-diagnostics An error is correctly emitted, but is confusing, for `min_const_generics`. labels Mar 9, 2021
@BoxyUwU BoxyUwU removed the F-const_generics `#![feature(const_generics)]` label Jun 24, 2022
@lcnr
Copy link
Contributor

lcnr commented Jun 24, 2022

new repro

#![allow(incomplete_features)]
#![feature(generic_const_exprs)]

struct ArrayVec<T: Array>(Option<T>);
impl<T: Array> ArrayVec<T> {
    fn new() -> Self {
        Self(None)
    }
    
    fn push(&mut self, v: T::Value) {}
    
    fn into_inner(self) -> Result<T, ()> {
        todo!()
    }
}

trait Array {
    type Value;
}
impl<T> Array for [T; 0] {
    type Value = T;
}
impl<T> Array for [T; 1] {
    type Value = T;
}

fn append<T, const N: usize>(start: [T; N], v: T) -> [T; N + 1] {
    let mut xs = ArrayVec::new();
    for _ in 0..N {
        xs.push(v);
    }
    xs.push(v);
    match xs.into_inner() {
        Ok(xs) => xs,
        _ => unreachable!()
    }
}

Error message is still bad, but at least somewhat sensible now

error[E0277]: the trait bound `[T; _]: Array` is not satisfied
  --> src/lib.rs:33:14
   |
33 |     match xs.into_inner() {
   |              ^^^^^^^^^^ the trait `Array` is not implemented for `[T; _]`
   |
note: required by a bound in `ArrayVec::<T>::into_inner`
  --> src/lib.rs:5:9
   |
5  | impl<T: Array> ArrayVec<T> {
   |         ^^^^^ required by this bound in `ArrayVec::<T>::into_inner`
...
12 |     fn into_inner(self) -> Result<T, ()> {
   |        ---------- required by a bound in this
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
   |
27 | fn append<T, const N: usize>(start: [T; N], v: T) -> [T; N + 1] where [T; _]: Array {
   |                                                                 +++++++++++++++++++

error[E0277]: the trait bound `[T; _]: Array` is not satisfied
  --> src/lib.rs:30:12
   |
30 |         xs.push(v);
   |            ^^^^ the trait `Array` is not implemented for `[T; _]`
   |
note: required by a bound in `ArrayVec::<T>::push`
  --> src/lib.rs:5:9
   |
5  | impl<T: Array> ArrayVec<T> {
   |         ^^^^^ required by this bound in `ArrayVec::<T>::push`
...
10 |     fn push(&mut self, v: T::Value) {}
   |        ---- required by a bound in this
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
   |
27 | fn append<T, const N: usize>(start: [T; N], v: T) -> [T; N + 1] where [T; _]: Array {
   |                                                                 +++++++++++++++++++

error[E0277]: the trait bound `[T; _]: Array` is not satisfied
  --> src/lib.rs:32:8
   |
32 |     xs.push(v);
   |        ^^^^ the trait `Array` is not implemented for `[T; _]`
   |
note: required by a bound in `ArrayVec::<T>::push`
  --> src/lib.rs:5:9
   |
5  | impl<T: Array> ArrayVec<T> {
   |         ^^^^^ required by this bound in `ArrayVec::<T>::push`
...
10 |     fn push(&mut self, v: T::Value) {}
   |        ---- required by a bound in this
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
   |
27 | fn append<T, const N: usize>(start: [T; N], v: T) -> [T; N + 1] where [T; _]: Array {
   |                                                                 +++++++++++++++++++

error[E0277]: the trait bound `[T; _]: Array` is not satisfied
  --> src/lib.rs:28:18
   |
28 |     let mut xs = ArrayVec::new();
   |                  ^^^^^^^^^^^^^ the trait `Array` is not implemented for `[T; _]`
   |
note: required by a bound in `ArrayVec::<T>::new`
  --> src/lib.rs:5:9
   |
5  | impl<T: Array> ArrayVec<T> {
   |         ^^^^^ required by this bound in `ArrayVec::<T>::new`
6  |     fn new() -> Self {
   |        --- required by a bound in this
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
   |
27 | fn append<T, const N: usize>(start: [T; N], v: T) -> [T; N + 1] where [T; _]: Array {
   |                                                                 +++++++++++++++++++

error[E0277]: the trait bound `[T; _]: Array` is not satisfied
  --> src/lib.rs:28:18
   |
28 |     let mut xs = ArrayVec::new();
   |                  ^^^^^^^^ the trait `Array` is not implemented for `[T; _]`
   |
note: required by a bound in `ArrayVec`
  --> src/lib.rs:4:20
   |
4  | struct ArrayVec<T: Array>(Option<T>);
   |                    ^^^^^ required by this bound in `ArrayVec`
help: consider introducing a `where` clause, but there might be an alternative better way to express this requirement
   |
27 | fn append<T, const N: usize>(start: [T; N], v: T) -> [T; N + 1] where [T; _]: Array {
   |                                                                 +++++++++++++++++++                                                                 +++++++++++++++++++

@lcnr
Copy link
Contributor

lcnr commented Jun 24, 2022

We do have to issue that unevaluated constants are printed as _ which is bad™, I think @b-naber has been working on a fix for that, or at least for something related in #90987

Maybe it makes sense to look at that again, but as we are slowly working towards a new const generics implementation, it might also not be worth the effort 😅

@lcnr lcnr changed the title Unmet trait bounds for a const generic return type give "type annotations needed" error instead. unsatisfied trait bound uses _ for unevaluated constants Jun 24, 2022
@BoxyUwU
Copy link
Member

BoxyUwU commented Feb 13, 2023

This seems to be fixed now, I suspect #106873 did it

@BoxyUwU BoxyUwU closed this as completed Feb 13, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-const-generics Area: const generics (parameters and arguments) A-diagnostics Area: Messages for errors, warnings, and lints const-generics-bad-diagnostics An error is correctly emitted, but is confusing, for `min_const_generics`. F-generic_const_exprs `#![feature(generic_const_exprs)]` 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