Why does sty::TyKind::Array have Unresolved const when given a literal length?

Example code:

struct The { array: [u8; 1] }

When accessing field.ty(tcx, substs) of The::array, the result is

Const {
    ty: usize,
    val: Unevaluated(
        DefId(0:123 ~ path[0]::{{constant}}[0]),
        [],
    ),
}

which is surprising since the length is provided as a literal. I'm sure there's a good reason for this, but I can't quite figure out what it is! It's especially confusing because Unevaluated is said to be for pre-monomorphization, but the struct isn't even generic.

Note: the context of this is in an after_analysis rustc hook.

Update: if anyone else runs into this issue, the simple workaround is to get the snippet for the span and then parse the length manually. I'd bet a shiny nickel that nobody else will have this issue though :wink:

1 Like

All array sizes start out as "unevaluated". After all, they can be arbitrarily complex CTFE expressions in general. There is no analysis that tries to determine if the constant is "simple enough" (that analysis would basically be yet another const evaluator).

Usually you can call eval_usize on the constant to get its integer value. Not sure if that works in an after_analysis hook already... @oli-obk might know.

3 Likes

Yes, there's a bunch of methods on constants that you can use: https://doc.rust-lang.org/nightly/nightly-rustc/rustc/ty/struct.Const.html

In contrast to parsing the snippet, these have the advantage that they'll work with named constants or even arbitrary expressions.