mirror of
https://github.com/rust-lang/rust.git
synced 2024-12-12 16:45:37 +00:00
Auto merge of #55672 - RalfJung:miri-extern-types, r=eddyb
miri: accept extern types in structs if they are the only field Fixes https://github.com/rust-lang/rust/issues/55541 Cc @oli-obk @eddyb https://github.com/rust-lang/rust/issues/43467
This commit is contained in:
commit
a9b791b3c0
@ -341,8 +341,21 @@ 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
|
// the last field). Can't have foreign types here, how would we
|
||||||
// adjust alignment and size for them?
|
// adjust alignment and size for them?
|
||||||
let field = layout.field(self, layout.fields.count() - 1)?;
|
let field = layout.field(self, layout.fields.count() - 1)?;
|
||||||
let (unsized_size, unsized_align) = self.size_and_align_of(metadata, field)?
|
let (unsized_size, unsized_align) = match self.size_and_align_of(metadata, field)? {
|
||||||
.expect("Fields cannot be extern types");
|
Some(size_and_align) => size_and_align,
|
||||||
|
None => {
|
||||||
|
// A field with extern type. If this field is at offset 0, we behave
|
||||||
|
// like the underlying extern type.
|
||||||
|
// FIXME: Once we have made decisions for how to handle size and alignment
|
||||||
|
// of `extern type`, this should be adapted. It is just a temporary hack
|
||||||
|
// to get some code to work that probably ought to work.
|
||||||
|
if sized_size == Size::ZERO {
|
||||||
|
return Ok(None)
|
||||||
|
} else {
|
||||||
|
bug!("Fields cannot be extern types, unless they are at offset 0")
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
// FIXME (#26403, #27023): We should be adding padding
|
// FIXME (#26403, #27023): We should be adding padding
|
||||||
// to `sized_size` (to accommodate the `unsized_align`
|
// to `sized_size` (to accommodate the `unsized_align`
|
||||||
|
@ -351,8 +351,17 @@ where
|
|||||||
// Offset may need adjustment for unsized fields
|
// Offset may need adjustment for unsized fields
|
||||||
let (meta, offset) = if field_layout.is_unsized() {
|
let (meta, offset) = if field_layout.is_unsized() {
|
||||||
// re-use parent metadata to determine dynamic field layout
|
// re-use parent metadata to determine dynamic field layout
|
||||||
let (_, align) = self.size_and_align_of(base.meta, field_layout)?
|
let align = match self.size_and_align_of(base.meta, field_layout)? {
|
||||||
.expect("Fields cannot be extern types");
|
Some((_, align)) => align,
|
||||||
|
None if offset == Size::ZERO =>
|
||||||
|
// An extern type at offset 0, we fall back to its static alignment.
|
||||||
|
// FIXME: Once we have made decisions for how to handle size and alignment
|
||||||
|
// of `extern type`, this should be adapted. It is just a temporary hack
|
||||||
|
// to get some code to work that probably ought to work.
|
||||||
|
field_layout.align,
|
||||||
|
None =>
|
||||||
|
bug!("Cannot compute offset for extern type field at non-0 offset"),
|
||||||
|
};
|
||||||
(base.meta, offset.abi_align(align))
|
(base.meta, offset.abi_align(align))
|
||||||
} else {
|
} else {
|
||||||
// base.meta could be present; we might be accessing a sized field of an unsized
|
// base.meta could be present; we might be accessing a sized field of an unsized
|
||||||
|
27
src/test/ui/consts/const-eval/issue-55541.rs
Normal file
27
src/test/ui/consts/const-eval/issue-55541.rs
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
// compile-pass
|
||||||
|
|
||||||
|
// Test that we can handle newtypes wrapping extern types
|
||||||
|
|
||||||
|
#![feature(extern_types, const_transmute)]
|
||||||
|
|
||||||
|
use std::marker::PhantomData;
|
||||||
|
|
||||||
|
extern "C" {
|
||||||
|
pub type ExternType;
|
||||||
|
}
|
||||||
|
unsafe impl Sync for ExternType {}
|
||||||
|
static MAGIC_FFI_STATIC: u8 = 42;
|
||||||
|
|
||||||
|
#[repr(transparent)]
|
||||||
|
pub struct Wrapper(ExternType);
|
||||||
|
pub static MAGIC_FFI_REF: &'static Wrapper = unsafe {
|
||||||
|
std::mem::transmute(&MAGIC_FFI_STATIC)
|
||||||
|
};
|
||||||
|
|
||||||
|
#[repr(transparent)]
|
||||||
|
pub struct Wrapper2(PhantomData<Vec<i32>>, ExternType);
|
||||||
|
pub static MAGIC_FFI_REF2: &'static Wrapper2 = unsafe {
|
||||||
|
std::mem::transmute(&MAGIC_FFI_STATIC)
|
||||||
|
};
|
||||||
|
|
||||||
|
fn main() {}
|
Loading…
Reference in New Issue
Block a user