diff options
author | bors-servo <lbergstrom+bors@mozilla.com> | 2018-01-29 12:43:06 -0600 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-01-29 12:43:06 -0600 |
commit | ce7e69bfbc5a6e47eb1d9ee4f0b43a5afeef0f31 (patch) | |
tree | 3dc2495a404344fe1b91f08fec4bc0a0b276bb37 /src | |
parent | 6adb00247896c7c1102e14c8a87d6a1a2e9031f9 (diff) | |
parent | 34b92160a7f6e65294a7b892fa46701d22c147ea (diff) |
Auto merge of #1241 - emilio:fwd-decl-no-fun, r=fitzgen
codegen: Make forward declarations go through the more generic path.
Instead of special-casing.
This allows to use the normal flags to control what can be or not derived for
them.
Arguably deriving Copy / Clone is kind of busted for those, but changing this by
default broke tests (RefPtr<ForwardDeclaredType> stopped working for example).
So I think this is a good compromise.
Fixes #1238
Diffstat (limited to 'src')
-rw-r--r-- | src/codegen/mod.rs | 48 | ||||
-rw-r--r-- | src/ir/analysis/derive_copy.rs | 7 | ||||
-rw-r--r-- | src/ir/analysis/derive_default.rs | 5 | ||||
-rw-r--r-- | src/ir/analysis/derive_hash.rs | 5 | ||||
-rw-r--r-- | src/ir/analysis/derive_partialeq_or_partialord.rs | 5 | ||||
-rw-r--r-- | src/ir/comp.rs | 21 | ||||
-rw-r--r-- | src/ir/context.rs | 6 |
7 files changed, 52 insertions, 45 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs index f9e5e77c..0ddcdc0a 100644 --- a/src/codegen/mod.rs +++ b/src/codegen/mod.rs @@ -1425,23 +1425,6 @@ impl CodeGenerator for CompInfo { let layout = ty.layout(ctx); let mut packed = self.is_packed(ctx, &layout); - // generate tuple struct if struct or union is a forward declaration, - // skip for now if template parameters are needed. - // - // NB: We generate a proper struct to avoid struct/function name - // collisions. - if self.is_forward_declaration() && used_template_params.is_none() { - let struct_name = item.canonical_name(ctx); - let struct_name = ctx.rust_ident_raw(struct_name); - let tuple_struct = quote! { - #[repr(C)] - #[derive(Debug, Copy, Clone)] - pub struct #struct_name { _unused: [u8; 0] } - }; - result.push(tuple_struct); - return; - } - let canonical_name = item.canonical_name(ctx); let canonical_ident = ctx.rust_ident(&canonical_name); @@ -1497,14 +1480,6 @@ impl CodeGenerator for CompInfo { } } - let is_union = self.kind() == CompKind::Union; - if is_union { - result.saw_union(); - if !self.can_be_rust_union(ctx) { - result.saw_bindgen_union(); - } - } - let mut methods = vec![]; if !is_opaque { let codegen_depth = item.codegen_depth(ctx); @@ -1529,8 +1504,14 @@ impl CodeGenerator for CompInfo { } } + let is_union = self.kind() == CompKind::Union; let layout = item.kind().expect_type().layout(ctx); - if is_union && !is_opaque { + if is_union && !is_opaque && !self.is_forward_declaration() { + result.saw_union(); + if !self.can_be_rust_union(ctx) { + result.saw_bindgen_union(); + } + let layout = layout.expect("Unable to get layout information?"); let ty = helpers::blob(layout); @@ -1594,7 +1575,11 @@ impl CodeGenerator for CompInfo { // // NOTE: This check is conveniently here to avoid the dummy fields we // may add for unused template parameters. - if item.is_zero_sized(ctx) { + if self.is_forward_declaration() { + fields.push(quote! { + _unused: [u8; 0], + }); + } else if item.is_zero_sized(ctx) { let has_address = if is_opaque { // Generate the address field if it's an opaque type and // couldn't determine the layout of the blob. @@ -1664,12 +1649,11 @@ impl CodeGenerator for CompInfo { if item.can_derive_default(ctx) { derives.push("Default"); } else { - needs_default_impl = ctx.options().derive_default; + needs_default_impl = + ctx.options().derive_default && !self.is_forward_declaration(); } - if item.can_derive_copy(ctx) && !item.annotations().disallow_copy() && - ctx.options().derive_copy - { + if item.can_derive_copy(ctx) && !item.annotations().disallow_copy() { derives.push("Copy"); if ctx.options().rust_features().builtin_clone_impls() || @@ -1762,7 +1746,7 @@ impl CodeGenerator for CompInfo { } } - if ctx.options().layout_tests { + if ctx.options().layout_tests && !self.is_forward_declaration() { if let Some(layout) = layout { let fn_name = format!("bindgen_test_layout_{}", canonical_ident.as_str()); diff --git a/src/ir/analysis/derive_copy.rs b/src/ir/analysis/derive_copy.rs index 8da47a7f..94d457d5 100644 --- a/src/ir/analysis/derive_copy.rs +++ b/src/ir/analysis/derive_copy.rs @@ -235,9 +235,10 @@ impl<'ctx> MonotoneFramework for CannotDeriveCopy<'ctx> { if info.kind() == CompKind::Union { if !self.ctx.options().rust_features().untagged_union() { - // NOTE: If there's no template parameters we can derive copy - // unconditionally, since arrays are magical for rustc, and - // __BindgenUnionField always implements copy. + // NOTE: If there's no template parameters we can derive + // copy unconditionally, since arrays are magical for + // rustc, and __BindgenUnionField always implements + // copy. trace!( " comp can always derive debug if it's a Union and no template parameters" ); diff --git a/src/ir/analysis/derive_default.rs b/src/ir/analysis/derive_default.rs index f8f02df7..2c79a437 100644 --- a/src/ir/analysis/derive_default.rs +++ b/src/ir/analysis/derive_default.rs @@ -265,6 +265,11 @@ impl<'ctx> MonotoneFramework for CannotDeriveDefault<'ctx> { "The early ty.is_opaque check should have handled this case" ); + if info.is_forward_declaration() { + trace!(" cannot derive Default for forward decls"); + return self.insert(id); + } + if info.kind() == CompKind::Union { if self.ctx.options().rust_features().untagged_union() { trace!(" cannot derive Default for Rust unions"); diff --git a/src/ir/analysis/derive_hash.rs b/src/ir/analysis/derive_hash.rs index 46790232..3fc31b39 100644 --- a/src/ir/analysis/derive_hash.rs +++ b/src/ir/analysis/derive_hash.rs @@ -251,6 +251,11 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> { "The early ty.is_opaque check should have handled this case" ); + if info.is_forward_declaration() { + trace!(" cannot derive Hash for forward decls"); + return self.insert(id); + } + if info.kind() == CompKind::Union { if self.ctx.options().rust_features().untagged_union() { trace!(" cannot derive Hash for Rust unions"); diff --git a/src/ir/analysis/derive_partialeq_or_partialord.rs b/src/ir/analysis/derive_partialeq_or_partialord.rs index 92861341..2641d2b3 100644 --- a/src/ir/analysis/derive_partialeq_or_partialord.rs +++ b/src/ir/analysis/derive_partialeq_or_partialord.rs @@ -236,6 +236,11 @@ impl<'ctx> CannotDerivePartialEqOrPartialOrd<'ctx> { "The early ty.is_opaque check should have handled this case" ); + if info.is_forward_declaration() { + trace!(" cannot derive for forward decls"); + return CanDerive::No; + } + if info.kind() == CompKind::Union { if self.ctx.options().rust_features().untagged_union() { trace!( diff --git a/src/ir/comp.rs b/src/ir/comp.rs index 5008dcfd..50d0ddb1 100644 --- a/src/ir/comp.rs +++ b/src/ir/comp.rs @@ -1543,13 +1543,20 @@ impl CompInfo { /// 1. Current RustTarget allows for `untagged_union` /// 2. Each field can derive `Copy` pub fn can_be_rust_union(&self, ctx: &BindgenContext) -> bool { - ctx.options().rust_features().untagged_union() && - self.fields().iter().all(|f| match *f { - Field::DataMember(ref field_data) => { - field_data.ty().can_derive_copy(ctx) - } - Field::Bitfields(_) => true, - }) + if !ctx.options().rust_features().untagged_union() { + return false; + } + + if self.is_forward_declaration() { + return false; + } + + self.fields().iter().all(|f| match *f { + Field::DataMember(ref field_data) => { + field_data.ty().can_derive_copy(ctx) + } + Field::Bitfields(_) => true, + }) } } diff --git a/src/ir/context.rs b/src/ir/context.rs index cddbeb2d..21801c9f 100644 --- a/src/ir/context.rs +++ b/src/ir/context.rs @@ -222,8 +222,7 @@ where T: Copy + Into<ItemId> { fn can_derive_default(&self, ctx: &BindgenContext) -> bool { - ctx.options().derive_default && - ctx.lookup_can_derive_default(*self) + ctx.options().derive_default && ctx.lookup_can_derive_default(*self) } } @@ -232,7 +231,7 @@ where T: Copy + Into<ItemId> { fn can_derive_copy(&self, ctx: &BindgenContext) -> bool { - ctx.lookup_can_derive_copy(*self) + ctx.options().derive_copy && ctx.lookup_can_derive_copy(*self) } } @@ -2452,6 +2451,7 @@ impl BindgenContext { // Look up the computed value for whether the item with `id` can // derive `Copy` or not. let id = id.into(); + !self.lookup_has_type_param_in_array(id) && !self.cannot_derive_copy.as_ref().unwrap().contains(&id) } |