Skip to content
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

Ensure that every item is in some module's children list #770

Merged
merged 5 commits into from
Jun 21, 2017

Conversation

fitzgen
Copy link
Member

@fitzgen fitzgen commented Jun 19, 2017

Previously, if an item's parent was not a module (eg a nested class definition whose parent it the outer class definition) and the parent was not whitelisted but the item was transitively whitelisted, then we could generate uses of the item without emitting any definition for it. This could happen because we were relying on the outer type calling for code generation on its inner types, but that relies on us doing code generation for the outer type, which won't happen if the outer type is not whitelisted.

This commit avoids this gotcha by ensuring that all items end up in a module's children list, and so will be code generated even if their parent is not whitelisted.

This does have the downside of changing the relative order of some of the emitted code, and so this has a big diff (as will the next bindgen update for downstream dependencies) but I actually think the newer order makes more sense, for what that is worth.

Fixes #769

r? @emilio

@highfive
Copy link

warning Warning warning

  • These commits modify unsafe code. Please review it carefully!

@fitzgen
Copy link
Member Author

fitzgen commented Jun 19, 2017

Looks like this uncovered a bug with static variables whose type is a template type parameter. Coming up with a fix for that too.

@fitzgen fitzgen force-pushed the issue-769-bad-instantiation-test branch 3 times, most recently from fcfc166 to 6a92092 Compare June 19, 2017 23:48
@fitzgen
Copy link
Member Author

fitzgen commented Jun 19, 2017

Huh, now I'm getting tripped up by the recent naming scheme change for the layout tests for template instantiations. It appears it isn't as unique as we'd hoped.

@fitzgen
Copy link
Member Author

fitzgen commented Jun 20, 2017

Going to use the overloaded function counter instead.

@fitzgen fitzgen force-pushed the issue-769-bad-instantiation-test branch from 6a92092 to 7519eb9 Compare June 20, 2017 00:06
Copy link
Contributor

@emilio emilio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks sensible, r=me

// Be sure to track all the generated children under namespace, even
// those generated after resolving typerefs, etc.
// Ensure that every item (other than the root module) is in a module's
// children list.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe point to the issue this is fixing or something? it may be slightly counter-intuitive otherwise.

}
}

