Skip to content

Commit e502f0c

Browse files
committed
Move most of Exported/Public res to rustc_resolve
1 parent bc89ee9 commit e502f0c

File tree

4 files changed

+169
-17
lines changed

4 files changed

+169
-17
lines changed

compiler/rustc_privacy/src/lib.rs

+2-3
Original file line numberDiff line numberDiff line change
@@ -591,9 +591,8 @@ impl Visitor<'tcx> for EmbargoVisitor<'tcx> {
591591
Option::<AccessLevel>::of_impl(item.hir_id(), self.tcx, &self.access_levels)
592592
}
593593
// Foreign modules inherit level from parents.
594-
hir::ItemKind::ForeignMod { .. } => self.prev_level,
595-
// Other `pub` items inherit levels from parents.
596-
hir::ItemKind::Const(..)
594+
hir::ItemKind::ForeignMod { .. }
595+
| hir::ItemKind::Const(..)
597596
| hir::ItemKind::Enum(..)
598597
| hir::ItemKind::ExternCrate(..)
599598
| hir::ItemKind::GlobalAsm(..)
+115
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,115 @@
1+
use rustc_ast::ast;
2+
use rustc_ast::visit;
3+
use rustc_ast::visit::Visitor;
4+
use rustc_ast::EnumDef;
5+
use rustc_ast::ForeignMod;
6+
use rustc_middle::middle::privacy::AccessLevel;
7+
8+
use crate::Resolver;
9+
10+
pub struct PrivacyVisitor<'r, 'a> {
11+
r: &'r mut Resolver<'a>,
12+
prev_level: Option<AccessLevel>,
13+
}
14+
15+
impl<'r, 'a> PrivacyVisitor<'r, 'a> {
16+
pub fn new(r: &'r mut Resolver<'a>, root_level: Option<AccessLevel>) -> PrivacyVisitor<'r, 'a> {
17+
PrivacyVisitor { r, prev_level: root_level }
18+
}
19+
}
20+
21+
impl<'r, 'a> Visitor<'a> for PrivacyVisitor<'a, 'r> {
22+
fn visit_item(&mut self, item: &'a ast::Item) {
23+
let inherited_item_level = match item.kind {
24+
// TODO Is this the correct behavior for those macros?
25+
ast::ItemKind::MacCall(..) | ast::ItemKind::MacroDef(..) => None,
26+
27+
ast::ItemKind::Impl(..) => None,
28+
ast::ItemKind::ForeignMod(..) => self.prev_level,
29+
30+
ast::ItemKind::ExternCrate(..)
31+
| ast::ItemKind::Use(..)
32+
| ast::ItemKind::Static(..)
33+
| ast::ItemKind::Const(..)
34+
| ast::ItemKind::Fn(..)
35+
| ast::ItemKind::Mod(..)
36+
| ast::ItemKind::GlobalAsm(..)
37+
| ast::ItemKind::TyAlias(..)
38+
| ast::ItemKind::Enum(..)
39+
| ast::ItemKind::Struct(..)
40+
| ast::ItemKind::Union(..)
41+
| ast::ItemKind::Trait(..)
42+
| ast::ItemKind::TraitAlias(..) => {
43+
if item.vis.kind.is_pub() {
44+
self.prev_level
45+
} else {
46+
None
47+
}
48+
}
49+
};
50+
51+
let access_level = self.r.set_access_level(item.id, inherited_item_level);
52+
53+
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+
66+
ast::ItemKind::ForeignMod(ForeignMod { ref items, .. }) => {
67+
for nested in items {
68+
if nested.vis.kind.is_pub() {
69+
self.r.set_access_level(nested.id, access_level);
70+
}
71+
}
72+
}
73+
ast::ItemKind::Enum(EnumDef { ref variants }, _) => {
74+
for variant in variants {
75+
let variant_level = self.r.set_access_level(variant.id, access_level);
76+
if let Some(ctor_id) = variant.data.ctor_id() {
77+
self.r.set_access_level(ctor_id, access_level);
78+
}
79+
80+
for field in variant.data.fields() {
81+
self.r.set_access_level(field.id, variant_level);
82+
}
83+
}
84+
}
85+
ast::ItemKind::Struct(ref def, _) | ast::ItemKind::Union(ref def, _) => {
86+
if let Some(ctor_id) = def.ctor_id() {
87+
self.r.set_access_level(ctor_id, access_level);
88+
for field in def.fields() {
89+
if field.vis.kind.is_pub() {
90+
self.r.set_access_level(field.id, access_level);
91+
}
92+
}
93+
}
94+
}
95+
ast::ItemKind::Trait(ref trait_kind) => {
96+
for nested in trait_kind.4.iter() {
97+
self.r.set_access_level(nested.id, access_level);
98+
}
99+
}
100+
ast::ItemKind::Impl(ref impl_kind) => {
101+
for nested in impl_kind.items.iter() {
102+
if impl_kind.of_trait.is_some() || nested.vis.kind.is_pub() {
103+
self.r.set_access_level(nested.id, access_level);
104+
}
105+
}
106+
}
107+
}
108+
109+
let orig_level = std::mem::replace(&mut self.prev_level, access_level);
110+
visit::walk_item(self, item);
111+
self.prev_level = orig_level;
112+
}
113+
114+
fn visit_block(&mut self, _block: &'a ast::Block) {}
115+
}

