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

privacy: Mark reachable but unnameable items as reachable #31641

Merged
merged 3 commits into from
Feb 18, 2016

Conversation

petrochenkov
Copy link
Contributor

Fixes #16734 and probably some other issues

This is a continuation of #29822, but the algorithm is mostly a copy of #29973, so
r? @alexcrichton or @nikomatsakis

@alexcrichton
Copy link
Member

Thanks @petrochenkov! Knocking out <20k bugs now should get like an extra badge or something...

I'll be honest though in that I'm not really following everything that's going on here, there's quite a few branches which try to add lots of items to the reachable set. I may just not be following what's going on here, but could this perhaps add a few more tests? There's a boatload of test cases dangling off #16734, and I suspect that each addition to the reachable set in this PR corresponds to some test case which wouldn't otherwise be caught.

@petrochenkov
Copy link
Contributor Author

Updated with more tests.

}
// Corner case: if the variant is reachable, but its
// enum is not, make the enum reachable as well.
self.update(item.id, Some(AccessLevel::Reachable));
Copy link
Contributor

Choose a reason for hiding this comment

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

Does this mean that you should go back and call visit_generics too (i.e., as would have happened on line 323?) If so, maybe we should promote this special case upward somewhere?

Copy link
Contributor

Choose a reason for hiding this comment

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

Also, do we have a regression test for this scenario? (Seems like a good one). If so, you should cite it in the comment here.

Copy link
Contributor

Choose a reason for hiding this comment

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

Ah, I see this scenario is covered in the test you added.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Does this mean that you should go back and call visit_generics too (i.e., as would have happened on line 323?)

The whole EmbargoVisitor::visit_crate runs in a loop until it saturates and nothing is updated anymore (yeah, it should probably be optimized into some DFS or BFS, but it's a separate task).
So, the worst thing can happen here is one more loop cycle in exceedingly rare case of unnameable enum with nameable variant.

@nikomatsakis
Copy link
Contributor

OK, I think I would r+ modulo my question about the variant case above.

if item_level.is_some() {
self.reach().visit_generics(generics);
for field in struct_def.fields() {
if field.node.kind.visibility() == hir::Public {
Copy link
Member

Choose a reason for hiding this comment

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

It's been awhile since I've done much with this code, but could you help clarify what's going on here? In other places here it looks like you're checking for "is this reachable" via checking self.get(item.id).is_some(). I think that get returns the level of exported-ness of the id, right?

If that's the case, how come this checks for Public instead of leveraging self.get?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Variants and foreign items have their own accessibility levels - they can be reexported independently from their parents enums and foreign modules. So, we have to check them with self.get(id).is_some().
pub struct fields and inherent impl items are always reachable if their parents are reachable, we could check them with self.get(id).is_some() as well, but it wouldn't make any difference.

Copy link
Member

Choose a reason for hiding this comment

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

Ah ok, thanks for the clarification! For readability could this move to self.get as the same pattern as well?

@alexcrichton
Copy link
Member

Also, thanks for expanding the test! I'm certainly much more comfortable with this now :)

@alexcrichton
Copy link
Member

ah yeah and to clarify r=me as well, thanks again @petrochenkov!

@petrochenkov
Copy link
Contributor Author

@alexcrichton
Updated.

@alexcrichton
Copy link
Member

@bors: r+ fadc95e

@bors
Copy link
Contributor

bors commented Feb 18, 2016

⌛ Testing commit fadc95e with merge a9430a3...

bors added a commit that referenced this pull request Feb 18, 2016
Fixes #16734 and probably some other issues

This is a continuation of #29822, but the algorithm is mostly a copy of #29973, so
r? @alexcrichton or @nikomatsakis
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.

4 participants