Skip to content

Commit

Permalink
Implement IsOpaque for CompInfo
Browse files Browse the repository at this point in the history
This allows us to properly detect structs that should be treated as opaque due
to their non-type template paramaters, which in turn lets us correctly codegen
template aliases to such things.

Fixes rust-lang#820
  • Loading branch information
fitzgen committed Jul 18, 2017
1 parent 10ea03c commit 0019d0e
Show file tree
Hide file tree
Showing 15 changed files with 62 additions and 11 deletions.
17 changes: 14 additions & 3 deletions src/ir/comp.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1422,6 +1422,14 @@ impl DotAttributes for CompInfo {
}
}

impl IsOpaque for CompInfo {
type Extra = ();

fn is_opaque(&self, _: &BindgenContext, _: &()) -> bool {
self.has_non_type_template_params
}
}

impl TemplateParameters for CompInfo {
fn self_template_params(&self,
_ctx: &BindgenContext)
Expand Down Expand Up @@ -1498,9 +1506,12 @@ impl CanDeriveDefault for CompInfo {
return false;
}

return layout.unwrap_or_else(Layout::zero)
.opaque()
.can_derive_default(ctx, ());
return layout.map_or(false, |l| l.opaque().can_derive_default(ctx, ()));

}

if self.has_non_type_template_params {
return layout.map_or(false, |l| l.opaque().can_derive_default(ctx, ()));
}

