Type validation failed: encountered 0 at .v.buf.ptr,


#1

внимание! пример чисто синтетический!

посмотреть

#![feature(const_vec_new)]
#![feature(const_transmute)]
use std::mem::transmute;

pub struct S {
    pub v: Vec<i32>,
}

unsafe impl std::marker::Sync for S {}

static dd: S = S { v: Vec::new() }; //OK

static ch: [u8; ::std::mem::size_of::<S>()] = unsafe { transmute([0u8; ::std::mem::size_of::<S>()]) }; //OK

//static ch2: S = unsafe { transmute(ch) }; // ?????

pub fn getS() -> S { unsafe { transmute(ch) } }//OK

fn main() {
    let ee: S = getS();
    let ddd = ee.v.capacity();
    let fff = ee.v.len();
    println!("{}", ddd);
    println!("{}", fff)
}

если раскомментировать строку получим ошибку…

error[E0080]: this static likely exhibits undefined behavior
  --> src/main.rs:14:1
   |
14 | static ch2: S = unsafe { transmute(ch) };
   | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ type validation failed: encountered 0 at .v.buf.ptr, but expected something greater or equal to 1
   |
   = note: The rules on what exactly is undefined behavior aren't clear, so this check might be overzealous. Please open an issue on the rust compiler repository if you believe it should not be considered undefined behavior

не критично, но…
хотелось бы иметь простое статическое поле.


понятно. разобрался
ну не нравится ей что .v.buf.ptr, == 0…
да не вопрос.
подсунул массив заполненный единицами

[1u8; ::std::mem::size_of::<S>()]

съело.
мдяяяя… оно при компиляции проверяет чтобы указатели статических полей небыли равны нулю (null).

впечатляет.

полюбопытствовал чему пойнтер пустого статического вектора равен

static dd: S = S { v: Vec::new() };

Unique::empty()

а вот в рантайме всё можно


#2

Хоть пример и синтетический, но и правда выглядит как нарушение инвариантов языка, т.е. UB.

https://github.com/rust-lang/rust/issues/53605 тоже не то что бы сильно законченным кажется, может еще в этом дело.


#3

объяснение добавил выше. не стал делать отдельно

capacity() == 72340172838076673 :sunglasses: