Skip to content

Regression in consteval: error[E0080]: could not evaluate static initializer (unable to turn pointer into raw bytes) #99923

Closed
@Manishearth

Description

@Manishearth

Unfortunately I'm not able to come up with a minimal working example for this, but running cargo check -p icu_datetime --examples on https://github.com/unicode-org/icu4x (commit unicode-org/icu4x@021a92e should be fine)

ends up throwing a ton of errors that look like this:

    Checking icu_testdata v0.6.0 (/home/manishearth/dev/icu4x/provider/testdata)
error[E0080]: could not evaluate static initializer
   --> /home/manishearth/dev/icu4x/utils/zerovec/src/zerovec/mod.rs:260:14
    |
260 |           let (data, mut metadata): (usize, usize) = core::mem::transmute(bytes);
    |                ^^^^
    |                |
    |                unable to turn pointer into raw bytes
    |                inside `ZeroVec::<(EraStartDate, tinystr::ascii::TinyAsciiStr<16>)>::from_bytes_unchecked` at /home/manishearth/dev/icu4x/utils/zerovec/src/zerovec/mod.rs:260:14
    |
   ::: /home/manishearth/dev/icu4x/provider/testdata/data/baked/calendar/japanese_v1_u_ca.rs:11:9
    |
11  | /         ::zerovec::ZeroVec::from_bytes_unchecked(&[
12  | |             76u8, 7u8, 0u8, 0u8, 9u8, 8u8, 109u8, 101u8, 105u8, 106u8, 105u8, 0u8, 0u8, 0u8, 0u8,
13  | |             0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 120u8, 7u8, 0u8, 0u8, 7u8, 30u8, 116u8, 97u8, 105u8,
14  | |             115u8, 104u8, 111u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 0u8, 134u8, 7u8, 0u8,
...   |
19  | |             0u8, 0u8,
20  | |         ])
    | |__________- inside `japanese_v1_u_ca::UND_U_CA_JAPANESE` at /home/manishearth/dev/icu4x/provider/testdata/data/baked/calendar/japanese_v1_u_ca.rs:11:9

(full errors; they're long since the "baked" stuff is a bunch of internationalization data that has been "serialized" to Rust code using https://docs.rs/databake)

We have a lot of consteval using unsafe code, which is what's tripping up here. The code that's breaking is code that's currently manually constructing a DST of &[T::ULE] from &[u8], and in a const environment that requires some pointer manipulation:

    pub const unsafe fn from_bytes_unchecked(bytes: &'a [u8]) -> Self {
        // &[u8] and &[T::ULE] are the same slice with different length metadata.
        let (data, mut metadata): (usize, usize) = core::mem::transmute(bytes);
        metadata /= core::mem::size_of::<T::ULE>();
        Self::Borrowed(core::mem::transmute((data, metadata)))
    }

Bisecting the regression points to #97684 (cc @oli-obk, @RalfJung), which seems to be about integer provenance. The code here isn't ideal; there are slightly better ways to do this but nothing is const, so this is what we've got.

Either way, this is a regression.

Bisection:

searched nightlies: from nightly-2022-06-01 to nightly-2022-06-30
regressed nightly: nightly-2022-06-07
searched commit range: fee3a45...50b0025
regressed commit: 9d20fd1

bisected with cargo-bisect-rustc v0.6.3

Host triple: x86_64-unknown-linux-gnu
Reproduce with:

cargo bisect-rustc --start=2022-06-01 --end=2022-06-30 --script=./test.sh 

Metadata

Metadata

Assignees

No one assigned

    Labels

    A-const-evalArea: Constant evaluation, covers all const contexts (static, const fn, ...)P-criticalCritical priorityT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.regression-from-stable-to-betaPerformance or correctness regression from stable to beta.

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions