Skip to content

Commit 68aaafd

Browse files
committed
Resolve rust-lang#962 - implement --no-copy with tests
1 parent 8582a90 commit 68aaafd

File tree

7 files changed

+68
-0
lines changed

7 files changed

+68
-0
lines changed

src/ir/analysis/derive_copy.rs

+4
Original file line numberDiff line numberDiff line change
@@ -143,6 +143,10 @@ impl<'ctx> MonotoneFramework for CannotDeriveCopy<'ctx> {
143143
}
144144
};
145145

146+
if self.ctx.no_copy_by_name(&item) {
147+
return self.insert(id);
148+
}
149+
146150
if item.is_opaque(self.ctx, &()) {
147151
let layout_can_derive = ty.layout(self.ctx).map_or(true, |l| {
148152
l.opaque().can_trivially_derive_copy()

src/ir/context.rs

+8
Original file line numberDiff line numberDiff line change
@@ -2450,8 +2450,16 @@ impl BindgenContext {
24502450
/// Check if `--no-partialeq` flag is enabled for this item.
24512451
pub fn no_partialeq_by_name(&self, item: &Item) -> bool {
24522452
let name = item.canonical_path(self)[1..].join("::");
2453+
24532454
self.options().no_partialeq_types.matches(&name)
24542455
}
2456+
2457+
/// Check if `--no-copy` flag is enabled for this item.
2458+
pub fn no_copy_by_name(&self, item: &Item) -> bool {
2459+
let name = item.canonical_path(self)[1..].join("::");
2460+
2461+
self.options().no_copy_types.matches(&name)
2462+
}
24552463
}
24562464

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

src/lib.rs

+26
Original file line numberDiff line numberDiff line change
@@ -522,6 +522,20 @@ impl Builder {
522522
})
523523
.count();
524524

525+
self.options
526+
.no_copy_types
527+
.get_items()
528+
.iter()
529+
.map(|item| {
530+
output_vector.push("--no-copy".into());
531+
output_vector.push(
532+
item.trim_left_matches("^")
533+
.trim_right_matches("$")
534+
.into(),
535+
);
536+
})
537+
.count();
538+
525539
output_vector
526540
}
527541

@@ -1158,6 +1172,13 @@ impl Builder {
11581172
self.options.no_partialeq_types.insert(arg);
11591173
self
11601174
}
1175+
1176+
/// Don't derive `Copy` for a given type. Regular
1177+
/// expressions are supported.
1178+
pub fn no_copy(mut self, arg: String) -> Self {
1179+
self.options.no_copy_types.insert(arg);
1180+
self
1181+
}
11611182
}
11621183

11631184
/// Configuration options for generated bindings.
@@ -1345,6 +1366,9 @@ struct BindgenOptions {
13451366

13461367
/// The set of types that we should not derive `PartialEq` for.
13471368
no_partialeq_types: RegexSet,
1369+
1370+
/// The set of types that we should not derive `Copy` for.
1371+
no_copy_types: RegexSet,
13481372
}
13491373

13501374
/// TODO(emilio): This is sort of a lie (see the error message that results from
@@ -1363,6 +1387,7 @@ impl BindgenOptions {
13631387
self.constified_enum_modules.build();
13641388
self.rustified_enums.build();
13651389
self.no_partialeq_types.build();
1390+
self.no_copy_types.build();
13661391
}
13671392

13681393
/// Update rust target version
@@ -1434,6 +1459,7 @@ impl Default for BindgenOptions {
14341459
rustfmt_bindings: true,
14351460
rustfmt_configuration_file: None,
14361461
no_partialeq_types: Default::default(),
1462+
no_copy_types: Default::default(),
14371463
}
14381464
}
14391465
}

src/options.rs

+13
Original file line numberDiff line numberDiff line change
@@ -285,6 +285,13 @@ where
285285
.takes_value(true)
286286
.multiple(true)
287287
.number_of_values(1),
288+
Arg::with_name("no-copy")
289+
.long("no-copy")
290+
.help("Avoid deriving Copy for types matching <regex>.")
291+
.value_name("regex")
292+
.takes_value(true)
293+
.multiple(true)
294+
.number_of_values(1),
288295
]) // .args()
289296
.get_matches_from(args);
290297

@@ -579,6 +586,12 @@ where
579586
}
580587
}
581588

589+
if let Some(no_partialeq) = matches.values_of("no-copy") {
590+
for regex in no_partialeq {
591+
builder = builder.no_copy(String::from(regex));
592+
}
593+
}
594+
582595
let verbose = matches.is_present("verbose");
583596

584597
Ok((builder, output, verbose))

tests/headers/no-copy-opaque.hpp

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// bindgen-flags: --with-derive-copy --opaque-type "NoCopy" --no-copy "NoCopy"
2+
3+
class NoCopy {
4+
int i;
5+
};

tests/headers/no-copy-whitelisted.h

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

0 commit comments

Comments
 (0)