if !added_as_child {
if let Some(mut current_module) = self.items.get_mut(&self.current_module) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can probably unwrap here instead of asserting below?

@emilio
Copy link
Contributor

emilio commented Jun 20, 2017

This seems to make the order of the generated bindings not match across libclang versions though, and thus CI is red.

@fitzgen
Copy link
Member Author

fitzgen commented Jun 20, 2017

Thanks for review! (Sorry it's such a huge diff)

This seems to make the order of the generated bindings not match across libclang versions though, and thus CI is red.

I'll make the children an ItemSet instead of a Vec. This has two advantages:

  1. An ItemSet is ordered, so we should get deterministic iteration of a module's children (and therefore emit them in that deterministic order during codegen)

  2. It disallows duplicate entries (which should be harmless, but its so easy to prevent that it seems crazy not to prevent it).

Before this commit, test-one.sh was unusable with tests/headers/template.hpp
because there were too many things with "template.hpp" as a suffix. This allows
us to specify "/template.hpp" to run the test.
@fitzgen fitzgen force-pushed the issue-769-bad-instantiation-test branch from 7519eb9 to 8536a6b Compare June 20, 2017 17:40
@fitzgen
Copy link
Member Author

fitzgen commented Jun 20, 2017

I expect CI will still be red, since I need to get the diffs for libclang 3.8 and 3.9

@fitzgen fitzgen force-pushed the issue-769-bad-instantiation-test branch from 8536a6b to c79a0a2 Compare June 20, 2017 21:48
@fitzgen
Copy link
Member Author

fitzgen commented Jun 20, 2017

This might need some more updates for other libclang versions, but I'm not 100%.

In any case, it probably deserves a second glance, since a bunch of code changed from the version you reviewed before, @emilio.

r? @emilio

@fitzgen fitzgen force-pushed the issue-769-bad-instantiation-test branch from c79a0a2 to 06a96bb Compare June 20, 2017 22:04
Previously, if an item's parent was not a module (eg a nested class definition
whose parent it the outer class definition) and the parent was not whitelisted
but the item was transitively whitelisted, then we could generate uses of the
item without emitting any definition for it. This could happen because we were
relying on the outer type calling for code generation on its inner types, but
that relies on us doing code generation for the outer type, which won't happen
if the outer type is not whitelisted.

This commit avoids this gotcha by ensuring that all items end up in a module's
children list, and so will be code generated even if their parent is not
whitelisted.

Fixes rust-lang#769
There's a lot of these edges so it helps to make them un-bold.
This commit adds assertions that run when the "testing_only_extra_assertions"
feature is enabled, which make sure that every single item we parse is a child
of some ancestor module.
@fitzgen fitzgen force-pushed the issue-769-bad-instantiation-test branch from 06a96bb to c736faa Compare June 20, 2017 22:35
@fitzgen
Copy link
Member Author

fitzgen commented Jun 20, 2017

Ok, tests for other libclang versions should be good to go.

Copy link
Contributor

@emilio emilio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks sensible, some questions

@@ -34,3 +34,7 @@ impl Clone for C {
impl Default for C {
fn default() -> Self { unsafe { ::std::mem::zeroed() } }
}
extern "C" {
#[link_name = "_ZN1C5matchEv"]
pub fn C_match(this: *mut ::std::os::raw::c_void);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So, these are somewhat surprising, because AIUI they aren't referenced from anywhere... Perhaps it's not a big deal...

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These get generated because the functions are no longer defined inline in the header, just declared -- maybe I am misunderstanding you?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Err, my fault, for some reason I thought this was a destructor... nevermind.

@@ -1038,13 +1105,14 @@ impl<'ctx> BindgenContext<'ctx> {
let sub_item = Item::new(sub_id,
None,
None,
template_decl_id,
self.current_module,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So we'll instantiate templates against the current module? Even if they're nested? That looks suspicious. The parentage relationship for...

struct Foo {
    template<typename T> struct Bar { T baz; };
    Bar<int> m_member;
};

So, if I'm reading this correctly, we'll scope Bar<int> to the gloal scope, not to Foo, right? Can you justify that? If it doesn't matter (which I think it could be true). Could you add a comment?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I just changed from one well-known-but-sort-of-bogus parent to another well-known-but-sort-of-bogus parent.

They used to always be parented by the template definition, which doesn't really make sense either, just happened to be handy when the "real" parent wasn't.

I can definitely add a comment.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Comment added.

@emilio
Copy link
Contributor

emilio commented Jun 20, 2017

@bors-servo r+

@bors-servo
Copy link

📌 Commit 5230565 has been approved by emilio

@bors-servo
Copy link

⌛ Testing commit 5230565 with merge 232a21e...

bors-servo pushed a commit that referenced this pull request Jun 20, 2017
Ensure that every item is in some module's children list

Previously, if an item's parent was not a module (eg a nested class definition whose parent it the outer class definition) and the parent was not whitelisted but the item was transitively whitelisted, then we could generate uses of the item without emitting any definition for it. This could happen because we were relying on the outer type calling for code generation on its inner types, but that relies on us doing code generation for the outer type, which won't happen if the outer type is not whitelisted.

This commit avoids this gotcha by ensuring that all items end up in a module's children list, and so will be code generated even if their parent is not whitelisted.

This does have the downside of changing the relative order of some of the emitted code, and so this has a big diff (as will the next bindgen update for downstream dependencies) but I actually think the newer order makes more sense, for what that is worth.

Fixes #769

r? @emilio
@fitzgen
Copy link
Member Author

fitzgen commented Jun 20, 2017

Thanks!

@bors-servo
Copy link

☀️ Test successful - status-travis
Approved by: emilio
Pushing 232a21e to master...

@bors-servo bors-servo merged commit 5230565 into rust-lang:master Jun 21, 2017
@fitzgen fitzgen deleted the issue-769-bad-instantiation-test branch June 21, 2017 00:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

4 participants