Stream: general

Topic: generic array map


gnzlbg (Sep 17 2019 at 12:21, on Zulip):

@oli

#![feature(const_fn)]
#![feature(const_generics)]
#![feature(untagged_unions)]
#![feature(const_fn_union)]
#![allow(incomplete_features)]

struct A<T, const N: usize>([T; N]);

#[derive(Copy,Clone)]
struct Bool(u8);

const fn bool_to_Bool(x: bool) -> Bool { Bool(x as u8) }
const fn u8_to_u8(x: u8) -> u8 { x }

trait Foo {
    type Input;
    const M: fn(Self::Input) -> Self;
}

impl Foo for Bool {
    type Input = bool;
    const M: fn(Self::Input) -> Self = bool_to_Bool;
}

impl Foo for u8 {
    type Input = u8;
    const M: fn(Self::Input) -> Self = u8_to_u8;
}

const MAX_ELEMS: usize = 10;
union U<T, const M: usize> {
    elements: [T; MAX_ELEMS],
    other: [T; M],
}

impl<T: Foo + Copy, const N: usize> A<T, {N}> {
    const fn splat(x: T::Input) -> Self {
        A(U::<T, {N}> { elements: [T::M(x); MAX_ELEMS] }.other)
    }
}

const U8x4: A<u8, 4> = A::splat(0);
const B8x4: A<Bool, 4> = A::splat(true);
gnzlbg (Sep 17 2019 at 12:22, on Zulip):

A couple of issues:

gnzlbg (Sep 17 2019 at 12:22, on Zulip):

error: function pointers are not allowed in const fn

oli (Sep 17 2019 at 12:22, on Zulip):

https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=24a31b93faa5a1b39e24100d0bb83758

gnzlbg (Sep 17 2019 at 12:22, on Zulip):

error: internal compiler error: src/librustc/ich/impls_ty.rs:209: ty::TyKind::hash_stable() - can't hash a TyVid _#1t.

oli (Sep 17 2019 at 12:23, on Zulip):

that error will disappear with -Zunleash-the-miri-inside-of-you

oli (Sep 17 2019 at 12:23, on Zulip):

O_o

gnzlbg (Sep 17 2019 at 12:23, on Zulip):

And if I don't do the weird union transmute thing, but instead try to create an array directly, I get another error saying that I can't create an array using const parameters

oli (Sep 17 2019 at 12:23, on Zulip):

the ICE I have no idea about, probably const generics

gnzlbg (Sep 17 2019 at 12:24, on Zulip):

I'm using -Zunleash-the-miri-inside-of-you, the error with function pointers appears :/

gnzlbg (Sep 17 2019 at 12:24, on Zulip):

Am I writing the option correctly?

gnzlbg (Sep 17 2019 at 12:24, on Zulip):

I see the "skipping const checks warnings"

oli (Sep 17 2019 at 12:24, on Zulip):

did you use #[feature(const_fn)]?

gnzlbg (Sep 17 2019 at 12:24, on Zulip):

yes, at the top

oli (Sep 17 2019 at 12:24, on Zulip):

ok, odd

gnzlbg (Sep 17 2019 at 12:24, on Zulip):

(first feature)

oli (Sep 17 2019 at 12:24, on Zulip):

not sure what's going on then

oli (Sep 17 2019 at 12:25, on Zulip):

const generics are not implemented all the way

oli (Sep 17 2019 at 12:25, on Zulip):

I'm assuming that's the problem

gnzlbg (Sep 17 2019 at 12:25, on Zulip):

I'd like this to work:

#![feature(const_generics)]
#![feature(const_fn)]
#![feature(untagged_unions)]
#![feature(const_fn_union)]
#![allow(incomplete_features)]

struct A<T, const N: usize>([T; N]);

#[derive(Copy,Clone)]
struct Bool(u8);

const fn bool_to_Bool(x: bool) -> Bool { Bool(x as u8) }
const fn u8_to_u8(x: u8) -> u8 { x }

trait Foo {
    type Input;
    const M: fn(Self::Input) -> Self;
}

impl Foo for Bool {
    type Input = bool;
    const M: fn(Self::Input) -> Self = bool_to_Bool;
}