compiler/rustc_resolve/src/lib.rs

+24-14
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ use macros::{MacroRulesBinding, MacroRulesScope, MacroRulesScopeRef};
7474

7575
type Res = def::Res<NodeId>;
7676

77+
mod access_levels;
7778
mod build_reduced_graph;
7879
mod check_unused;
7980
mod def_collector;
@@ -1520,7 +1521,7 @@ impl<'a> Resolver<'a> {
15201521
pub fn resolve_crate(&mut self, krate: &Crate) {
15211522
self.session.time("resolve_crate", || {
15221523
self.session.time("finalize_imports", || ImportResolver { r: self }.finalize_imports());
1523-
self.session.time("resolve_export_privacy", || self.resolve_export_privacy());
1524+
self.session.time("resolve_access_level", || self.resolve_access_level(krate));
15241525
self.session.time("finalize_macro_resolutions", || self.finalize_macro_resolutions());
15251526
self.session.time("late_resolve_crate", || self.late_resolve_crate(krate));
15261527
self.session.time("resolve_main", || self.resolve_main());
@@ -1531,7 +1532,11 @@ impl<'a> Resolver<'a> {
15311532
}
15321533

15331534
/// Compute access levels for exports and intermediate use statements
1534-
fn resolve_export_privacy(&mut self) {
1535+
fn resolve_access_level(&mut self, krate: &Crate) {
1536+
let mut privacy_levels =
1537+
access_levels::PrivacyVisitor::new(self, Some(AccessLevel::Public));
1538+
visit::walk_crate(&mut privacy_levels, krate);
1539+
15351540
let root = self.graph_root();
15361541
let exports = root.def_id().and_then(|id| self.export_map.get(&id.expect_local()));
15371542

@@ -1544,7 +1549,7 @@ impl<'a> Resolver<'a> {
15441549
let key = self.new_key(export.ident, ns);
15451550
let name_res = self.resolution(root, key);
15461551
if let Some(binding) = name_res.borrow().binding() {
1547-
self.compute_binding_access_level(binding);
1552+
self.set_binding_to_public(binding);
15481553
}
15491554
}
15501555
}
@@ -1556,30 +1561,35 @@ impl<'a> Resolver<'a> {
15561561
/// Set the given binding access level to `AccessLevel::Public` and
15571562
/// sets the rest of the `use` chain to `AccessLevel::Exported` until
15581563
/// we hit the actual exported item
1559-
fn compute_binding_access_level(&mut self, mut binding: &NameBinding<'a>) {
1560-
let mut access_level = AccessLevel::Public;
1564+
fn set_binding_to_public(&mut self, mut binding: &NameBinding<'a>) {
1565+
let mut access_level = Some(AccessLevel::Public);
15611566
while let NameBindingKind::Import { binding: nested_binding, import, .. } = binding.kind {
1562-
self.mark_node_with_access_level(import.id, access_level);
1567+
self.set_access_level(import.id, access_level);
15631568

15641569
match import.kind {
15651570
ImportKind::Single { additional_ids, .. } => {
1566-
self.mark_node_with_access_level(additional_ids.0, access_level);
1567-
self.mark_node_with_access_level(additional_ids.1, access_level);
1571+
self.set_access_level(additional_ids.0, access_level);
1572+
self.set_access_level(additional_ids.1, access_level);
15681573
}
15691574
_ => {}
15701575
};
15711576

1572-
access_level = AccessLevel::Exported;
1577+
access_level = Some(AccessLevel::Exported);
15731578
binding = nested_binding;
15741579
}
15751580
}
15761581

1577-
fn mark_node_with_access_level(&mut self, node_id: NodeId, access_level: AccessLevel) -> bool {
1578-
if let Some(def_id) = self.opt_local_def_id(node_id) {
1579-
self.nodes_access_level.insert(def_id, access_level).is_none()
1580-
} else {
1581-
false
1582+
fn set_access_level(
1583+
&mut self,
1584+
node_id: NodeId,
1585+
access_level: Option<AccessLevel>,
1586+
) -> 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);
15821590
}
1591+
1592+
access_level
15831593
}
15841594

15851595
pub fn traits_in_scope(
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
// check-pass
2+
3+
#![deny(unreachable_pub)]
4+
5+
pub use self::m1::*;
6+
7+
mod m1 {
8+
pub use self::m2::*;
9+
10+
mod m2 {
11+
pub struct Item1;
12+
pub struct Item2;
13+
}
14+
}
15+
16+
17+
pub use self::o1::{ Item42, Item24 };
18+
19+
mod o1 {
20+
pub use self::o2::{ Item42, Item24 };
21+
22+
mod o2 {
23+
pub struct Item42;
24+
pub struct Item24;
25+
}
26+
}
27+
28+
fn main() {}

0 commit comments

Comments
 (0)