Stream: t-compiler

Topic: unevaluated const in typeck


gnzlbg (Aug 05 2019 at 15:41, on Zulip):

I am trying to call Const.unwrap_usize in typeck chec, but am getting:

error: internal compiler error: src/librustc/ty/sty.rs:2337: expected constant usize, got Const {
    ty: usize,
    val: Unevaluated(
        DefId(0:15 ~ simd_array_type[317d]::S[0]::0[0]::{{constant}}[0]),
        [],
    ),
}

IIUC, the ty is correctly an usize, but the value is not an usize, but Unevaluated instead

gnzlbg (Aug 05 2019 at 15:42, on Zulip):

@oli i'm not sure how to deal with that. Is there a way to evaluate it ?

gnzlbg (Aug 05 2019 at 15:42, on Zulip):

In my case, the value can either be a power of two, or a const generic

oli (Aug 05 2019 at 15:43, on Zulip):

you can't eval a const generic

oli (Aug 05 2019 at 15:43, on Zulip):

unless you substitute the const generic, at which point you're not evaluating a const generic

gnzlbg (Aug 05 2019 at 15:43, on Zulip):

it currently isn't a const generic though

oli (Aug 05 2019 at 15:43, on Zulip):

it's generic, you can't know its value

oli (Aug 05 2019 at 15:43, on Zulip):

hmm

gnzlbg (Aug 05 2019 at 15:44, on Zulip):

currently i have an [i32; 4] array

oli (Aug 05 2019 at 15:44, on Zulip):

so you want me to work on https://github.com/rust-lang/rust/pull/59369 :D

gnzlbg (Aug 05 2019 at 15:44, on Zulip):

:D

gnzlbg (Aug 05 2019 at 15:45, on Zulip):

ok, I think I will skip the check for now

oli (Aug 05 2019 at 18:15, on Zulip):

You can also try to subst and normalize first

oli (Aug 05 2019 at 18:15, on Zulip):

It's hacky but should work until my PR is through

oli (Aug 05 2019 at 18:36, on Zulip):

ok, nevermind, got the PR ready and sent it to bors

oli (Aug 05 2019 at 18:36, on Zulip):

you should be able to rebase over it soonish

gnzlbg (Aug 07 2019 at 14:21, on Zulip):

thanks @oli , it looks like this landed, i'll try it out

oli (Aug 07 2019 at 14:21, on Zulip):

let me know if anything is off

gnzlbg (Aug 07 2019 at 14:22, on Zulip):

I want to support #[repr(simd)] struct Simd<T, const N: usize>([T; N]);

gnzlbg (Aug 07 2019 at 14:22, on Zulip):

so needed that for a piece in layout where simd_size is called

oli (Aug 07 2019 at 14:23, on Zulip):

uh

gnzlbg (Aug 07 2019 at 14:23, on Zulip):
rg 'simd_size\(' src/
src/librustc_codegen_llvm/intrinsic.rs
1095:        let v_len = arg_tys[1].simd_size(tcx);
1110:    let in_len = arg_tys[0].simd_size(tcx);
1125:        let out_len = ret_ty.simd_size(tcx);
1150:        let out_len = ret_ty.simd_size(tcx);
1211:        let v_len = arg_tys[1].simd_size(tcx);
1427:        require!(in_len == arg_tys[1].simd_size(tcx),
1430:                 arg_tys[1].simd_size(tcx));
1431:        require!(in_len == arg_tys[2].simd_size(tcx),
1434:                 arg_tys[2].simd_size(tcx));
1531:        require!(in_len == arg_tys[1].simd_size(tcx),
1534:                 arg_tys[1].simd_size(tcx));
1535:        require!(in_len == arg_tys[2].simd_size(tcx),
1538:                 arg_tys[2].simd_size(tcx));
1758:        let out_len = ret_ty.simd_size(tcx);

