Skip to content

Commit

Permalink
ir: Whitelist items that don't generate code to improve derive behavior.
Browse files Browse the repository at this point in the history
When not whitelisting recursively.

Fixes rust-lang#1454
  • Loading branch information
emilio committed Mar 25, 2019
1 parent d699813 commit 98a89fc
Show file tree
Hide file tree
Showing 5 changed files with 48 additions and 56 deletions.
2 changes: 2 additions & 0 deletions src/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,8 @@ impl CodeGenerator for Type {
TypeKind::TypeParam => {
// These items don't need code generation, they only need to be
// converted to rust types in fields, arguments, and such.
// NOTE(emilio): If you add to this list, make sure to also add
// it to BindgenContext::compute_whitelisted_and_codegen_items.
return;
}
TypeKind::TemplateInstantiation(ref inst) => {
Expand Down
22 changes: 22 additions & 0 deletions src/ir/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2314,6 +2314,28 @@ If you encounter an error missing from this list, please file an issue or a PR!"
return true;
}

// Auto-whitelist types that don't need code
// generation if not whitelisting recursively, to
// make the #[derive] analysis not be lame.
if !self.options().whitelist_recursively {
match *ty.kind() {
TypeKind::Void |
TypeKind::NullPtr |
TypeKind::Int(..) |
TypeKind::Float(..) |
TypeKind::Complex(..) |
TypeKind::Array(..) |
TypeKind::Vector(..) |
TypeKind::Pointer(..) |
TypeKind::Reference(..) |
TypeKind::Function(..) |
TypeKind::ResolvedTypeRef(..) |
TypeKind::Opaque |
TypeKind::TypeParam => return true,
_ => {},
};
}

// Unnamed top-level enums are special and we
// whitelist them via the `whitelisted_vars` filter,
// since they're effectively top-level constants,
Expand Down
53 changes: 6 additions & 47 deletions tests/expectations/tests/issue-1285.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,57 +8,16 @@
)]

#[repr(C)]
pub struct __BindgenUnionField<T>(::std::marker::PhantomData<T>);
impl<T> __BindgenUnionField<T> {
#[inline]
pub fn new() -> Self {
__BindgenUnionField(::std::marker::PhantomData)
}
#[inline]
pub unsafe fn as_ref(&self) -> &T {
::std::mem::transmute(self)
}
#[inline]
pub unsafe fn as_mut(&mut self) -> &mut T {
::std::mem::transmute(self)
}
}
impl<T> ::std::default::Default for __BindgenUnionField<T> {
#[inline]
fn default() -> Self {
Self::new()
}
}
impl<T> ::std::clone::Clone for __BindgenUnionField<T> {
#[inline]
fn clone(&self) -> Self {
Self::new()
}
}
impl<T> ::std::marker::Copy for __BindgenUnionField<T> {}
impl<T> ::std::fmt::Debug for __BindgenUnionField<T> {
fn fmt(&self, fmt: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
fmt.write_str("__BindgenUnionField")
}
}
impl<T> ::std::hash::Hash for __BindgenUnionField<T> {
fn hash<H: ::std::hash::Hasher>(&self, _state: &mut H) {}
}
impl<T> ::std::cmp::PartialEq for __BindgenUnionField<T> {
fn eq(&self, _other: &__BindgenUnionField<T>) -> bool {
true
}
}
impl<T> ::std::cmp::Eq for __BindgenUnionField<T> {}
#[repr(C)]
#[derive(Copy, Clone)]
pub struct foo {
pub bar: foo__bindgen_ty_1,
}
#[repr(C)]
pub struct foo__bindgen_ty_1 {
pub a: __BindgenUnionField<::std::os::raw::c_uint>,
pub b: __BindgenUnionField<::std::os::raw::c_ushort>,
pub bindgen_union_field: u32,
#[derive(Copy, Clone)]
pub union foo__bindgen_ty_1 {
pub a: ::std::os::raw::c_uint,
pub b: ::std::os::raw::c_ushort,
_bindgen_union_align: u32,
}
#[test]
fn bindgen_test_layout_foo__bindgen_ty_1() {
Expand Down
18 changes: 11 additions & 7 deletions tests/expectations/tests/libclang-5/objc_template.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,22 @@
/* automatically generated by rust-bindgen */


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

#![cfg(target_os="macos")]
#![allow(
dead_code,
non_snake_case,
non_camel_case_types,
non_upper_case_globals
)]
#![cfg(target_os = "macos")]

#[macro_use]
extern crate objc;
#[allow(non_camel_case_types)]
pub type id = *mut objc::runtime::Object;
pub trait Foo {
unsafe fn get(self)
-> *mut ObjectType;
unsafe fn get(self) -> u64;
}
impl Foo for id {
unsafe fn get(self) -> *mut ObjectType { msg_send!(self , get) }
unsafe fn get(self) -> u64 {
msg_send!(self, get)
}
}
9 changes: 7 additions & 2 deletions tests/expectations/tests/no-recursive-whitelisting.rs
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
/* automatically generated by rust-bindgen */


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

pub enum Bar {}

#[repr(C)]
#[derive(Debug, Copy, Clone)]
pub struct Foo {
pub baz: *mut Bar,
}
Expand Down

0 comments on commit 98a89fc

Please sign in to comment.