Skip to content

Commit 4842973

Browse files
author
bors-servo
authored
Auto merge of #996 - alexeyzab:add-no-partialeq-command, r=fitzgen
Add --no-partialeq <regex> flag Related to #965. - [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 This is my first pass at implementing this functionality, I haven't implemented the tests yet. I wanted to make sure I am on the right track, particularly when it comes to updating `MonotoneFramework::constrain`. r? @fitzgen
2 parents de0180e + ec8456b commit 4842973

10 files changed

+197
-0
lines changed

src/ir/analysis/derive_partial_eq_or_partial_ord.rs

+4
Original file line numberDiff line numberDiff line change
@@ -128,6 +128,10 @@ impl<'ctx> MonotoneFramework for CannotDerivePartialEqOrPartialOrd<'ctx> {
128128
}
129129
};
130130

131+
if self.ctx.no_partialeq_by_name(&item) {
132+
return self.insert(id)
133+
}
134+
131135
trace!("ty: {:?}", ty);
132136
if item.is_opaque(self.ctx, &()) {
133137
let layout_can_derive = ty.layout(self.ctx).map_or(true, |l| {

src/ir/context.rs

+6
Original file line numberDiff line numberDiff line change
@@ -2213,6 +2213,12 @@ impl BindgenContext {
22132213
// float or not.
22142214
self.has_float.as_ref().unwrap().contains(id)
22152215
}
2216+
2217+
/// Check if `--no-partialeq` flag is enabled for this item.
2218+
pub fn no_partialeq_by_name(&self, item: &Item) -> bool {
2219+
let name = item.canonical_path(self)[1..].join("::");
2220+
self.options().no_partialeq_types.matches(&name)
2221+
}
22162222
}
22172223

22182224
/// A builder struct for configuring item resolution options.

src/lib.rs

+27
Original file line numberDiff line numberDiff line change
@@ -504,6 +504,20 @@ impl Builder {
504504
output_vector.push(path.into());
505505
}
506506

507+
self.options
508+
.no_partialeq_types
509+
.get_items()
510+
.iter()
511+
.map(|item| {
512+
output_vector.push("--no-partialeq".into());
513+
output_vector.push(
514+
item.trim_left_matches("^")
515+
.trim_right_matches("$")
516+
.into(),
517+
);
518+
})
519+
.count();
520+
507521
output_vector
508522
}
509523

@@ -1123,6 +1137,13 @@ impl Builder {
11231137
))
11241138
}
11251139
}
1140+
1141+
/// Don't derive `PartialEq` for a given type. Regular
1142+
/// expressions are supported.
1143+
pub fn no_partialeq(mut self, arg: String) -> Builder {
1144+
self.options.no_partialeq_types.insert(arg);
1145+
self
1146+
}
11261147
}
11271148

11281149
/// Configuration options for generated bindings.
@@ -1301,7 +1322,11 @@ struct BindgenOptions {
13011322

13021323
/// The absolute path to the rustfmt configuration file, if None, the standard rustfmt
13031324
/// options are used.
1325+
13041326
rustfmt_configuration_file: Option<PathBuf>,
1327+
1328+
/// The set of types that we should not derive `PartialEq` for.
1329+
no_partialeq_types: RegexSet,
13051330
}
13061331

13071332
/// TODO(emilio): This is sort of a lie (see the error message that results from
@@ -1319,6 +1344,7 @@ impl BindgenOptions {
13191344
self.bitfield_enums.build();
13201345
self.constified_enum_modules.build();
13211346
self.rustified_enums.build();
1347+
self.no_partialeq_types.build();
13221348
}
13231349

13241350
/// Update rust target version
@@ -1388,6 +1414,7 @@ impl Default for BindgenOptions {
13881414
time_phases: false,
13891415
rustfmt_bindings: false,
13901416
rustfmt_configuration_file: None,
1417+
no_partialeq_types: Default::default(),
13911418
}
13921419
}
13931420
}

src/options.rs

+13
Original file line numberDiff line numberDiff line change
@@ -270,6 +270,13 @@ where
270270
.takes_value(true)
271271
.multiple(false)
272272
.number_of_values(1),
273+
Arg::with_name("no-partialeq")
274+
.long("no-partialeq")
275+
.help("Avoid deriving PartialEq for types matching <regex>.")
276+
.value_name("regex")
277+
.takes_value(true)
278+
.multiple(true)
279+
.number_of_values(1),
273280
]) // .args()
274281
.get_matches_from(args);
275282

@@ -546,6 +553,12 @@ where
546553
builder = builder.rustfmt_configuration_file(Some(path));
547554
}
548555

