Skip to content

Commit eeebba0

Browse files
author
bors-servo
authored
Auto merge of #575 - fitzgen:issue-574-anonymous-template-parameters-and-assertion-failure, r=fitzgen
Allow anonymous template types We have various assertions that the only way that some template parameter related methods will return `None` is if the template definition is marked opaque. These assertions fail in the presence of test cases with unnamed template types, because we never save an IR item for the template type, and subsequently think that the template definition has no template parameters. The assertions are in fact sound and correct, so it doesn't make sense to remove them. Instead it is more correct to save IR items for the anonymous template types and simply let the template usage analysis prevent them from getting codegen'd. Fixes #574 r? @emilio
2 parents 1320efe + b7f7850 commit eeebba0

12 files changed

+133
-36
lines changed

src/ir/comp.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -597,14 +597,6 @@ impl CompInfo {
597597
ci.packed = true;
598598
}
599599
CXCursor_TemplateTypeParameter => {
600-
// Yes! You can arrive here with an empty template parameter
601-
// name! Awesome, isn't it?
602-
//
603-
// see tests/headers/empty_template_param_name.hpp
604-
if cur.spelling().is_empty() {
605-
return CXChildVisit_Continue;
606-
}
607-
608600
let param = Item::named_type(None, cur, ctx)
609601
.expect("Item::named_type should't fail when pointing \
610602
at a TemplateTypeParameter");

src/ir/context.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1032,10 +1032,10 @@ impl<'ctx> BindgenContext<'ctx> {
10321032
}
10331033

10341034
return self.instantiate_template(with_id,
1035-
id,
1036-
parent_id,
1037-
ty,
1038-
location)
1035+
id,
1036+
parent_id,
1037+
ty,
1038+
location)
10391039
.or_else(|| Some(id));
10401040
}
10411041

src/ir/item.rs

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ use std::collections::BTreeSet;
1919
use std::fmt::Write;
2020
use std::io;
2121
use std::iter;
22+
use regex;
2223

