Rust: New compiler error in beta: this constant cannot be used, attempted to read undefined bytes

Created on 20 Sep 2018  路  11Comments  路  Source: rust-lang/rust

Since latest beta (and nightly), some of my crates have errors like the following

error: this constant cannot be used
  --> src/udpsrc.rs:47:1
   |
47 | const DEFAULT_CAPS: Option<gst::Caps> = None;
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempted to read undefined bytes

A standalone testcase replicating all the involved types can be found below (depends only on the libc crate).

I don't know if the error is valid, but in any case I don't understand what it means so at least the error message could be improved a bit :)

use std::marker;
use std::ptr;

extern crate libc;
use libc::{c_int, c_uint, c_void, size_t};

#[repr(C)]
pub struct CapsRef(ffi::GstCaps);

pub type Caps = GstRc<CapsRef>;

pub trait MiniObject {}
impl MiniObject for CapsRef {}

pub struct GstRc<T: MiniObject> {
    obj: ptr::NonNull<T>,
    borrowed: bool,
    phantom: marker::PhantomData<T>,
}

mod ffi {
    use super::*;

    #[repr(C)]
    #[derive(Copy, Clone)]
    pub struct GstCaps {
        pub mini_object: GstMiniObject,
    }

    #[repr(C)]
    #[derive(Copy, Clone)]
    pub struct GstMiniObject {
        pub type_: GType,
        pub refcount: c_int,
        pub lockstate: c_int,
        pub flags: c_uint,
        pub copy: GstMiniObjectCopyFunction,
        pub dispose: GstMiniObjectDisposeFunction,
        pub free: GstMiniObjectFreeFunction,
        pub n_qdata: c_uint,
        pub qdata: gpointer,
    }

    pub type GstMiniObjectCopyFunction =
        Option<unsafe extern "C" fn(*const GstMiniObject) -> *mut GstMiniObject>;
    pub type GstMiniObjectDisposeFunction =
        Option<unsafe extern "C" fn(*mut GstMiniObject) -> gboolean>;
    pub type GstMiniObjectFreeFunction = Option<unsafe extern "C" fn(*mut GstMiniObject)>;

    pub type gboolean = c_int;

    pub type GType = size_t;

    pub type gpointer = *mut c_void;

}

const FOO: Option<Caps> = None;

fn main() {
    let _meh = FOO;
}
A-const-eval P-high T-compiler regression-from-stable-to-beta

Most helpful comment

Minimized:

pub struct GstRc {
    _obj: *const (),
    _borrowed: bool,
}

const FOO: Option<GstRc> = None;

fn main() {
    let _meh = FOO;
}

All 11 comments

the testcase compiles with stable-1.29.0.

Minimized:

pub struct GstRc {
    _obj: *const (),
    _borrowed: bool,
}

const FOO: Option<GstRc> = None;

fn main() {
    let _meh = FOO;
}

Visited during T-compiler meeting. Tentatively assigning to @eddyb for investigation.

cc @RalfJung @oli-obk I can't find anything in the validation code that's reading the wrong thing - it should be able to tell this is a None, which has 0 fields.

I've been looking into this. It seems that the issue stems from here. Specifically, because the niche-filling enum representation is used for Option<GstRc> and similar types, and the niche that gets filled is the second field (the bool), it is actually the second part of the ScalarPair that is defined, not the first.

Ahh, you're right! I don't know why only the second component was special-cased.

Seems like @oli-obk's quest to keep Undef contained within the CTFE engine failed at last. :/

However, in this case nothing should even be trying to convert to a ConstValue. So I am not sure if that's really the problem.

Actually it looks like this is not a ScalarPair, but a Scalar being undef. At least that's what the line numbers are saying. It does not make much sense though.

EDIT: It is definitely a ScalarPair, just the line numbers seem to be wrong.

I am working on a fix.

EDIT: Submitted as https://github.com/rust-lang/rust/pull/54693

Should this be closed before we get a beta backport?

Backported to beta. Closing this.

Was this page helpful?
0 / 5 - 0 ratings