Skip to content

Extra assertions and cargo features #618

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 7, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -65,12 +65,12 @@ $ export LD_LIBRARY_PATH=path/to/clang-3.9/lib # for Linux
$ export DYLD_LIBRARY_PATH=path/to/clang-3.9/lib # for macOS
```

Additionally, you may want to build and test with the `docs_` feature to ensure
that you aren't forgetting to document types and functions. CI will catch it if
you forget, but the turn around will be a lot slower ;)
Additionally, you may want to build and test with the `testing_only_docs`
feature to ensure that you aren't forgetting to document types and functions. CI
will catch it if you forget, but the turn around will be a lot slower ;)

```
$ cargo build --features docs_
$ cargo build --features testing_only_docs
```

## Testing
Expand Down
10 changes: 6 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,12 @@ features = ["with-syntex"]
version = "0.29"

[features]
assert_no_dangling_items = []
default = ["logging"]
testing_only_llvm_stable = []
logging = ["env_logger", "log"]
static = []
# This feature only exists for CI -- don't use it!
docs_ = []

# These features only exist for CI testing -- don't use them if you're not hacking
# on bindgen!
testing_only_docs = []
testing_only_extra_assertions = []
testing_only_llvm_stable = []
2 changes: 1 addition & 1 deletion ci/assert-docs.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,4 +3,4 @@
set -xeu
cd "$(dirname "$0")/.."

cargo build --features "$BINDGEN_FEATURES docs_"
cargo build --features "$BINDGEN_FEATURES testing_only_docs"
7 changes: 5 additions & 2 deletions ci/test.sh
Original file line number Diff line number Diff line change
Expand Up @@ -6,10 +6,13 @@ cd "$(dirname "$0")/.."
# Regenerate the test headers' bindings in debug and release modes, and assert
# that we always get the expected generated bindings.

cargo test --features "$BINDGEN_FEATURES assert_no_dangling_items"
cargo test --features "$BINDGEN_FEATURES"
./ci/assert-no-diff.sh

cargo test --features "$BINDGEN_FEATURES testing_only_extra_assertions"
./ci/assert-no-diff.sh

cargo test --release --features "$BINDGEN_FEATURES assert_no_dangling_items"
cargo test --release --features "$BINDGEN_FEATURES testing_only_extra_assertions"
./ci/assert-no-diff.sh

# Now test the expectations' size and alignment tests.
Expand Down
2 changes: 1 addition & 1 deletion src/codegen/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2642,7 +2642,7 @@ impl TryToRustTy for TemplateInstantiation {
// This can happen if we generated an opaque type for a partial
// template specialization, and we've hit an instantiation of
// that partial specialization.
debug_assert!(ctx.resolve_type_through_type_refs(decl)
extra_assert!(ctx.resolve_type_through_type_refs(decl)
.is_opaque());
return Err(error::Error::InstantiationOfOpaqueType);
}
Expand Down
30 changes: 30 additions & 0 deletions src/extra_assertions.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
//! Macros for defining extra assertions that should only be checked in testing
//! and/or CI when the `testing_only_extra_assertions` feature is enabled.

#[macro_export]
macro_rules! extra_assert {
( $cond:expr ) => {
if cfg!(feature = "testing_only_extra_assertions") {
assert!($cond);
}
};
( $cond:expr , $( $arg:tt )+ ) => {
if cfg!(feature = "testing_only_extra_assertions") {
assert!($cond, $( $arg )* )
}
};
}

#[macro_export]
macro_rules! extra_assert_eq {
( $lhs:expr , $rhs:expr ) => {
if cfg!(feature = "testing_only_extra_assertions") {
assert_eq!($lhs, $rhs);
}
};
( $lhs:expr , $rhs:expr , $( $arg:tt )+ ) => {
if cfg!(feature = "testing_only_extra_assertions") {
assert!($lhs, $rhs, $( $arg )* );
}
};
}
6 changes: 4 additions & 2 deletions src/ir/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -584,9 +584,11 @@ impl<'ctx> BindgenContext<'ctx> {
ret
}

/// This function trying to find any dangling references inside of `items`
/// When the `testing_only_extra_assertions` feature is enabled, this
/// function walks the IR graph and asserts that we do not have any edges
/// referencing an ItemId for which we do not have an associated IR item.
fn assert_no_dangling_references(&self) {
if cfg!(feature = "assert_no_dangling_items") {
if cfg!(feature = "testing_only_extra_assertions") {
for _ in self.assert_no_dangling_item_traversal() {
// The iterator's next method does the asserting for us.
}
Expand Down
6 changes: 3 additions & 3 deletions src/ir/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,7 @@ pub trait ItemAncestors {
}

cfg_if! {
if #[cfg(debug_assertions)] {
if #[cfg(testing_only_extra_assertions)] {
type DebugOnlyItemSet = ItemSet;
} else {
struct DebugOnlyItemSet;
Expand Down Expand Up @@ -123,7 +123,7 @@ impl<'a, 'b> Iterator for ItemAncestorsIter<'a, 'b>
} else {
self.item = item.parent_id();

debug_assert!(!self.seen.contains(&item.id()));
extra_assert!(!self.seen.contains(&item.id()));
self.seen.insert(item.id());

Some(item.id())
Expand Down Expand Up @@ -614,7 +614,7 @@ impl Item {
let mut item = self;

loop {
debug_assert!(!targets_seen.contains(&item.id()));
extra_assert!(!targets_seen.contains(&item.id()));
targets_seen.insert(item.id());

if self.annotations().use_instead_of().is_some() {
Expand Down
4 changes: 2 additions & 2 deletions src/ir/named.rs
Original file line number Diff line number Diff line change
Expand Up @@ -371,7 +371,7 @@ impl<'ctx, 'gen> MonotoneFramework for UsedTemplateParameters<'ctx, 'gen> {
fn constrain(&mut self, id: ItemId) -> bool {
// Invariant: all hash map entries' values are `Some` upon entering and
// exiting this method.
debug_assert!(self.used.values().all(|v| v.is_some()));
extra_assert!(self.used.values().all(|v| v.is_some()));

// Take the set for this id out of the hash map while we mutate it based
// on other hash map entries. We *must* put it back into the hash map at
Expand Down Expand Up @@ -437,7 +437,7 @@ impl<'ctx, 'gen> MonotoneFramework for UsedTemplateParameters<'ctx, 'gen> {

// Put the set back in the hash map and restore our invariant.
self.used.insert(id, Some(used_by_this_id));
debug_assert!(self.used.values().all(|v| v.is_some()));
extra_assert!(self.used.values().all(|v| v.is_some()));

new_len != original_len
}
Expand Down
11 changes: 7 additions & 4 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -37,16 +37,19 @@ extern crate log;
#[macro_use]
mod log_stubs;

#[macro_use]
mod extra_assertions;

// A macro to declare an internal module for which we *must* provide
// documentation for. If we are building with the "docs_" feature, then the
// module is declared public, and our `#![deny(missing_docs)]` pragma applies to
// it. This feature is used in CI, so we won't let anything slip by
// documentation for. If we are building with the "testing_only_docs" feature,
// then the module is declared public, and our `#![deny(missing_docs)]` pragma
// applies to it. This feature is used in CI, so we won't let anything slip by
// undocumented. Normal builds, however, will leave the module private, so that
// we don't expose internals to library consumers.
macro_rules! doc_mod {
($m:ident, $doc_mod_name:ident) => {
cfg_if! {
if #[cfg(feature = "docs_")] {
if #[cfg(feature = "testing_only_docs")] {
pub mod $doc_mod_name {
//! Autogenerated documentation module.
pub use super::$m::*;
Expand Down