impl Foo for u8 {
    type Input = u8;
    const M: fn(Self::Input) -> Self = u8_to_u8;
}

impl<T: Foo + Copy, const N: usize> A<T, {N}> {
    const fn splat(x: T::Input) -> Self {
        A([T::M(x); {N}])
    }
}

const U8x4: A<u8, 4> = A::splat(0);
const B8x4: A<Bool, 4> = A::splat(true);
gnzlbg (Sep 17 2019 at 12:25, on Zulip):

(that is, without the weird union transmute thing)

gnzlbg (Sep 17 2019 at 12:26, on Zulip):

All my other APIs work, but I essentially need to create a [T; MAX_LEN] externally, and use an union to access the [T; N] sub-array..

gnzlbg (Sep 17 2019 at 12:26, on Zulip):

for some reason that works, but creating the [T; N] array directly does not :D

oli (Sep 17 2019 at 12:31, on Zulip):

Huh, I thought that was supposed to work, or is it only for types not for repeat expressions?

oli (Sep 17 2019 at 12:32, on Zulip):

hmm, apparently not: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=c21ec1c19653beee9444c0e0426a4e23

gnzlbg (Sep 17 2019 at 12:58, on Zulip):

It would be good to have nightly features that allow using these in array lengths

gnzlbg (Sep 17 2019 at 12:59, on Zulip):

and also one that allows using function pointers in const fn

gnzlbg (Sep 17 2019 at 12:59, on Zulip):

That would allow playing with these

oli (Sep 17 2019 at 12:59, on Zulip):

It would be good to have nightly features that allow using these in array lengths

that's like saying it would be good to have a nightly feature for $insert_your_favourite_unimplemented_feature

oli (Sep 17 2019 at 13:00, on Zulip):

it's not implemented

oli (Sep 17 2019 at 13:00, on Zulip):

the nice error message is just there to prevent ICEs

oli (Sep 17 2019 at 13:00, on Zulip):

you can't play with it ;)

oli (Sep 17 2019 at 13:00, on Zulip):

there's no implemented feature to play with

gnzlbg (Sep 17 2019 at 13:00, on Zulip):

I see, I thought miri supported function pointer calls

gnzlbg (Sep 17 2019 at 13:00, on Zulip):

and that this was just a check preventing them

gnzlbg (Sep 17 2019 at 13:00, on Zulip):

not that such support for function pointer calls would need to be implemented

gnzlbg (Sep 17 2019 at 13:01, on Zulip):

(there are workarounds for the array stuff)

oli (Sep 17 2019 at 13:01, on Zulip):

oh... -Zunleash-the-miri-inside-of-you actually is that support

oli (Sep 17 2019 at 13:01, on Zulip):

it's just not working right :D

oli (Sep 17 2019 at 13:01, on Zulip):

feel free to fix it

oli (Sep 17 2019 at 13:02, on Zulip):

follow the error message and wrap that in the appropriate check as seen elsewhere in the file

gnzlbg (Sep 17 2019 at 13:03, on Zulip):

also this works: https://play.rust-lang.org/?version=nightly&mode=debug&edition=2018&gist=cfdb78fc16f375e8fb013c29aa299c25

gnzlbg (Sep 17 2019 at 13:03, on Zulip):

I'm not really sure how that works, but the other code does not :D

gnzlbg (Sep 17 2019 at 13:04, on Zulip):
union ConstFnArray<T, const N: usize> {
    input: [T; usize::max_value()],
    output: [T; N]
}
gnzlbg (Sep 17 2019 at 13:05, on Zulip):

Now you can create arrays inside const fn as follows ConstFnArray { input [val; _] }.output }

gnzlbg (Sep 17 2019 at 13:06, on Zulip):

The type and length of ConstFnArray::output are properly deduced, so that must already work somehow :D

oli (Sep 17 2019 at 13:08, on Zulip):

it works for types

oli (Sep 17 2019 at 13:08, on Zulip):

just not for the repeat expression

gnzlbg (Sep 17 2019 at 13:14, on Zulip):

ah I see

gnzlbg (Sep 17 2019 at 13:15, on Zulip):

I'll try to find out what's special about repeat expressions there, and see if I can add a feature gate to enable that

Last update: Nov 20 2019 at 11:45UTC