diff options
Diffstat (limited to 'src/ir/comp.rs')
-rw-r--r-- | src/ir/comp.rs | 35 |
1 files changed, 26 insertions, 9 deletions
diff --git a/src/ir/comp.rs b/src/ir/comp.rs index fdf6a963..f44c5d67 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -14,6 +14,7 @@ use crate::codegen::struct_layout::{align_to, bytes_from_bits_pow2}; use crate::ir::derive::CanDeriveCopy; use crate::parse::{ClangItemParser, ParseError}; use crate::HashMap; +use crate::NonCopyUnionStyle; use peeking_take_while::PeekableExt; use std::cmp; use std::io; @@ -1680,21 +1681,37 @@ impl CompInfo { /// /// Requirements: /// 1. Current RustTarget allows for `untagged_union` - /// 2. Each field can derive `Copy` + /// 2. Each field can derive `Copy` or we use ManuallyDrop. /// 3. It's not zero-sized. - pub fn can_be_rust_union( + /// + /// Second boolean returns whether all fields can be copied (and thus + /// ManuallyDrop is not needed). + pub fn is_rust_union( &self, ctx: &BindgenContext, layout: Option<&Layout>, - ) -> bool { + name: &str, + ) -> (bool, bool) { + if !self.is_union() { + return (false, false); + } + if !ctx.options().rust_features().untagged_union { - return false; + return (false, false); } if self.is_forward_declaration() { - return false; + return (false, false); } + let union_style = if ctx.options().bindgen_wrapper_union.matches(name) { + NonCopyUnionStyle::BindgenWrapper + } else if ctx.options().manually_drop_union.matches(name) { + NonCopyUnionStyle::ManuallyDrop + } else { + ctx.options().default_non_copy_union_style + }; + let all_can_copy = self.fields().iter().all(|f| match *f { Field::DataMember(ref field_data) => { field_data.ty().can_derive_copy(ctx) @@ -1702,15 +1719,15 @@ impl CompInfo { Field::Bitfields(_) => true, }); - if !all_can_copy { - return false; + if !all_can_copy && union_style == NonCopyUnionStyle::BindgenWrapper { + return (false, false); } if layout.map_or(false, |l| l.size == 0) { - return false; + return (false, false); } - true + (true, all_can_copy) } } |