summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/codegen/mod.rs26
-rw-r--r--src/ir/comp.rs52
-rw-r--r--src/ir/context.rs2
-rw-r--r--src/ir/item.rs8
-rw-r--r--src/ir/ty.rs14
5 files changed, 68 insertions, 34 deletions
diff --git a/src/codegen/mod.rs b/src/codegen/mod.rs
index 36f20689..d95364a2 100644
--- a/src/codegen/mod.rs
+++ b/src/codegen/mod.rs
@@ -546,13 +546,14 @@ impl CodeGenerator for CompInfo {
attributes.push(attributes::repr("C"));
}
+ let is_union = self.kind() == CompKind::Union;
let mut derives = vec![];
let ty = item.expect_type();
if ty.can_derive_debug(ctx) {
derives.push("Debug");
}
- if ty.can_derive_copy(ctx) && !item.annotations().disallow_copy() {
+ if item.can_derive_copy(ctx) && !item.annotations().disallow_copy() {
derives.push("Copy");
if !applicable_template_args.is_empty() {
// FIXME: This requires extra logic if you have a big array in a
@@ -573,9 +574,15 @@ impl CodeGenerator for CompInfo {
let mut template_args_used = vec![false; applicable_template_args.len()];
let canonical_name = item.canonical_name(ctx);
- let builder = aster::AstBuilder::new().item().pub_()
- .with_attrs(attributes)
- .struct_(&canonical_name);
+ let builder = if is_union && ctx.options().unstable_rust {
+ aster::AstBuilder::new().item().pub_()
+ .with_attrs(attributes)
+ .union_(&canonical_name)
+ } else {
+ aster::AstBuilder::new().item().pub_()
+ .with_attrs(attributes)
+ .struct_(&canonical_name)
+ };
// Generate the vtable from the method list if appropriate.
// TODO: I don't know how this could play with virtual methods that are
@@ -633,8 +640,6 @@ impl CodeGenerator for CompInfo {
.pub_().build_ty(inner);
fields.push(field);
}
-
- let is_union = self.kind() == CompKind::Union;
if is_union {
result.saw_union();
}
@@ -705,7 +710,8 @@ impl CodeGenerator for CompInfo {
let ty = field.ty().to_rust_ty(ctx);
- let ty = if is_union {
+ // NB: In unstable rust we use proper `union` types.
+ let ty = if is_union && !ctx.options().unstable_rust {
quote_ty!(ctx.ext_cx(), __BindgenUnionField<$ty>)
} else {
ty
@@ -817,7 +823,7 @@ impl CodeGenerator for CompInfo {
}
debug_assert!(current_bitfield_fields.is_empty());
- if is_union {
+ if is_union && !ctx.options().unstable_rust {
let layout = layout.expect("Unable to get layout information?");
let ty = BlobTyBuilder::new(layout).build();
let field = StructFieldBuilder::named("bindgen_union_field").pub_()
@@ -1375,7 +1381,7 @@ impl ToRustTy for Type {
}
None => {
warn!("Couldn't compute layout for a type with non \
- template params or opaque, expect dragons!");
+ type template params or opaque, expect dragons!");
aster::AstBuilder::new().ty().unit()
}
}
@@ -1756,7 +1762,7 @@ pub fn codegen(context: &mut BindgenContext) -> Vec<P<ast::Item>> {
}
let saw_union = result.saw_union;
let mut result = result.items;
- if saw_union {
+ if saw_union && !context.options().unstable_rust {
utils::prepend_union_types(context, &mut result);
}
result
diff --git a/src/ir/comp.rs b/src/ir/comp.rs
index 1e6bf555..d31b7adf 100644
--- a/src/ir/comp.rs
+++ b/src/ir/comp.rs
@@ -215,6 +215,10 @@ impl CompInfo {
}
if self.kind == CompKind::Union {
+ if type_resolver.options().unstable_rust {
+ return false;
+ }
+
let layout = layout.unwrap_or_else(Layout::zero);
let size_divisor = cmp::max(1, layout.align);
return layout.size / size_divisor <= RUST_DERIVE_IN_ARRAY_LIMIT;
@@ -223,6 +227,10 @@ impl CompInfo {
self.detect_derive_debug_cycle.set(true);
let can_derive_debug =
+ self.base_members.iter().all(|ty| {
+ type_resolver.resolve_type(*ty)
+ .can_derive_debug(type_resolver)
+ }) &&
self.template_args.iter().all(|ty| {
type_resolver.resolve_type(*ty)
.can_derive_debug(type_resolver)
@@ -230,6 +238,10 @@ impl CompInfo {
self.fields.iter().all(|field| {
type_resolver.resolve_type(field.ty)
.can_derive_debug(type_resolver)
+ }) &&
+ self.ref_template.map_or(true, |template| {
+ type_resolver.resolve_type(template)
+ .can_derive_debug(type_resolver)
});
self.detect_derive_debug_cycle.set(false);
@@ -287,7 +299,7 @@ impl CompInfo {
has_destructor
}
- pub fn can_derive_copy(&self, type_resolver: &TypeResolver) -> bool {
+ pub fn can_derive_copy(&self, type_resolver: &TypeResolver, item: &Item) -> bool {
// NOTE: Take into account that while unions in C and C++ are copied by
// default, the may have an explicit destructor in C++, so we can't
// defer this check just for the union case.
@@ -295,23 +307,31 @@ impl CompInfo {
return false;
}
- match self.kind {
- CompKind::Union => true,
- CompKind::Struct => {
- // With template args, use a safe subset of the types,
- // since copyability depends on the types itself.
- self.ref_template.as_ref().map_or(true, |t| {
- type_resolver.resolve_type(*t).can_derive_copy(type_resolver)
- }) &&
- self.base_members.iter().all(|t| {
- type_resolver.resolve_type(*t).can_derive_copy(type_resolver)
- }) &&
- self.fields.iter().all(|field| {
- type_resolver.resolve_type(field.ty)
- .can_derive_copy(type_resolver)
- })
+ if self.kind == CompKind::Union {
+ if !type_resolver.options().unstable_rust {
+ return true;
+ }
+
+ // https://github.com/rust-lang/rust/issues/36640
+ if !self.template_args.is_empty() ||
+ self.ref_template.is_some() ||
+ !item.applicable_template_args(type_resolver).is_empty() {
+ return false;
}
}
+
+ // With template args, use a safe subset of the types,
+ // since copyability depends on the types itself.
+ self.ref_template.as_ref().map_or(true, |t| {
+ type_resolver.resolve_item(*t).can_derive_copy(type_resolver)
+ }) &&
+ self.base_members.iter().all(|t| {
+ type_resolver.resolve_item(*t).can_derive_copy(type_resolver)
+ }) &&
+ self.fields.iter().all(|field| {
+ type_resolver.resolve_item(field.ty)
+ .can_derive_copy(type_resolver)
+ })
}
pub fn is_template_specialization(&self) -> bool {
diff --git a/src/ir/context.rs b/src/ir/context.rs
index 559dd2ba..4842eb94 100644
--- a/src/ir/context.rs
+++ b/src/ir/context.rs
@@ -333,7 +333,7 @@ impl<'ctx> BindgenContext<'ctx> {
let cfg = ExpansionConfig::default("xxx".to_owned());
let sess = parse::ParseSess::new();
- let mut loader = base::DummyMacroLoader;
+ let mut loader = base::DummyResolver;
let mut ctx =
GenContext(base::ExtCtxt::new(&sess, vec![], cfg, &mut loader));
diff --git a/src/ir/item.rs b/src/ir/item.rs
index 75c3b857..80085c8b 100644
--- a/src/ir/item.rs
+++ b/src/ir/item.rs
@@ -338,6 +338,14 @@ impl Item {
_ => None,
}
}
+
+ pub fn can_derive_copy(&self, ctx: &BindgenContext) -> bool {
+ self.expect_type().can_derive_copy(ctx, self)
+ }
+
+ pub fn can_derive_copy_in_array(&self, ctx: &BindgenContext) -> bool {
+ self.expect_type().can_derive_copy_in_array(ctx, self)
+ }
}
impl ClangItemParser for Item {
diff --git a/src/ir/ty.rs b/src/ir/ty.rs
index 97cdf925..74452243 100644
--- a/src/ir/ty.rs
+++ b/src/ir/ty.rs
@@ -175,32 +175,32 @@ impl Type {
// is an error.
//
// That's the point of the existence of can_derive_copy_in_array().
- pub fn can_derive_copy_in_array(&self, type_resolver: &TypeResolver) -> bool {
+ pub fn can_derive_copy_in_array(&self, type_resolver: &TypeResolver, item: &Item) -> bool {
match self.kind {
TypeKind::ResolvedTypeRef(t) |
TypeKind::Alias(_, t) |
TypeKind::Array(t, _) => {
- type_resolver.resolve_type(t)
+ type_resolver.resolve_item(t)
.can_derive_copy_in_array(type_resolver)
}
TypeKind::Named(..) => false,
- _ => self.can_derive_copy(type_resolver),
+ _ => self.can_derive_copy(type_resolver, item),
}
}
- pub fn can_derive_copy(&self, type_resolver: &TypeResolver) -> bool {
+ pub fn can_derive_copy(&self, type_resolver: &TypeResolver, item: &Item) -> bool {
!self.is_opaque(type_resolver) && match self.kind {
TypeKind::Array(t, len) => {
len <= RUST_DERIVE_IN_ARRAY_LIMIT &&
- type_resolver.resolve_type(t).can_derive_copy_in_array(type_resolver)
+ type_resolver.resolve_item(t).can_derive_copy_in_array(type_resolver)
}
TypeKind::ResolvedTypeRef(t) |
TypeKind::TemplateRef(t, _) |
TypeKind::Alias(_, t) => {
- type_resolver.resolve_type(t).can_derive_copy(type_resolver)
+ type_resolver.resolve_item(t).can_derive_copy(type_resolver)
}
TypeKind::Comp(ref info) => {
- info.can_derive_copy(type_resolver)
+ info.can_derive_copy(type_resolver, item)
}
_ => true,
}