self.detect_derive_default_cycle.set(true);
Expand Down
2 changes: 1 addition & 1 deletion src/ir/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -283,7 +283,7 @@ impl CanDeriveDebug for Item {
ItemKind::Type(ref ty) => {
if self.is_opaque(ctx, &()) {
ty.layout(ctx)
.map_or(true, |l| l.opaque().can_derive_debug(ctx, ()))
.map_or(false, |l| l.opaque().can_derive_debug(ctx, ()))
} else {
ty.can_derive_debug(ctx, ())
}
Expand Down
6 changes: 5 additions & 1 deletion src/ir/ty.rs
Original file line number Diff line number Diff line change
Expand Up @@ -358,6 +358,7 @@ impl IsOpaque for Type {
match self.kind {
TypeKind::Opaque => true,
TypeKind::TemplateInstantiation(ref inst) => inst.is_opaque(ctx, item),
TypeKind::Comp(ref comp) => comp.is_opaque(ctx, &()),
_ => false,
}
}
Expand Down Expand Up @@ -562,6 +563,9 @@ impl CanDeriveDebug for Type {
TypeKind::TemplateInstantiation(ref inst) => {
inst.can_derive_debug(ctx, self.layout(ctx))
}
TypeKind::Opaque => {
self.layout.map_or(false, |l| l.opaque().can_derive_debug(ctx, ()))
}
_ => true,
}
}
Expand All @@ -584,7 +588,7 @@ impl CanDeriveDefault for Type {
}
TypeKind::Opaque => {
self.layout
.map_or(true, |l| l.opaque().can_derive_default(ctx, ()))
.map_or(false, |l| l.opaque().can_derive_default(ctx, ()))
}
TypeKind::Void |
TypeKind::Named |
Expand Down
4 changes: 4 additions & 0 deletions tests/expectations/tests/issue-372.rs
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,7 @@ pub mod root {
ai = 11,
}
#[repr(C)]
#[derive(Copy)]
pub struct F {
pub w: [u64; 33usize],
}
Expand All @@ -98,6 +99,9 @@ pub mod root {
"Alignment of field: " , stringify ! ( F ) , "::" ,
stringify ! ( w ) ));
}
impl Clone for F {
fn clone(&self) -> Self { *self }
}
impl Default for F {
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,15 @@ pub const ENUM_VARIANT_2: _bindgen_ty_1 = _bindgen_ty_1::ENUM_VARIANT_2;
pub enum _bindgen_ty_1 { ENUM_VARIANT_1 = 0, ENUM_VARIANT_2 = 1, }
pub type JS_Alias = u8;
#[repr(C)]
#[derive(Copy, Clone)]
pub struct JS_Base {
pub f: JS_Alias,
}
impl Default for JS_Base {
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
#[repr(C)]
#[derive(Copy)]
pub struct JS_AutoIdVector {
pub _base: JS_Base,
}
Expand All @@ -28,6 +30,9 @@ fn bindgen_test_layout_JS_AutoIdVector() {
assert_eq! (::std::mem::align_of::<JS_AutoIdVector>() , 1usize , concat !
( "Alignment of " , stringify ! ( JS_AutoIdVector ) ));
}
impl Clone for JS_AutoIdVector {
fn clone(&self) -> Self { *self }
}
impl Default for JS_AutoIdVector {
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
Expand Down
9 changes: 8 additions & 1 deletion tests/expectations/tests/issue-573-layout-test-failures.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,11 +5,15 @@


#[repr(C)]
#[derive(Default)]
#[derive(Copy, Clone)]
pub struct Outer {
pub i: u8,
}
impl Default for Outer {
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
#[repr(C)]
#[derive(Copy)]
pub struct AutoIdVector {
pub ar: Outer,
}
Expand All @@ -25,6 +29,9 @@ fn bindgen_test_layout_AutoIdVector() {
"Alignment of field: " , stringify ! ( AutoIdVector ) , "::" ,
stringify ! ( ar ) ));
}
impl Clone for AutoIdVector {
fn clone(&self) -> Self { *self }
}
impl Default for AutoIdVector {
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
Expand Down
2 changes: 1 addition & 1 deletion tests/expectations/tests/issue-674-1.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub mod root {
#[allow(unused_imports)]
use self::super::super::root;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
#[derive(Copy, Clone)]
pub struct Maybe {
pub _address: u8,
}
Expand Down
2 changes: 1 addition & 1 deletion tests/expectations/tests/issue-674-2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ pub mod root {
#[allow(unused_imports)]
use self::super::super::root;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
#[derive(Copy, Clone)]
pub struct Rooted {
pub _address: u8,
}
Expand Down
2 changes: 1 addition & 1 deletion tests/expectations/tests/issue-674-3.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ pub mod root {
#[allow(unused_imports)]
use self::super::root;
#[repr(C)]
#[derive(Debug, Copy, Clone)]
#[derive(Copy, Clone)]
pub struct nsRefPtrHashtable {
pub _address: u8,
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
/* automatically generated by rust-bindgen */


#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]


pub type Foo_self_type = u8;
4 changes: 4 additions & 0 deletions tests/expectations/tests/non-type-params.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
pub type Array16 = u8;
pub type ArrayInt4 = [u32; 4usize];
#[repr(C)]
#[derive(Copy)]
pub struct UsesArray {
pub array_char_16: [u8; 16usize],
pub array_bool_8: [u8; 8usize],
Expand Down Expand Up @@ -34,6 +35,9 @@ fn bindgen_test_layout_UsesArray() {
"Alignment of field: " , stringify ! ( UsesArray ) , "::" ,
stringify ! ( array_int_4 ) ));
}
impl Clone for UsesArray {
fn clone(&self) -> Self { *self }
}
impl Default for UsesArray {
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
Expand Down
2 changes: 1 addition & 1 deletion tests/expectations/tests/opaque_pointer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ impl Clone for OtherOpaque {
}
/// <div rustbindgen opaque></div>
#[repr(C)]
#[derive(Debug, Copy, Clone)]
#[derive(Copy, Clone)]
pub struct Opaque {
}
impl Default for Opaque {
Expand Down
4 changes: 4 additions & 0 deletions tests/expectations/tests/size_t_template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@


#[repr(C)]
#[derive(Copy)]
pub struct C {
pub arr: [u32; 3usize],
}
Expand All @@ -20,6 +21,9 @@ fn bindgen_test_layout_C() {
"Alignment of field: " , stringify ! ( C ) , "::" , stringify
! ( arr ) ));
}
impl Clone for C {
fn clone(&self) -> Self { *self }
}
impl Default for C {
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
Expand Down
2 changes: 1 addition & 1 deletion tests/expectations/tests/template.rs
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ impl Default for PODButContainsDtor {
}
/// <div rustbindgen opaque>
#[repr(C)]
#[derive(Debug, Copy, Clone)]
#[derive(Copy, Clone)]
pub struct Opaque {
}
impl Default for Opaque {
Expand Down
5 changes: 5 additions & 0 deletions tests/headers/issue-820-unused-template-param-in-alias.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
template<typename E, int N>
class Foo {
typedef Foo<E, N> self_type;
E mBar;
};

0 comments on commit 0019d0e

Please sign in to comment.