src/librustc/ty/sty.rs
1839:    pub fn simd_size(&self, tcx: TyCtxt<'tcx>) -> usize {

src/librustc/ty/layout.rs
697:                let count = ty.simd_size(tcx) as u64;
gnzlbg (Aug 07 2019 at 14:24, on Zulip):

that's everywhere where it is used - in librustc_codegen_llvm the value of N should be known

gnzlbg (Aug 07 2019 at 14:25, on Zulip):

only in librustc/ty/layout.rs we use it in a place where N maybe isn't known, no idea

oli (Aug 07 2019 at 14:25, on Zulip):

yes, but you're doing "the wrong thing"^TM if you're using eval_usize

oli (Aug 07 2019 at 14:25, on Zulip):

you should not touch librustc/ty/layout

oli (Aug 07 2019 at 14:25, on Zulip):

sorry I should have asked what you are trying to solve

gnzlbg (Aug 07 2019 at 14:25, on Zulip):

i'm only touching librustc/ty/sty.rs which is where simd_size is implemented

oli (Aug 07 2019 at 14:26, on Zulip):

just monomorphize arg_tys[1] or whatever type you wanna call simd_size on

gnzlbg (Aug 07 2019 at 14:26, on Zulip):

I think a layout is only computed for monomorphized types

oli (Aug 07 2019 at 14:26, on Zulip):

yea, but you should not touch it I believe

oli (Aug 07 2019 at 14:26, on Zulip):

yes, but your type is not monomorphic

gnzlbg (Aug 07 2019 at 14:26, on Zulip):

I have to touch it, because currently [T; N] isn't supported in repr(simd) types, only tuple structs are

gnzlbg (Aug 07 2019 at 14:27, on Zulip):

and the number of elements of tuple structs is always known, even if they are generic

oli (Aug 07 2019 at 14:27, on Zulip):

oh, you're doing two things

gnzlbg (Aug 07 2019 at 14:27, on Zulip):

so I at least need to patternmatch on elements that are arrays there, and do something about them

oli (Aug 07 2019 at 14:27, on Zulip):

go ahead then

gnzlbg (Aug 07 2019 at 14:27, on Zulip):

ah yes

oli (Aug 07 2019 at 14:27, on Zulip):

but my changes should not have an effect on anything you do

gnzlbg (Aug 07 2019 at 14:27, on Zulip):

so repr(simd) struct X([f32; 4]); is not supported yet either (my branch does)

oli (Aug 07 2019 at 14:28, on Zulip):

you'll still hit the same thing

gnzlbg (Aug 07 2019 at 14:28, on Zulip):

but I wanted to try to make sure that #[repr(simd)] struct X<const N: usize>([f32; N]) works as well

gnzlbg (Aug 07 2019 at 14:28, on Zulip):

yes, I was hitting the same thing with a concrete 4

oli (Aug 07 2019 at 14:28, on Zulip):

do you have a backtrace available?

gnzlbg (Aug 07 2019 at 14:28, on Zulip):

hmm

oli (Aug 07 2019 at 14:28, on Zulip):

I think you forgot a monomorphize call somewhere

gnzlbg (Aug 07 2019 at 14:28, on Zulip):

let me scroll, like a couple of days

oli (Aug 07 2019 at 14:28, on Zulip):

don't try to get concrete 4 working

oli (Aug 07 2019 at 14:29, on Zulip):

just go directly for const generics

gnzlbg (Aug 07 2019 at 14:29, on Zulip):

I worked around this by doing something else

gnzlbg (Aug 07 2019 at 14:29, on Zulip):

I think, by removing the simd_size call

gnzlbg (Aug 07 2019 at 14:29, on Zulip):

there was a stale check in rustc_typeck that checked that N was a power of two

gnzlbg (Aug 07 2019 at 14:30, on Zulip):

I don't think we can check that there if we want to support const generics

oli (Aug 07 2019 at 14:33, on Zulip):

you can check it after monomorphization, but that's a bit bad

oli (Aug 07 2019 at 14:33, on Zulip):

you can also make the generic arg be the power of two that should be used :P

oli (Aug 07 2019 at 14:34, on Zulip):

so 1 for 2 and 2 for 4 and 3 for 8 and so on

oli (Aug 07 2019 at 14:34, on Zulip):

const N: NonZeroUsize :D

gnzlbg (Aug 07 2019 at 14:35, on Zulip):

we have an upper bound on the largest power of two supported problably

gnzlbg (Aug 07 2019 at 14:36, on Zulip):

ok i rebased, and migrated unwrap_usize to eval_usize

gnzlbg (Aug 07 2019 at 14:36, on Zulip):

but i'm now missing a ParamEnv

gnzlbg (Aug 07 2019 at 14:37, on Zulip):

either way, for the time being, we just support all Ns

gnzlbg (Aug 07 2019 at 14:37, on Zulip):

it will be up to libcore to constraint things in meaningful ways

oli (Aug 07 2019 at 14:39, on Zulip):

pass down the param_env as an argument of simd_size

oli (Aug 07 2019 at 14:39, on Zulip):

in llvm you can just do ParamEnv::reveal_all()

oli (Aug 07 2019 at 14:39, on Zulip):

everywhere else you should take the ParamEnv from the surroundings

gnzlbg (Aug 07 2019 at 14:50, on Zulip):

TyS doesn't have a ParamEnv

gnzlbg (Aug 07 2019 at 14:50, on Zulip):

i ended up using ty::ParamEnv::empty()

gnzlbg (Aug 07 2019 at 15:22, on Zulip):

@oli it... just works...

gnzlbg (Aug 07 2019 at 15:23, on Zulip):

is this a good thing ?

oli (Aug 07 2019 at 15:42, on Zulip):

uh

gnzlbg (Aug 07 2019 at 15:58, on Zulip):

ok only the basic tests work, adding more complex tests things start breaking

Last update: Nov 22 2019 at 05:30UTC