Pre-RFC: Unsafe reasons

How does this proposal handle situations where the unsafe code is relying on the well-formedness of a complex data structure? For example, here is some FFI code I just wrote...

    unsafe {
        use shim::{UAPIStruct, STRUCTS};
        let mut map = HashMap::new();
        for UAPIStruct { name, align, size, fields, } in &STRUCTS
        {
            let name = CStr::from_ptr(*name);
            let name = name.to_str().expect("struct tag name not valid UTF-8");
            let mut rfields = Vec::new();
            for i in 0.. {
                let field = fields.offset(i).read();
                if field.name.is_null() {
                    break;
                }
                let fname = CStr::from_ptr(field.name);
                let fname = fname.to_str().expect("field name not valid UTF-8");
                rfields.push(Field {
                    name: fname,
                    size: field.size,
                    offset: field.offset,
                });
            }
            map.insert(name, Struct { size, align, fields: rfields })
        }
        map
    }

where STRUCTS is static data generated by compiling a C module. The safety requirements for this code are

  • the definitions of UAPIStruct and its daughter struct UAPIField (the type of fields) must agree with the matching definitions on the C side of the fence
  • On the Rust side STRUCTS is declared as static STRUCTS: [UAPIStruct; n]; n must be accurate
  • all the pointer dereferences need to be valid
  • all the pointers passed to CStr::from_ptr must be valid C strings
  • there must actually be a null pointer terminator for each fields array
  • probably some other stuff I forgot

How much of this can be captured in your proposal and how would it be written? I can provide more fragments if it will help.