2324
/// A trait to get the canonical name from an item.
2425
///
@@ -1313,8 +1314,19 @@ impl ClangItemParser for Item {
13131314
fn is_template_with_spelling(refd: &clang::Cursor,
13141315
spelling: &str)
13151316
-> bool {
1316-
refd.kind() == clang_sys::CXCursor_TemplateTypeParameter &&
1317-
refd.spelling() == spelling
1317+
lazy_static! {
1318+
static ref ANON_TYPE_PARAM_RE: regex::Regex =
1319+
regex::Regex::new(r"^type\-parameter\-\d+\-\d+$").unwrap();
1320+
}
1321+
1322+
if refd.kind() != clang_sys::CXCursor_TemplateTypeParameter {
1323+
return false;
1324+
}
1325+
1326+
let refd_spelling = refd.spelling();
1327+
refd_spelling == spelling ||
1328+
// Allow for anonymous template parameters.
1329+
(refd_spelling.is_empty() && ANON_TYPE_PARAM_RE.is_match(spelling.as_ref()))
13181330
}
13191331

13201332
let definition = if is_template_with_spelling(&location,

src/ir/ty.rs

Lines changed: 6 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -292,8 +292,12 @@ impl Type {
292292

293293
/// Creates a new named type, with name `name`.
294294
pub fn named(name: String) -> Self {
295-
assert!(!name.is_empty());
296-
Self::new(Some(name), None, TypeKind::Named, false)
295+
let name = if name.is_empty() {
296+
None
297+
} else {
298+
Some(name)
299+
};
300+
Self::new(name, None, TypeKind::Named, false)
297301
}
298302

299303
/// Is this a floating point type?
@@ -1127,12 +1131,6 @@ impl Type {
11271131
ctx);
11281132
}
11291133
CXCursor_TemplateTypeParameter => {
1130-
// See the comment in src/ir/comp.rs
1131-
// about the same situation.
1132-
if cur.spelling().is_empty() {
1133-
return CXChildVisit_Continue;
1134-
}
1135-
11361134
let param =
11371135
Item::named_type(None,
11381136
cur,
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
4+
#![allow(non_snake_case)]
5+
6+
7+
#[repr(C)]
8+
#[derive(Debug, Copy, Clone)]
9+
pub struct Foo<T> {
10+
pub t_member: T,
11+
}
12+
impl <T> Default for Foo<T> {
13+
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
14+
}
15+
#[repr(C)]
16+
#[derive(Debug, Default, Copy, Clone)]
17+
pub struct Bar {
18+
pub member: ::std::os::raw::c_schar,
19+
}
20+
#[repr(C)]
21+
#[derive(Debug, Copy, Clone)]
22+
pub struct Quux<V> {
23+
pub v_member: V,
24+
}
25+
impl <V> Default for Quux<V> {
26+
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
27+
}
28+
#[repr(C)]
29+
#[derive(Debug, Default, Copy, Clone)]
30+
pub struct Lobo {
31+
pub also_member: ::std::os::raw::c_schar,
32+
}
33+
pub type AliasWithAnonType = ::std::os::raw::c_schar;

tests/expectations/tests/bad-namespace-parenthood-inheritance.rs

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,15 @@
55

66

77
#[repr(C)]
8-
#[derive(Debug, Default, Copy, Clone)]
8+
#[derive(Debug, Copy, Clone)]
99
pub struct std_char_traits {
1010
pub _address: u8,
1111
}
12+
impl Default for std_char_traits {
13+
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
14+
}
1215
#[repr(C)]
13-
#[derive(Debug, Default, Copy)]
16+
#[derive(Debug, Default, Copy, Clone)]
1417
pub struct __gnu_cxx_char_traits {
1518
pub _address: u8,
1619
}
17-
impl Clone for __gnu_cxx_char_traits {
18-
fn clone(&self) -> Self { *self }
19-
}

tests/expectations/tests/issue-358.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -13,13 +13,10 @@ impl Default for JS_PersistentRooted {
1313
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
1414
}
1515
#[repr(C)]
16-
#[derive(Debug, Copy)]
16+
#[derive(Debug, Copy, Clone)]
1717
pub struct a {
1818
pub b: *mut a,
1919
}
20-
impl Clone for a {
21-
fn clone(&self) -> Self { *self }
22-
}
2320
impl Default for a {
2421
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
2522
}

tests/expectations/tests/issue-544-stylo-creduce.rs

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,7 @@
55

66

77
#[repr(C)]
8-
#[derive(Debug, Default, Copy)]
8+
#[derive(Debug, Default, Copy, Clone)]
99
pub struct a {
1010
pub _address: u8,
1111
}
12-
impl Clone for a {
13-
fn clone(&self) -> Self { *self }
14-
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ impl Default for JS_AutoIdVector {
3232
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
3333
}
3434
#[test]
35-
fn __bindgen_test_layout_JS_Base_instantiation_16() {
35+
fn __bindgen_test_layout_JS_Base_instantiation_20() {
3636
assert_eq!(::std::mem::size_of::<JS_Base>() , 1usize , concat ! (
3737
"Size of template specialization: " , stringify ! ( JS_Base )
3838
));
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
/* automatically generated by rust-bindgen */
2+
3+
4+
#![allow(non_snake_case)]
5+
6+
7+
#[repr(C)]
8+
#[derive(Debug, Default, Copy, Clone)]
9+
pub struct a {
10+
pub _address: u8,
11+
}
12+
#[repr(C)]
13+
#[derive(Debug, Copy)]
14+
pub struct _bindgen_ty_1 {
15+
pub ar: a,
16+
}
17+
#[test]
18+
fn bindgen_test_layout__bindgen_ty_1() {
19+
assert_eq!(::std::mem::size_of::<_bindgen_ty_1>() , 1usize , concat ! (
20+
"Size of: " , stringify ! ( _bindgen_ty_1 ) ));
21+
assert_eq! (::std::mem::align_of::<_bindgen_ty_1>() , 1usize , concat ! (
22+
"Alignment of " , stringify ! ( _bindgen_ty_1 ) ));
23+
assert_eq! (unsafe {
24+
& ( * ( 0 as * const _bindgen_ty_1 ) ) . ar as * const _ as
25+
usize } , 0usize , concat ! (
26+
"Alignment of field: " , stringify ! ( _bindgen_ty_1 ) , "::"
27+
, stringify ! ( ar ) ));
28+
}
29+
impl Clone for _bindgen_ty_1 {
30+
fn clone(&self) -> Self { *self }
31+
}
32+
impl Default for _bindgen_ty_1 {
33+
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
34+
}
35+
extern "C" {
36+
#[link_name = "AutoIdVector"]
37+
pub static mut AutoIdVector: _bindgen_ty_1;
38+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
// bindgen-flags: -- -std=c++14
2+
3+
template <typename T, typename>
4+
struct Foo {
5+
T t_member;
6+
};
7+
8+
template <typename U, typename>
9+
struct Bar {
10+
char member;
11+
};
12+
13+
template <typename, typename V>
14+
struct Quux {
15+
V v_member;
16+
};
17+
18+
template <typename, typename W>
19+
struct Lobo {
20+
char also_member;
21+
};
22+
23+
template <typename>
24+
using AliasWithAnonType = char;
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// bindgen-flags: -- -std=c++14
2+
3+
template <class> class a {};
4+
class {
5+
a<int> ar;
6+
} AutoIdVector;

0 commit comments

Comments
 (0)