Skip to content

Commit 439e277

Browse files
committed
Extract privacy checking from name resolution
This commit is the culmination of my recent effort to refine Rust's notion of privacy and visibility among crates. The major goals of this commit were to remove privacy checking from resolve for the sake of sane error messages, and to attempt a much more rigid and well-tested implementation of visibility throughout rust. The implemented rules for name visibility are: 1. Everything pub from the root namespace is visible to anyone 2. You may access any private item of your ancestors. "Accessing a private item" depends on what the item is, so for a function this means that you can call it, but for a module it means that you can look inside of it. Once you look inside a private module, any accessed item must be "pub from the root" where the new root is the private module that you looked into. These rules required some more analysis results to get propagated from trans to privacy in the form of a few hash tables. I added a new test in which my goal was to showcase all of the privacy nuances of the language, and I hope to place any new bugs into this file to prevent regressions. Overall, I was unable to completely remove the notion of privacy from resolve. One use of privacy is for dealing with glob imports. Essentially a glob import can only import *public* items from the destination, and because this must be done at namespace resolution time, resolve must maintain the notion of "what items are public in a module". There are some sad approximations of privacy, but I unfortunately can't see clear methods to extract them outside. The other use case of privacy in resolve now is one that must stick around regardless of glob imports. When dealing with privacy, checking a private path needs to know "what the last private thing was" when looking at a path. Resolve is the only compiler pass which knows the answer to this question, so it maintains the answer on a per-path resolution basis (works similarly to the def_map generated). Closes #8215
1 parent 8eb28bb commit 439e277

File tree

13 files changed

+1459
-1103
lines changed

13 files changed

+1459
-1103
lines changed

src/librustc/driver/driver.rs

Lines changed: 7 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,6 @@ pub fn phase_2_configure_and_expand(sess: Session,
199199

200200
pub struct CrateAnalysis {
201201
exp_map2: middle::resolve::ExportMap2,
202-
exported_items: @middle::privacy::ExportedItems,
203202
ty_cx: ty::ctxt,
204203
maps: astencode::Maps,
205204
reachable: @mut HashSet<ast::NodeId>
@@ -229,7 +228,9 @@ pub fn phase_3_run_analysis_passes(sess: Session,
229228
let middle::resolve::CrateMap {
230229
def_map: def_map,
231230
exp_map2: exp_map2,
232-
trait_map: trait_map
231+
trait_map: trait_map,
232+
external_exports: external_exports,
233+
last_private_map: last_private_map
233234
} =
234235
time(time_passes, "resolution", (), |_|
235236
middle::resolve::resolve_crate(sess, lang_items, crate));
@@ -261,9 +262,10 @@ pub fn phase_3_run_analysis_passes(sess: Session,
261262
middle::check_const::check_crate(sess, crate, ast_map, def_map,
262263
method_map, ty_cx));
263264

264-
let exported_items =
265-
time(time_passes, "privacy checking", (), |_|
266-
middle::privacy::check_crate(ty_cx, &method_map, &exp_map2, crate));
265+
let maps = (external_exports, last_private_map);
266+
time(time_passes, "privacy checking", maps, |(a, b)|
267+
middle::privacy::check_crate(ty_cx, &method_map, &exp_map2,
268+
a, b, crate));
267269

268270
time(time_passes, "effect checking", (), |_|
269271
middle::effect::check_crate(ty_cx, method_map, crate));
@@ -305,7 +307,6 @@ pub fn phase_3_run_analysis_passes(sess: Session,
305307

306308
CrateAnalysis {
307309
exp_map2: exp_map2,
308-
exported_items: @exported_items,
309310
ty_cx: ty_cx,
310311
maps: astencode::Maps {
311312
root_map: root_map,

src/librustc/metadata/decoder.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -837,8 +837,9 @@ fn each_child_of_item_or_crate(intr: @ident_interner,
837837
let def_like = item_to_def_like(child_item_doc,
838838
child_def_id,
839839
cdata.cnum);
840-
callback(def_like, token::str_to_ident(name),
841-
item_visibility(child_item_doc));
840+
// These items have a public visibility because they're part of
841+
// a public re-export.
842+
callback(def_like, token::str_to_ident(name), ast::public);
842843
}
843844
}
844845

src/librustc/metadata/encoder.rs

Lines changed: 2 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,6 @@ pub struct EncodeParams<'self> {
5858
diag: @mut span_handler,
5959
tcx: ty::ctxt,
6060
reexports2: middle::resolve::ExportMap2,
61-
exported_items: @middle::privacy::ExportedItems,
6261
item_symbols: &'self HashMap<ast::NodeId, ~str>,
6362
discrim_symbols: &'self HashMap<ast::NodeId, @str>,
6463
non_inlineable_statics: &'self HashSet<ast::NodeId>,
@@ -89,7 +88,6 @@ pub struct EncodeContext<'self> {
8988
tcx: ty::ctxt,
9089
stats: @mut Stats,
9190
reexports2: middle::resolve::ExportMap2,
92-
exported_items: @middle::privacy::ExportedItems,
9391
item_symbols: &'self HashMap<ast::NodeId, ~str>,
9492
discrim_symbols: &'self HashMap<ast::NodeId, @str>,
9593
non_inlineable_statics: &'self HashSet<ast::NodeId>,
@@ -1277,12 +1275,7 @@ fn my_visit_item(i:@item, items: ast_map::map, ebml_w:&writer::Encoder,
12771275
let mut ebml_w = ebml_w.clone();
12781276
// See above
12791277
let ecx : &EncodeContext = unsafe { cast::transmute(ecx_ptr) };
1280-
let vis = if ecx.exported_items.contains(&i.id) {
1281-
ast::public
1282-
} else {
1283-
ast::inherited
1284-
};
1285-
encode_info_for_item(ecx, &mut ebml_w, i, index, *pt, vis);
1278+
encode_info_for_item(ecx, &mut ebml_w, i, index, *pt, i.vis);
12861279
}
12871280
_ => fail2!("bad item")
12881281
}
@@ -1628,7 +1621,7 @@ impl<'self> Visitor<()> for ImplVisitor<'self> {
16281621

16291622
// Load eagerly if this is an implementation of the Drop trait
16301623
// or if the trait is not defined in this crate.
1631-
if def_id == self.ecx.tcx.lang_items.drop_trait().unwrap() ||
1624+
if Some(def_id) == self.ecx.tcx.lang_items.drop_trait() ||
16321625
def_id.crate != LOCAL_CRATE {
16331626
self.ebml_w.start_tag(tag_impls_impl);
16341627
encode_def_id(self.ebml_w, local_def(item.id));
@@ -1744,7 +1737,6 @@ pub fn encode_metadata(parms: EncodeParams, crate: &Crate) -> ~[u8] {
17441737
diag,
17451738
tcx,
17461739
reexports2,
1747-
exported_items,
17481740
discrim_symbols,
17491741
cstore,
17501742
encode_inlined_item,
@@ -1760,7 +1752,6 @@ pub fn encode_metadata(parms: EncodeParams, crate: &Crate) -> ~[u8] {
17601752
tcx: tcx,
17611753
stats: stats,
17621754
reexports2: reexports2,
1763-
exported_items: exported_items,
17641755
item_symbols: item_symbols,
17651756
discrim_symbols: discrim_symbols,
17661757
non_inlineable_statics: non_inlineable_statics,

0 commit comments

Comments
 (0)