Skip to content

Commit b888dc9

Browse files
committed
moving public/export res to resolve
1 parent e502f0c commit b888dc9

File tree

6 files changed

+75
-143
lines changed

6 files changed

+75
-143
lines changed

Diff for: compiler/rustc_middle/src/middle/privacy.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ pub enum AccessLevel {
2626
}
2727

2828
/// Holds a map of accessibility levels for reachable HIR nodes.
29-
#[derive(Debug)]
29+
#[derive(Debug, Clone)]
3030
pub struct AccessLevels<Id = LocalDefId> {
3131
pub map: FxHashMap<Id, AccessLevel>,
3232
}

Diff for: compiler/rustc_middle/src/ty/context.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use crate::infer::canonical::{Canonical, CanonicalVarInfo, CanonicalVarInfos};
88
use crate::lint::{struct_lint_level, LintDiagnosticBuilder, LintLevelSource};
99
use crate::middle;
1010
use crate::middle::cstore::EncodedMetadata;
11-
use crate::middle::privacy::AccessLevel;
11+
use crate::middle::privacy::AccessLevels;
1212
use crate::middle::resolve_lifetime::{self, LifetimeScopeForPath, ObjectLifetimeDefault};
1313
use crate::middle::stability;
1414
use crate::mir::interpret::{self, AllocId, Allocation, ConstValue, Scalar};
@@ -1161,8 +1161,8 @@ impl<'tcx> TyCtxt<'tcx> {
11611161
)
11621162
}
11631163

