Skip to content

Commit f315d2c

Browse files
author
bors-servo
authored
Auto merge of #1105 - seemyvest:issue-964, r=seemyvest
Add --no-hash <regex> flag Issue #964 - [x] Adding 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-hash <regex> CLI flags into invocations of the builder method. - [x] Making the MonotoneFramework::constrain function in src/ir/analysis/derive_hash.rs check if the given item is explicitly marked not to be Hash, and if so, inserting it into the self.cannot_derive_hash set via return self.insert(id). - [x] Tests! - [x] When the no-hash type is transitively referenced by a whitelisted item - [x] When the no-hash type is explicitly whitelisted - [x] When the no-hash type is marked opaque r? @fitzgen
2 parents 208b98a + 5d27156 commit f315d2c

File tree

10 files changed

+176
-0
lines changed

10 files changed

+176
-0
lines changed

src/ir/analysis/derive_hash.rs

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,10 @@ impl<'ctx> MonotoneFramework for CannotDeriveHash<'ctx> {
127127
}
128128
};
129129

130+
if self.ctx.no_hash_by_name(&item) {
131+
return self.insert(id)
132+
}
133+
130134
if item.is_opaque(self.ctx, &()) {
131135
let layout_can_derive = ty.layout(self.ctx).map_or(true, |l| {
132136
l.opaque().can_trivially_derive_hash()

src/ir/context.rs

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2495,6 +2495,12 @@ impl BindgenContext {
24952495
let name = item.canonical_path(self)[1..].join("::");
24962496
self.options().no_copy_types.matches(&name)
24972497
}
2498+
2499+
/// Chech if `--no-hash` flag is enabled for this item.
2500+
pub fn no_hash_by_name(&self, item: &Item) -> bool {
2501+
let name = item.canonical_path(self)[1..].join("::");
2502+
self.options().no_hash_types.matches(&name)
2503+
}
24982504
}
24992505

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

src/lib.rs

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -536,6 +536,20 @@ impl Builder {
536536
})
537537
.count();
538538

539+
self.options
540+
.no_hash_types
541+
.get_items()
542+
.iter()
543+
.map(|item| {
544+
output_vector.push("--no-hash".into());
545+
output_vector.push(
546+
item.trim_left_matches("^")
547+
.trim_right_matches("$")
548+
.into(),
549+
);
550+
})
551+
.count();
552+
539553
output_vector
540554
}
541555

@@ -1179,6 +1193,13 @@ impl Builder {
11791193
self.options.no_copy_types.insert(arg);
11801194
self
11811195
}
1196+
1197+
/// Don't derive `Hash` for a given type. Regular
1198+
/// expressions are supported.
1199+
pub fn no_hash(mut self, arg: String) -> Builder {
1200+
self.options.no_hash_types.insert(arg);
1201+
self
1202+
}
11821203
}
11831204

11841205
/// Configuration options for generated bindings.
@@ -1369,6 +1390,9 @@ struct BindgenOptions {
13691390

13701391
/// The set of types that we should not derive `Copy` for.
13711392
no_copy_types: RegexSet,
1393+
1394+
/// The set of types that we should not derive `Hash` for.
1395+
no_hash_types: RegexSet,
13721396
}
13731397

13741398
/// TODO(emilio): This is sort of a lie (see the error message that results from
@@ -1388,6 +1412,7 @@ impl BindgenOptions {
13881412
self.rustified_enums.build();
13891413
self.no_partialeq_types.build();
13901414
self.no_copy_types.build();
1415+
self.no_hash_types.build();
13911416
}
13921417

13931418
/// Update rust target version
@@ -1460,6 +1485,7 @@ impl Default for BindgenOptions {
14601485
rustfmt_configuration_file: None,
14611486
no_partialeq_types: Default::default(),
14621487
no_copy_types: Default::default(),
1488+
no_hash_types: Default::default(),
14631489
}
14641490
}
14651491
}

src/options.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -292,6 +292,13 @@ where
292292
.takes_value(true)
293293
.multiple(true)
294294
.number_of_values(1),
295+
Arg::with_name("no-hash")
296+
.long("no-hash")
297+
.help("Avoid deriving Hash for types matching <regex>.")
298+
.value_name("regex")
299+
.takes_value(true)
300+
.multiple(true)
301+
.number_of_values(1),
295302
]) // .args()
296303
.get_matches_from(args);
297304

@@ -592,6 +599,12 @@ where
592599
}
593600
}
594601

602+
if let Some(no_hash) = matches.values_of("no-hash") {
603+
for regex in no_hash {
604+
builder = builder.no_hash(String::from(regex));
605+
}
606+
}
607+
595608
let verbose = matches.is_present("verbose");
596609

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

tests/headers/no-hash-opaque.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// bindgen-flags: --with-derive-hash --opaque-type "NoHash" --no-hash "NoHash"
2+
3+
class NoHash {
4+
int i;
5+
};

tests/headers/no-hash-whitelisted.hpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// bindgen-flags: --with-derive-hash --whitelist-type "NoHash" --no-hash "NoHash"
2+
3+
class NoHash {
4+
int i;
5+
};
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
// bindgen-flags: --with-derive-hash --whitelist-type "WhitelistMe" --no-hash "NoHash"
2+
3+
struct NoHash {};
4+
5+
class WhitelistMe {
6+
NoHash a;
7+
};

0 commit comments

Comments
 (0)