Skip to content

Commit 36a2da9

Browse files
fitzgentmfink
authored andcommitted
Implement IsOpaque for CompInfo
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
1 parent 6053d99 commit 36a2da9

10 files changed

+67
-8
lines changed

src/ir/comp.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1422,6 +1422,14 @@ impl DotAttributes for CompInfo {
14221422
}
14231423
}
14241424

1425+
impl IsOpaque for CompInfo {
1426+
type Extra = ();
1427+
1428+
fn is_opaque(&self, _: &BindgenContext, _: &()) -> bool {
1429+
self.has_non_type_template_params
1430+
}
1431+
}
1432+
14251433
impl TemplateParameters for CompInfo {
14261434
fn self_template_params(&self,
14271435
_ctx: &BindgenContext)
@@ -1442,7 +1450,7 @@ impl CanDeriveDebug for CompInfo {
14421450
layout: Option<Layout>)
14431451
-> bool {
14441452
if self.has_non_type_template_params() {
1445-
return layout.map_or(false, |l| l.opaque().can_derive_debug(ctx, ()));
1453+
return layout.map_or(true, |l| l.opaque().can_derive_debug(ctx, ()));
14461454
}
14471455

14481456
// We can reach here recursively via template parameters of a member,
@@ -1498,9 +1506,11 @@ impl CanDeriveDefault for CompInfo {
14981506
return false;
14991507
}
15001508

1501-
return layout.unwrap_or_else(Layout::zero)
1502-
.opaque()
1503-
.can_derive_default(ctx, ());
1509+
return layout.map_or(true, |l| l.opaque().can_derive_default(ctx, ()));
1510+
}
1511+
1512+
if self.has_non_type_template_params {
1513+
return layout.map_or(true, |l| l.opaque().can_derive_default(ctx, ()));
15041514
}
15051515

15061516
self.detect_derive_default_cycle.set(true);
@@ -1528,7 +1538,7 @@ impl<'a> CanDeriveCopy<'a> for CompInfo {
15281538
(item, layout): (&Item, Option<Layout>))
15291539
-> bool {
15301540
if self.has_non_type_template_params() {
1531-
return layout.map_or(false, |l| l.opaque().can_derive_copy(ctx, ()));
1541+
return layout.map_or(true, |l| l.opaque().can_derive_copy(ctx, ()));
15321542
}
15331543

15341544
// NOTE: Take into account that while unions in C and C++ are copied by

src/ir/template.rs

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -361,14 +361,23 @@ impl CanDeriveDebug for TemplateInstantiation {
361361
layout: Option<Layout>)
362362
-> bool {
363363
self.args.iter().all(|arg| arg.can_derive_debug(ctx, ())) &&
364-
ctx.resolve_type(self.definition)
364+
self.definition
365+
.into_resolver()
366+
.through_type_refs()
367+
.through_type_aliases()
368+
.resolve(ctx)
369+
.as_type()
370+
.expect("Instantiation of a non-type?")
365371
.as_comp()
366372
.and_then(|c| {
367373
// For non-type template parameters, we generate an opaque
368374
// blob, and in this case the instantiation has a better
369375
// idea of the layout than the definition does.
370376
if c.has_non_type_template_params() {
371-
let opaque = layout.unwrap_or(Layout::zero()).opaque();
377+
let opaque = layout
378+
.or_else(|| ctx.resolve_type(self.definition).layout(ctx))
379+
.unwrap_or(Layout::zero())
380+
.opaque();
372381
Some(opaque.can_derive_debug(ctx, ()))
373382
} else {
374383
None

src/ir/ty.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -358,6 +358,7 @@ impl IsOpaque for Type {
358358
match self.kind {
359359
TypeKind::Opaque => true,
360360
TypeKind::TemplateInstantiation(ref inst) => inst.is_opaque(ctx, item),
361+
TypeKind::Comp(ref comp) => comp.is_opaque(ctx, &()),
361362
_ => false,
362363
}
363364
}
@@ -562,6 +563,9 @@ impl CanDeriveDebug for Type {
562563
TypeKind::TemplateInstantiation(ref inst) => {
563564
inst.can_derive_debug(ctx, self.layout(ctx))
564565
}
566+
TypeKind::Opaque => {
567+
self.layout.map_or(true, |l| l.opaque().can_derive_debug(ctx, ()))
568+
}
565569
_ => true,
566570
}
567571
}

tests/expectations/tests/issue-372.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ pub mod root {
8383
ai = 11,
8484
}
8585
#[repr(C)]
86+
#[derive(Copy)]
8687
pub struct F {
8788
pub w: [u64; 33usize],
8889
}
@@ -98,6 +99,9 @@ pub mod root {
9899
"Alignment of field: " , stringify ! ( F ) , "::" ,
99100
stringify ! ( w ) ));
100101
}
102+
impl Clone for F {
103+
fn clone(&self) -> Self { *self }
104+
}
101105
impl Default for F {
102106
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
103107
}

tests/expectations/tests/issue-569-non-type-template-params-causing-layout-test-failures.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,15 @@ pub const ENUM_VARIANT_2: _bindgen_ty_1 = _bindgen_ty_1::ENUM_VARIANT_2;
1111
pub enum _bindgen_ty_1 { ENUM_VARIANT_1 = 0, ENUM_VARIANT_2 = 1, }
1212
pub type JS_Alias = u8;
1313
#[repr(C)]
14+
#[derive(Debug, Copy, Clone)]
1415
pub struct JS_Base {
1516
pub f: JS_Alias,
1617
}
1718
impl Default for JS_Base {
1819
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
1920
}
2021
#[repr(C)]
22+
#[derive(Debug, Copy)]
2123
pub struct JS_AutoIdVector {
2224
pub _base: JS_Base,
2325
}
@@ -28,6 +30,9 @@ fn bindgen_test_layout_JS_AutoIdVector() {
2830
assert_eq! (::std::mem::align_of::<JS_AutoIdVector>() , 1usize , concat !
2931
( "Alignment of " , stringify ! ( JS_AutoIdVector ) ));
3032
}
33+
impl Clone for JS_AutoIdVector {
34+
fn clone(&self) -> Self { *self }
35+
}
3136
impl Default for JS_AutoIdVector {
3237
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
3338
}

tests/expectations/tests/issue-573-layout-test-failures.rs

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,15 @@
55

66

77
#[repr(C)]
8-
#[derive(Default)]
8+
#[derive(Debug, Copy, Clone)]
99
pub struct Outer {
1010
pub i: u8,
1111
}
12+
impl Default for Outer {
13+
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
14+
}
1215
#[repr(C)]
16+
#[derive(Debug, Copy)]
1317
pub struct AutoIdVector {
1418
pub ar: Outer,
1519
}
@@ -25,6 +29,9 @@ fn bindgen_test_layout_AutoIdVector() {
2529
"Alignment of field: " , stringify ! ( AutoIdVector ) , "::" ,
2630
stringify ! ( ar ) ));
2731
}
32+
impl Clone for AutoIdVector {
33+
fn clone(&self) -> Self { *self }
34+
}
2835
impl Default for AutoIdVector {
2936
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
3037
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
4+
#![allow(dead_code, non_snake_case, non_camel_case_types, non_upper_case_globals)]
5+
6+
7+
pub type Foo_self_type = u8;

tests/expectations/tests/non-type-params.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
pub type Array16 = u8;
88
pub type ArrayInt4 = [u32; 4usize];
99
#[repr(C)]
10+
#[derive(Debug, Copy)]
1011
pub struct UsesArray {
1112
pub array_char_16: [u8; 16usize],
1213
pub array_bool_8: [u8; 8usize],
@@ -34,6 +35,9 @@ fn bindgen_test_layout_UsesArray() {
3435
"Alignment of field: " , stringify ! ( UsesArray ) , "::" ,
3536
stringify ! ( array_int_4 ) ));
3637
}
38+
impl Clone for UsesArray {
39+
fn clone(&self) -> Self { *self }
40+
}
3741
impl Default for UsesArray {
3842
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
3943
}

tests/expectations/tests/size_t_template.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66

77
#[repr(C)]
8+
#[derive(Debug, Copy)]
89
pub struct C {
910
pub arr: [u32; 3usize],
1011
}
@@ -20,6 +21,9 @@ fn bindgen_test_layout_C() {
2021
"Alignment of field: " , stringify ! ( C ) , "::" , stringify
2122
! ( arr ) ));
2223
}
24+
impl Clone for C {
25+
fn clone(&self) -> Self { *self }
26+
}
2327
impl Default for C {
2428
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
2529
}
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
template<typename E, int N>
2+
class Foo {
3+
typedef Foo<E, N> self_type;
4+
E mBar;
5+
};

0 commit comments

Comments
 (0)