Skip to content

Impls are not resolved correctly when using generic const expressions #112341

Open
@wdanilo

Description

@wdanilo

Hi, consider the following code (live version here), which basically implements heterogeneous lists:

#![feature(generic_const_exprs)]
#![feature(auto_traits)]
#![feature(negative_impls)]
#![feature(trait_alias)]


// =============
// === HList ===
// =============

pub struct Nil;
pub struct Cons<Head, Tail>(pub Head, pub Tail);


// ===============
// === NotZero ===
// ===============

struct PhantomConstUsize<const N: usize>;
auto trait NotZeroCheck {}
impl !NotZeroCheck for PhantomConstUsize<0> {}
trait NotZero<const N: usize> = where PhantomConstUsize<N>: NotZeroCheck;


// ==================
// === FieldIndex ===
// ==================

pub trait FieldIndex<const I: usize> {
    type Type;
}

impl<H, T> FieldIndex<0> for Cons<H, T> {
    type Type = H;
}

impl<H, T, const N: usize> FieldIndex<N> for Cons<H, T>
where
    (): NotZero<N>,
    T: FieldIndex<{ N - 1 }>,
{
    type Type = <T as FieldIndex<{ N - 1 }>>::Type;
}

pub type FieldAt<const I: usize, T> = <T as FieldIndex<I>>::Type;


// =============
// === Tests ===
// =============

type Test0 = FieldAt<0, Cons<usize, Cons<usize, Cons<usize, Nil>>>>;
type Test1 = FieldAt<1, Cons<usize, Cons<usize, Cons<usize, Nil>>>>;
type Test2 = FieldAt<2, Cons<usize, Cons<usize, Cons<usize, Nil>>>>;

fn main() {
    let t0: Test0 = 1; // WORKS OK
    let t1: Test1 = 1; // WORKS OK
    // let t2: Test2 = 1; // DOES NOT WORK
}

After uncommenting the last line we got an error:

the trait bound `Cons<usize, Cons<usize, Nil>>: FieldIndex<{ N - 1 }>` is not satisfied

Which is incorrect. Please note, that Rust was able to resolve it for N=0 and N=1, but not for N=2.

Another bug is that if we reverse the order of these lines:

    (): NotZero<N>,
    T: FieldIndex<{ N - 1 }>,

The code does not compile either.

Metadata

Metadata

Assignees

No one assigned

    Labels

    C-bugCategory: This is a bug.F-generic_const_exprs`#![feature(generic_const_exprs)]`F-negative_impls#![feature(negative_impls)]requires-incomplete-featuresThis issue requires the use of incomplete features.requires-nightlyThis issue requires a nightly compiler in some way.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions