Skip to content

Commit 781385f

Browse files
author
bors-servo
authored
Auto merge of #823 - fitzgen:issue-820-unused-template-param-in-alias, r=emilio
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 #820 r? @emilio
2 parents 6053d99 + 20253fc commit 781385f

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)