Skip to content

Commit

Permalink
Auto merge of #81574 - tmiasko:p, r=oli-obk
Browse files Browse the repository at this point in the history
Precompute ancestors when checking privacy

Precompute ancestors of the old error node set so that check for private
types and traits in public interfaces can in constant time determine if
the current item has any descendants in the old error set.

This removes disparity in compilation time between public and private type
aliases reported in #50614 (from 30 s to 5 s, in an example making extensive use
of private type aliases).

No functional changes intended.
  • Loading branch information
bors committed Feb 18, 2021
2 parents 25a2c13 + b01976a commit cb2effd
Showing 1 changed file with 21 additions and 33 deletions.
54 changes: 21 additions & 33 deletions compiler/rustc_privacy/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1849,49 +1849,26 @@ impl DefIdVisitor<'tcx> for SearchInterfaceForPrivateItemsVisitor<'tcx> {
}
}

struct PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> {
struct PrivateItemsInPublicInterfacesVisitor<'tcx> {
tcx: TyCtxt<'tcx>,
has_pub_restricted: bool,
old_error_set: &'a HirIdSet,
old_error_set_ancestry: HirIdSet,
}

impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> {
impl<'tcx> PrivateItemsInPublicInterfacesVisitor<'tcx> {
fn check(
&self,
item_id: hir::HirId,
required_visibility: ty::Visibility,
) -> SearchInterfaceForPrivateItemsVisitor<'tcx> {
let mut has_old_errors = false;

// Slow path taken only if there any errors in the crate.
for &id in self.old_error_set {
// Walk up the nodes until we find `item_id` (or we hit a root).
let mut id = id;
loop {
if id == item_id {
has_old_errors = true;
break;
}
let parent = self.tcx.hir().get_parent_node(id);
if parent == id {
break;
}
id = parent;
}

if has_old_errors {
break;
}
}

SearchInterfaceForPrivateItemsVisitor {
tcx: self.tcx,
item_id,
item_def_id: self.tcx.hir().local_def_id(item_id).to_def_id(),
span: self.tcx.hir().span(item_id),
required_visibility,
has_pub_restricted: self.has_pub_restricted,
has_old_errors,
has_old_errors: self.old_error_set_ancestry.contains(&item_id),
in_assoc_ty: false,
}
}
Expand All @@ -1917,7 +1894,7 @@ impl<'a, 'tcx> PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> {
}
}

impl<'a, 'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'a, 'tcx> {
impl<'tcx> Visitor<'tcx> for PrivateItemsInPublicInterfacesVisitor<'tcx> {
type Map = Map<'tcx>;

fn nested_visit_map(&mut self) -> NestedVisitorMap<Self::Map> {
Expand Down Expand Up @@ -2137,11 +2114,22 @@ fn check_private_in_public(tcx: TyCtxt<'_>, krate: CrateNum) {
pub_restricted_visitor.has_pub_restricted
};

let mut old_error_set_ancestry = HirIdSet::default();
for mut id in visitor.old_error_set.iter().copied() {
loop {
if !old_error_set_ancestry.insert(id) {
break;
}
let parent = tcx.hir().get_parent_node(id);
if parent == id {
break;
}
id = parent;
}
}

// Check for private types and traits in public interfaces.
let mut visitor = PrivateItemsInPublicInterfacesVisitor {
tcx,
has_pub_restricted,
old_error_set: &visitor.old_error_set,
};
let mut visitor =
PrivateItemsInPublicInterfacesVisitor { tcx, has_pub_restricted, old_error_set_ancestry };
krate.visit_all_item_likes(&mut DeepVisitor::new(&mut visitor));
}

0 comments on commit cb2effd

Please sign in to comment.