556+
if let Some(no_partialeq) = matches.values_of("no-partialeq") {
557+
for regex in no_partialeq {
558+
builder = builder.no_partialeq(String::from(regex));
559+
}
560+
}
561+
549562
let verbose = matches.is_present("verbose");
550563

551564
Ok((builder, output, verbose))
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
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+
#[repr(C)]
8+
#[derive(Debug, Default, Copy)]
9+
pub struct NoPartialEq {
10+
pub _bindgen_opaque_blob: u32,
11+
}
12+
#[test]
13+
fn bindgen_test_layout_NoPartialEq() {
14+
assert_eq!(
15+
::std::mem::size_of::<NoPartialEq>(),
16+
4usize,
17+
concat!("Size of: ", stringify!(NoPartialEq))
18+
);
19+
assert_eq!(
20+
::std::mem::align_of::<NoPartialEq>(),
21+
4usize,
22+
concat!("Alignment of ", stringify!(NoPartialEq))
23+
);
24+
}
25+
impl Clone for NoPartialEq {
26+
fn clone(&self) -> Self {
27+
*self
28+
}
29+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
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+
#[repr(C)]
8+
#[derive(Debug, Default, Copy)]
9+
pub struct NoPartialEq {
10+
pub i: ::std::os::raw::c_int,
11+
}
12+
#[test]
13+
fn bindgen_test_layout_NoPartialEq() {
14+
assert_eq!(
15+
::std::mem::size_of::<NoPartialEq>(),
16+
4usize,
17+
concat!("Size of: ", stringify!(NoPartialEq))
18+
);
19+
assert_eq!(
20+
::std::mem::align_of::<NoPartialEq>(),
21+
4usize,
22+
concat!("Alignment of ", stringify!(NoPartialEq))
23+
);
24+
assert_eq!(
25+
unsafe { &(*(0 as *const NoPartialEq)).i as *const _ as usize },
26+
0usize,
27+
concat!(
28+
"Alignment of field: ",
29+
stringify!(NoPartialEq),
30+
"::",
31+
stringify!(i)
32+
)
33+
);
34+
}
35+
impl Clone for NoPartialEq {
36+
fn clone(&self) -> Self {
37+
*self
38+
}
39+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
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+
#[repr(C)]
8+
#[derive(Debug, Default, Copy)]
9+
pub struct NoPartialEq {
10+
pub _address: u8,
11+
}
12+
#[test]
13+
fn bindgen_test_layout_NoPartialEq() {
14+
assert_eq!(
15+
::std::mem::size_of::<NoPartialEq>(),
16+
1usize,
17+
concat!("Size of: ", stringify!(NoPartialEq))
18+
);
19+
assert_eq!(
20+
::std::mem::align_of::<NoPartialEq>(),
21+
1usize,
22+
concat!("Alignment of ", stringify!(NoPartialEq))
23+
);
24+
}
25+
impl Clone for NoPartialEq {
26+
fn clone(&self) -> Self {
27+
*self
28+
}
29+
}
30+
#[repr(C)]
31+
#[derive(Debug, Default, Copy)]
32+
pub struct WhitelistMe {
33+
pub a: NoPartialEq,
34+
}
35+
#[test]
36+
fn bindgen_test_layout_WhitelistMe() {
37+
assert_eq!(
38+
::std::mem::size_of::<WhitelistMe>(),
39+
1usize,
40+
concat!("Size of: ", stringify!(WhitelistMe))
41+
);
42+
assert_eq!(
43+
::std::mem::align_of::<WhitelistMe>(),
44+
1usize,
45+
concat!("Alignment of ", stringify!(WhitelistMe))
46+
);
47+
assert_eq!(
48+
unsafe { &(*(0 as *const WhitelistMe)).a as *const _ as usize },
49+
0usize,
50+
concat!(
51+
"Alignment of field: ",
52+
stringify!(WhitelistMe),
53+
"::",
54+
stringify!(a)
55+
)
56+
);
57+
}
58+
impl Clone for WhitelistMe {
59+
fn clone(&self) -> Self {
60+
*self
61+
}
62+
}

tests/headers/no-partialeq-opaque.hpp

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// bindgen-flags: --with-derive-partialeq --opaque-type "NoPartialEq" --no-partialeq "NoPartialEq"
2+
3+
class NoPartialEq {
4+
int i;
5+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// bindgen-flags: --with-derive-partialeq --whitelist-type "NoPartialEq" --no-partialeq "NoPartialEq"
2+
3+
class NoPartialEq {
4+
int i;
5+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// bindgen-flags: --with-derive-partialeq --whitelist-type "WhitelistMe" --no-partialeq "NoPartialEq"
2+
3+
struct NoPartialEq {};
4+
5+
class WhitelistMe {
6+
NoPartialEq a;
7+
};

0 commit comments

Comments
 (0)