1164-
pub fn get_resolver_access_level(self, local_def_id: LocalDefId) -> Option<AccessLevel> {
1165-
self.gcx.untracked_resolutions.access_levels.get(&local_def_id).copied()
1164+
pub fn get_resolver_access_levels(self) -> AccessLevels {
1165+
self.gcx.untracked_resolutions.access_levels.clone()
11661166
}
11671167

11681168
pub fn lift<T: Lift<'tcx>>(self, value: T) -> Option<T::Lifted> {

Diff for: compiler/rustc_middle/src/ty/mod.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ pub use vtable::*;
2323
use crate::hir::exports::ExportMap;
2424
use crate::ich::StableHashingContext;
2525
use crate::middle::cstore::CrateStoreDyn;
26-
use crate::middle::privacy::AccessLevel;
26+
use crate::middle::privacy::AccessLevels;
2727
use crate::mir::{Body, GeneratorLayout};
2828
use crate::traits::{self, Reveal};
2929
use crate::ty;
@@ -119,7 +119,7 @@ pub struct ResolverOutputs {
119119
pub definitions: rustc_hir::definitions::Definitions,
120120
pub cstore: Box<CrateStoreDyn>,
121121
pub visibilities: FxHashMap<LocalDefId, Visibility>,
122-
pub access_levels: FxHashMap<LocalDefId, AccessLevel>,
122+
pub access_levels: AccessLevels,
123123
pub extern_crate_map: FxHashMap<LocalDefId, CrateNum>,
124124
pub maybe_unused_trait_imports: FxHashSet<LocalDefId>,
125125
pub maybe_unused_extern_crates: Vec<(LocalDefId, Span)>,

Diff for: compiler/rustc_privacy/src/lib.rs

+13-111
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ use rustc_data_structures::fx::FxHashSet;
1111
use rustc_errors::struct_span_err;
1212
use rustc_hir as hir;
1313
use rustc_hir::def::{DefKind, Res};
14-
use rustc_hir::def_id::{DefId, LocalDefId};
14+
use rustc_hir::def_id::{DefId, LocalDefId, CRATE_DEF_ID};
1515
use rustc_hir::intravisit::{self, DeepVisitor, NestedVisitorMap, Visitor};
1616
use rustc_hir::{AssocItemKind, HirIdSet, Node, PatKind};
1717
use rustc_middle::bug;
@@ -586,107 +586,26 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
586586
}
587587

588588
fn visit_item(&mut self, item: &'tcx hir::Item<'tcx>) {
589-
let inherited_item_level = match item.kind {
590-
hir::ItemKind::Impl { .. } => {
591-
Option::<AccessLevel>::of_impl(item.hir_id(), self.tcx, &self.access_levels)
592-
}
593-
// Foreign modules inherit level from parents.
594-
hir::ItemKind::ForeignMod { .. }
595-
| hir::ItemKind::Const(..)
596-
| hir::ItemKind::Enum(..)
597-
| hir::ItemKind::ExternCrate(..)
598-
| hir::ItemKind::GlobalAsm(..)
599-
| hir::ItemKind::Fn(..)
600-
| hir::ItemKind::Mod(..)
601-
| hir::ItemKind::Static(..)
602-
| hir::ItemKind::Struct(..)
603-
| hir::ItemKind::Trait(..)
604-
| hir::ItemKind::TraitAlias(..)
605-
| hir::ItemKind::OpaqueTy(..)
606-
| hir::ItemKind::TyAlias(..)
607-
| hir::ItemKind::Union(..)
608-
| hir::ItemKind::Use(..) => {
609-
if item.vis.node.is_pub() {
610-
self.prev_level
611-
} else {
612-
None
613-
}
614-
}
615-
};
616-
617-
// Update level of the item itself.
618-
let item_level = self.update(item.def_id, inherited_item_level);
619-
620-
// Update levels of nested things.
621-
match item.kind {
622-
hir::ItemKind::Enum(ref def, _) => {
623-
for variant in def.variants {
624-
let variant_level =
625-
self.update(self.tcx.hir().local_def_id(variant.id), item_level);
626-
if let Some(ctor_hir_id) = variant.data.ctor_hir_id() {
627-
self.update(self.tcx.hir().local_def_id(ctor_hir_id), item_level);
628-
}
629-
for field in variant.data.fields() {
630-
self.update(self.tcx.hir().local_def_id(field.hir_id), variant_level);
631-
}
632-
}
633-
}
634-
hir::ItemKind::Impl(ref impl_) => {
635-
for impl_item_ref in impl_.items {
636-
if impl_.of_trait.is_some() || impl_item_ref.vis.node.is_pub() {
637-
self.update(impl_item_ref.id.def_id, item_level);
638-
}
639-
}
640-
}
641-
hir::ItemKind::Trait(.., trait_item_refs) => {
642-
for trait_item_ref in trait_item_refs {
643-
self.update(trait_item_ref.id.def_id, item_level);
589+
if let hir::ItemKind::Impl(ref impl_data) = item.kind {
590+
let impl_level =
591+
Option::<AccessLevel>::of_impl(item.hir_id(), self.tcx, &self.access_levels);
592+
self.update(item.def_id, impl_level);
593+
for nested in impl_data.items {
594+
if impl_data.of_trait.is_some() || nested.vis.node.is_pub() {
595+
self.update(nested.id.def_id, impl_level);
644596
}
645597
}
646-
hir::ItemKind::Struct(ref def, _) | hir::ItemKind::Union(ref def, _) => {
647-
if let Some(ctor_hir_id) = def.ctor_hir_id() {
648-
self.update(self.tcx.hir().local_def_id(ctor_hir_id), item_level);
649-
}
650-
for field in def.fields() {
651-
if field.vis.node.is_pub() {
652-
self.update(self.tcx.hir().local_def_id(field.hir_id), item_level);
653-
}
654-
}
655-
}
656-
hir::ItemKind::ForeignMod { items, .. } => {
657-
for foreign_item in items {
658-
if foreign_item.vis.node.is_pub() {
659-
self.update(foreign_item.id.def_id, item_level);
660-
}
661-
}
662-
}
663-
hir::ItemKind::OpaqueTy(..)
664-
| hir::ItemKind::Use(..)
665-
| hir::ItemKind::Static(..)
666-
| hir::ItemKind::Const(..)
667-
| hir::ItemKind::GlobalAsm(..)
668-
| hir::ItemKind::TyAlias(..)
669-
| hir::ItemKind::Mod(..)
670-
| hir::ItemKind::TraitAlias(..)
671-
| hir::ItemKind::Fn(..)
672-
| hir::ItemKind::ExternCrate(..) => {}
673598
}
674599

600+
let item_level = self.get(item.def_id);
601+
675602
// Mark all items in interfaces of reachable items as reachable.
676603
match item.kind {
677604
// The interface is empty.
678605
hir::ItemKind::ExternCrate(..) => {}
679606
// All nested items are checked by `visit_item`.
680607
hir::ItemKind::Mod(..) => {}
681-
// Re-exports are handled in `visit_mod`. However, in order to avoid looping over
682-
// all of the items of a mod in `visit_mod` looking for use statements, we handle
683-
// making sure that intermediate use statements have their visibilities updated here.
684-
hir::ItemKind::Use(..) => {
685-
if item.vis.node.is_pub() {
686-
let access_level = self.tcx.get_resolver_access_level(item.def_id);
687-
self.update(item.hir_id(), access_level);
688-
}
689-
}
608+
hir::ItemKind::Use(..) => {}
690609
// The interface is empty.
691610
hir::ItemKind::GlobalAsm(..) => {}
692611
hir::ItemKind::OpaqueTy(..) => {
@@ -810,23 +729,6 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
810729
}
811730

812731
fn visit_mod(&mut self, m: &'tcx hir::Mod<'tcx>, _sp: Span, id: hir::HirId) {
813-
// This code is here instead of in visit_item so that the
814-
// crate module gets processed as well.
815-
if self.prev_level.is_some() {
816-
let def_id = self.tcx.hir().local_def_id(id);
817-
if let Some(exports) = self.tcx.module_exports(def_id) {
818-
for export in exports.iter() {
819-
if export.vis == ty::Visibility::Public {
820-
if let Some(def_id) = export.res.opt_def_id() {
821-
if let Some(def_id) = def_id.as_local() {
822-
self.update(def_id, Some(AccessLevel::Exported));
823-
}
824-
}
825-
}
826-
}
827-
}
828-
}
829-
830732
intravisit::walk_mod(self, m, id);
831733
}
832734

@@ -2086,11 +1988,12 @@ fn privacy_access_levels(tcx: TyCtxt<'_>, (): ()) -> &AccessLevels {
20861988
// items which are reachable from external crates based on visibility.
20871989
let mut visitor = EmbargoVisitor {
20881990
tcx,
2089-
access_levels: Default::default(),
1991+
access_levels: tcx.get_resolver_access_levels(),
20901992
macro_reachable: Default::default(),
20911993
prev_level: Some(AccessLevel::Public),
20921994
changed: false,
20931995
};
1996+
20941997
loop {
20951998
intravisit::walk_crate(&mut visitor, tcx.hir().krate());
20961999
if visitor.changed {
@@ -2099,7 +2002,6 @@ fn privacy_access_levels(tcx: TyCtxt<'_>, (): ()) -> &AccessLevels {
20992002
break;
21002003
}
21012004
}
2102-
visitor.update(CRATE_DEF_ID, Some(AccessLevel::Public));
21032005

21042006
tcx.arena.alloc(visitor.access_levels)
21052007
}

Diff for: compiler/rustc_resolve/src/access_levels.rs

+26-15
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ use rustc_ast::visit;
33
use rustc_ast::visit::Visitor;
44
use rustc_ast::EnumDef;
55
use rustc_ast::ForeignMod;
6+
use rustc_ast_lowering::ResolverAstLowering;
67
use rustc_middle::middle::privacy::AccessLevel;
78

89
use crate::Resolver;
@@ -18,13 +19,15 @@ impl<'r, 'a> PrivacyVisitor<'r, 'a> {
1819
}
1920
}
2021

21-
impl<'r, 'a> Visitor<'a> for PrivacyVisitor<'a, 'r> {
22-
fn visit_item(&mut self, item: &'a ast::Item) {
22+
impl<'r, 'ast> Visitor<'ast> for PrivacyVisitor<'ast, 'r> {
23+
fn visit_item(&mut self, item: &'ast ast::Item) {
2324
let inherited_item_level = match item.kind {
2425
// TODO Is this the correct behavior for those macros?
2526
ast::ItemKind::MacCall(..) | ast::ItemKind::MacroDef(..) => None,
2627

28+
// Resolved in privacy when hir is available
2729
ast::ItemKind::Impl(..) => None,
30+
2831
ast::ItemKind::ForeignMod(..) => self.prev_level,
2932

3033
ast::ItemKind::ExternCrate(..)
@@ -51,18 +54,6 @@ impl<'r, 'a> Visitor<'a> for PrivacyVisitor<'a, 'r> {
5154
let access_level = self.r.set_access_level(item.id, inherited_item_level);
5255

5356
match item.kind {
54-
ast::ItemKind::ExternCrate(..)
55-
| ast::ItemKind::Use(..)
56-
| ast::ItemKind::Static(..)
57-
| ast::ItemKind::Const(..)
58-
| ast::ItemKind::GlobalAsm(..)
59-
| ast::ItemKind::TyAlias(..)
60-
| ast::ItemKind::Mod(..)
61-
| ast::ItemKind::TraitAlias(..)
62-
| ast::ItemKind::MacroDef(..)
63-
| ast::ItemKind::MacCall(..)
64-
| ast::ItemKind::Fn(..) => {}
65-
6657
ast::ItemKind::ForeignMod(ForeignMod { ref items, .. }) => {
6758
for nested in items {
6859
if nested.vis.kind.is_pub() {
@@ -99,17 +90,37 @@ impl<'r, 'a> Visitor<'a> for PrivacyVisitor<'a, 'r> {
9990
}
10091
ast::ItemKind::Impl(ref impl_kind) => {
10192
for nested in impl_kind.items.iter() {
93+
tracing::info!(
94+
"ast::ItemKind::Impl: nested={:?}",
95+
self.r.opt_local_def_id(nested.id)
96+
);
10297
if impl_kind.of_trait.is_some() || nested.vis.kind.is_pub() {
10398
self.r.set_access_level(nested.id, access_level);
10499
}
105100
}
106101
}
102+
103+
ast::ItemKind::ExternCrate(..)
104+
| ast::ItemKind::Use(..)
105+
| ast::ItemKind::Static(..)
106+
| ast::ItemKind::Const(..)
107+
| ast::ItemKind::GlobalAsm(..)
108+
| ast::ItemKind::TyAlias(..)
109+
| ast::ItemKind::Mod(..)
110+
| ast::ItemKind::TraitAlias(..)
111+
| ast::ItemKind::MacroDef(..)
112+
| ast::ItemKind::MacCall(..)
113+
| ast::ItemKind::Fn(..) => {}
107114
}
108115

109116
let orig_level = std::mem::replace(&mut self.prev_level, access_level);
110117
visit::walk_item(self, item);
111118
self.prev_level = orig_level;
112119
}
113120

114-
fn visit_block(&mut self, _block: &'a ast::Block) {}
121+
fn visit_block(&mut self, block: &'ast ast::Block) {
122+
let orig_level = std::mem::take(&mut self.prev_level);
123+
visit::walk_block(self, block);
124+
self.prev_level = orig_level;
125+
}
115126
}

Diff for: compiler/rustc_resolve/src/lib.rs

+30-11
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ use rustc_index::vec::IndexVec;
4646
use rustc_metadata::creader::{CStore, CrateLoader};
4747
use rustc_middle::hir::exports::ExportMap;
4848
use rustc_middle::middle::cstore::{CrateStore, MetadataLoaderDyn};
49-
use rustc_middle::middle::privacy::AccessLevel;
49+
use rustc_middle::middle::privacy::{AccessLevel, AccessLevels};
5050
use rustc_middle::span_bug;
5151
use rustc_middle::ty::query::Providers;
5252
use rustc_middle::ty::{self, DefIdTree, MainDefinition, ResolverOutputs, Visibility};
@@ -1035,7 +1035,7 @@ pub struct Resolver<'a> {
10351035

10361036
main_def: Option<MainDefinition>,
10371037

1038-
nodes_access_level: FxHashMap<LocalDefId, AccessLevel>,
1038+
nodes_access_level: AccessLevels,
10391039
}
10401040

10411041
/// Nothing really interesting here; it just provides memory for the rest of the crate.
@@ -1533,10 +1533,18 @@ impl<'a> Resolver<'a> {
15331533

15341534
/// Compute access levels for exports and intermediate use statements
15351535
fn resolve_access_level(&mut self, krate: &Crate) {
1536-
let mut privacy_levels =
1536+
self.set_access_level(CRATE_NODE_ID, Some(AccessLevel::Public));
1537+
1538+
let mut privacy_visitor =
15371539
access_levels::PrivacyVisitor::new(self, Some(AccessLevel::Public));
1538-
visit::walk_crate(&mut privacy_levels, krate);
1540+
visit::walk_crate(&mut privacy_visitor, krate);
1541+
1542+
self.set_exports_access_level();
1543+
1544+
tracing::info!("nodes_access_level: {:#?}", self.nodes_access_level);
1545+
}
15391546

1547+
fn set_exports_access_level(&mut self) {
15401548
let root = self.graph_root();
15411549
let exports = root.def_id().and_then(|id| self.export_map.get(&id.expect_local()));
15421550

@@ -1545,6 +1553,10 @@ impl<'a> Resolver<'a> {
15451553
exports.iter().filter(|ex| ex.vis == Visibility::Public).collect::<Vec<_>>();
15461554

15471555
for export in public_exports {
1556+
if let Some(export_def_id) = export.res.def_id().as_local() {
1557+
self.set_access_level_def_id(export_def_id, Some(AccessLevel::Public));
1558+
}
1559+
15481560
if let Some(ns) = export.res.ns() {
15491561
let key = self.new_key(export.ident, ns);
15501562
let name_res = self.resolution(root, key);
@@ -1554,8 +1566,6 @@ impl<'a> Resolver<'a> {
15541566
}
15551567
}
15561568
}
1557-
1558-
tracing::debug!("nodes_access_level: {:?}", self.nodes_access_level);
15591569
}
15601570

15611571
/// Set the given binding access level to `AccessLevel::Public` and
@@ -1584,12 +1594,21 @@ impl<'a> Resolver<'a> {
15841594
node_id: NodeId,
15851595
access_level: Option<AccessLevel>,
15861596
) -> Option<AccessLevel> {
1587-
if let Some(access_level) = access_level {
1588-
let def_id = self.local_def_id(node_id);
1589-
self.nodes_access_level.insert(def_id, access_level);
1590-
}
1597+
self.set_access_level_def_id(self.local_def_id(node_id), access_level)
1598+
}
15911599

1592-
access_level
1600+
fn set_access_level_def_id(
1601+
&mut self,
1602+
def_id: LocalDefId,
1603+
access_level: Option<AccessLevel>,
1604+
) -> Option<AccessLevel> {
1605+
let old_level = self.nodes_access_level.map.get(&def_id).copied();
1606+
if old_level < access_level {
1607+
self.nodes_access_level.map.insert(def_id, access_level.unwrap());
1608+
access_level
1609+
} else {
1610+
old_level
1611+
}
15931612
}
15941613

15951614
pub fn traits_in_scope(

0 commit comments

Comments
 (0)