Stream: t-compiler/const-eval

Topic: const generics


RalfJ (Jul 13 2019 at 08:10, on Zulip):

using const generics broke miri for some array stuff, we likely need to do something to monomorphize them or so? No idea what and how though. See https://github.com/rust-lang/rust/pull/62435#issuecomment-511100890.
@oli I think I need your help for this.

oli (Jul 13 2019 at 08:11, on Zulip):

Uh. I was hoping that would be transparent for us. I thought these were fixes in the engine.

oli (Jul 13 2019 at 08:11, on Zulip):

Are you by any chance getting an ICE?

oli (Jul 13 2019 at 08:12, on Zulip):

Ah no

oli (Jul 13 2019 at 08:12, on Zulip):

They are just bailing outnow

oli (Jul 13 2019 at 08:13, on Zulip):

I thought i left some comments to not just bail out

oli (Jul 13 2019 at 08:13, on Zulip):

Oh well

oli (Jul 13 2019 at 08:14, on Zulip):

I wonder why monomorphization doesn't catch this

oli (Jul 13 2019 at 08:14, on Zulip):

We may nees to replicate some codegen changes from that PR in the engine

oli (Jul 13 2019 at 08:15, on Zulip):

I'll try to find some time next week

RalfJ (Jul 13 2019 at 08:16, on Zulip):

the error is

error[E0080]: Miri evaluation error: encountered overly generic constant
   --> /home/r/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/array.rs:337:16
    |
