Join GitHub today
GitHub is home to over 31 million developers working together to host and review code, manage projects, and build software together.
Sign upprivacy: Mark reachable but unnameable items as reachable #31641
Conversation
rust-highfive
assigned
alexcrichton
Feb 13, 2016
This comment has been minimized.
This comment has been minimized.
|
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. |
This comment has been minimized.
This comment has been minimized.
|
Updated with more tests. |
nikomatsakis
reviewed
Feb 16, 2016
| } | ||
| // 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)); |
This comment has been minimized.
This comment has been minimized.
nikomatsakis
Feb 16, 2016
Contributor
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?
This comment has been minimized.
This comment has been minimized.
nikomatsakis
Feb 16, 2016
Contributor
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.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
petrochenkov
Feb 16, 2016
Author
Contributor
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.
This comment has been minimized.
This comment has been minimized.
|
OK, I think I would r+ modulo my question about the variant case above. |
alexcrichton
reviewed
Feb 17, 2016
| if item_level.is_some() { | ||
| self.reach().visit_generics(generics); | ||
| for field in struct_def.fields() { | ||
| if field.node.kind.visibility() == hir::Public { |
This comment has been minimized.
This comment has been minimized.
alexcrichton
Feb 17, 2016
Member
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?
This comment has been minimized.
This comment has been minimized.
petrochenkov
Feb 17, 2016
Author
Contributor
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.
This comment has been minimized.
This comment has been minimized.
alexcrichton
Feb 17, 2016
Member
Ah ok, thanks for the clarification! For readability could this move to self.get as the same pattern as well?
alexcrichton
reviewed
Feb 17, 2016
| } | ||
|
|
||
| impl<'b, 'a, 'tcx: 'a, 'v> Visitor<'v> for ReachEverythingInTheInterfaceVisitor<'b, 'a, 'tcx> { | ||
| fn visit_ty(&mut self, ty: &hir::Ty) { |
This comment has been minimized.
This comment has been minimized.
alexcrichton
Feb 17, 2016
Member
I guess so another thing I'm a little confused about is why two visitors are needed? It looks like the EmbargoVisitor should walk the entire AST, right? In that case, couldn't this just be part of that?
I guess to me this algorithm should look like:
- Initialize a reachable set with all public items
- While the set has an item in it:
- Walk the reachable interface of the item
- For each item encountered, add it to the global reachable
This is then repeated iteratively until the set is saturated. There's only one "recurse the interface" step, however, so I'm not entirely sure where this second visitor fits in?
I may and probably am missing something though! Could you help clarify?
This comment has been minimized.
This comment has been minimized.
petrochenkov
Feb 17, 2016
Author
Contributor
This PR merely extends the existing pretty inefficient implementation of EmbargoVisito which runs walk_crate several times in a loop without any working set and graph-like traversal. I plan to rewrite it eventually, but don't have time to do it right now.
Regardless of that, having two visitors with different purposes is just convenient. One big visitor walks items and recurses into them, another small and shallow visitor walks item's surfaces without going too deep. Private-in-public visitor has the same separation of concerns.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
This comment has been minimized.
|
Also, thanks for expanding the test! I'm certainly much more comfortable with this now :) |
This comment has been minimized.
This comment has been minimized.
|
ah yeah and to clarify r=me as well, thanks again @petrochenkov! |
petrochenkov
added some commits
Feb 13, 2016
petrochenkov
force-pushed the
petrochenkov:reach
branch
from
eb3bb4e
to
fadc95e
Feb 17, 2016
This comment has been minimized.
This comment has been minimized.
|
@alexcrichton |
petrochenkov commentedFeb 13, 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