Skip to content

Commit

Permalink
Add --no-partialeq <regex> flag
Browse files Browse the repository at this point in the history
- [x] Add a new RegexSet member to bindgen::Builder (similar to the whitelisted_types set).

- [x] A Builder method to add strings to that RegexSet.

- [x] Plumbing in src/options.rs to convert --no-partialeq <regex> CLI flags into invocations of the builder method.

- [x] Make the MonotoneFramework::constrain function in src/ir/analysis/derive_partialeq.rs check if the given item is explicitly marked not to be Partialeq, and if so, insert it into the self.cannot_derive_partialeq set via return self.insert(id).

- [x] Tests!

- [x] When the no-partialeq type is transitively referenced by a whitelisted item

- [x] When the no-partialeq type is explicitly whitelisted

- [x] When the no-partialeq type is marked opaque

Fixes #965
  • Loading branch information
alexeyzab committed Sep 19, 2017
1 parent 1906a26 commit ec8456b
Show file tree
Hide file tree
Showing 10 changed files with 197 additions and 0 deletions.
4 changes: 4 additions & 0 deletions src/ir/analysis/derive_partial_eq_or_partial_ord.rs
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,10 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> {
}
};

if self.ctx.no_partialeq_by_name(&item) {
return self.insert(id)
}

trace!("ty: {:?}", ty);
if item.is_opaque(self.ctx, &()) {
let layout_can_derive = ty.layout(self.ctx).map_or(true, |l| {
Expand Down
6 changes: 6 additions & 0 deletions src/ir/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2205,6 +2205,12 @@ impl BindgenContext {
// float or not.
self.has_float.as_ref().unwrap().contains(id)
}

/// Check if `--no-partialeq` flag is enabled for this item.
pub fn no_partialeq_by_name(&self, item: &Item) -> bool {
let name = item.canonical_path(self)[1..].join("::");
self.options().no_partialeq_types.matches(&name)
}
}

/// A builder struct for configuring item resolution options.
Expand Down
27 changes: 27 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -500,6 +500,20 @@ impl Builder {
output_vector.push(path.into());
}

self.options
.no_partialeq_types
.get_items()
.iter()
.map(|item| {
output_vector.push("--no-partialeq".into());
output_vector.push(
item.trim_left_matches("^")
.trim_right_matches("$")
.into(),
);
})
.count();

output_vector
}

Expand Down Expand Up @@ -1105,6 +1119,13 @@ impl Builder {
))
}
}

/// Don't derive `PartialEq` for a given type. Regular
/// expressions are supported.
pub fn no_partialeq(mut self, arg: String) -> Builder {
self.options.no_partialeq_types.insert(arg);
self
}
}

/// Configuration options for generated bindings.
Expand Down Expand Up @@ -1279,7 +1300,11 @@ struct BindgenOptions {

/// The absolute path to the rustfmt configuration file, if None, the standard rustfmt
/// options are used.

rustfmt_configuration_file: Option<PathBuf>,

/// The set of types that we should not derive `PartialEq` for.
no_partialeq_types: RegexSet,
}

/// TODO(emilio): This is sort of a lie (see the error message that results from
Expand All @@ -1297,6 +1322,7 @@ impl BindgenOptions {
self.bitfield_enums.build();
self.constified_enum_modules.build();
self.rustified_enums.build();
self.no_partialeq_types.build();
}

/// Update rust target version
Expand Down Expand Up @@ -1365,6 +1391,7 @@ impl Default for BindgenOptions {
time_phases: false,
rustfmt_bindings: false,
rustfmt_configuration_file: None,
no_partialeq_types: Default::default(),
}
}
}
Expand Down
13 changes: 13 additions & 0 deletions src/options.rs
Original file line number Diff line number Diff line change
Expand Up @@ -265,6 +265,13 @@ where
.takes_value(true)
.multiple(false)
.number_of_values(1),
Arg::with_name("no-partialeq")
.long("no-partialeq")
.help("Avoid deriving PartialEq for types matching <regex>.")
.value_name("regex")
.takes_value(true)
.multiple(true)
.number_of_values(1),
]) // .args()
.get_matches_from(args);