337 |             if slice.len() == N {
    |                ^^^^^^^^^^^^^^^^ Miri evaluation error: encountered overly generic constant
    |
note: inside call to `std::array::impls_using_const_generics::<impl std::convert::TryFrom<&[u8]> for &[u8; 0]>::try_from` at core_miri_test/../libcore/tests/array.rs:31:30
   --> core_miri_test/../libcore/tests/array.rs:31:30
    |
31  |                   let result = <&Array>::try_from(slice);
    |                                ^^^^^^^^^^^^^^^^^^^^^^^^^
...
36  | /     test! {
37  | |          0  1  2  3  4  5  6  7  8  9
38  | |         10 11 12 13 14 15 16 17 18 19
39  | |         20 21 22 23 24 25 26 27 28 29
40  | |         30 31 32
41  | |     }
    | |_____- in this macro invocation
note: inside call to `array::array_try_from` at core_miri_test/../libcore/tests/array.rs:23:1
   --> core_miri_test/../libcore/tests/array.rs:23:1
    |
23  | / fn array_try_from() {
24  | |     macro_rules! test {
25  | |         ($($N:expr)+) => {
26  | |             $({
...   |
41  | |     }
42  | | }
    | |_^
    = note: inside call to closure at /home/r/.rustup/toolchains/nightly-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/src/libcore/ops/function.rs:231:5
RalfJ (Jul 13 2019 at 08:17, on Zulip):

We may nees to replicate some codegen changes from that PR in the engine

hm ideally we'd share that code?^^

RalfJ (Jul 13 2019 at 08:17, on Zulip):

I'll try to find some time next week

great! it seems to only concern try_from so far so it's not high priority

RalfJ (Jul 13 2019 at 08:18, on Zulip):

hm no there are also other methods

RalfJ (Jul 13 2019 at 08:18, on Zulip):

but none of them are used by the libcore test suite :D

RalfJ (Jul 13 2019 at 08:23, on Zulip):

or maybe they do... but interestingly, other methods seem to work fine

oli (Jul 13 2019 at 08:36, on Zulip):

It may becalling generic methods from generic methods

RalfJ (Jul 13 2019 at 08:53, on Zulip):

what sets it apart from the others is that it uses the const generic N in the body of the code

oli (Jul 13 2019 at 09:05, on Zulip):

Heh, that would make a difference

oli (Jul 13 2019 at 09:13, on Zulip):

Where does the const generic come from

oli (Jul 13 2019 at 09:13, on Zulip):

A local variable's type?

oli (Jul 13 2019 at 09:25, on Zulip):

Ah no, it's using it literally

oli (Jul 13 2019 at 09:25, on Zulip):

Yea we aren't monomorphizing constants yet

RalfJ (Jul 13 2019 at 09:25, on Zulip):
    impl<'a, T, const N: usize> TryFrom<&'a mut [T]> for &'a mut [T; N]
    where
        [T; N]: LengthAtMost32,
    {
        type Error = TryFromSliceError;

        fn try_from(slice: &mut [T]) -> Result<&mut [T; N], TryFromSliceError> {
            if slice.len() == N { // <-- const generic used HERE
                let ptr = slice.as_mut_ptr() as *mut [T; N];
                unsafe { Ok(&mut *ptr) }
            } else {
                Err(TryFromSliceError(()))
            }
        }
    }
oli (Jul 13 2019 at 09:26, on Zulip):

Wherever we get a ty::Const out of the MIR we need to feed it through self.monomorphize

oli (Jul 13 2019 at 09:26, on Zulip):

That should be all that is needed

RalfJ (Jul 13 2019 at 09:26, on Zulip):

really? I can try that or are you on it?

oli (Jul 13 2019 at 09:34, on Zulip):

I am in an airport, so not on it ^^

oli (Jul 13 2019 at 09:36, on Zulip):

May be more efficient to just do it on the ConstValue in the very end

oli (Jul 13 2019 at 09:36, on Zulip):

So we don't intern the monomorphization result

RalfJ (Jul 13 2019 at 09:53, on Zulip):

not sure what you mean, this errors out very early

RalfJ (Jul 13 2019 at 09:53, on Zulip):

so we kind of have to monomorphize early

oli (Jul 13 2019 at 10:01, on Zulip):

We could monomorphize right before that match that errors out

oli (Jul 13 2019 at 10:02, on Zulip):

And match on the result of the monomorphization

RalfJ (Jul 13 2019 at 10:02, on Zulip):

yes that's what I am doing

oli (Jul 13 2019 at 10:02, on Zulip):

I only have a vague memory of the relevant code

RalfJ (Jul 13 2019 at 10:02, on Zulip):

not sure what other option you had in mind

RalfJ (Jul 13 2019 at 10:02, on Zulip):

okay :)

oli (Jul 13 2019 at 10:02, on Zulip):

Oh xD

oli (Jul 13 2019 at 10:02, on Zulip):

Perfect then

oli (Jul 13 2019 at 10:03, on Zulip):

You should be able to write const eval regression tests (if your changes don't cause existing tests to pass)

oli (Jul 13 2019 at 10:04, on Zulip):

cc @varkor

RalfJ (Jul 13 2019 at 10:08, on Zulip):

ah, I added a test to Miri but I never know how to fit those into the CTFE restrictions^^

oli (Jul 13 2019 at 10:11, on Zulip):

worst case you can use the const_fn feature gate

oli (Jul 13 2019 at 10:12, on Zulip):

a generic const function that returns its generic parameter as a runtime value should be enough

oli (Jul 13 2019 at 10:12, on Zulip):

(well, and calling it in a const context)

RalfJ (Jul 13 2019 at 10:12, on Zulip):

okay

RalfJ (Jul 13 2019 at 10:59, on Zulip):

@oli uh, that monomorphize leads to ICEs...

error: internal compiler error: src/librustc/ty/subst.rs:557: type parameter `Self/#0` (Self/0) out of range when substituting (root type=Some(<Self as float::Float>::Int)) substs=[]

thread 'rustc' panicked at 'Box<Any>', src/librustc_errors/lib.rs:584:9
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace.
error: aborting due to previous error
oli (Jul 13 2019 at 11:00, on Zulip):

Hmm i've seen that before

oli (Jul 13 2019 at 11:00, on Zulip):

I have a PR working on it

oli (Jul 13 2019 at 11:00, on Zulip):

We are doing monomorphizations the wrong way iirc

oli (Jul 13 2019 at 11:01, on Zulip):

Like we take the wrong substs

RalfJ (Jul 13 2019 at 11:03, on Zulip):

is that https://github.com/rust-lang/rust/pull/61041?

oli (Jul 13 2019 at 14:22, on Zulip):

Jop

Last update: Nov 15 2019 at 20:05UTC