miri: accept extern types in structs if they are the only field
This commit is contained in:
parent
6d69fe7a2f
commit
e753d21051
@ -371,8 +371,19 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc
|
||||
// the last field). Can't have foreign types here, how would we
|
||||
// adjust alignment and size for them?
|
||||
let field = layout.field(self, layout.fields.count() - 1)?;
|
||||
let (unsized_size, unsized_align) = self.size_and_align_of(metadata, field)?
|
||||
.expect("Fields cannot be extern types");
|
||||
let (unsized_size, unsized_align) = match self.size_and_align_of(metadata, field)? {
|
||||
Some(size_and_align) => size_and_align,
|
||||
None => {
|
||||
// A field with extern type. If this is the only field,
|
||||
// we treat this struct just the same. Else, this is an error
|
||||
// (for now).
|
||||
if layout.fields.count() == 1 {
|
||||
return Ok(None)
|
||||
} else {
|
||||
bug!("Fields cannot be extern types, unless they are the only field")
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// FIXME (#26403, #27023): We should be adding padding
|
||||
// to `sized_size` (to accommodate the `unsized_align`
|
||||
|
@ -354,7 +354,8 @@ where
|
||||
let (meta, offset) = if field_layout.is_unsized() {
|
||||
// re-use parent metadata to determine dynamic field layout
|
||||
let (_, align) = self.size_and_align_of(base.meta, field_layout)?
|
||||
.expect("Fields cannot be extern types");
|
||||
// If this is an extern type, we fall back to its static size and alignment.
|
||||
.unwrap_or_else(|| base.layout.size_and_align());
|
||||
(base.meta, offset.abi_align(align))
|
||||
} else {
|
||||
// base.meta could be present; we might be accessing a sized field of an unsized
|
||||
|
21
src/test/ui/consts/const-eval/issue-55541.rs
Normal file
21
src/test/ui/consts/const-eval/issue-55541.rs
Normal file
@ -0,0 +1,21 @@
|
||||
// compile-pass
|
||||
|
||||
// Test that we can handle newtypes wrapping extern types
|
||||
|
||||
#![feature(extern_types, const_transmute)]
|
||||
|
||||
extern "C" {
|
||||
pub type ExternType;
|
||||
}
|
||||
unsafe impl Sync for ExternType {}
|
||||
|
||||
#[repr(transparent)]
|
||||
pub struct Wrapper(ExternType);
|
||||
|
||||
static MAGIC_FFI_STATIC: u8 = 42;
|
||||
|
||||
pub static MAGIC_FFI_REF: &'static Wrapper = unsafe {
|
||||
std::mem::transmute(&MAGIC_FFI_STATIC)
|
||||
};
|
||||
|
||||
fn main() {}
|
Loading…
x
Reference in New Issue
Block a user