Expand Down Expand Up @@ -537,6 +544,12 @@ where
builder = builder.rustfmt_configuration_file(Some(path));
}

if let Some(no_partialeq) = matches.values_of("no-partialeq") {
for regex in no_partialeq {
builder = builder.no_partialeq(String::from(regex));
}
}

let verbose = matches.is_present("verbose");

Ok((builder, output, verbose))
Expand Down
29 changes: 29 additions & 0 deletions tests/expectations/tests/no-partialeq-opaque.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
/* automatically generated by rust-bindgen */


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


#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct NoPartialEq {
pub _bindgen_opaque_blob: u32,
}
#[test]
fn bindgen_test_layout_NoPartialEq() {
assert_eq!(
::std::mem::size_of::<NoPartialEq>(),
4usize,
concat!("Size of: ", stringify!(NoPartialEq))
);
assert_eq!(
::std::mem::align_of::<NoPartialEq>(),
4usize,
concat!("Alignment of ", stringify!(NoPartialEq))
);
}
impl Clone for NoPartialEq {
fn clone(&self) -> Self {
*self
}
}
39 changes: 39 additions & 0 deletions tests/expectations/tests/no-partialeq-whitelisted.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/* automatically generated by rust-bindgen */


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


#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct NoPartialEq {
pub i: ::std::os::raw::c_int,
}
#[test]
fn bindgen_test_layout_NoPartialEq() {
assert_eq!(
::std::mem::size_of::<NoPartialEq>(),
4usize,
concat!("Size of: ", stringify!(NoPartialEq))
);
assert_eq!(
::std::mem::align_of::<NoPartialEq>(),
4usize,
concat!("Alignment of ", stringify!(NoPartialEq))
);
assert_eq!(
unsafe { &(*(0 as *const NoPartialEq)).i as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
stringify!(NoPartialEq),
"::",
stringify!(i)
)
);
}
impl Clone for NoPartialEq {
fn clone(&self) -> Self {
*self
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
/* automatically generated by rust-bindgen */


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


#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct NoPartialEq {
pub _address: u8,
}
#[test]
fn bindgen_test_layout_NoPartialEq() {
assert_eq!(
::std::mem::size_of::<NoPartialEq>(),
1usize,
concat!("Size of: ", stringify!(NoPartialEq))
);
assert_eq!(
::std::mem::align_of::<NoPartialEq>(),
1usize,
concat!("Alignment of ", stringify!(NoPartialEq))
);
}
impl Clone for NoPartialEq {
fn clone(&self) -> Self {
*self
}
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct WhitelistMe {
pub a: NoPartialEq,
}
#[test]
fn bindgen_test_layout_WhitelistMe() {
assert_eq!(
::std::mem::size_of::<WhitelistMe>(),
1usize,
concat!("Size of: ", stringify!(WhitelistMe))
);
assert_eq!(
::std::mem::align_of::<WhitelistMe>(),
1usize,
concat!("Alignment of ", stringify!(WhitelistMe))
);
assert_eq!(
unsafe { &(*(0 as *const WhitelistMe)).a as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
stringify!(WhitelistMe),
"::",
stringify!(a)
)
);
}
impl Clone for WhitelistMe {
fn clone(&self) -> Self {
*self
}
}
5 changes: 5 additions & 0 deletions tests/headers/no-partialeq-opaque.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// bindgen-flags: --with-derive-partialeq --opaque-type "NoPartialEq" --no-partialeq "NoPartialEq"

class NoPartialEq {
int i;
};
5 changes: 5 additions & 0 deletions tests/headers/no-partialeq-whitelisted.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
// bindgen-flags: --with-derive-partialeq --whitelist-type "NoPartialEq" --no-partialeq "NoPartialEq"

class NoPartialEq {
int i;
};
7 changes: 7 additions & 0 deletions tests/headers/whitelisted-item-references-no-partialeq.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
// bindgen-flags: --with-derive-partialeq --whitelist-type "WhitelistMe" --no-partialeq "NoPartialEq"

struct NoPartialEq {};

class WhitelistMe {
NoPartialEq a;
};

0 comments on commit ec8456b

Please sign in to comment.