2013-11-11 22:17:47 -06:00
|
|
|
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
|
2012-12-03 18:48:01 -06:00
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2013-08-08 13:38:10 -05:00
|
|
|
//! A pass that checks to make sure private fields and methods aren't used
|
2013-08-07 02:11:34 -05:00
|
|
|
//! outside their scopes. This pass will also generate a set of exported items
|
|
|
|
//! which are available for use externally when compiled as a library.
|
|
|
|
|
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
2013-10-05 16:37:39 -05:00
|
|
|
use std::hashmap::{HashSet, HashMap};
|
2013-11-05 20:06:27 -06:00
|
|
|
use std::util;
|
2013-05-17 17:28:44 -05:00
|
|
|
|
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
2013-10-05 16:37:39 -05:00
|
|
|
use middle::resolve;
|
2012-12-23 16:41:37 -06:00
|
|
|
use middle::ty;
|
2013-07-22 19:42:45 -05:00
|
|
|
use middle::typeck::{method_map, method_origin, method_param};
|
2013-08-13 15:22:58 -05:00
|
|
|
use middle::typeck::{method_static, method_object};
|
2012-12-23 16:41:37 -06:00
|
|
|
|
|
|
|
use syntax::ast;
|
|
|
|
use syntax::ast_map;
|
2013-11-20 17:15:34 -06:00
|
|
|
use syntax::ast_util::{is_local, def_id_of_def, local_def};
|
2013-03-18 19:20:45 -05:00
|
|
|
use syntax::attr;
|
2013-08-31 11:13:04 -05:00
|
|
|
use syntax::codemap::Span;
|
2013-05-14 19:27:27 -05:00
|
|
|
use syntax::parse::token;
|
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
2013-10-05 16:37:39 -05:00
|
|
|
use syntax::opt_vec;
|
2013-08-13 06:21:45 -05:00
|
|
|
use syntax::visit;
|
|
|
|
use syntax::visit::Visitor;
|
2012-09-04 16:48:32 -05:00
|
|
|
|
2013-12-10 01:16:18 -06:00
|
|
|
type Context<'a> = (&'a method_map, &'a resolve::ExportMap2);
|
2013-08-07 02:11:34 -05:00
|
|
|
|
2013-11-11 22:17:47 -06:00
|
|
|
/// A set of AST nodes exported by the crate.
|
2013-10-09 23:16:51 -05:00
|
|
|
pub type ExportedItems = HashSet<ast::NodeId>;
|
|
|
|
|
2013-11-20 17:15:34 -06:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// The parent visitor, used to determine what's the parent of what (node-wise)
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
struct ParentVisitor {
|
|
|
|
parents: HashMap<ast::NodeId, ast::NodeId>,
|
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
2013-10-05 16:37:39 -05:00
|
|
|
curparent: ast::NodeId,
|
2013-08-13 06:21:45 -05:00
|
|
|
}
|
2012-09-04 16:48:32 -05:00
|
|
|
|
2013-11-20 17:15:34 -06:00
|
|
|
impl Visitor<()> for ParentVisitor {
|
2014-01-06 06:00:46 -06:00
|
|
|
fn visit_item(&mut self, item: &ast::item, _: ()) {
|
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
2013-10-05 16:37:39 -05:00
|
|
|
self.parents.insert(item.id, self.curparent);
|
|
|
|
|
|
|
|
let prev = self.curparent;
|
2013-03-18 19:20:45 -05:00
|
|
|
match item.node {
|
2013-11-28 14:22:53 -06:00
|
|
|
ast::item_mod(..) => { self.curparent = item.id; }
|
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
2013-10-05 16:37:39 -05:00
|
|
|
// Enum variants are parented to the enum definition itself beacuse
|
|
|
|
// they inherit privacy
|
|
|
|
ast::item_enum(ref def, _) => {
|
|
|
|
for variant in def.variants.iter() {
|
|
|
|
// If variants are private, then their logical "parent" is
|
|
|
|
// the enclosing module because everyone in the enclosing
|
|
|
|
// module can still use the private variant
|
|
|
|
if variant.node.vis == ast::private {
|
|
|
|
self.parents.insert(variant.node.id, self.curparent);
|
|
|
|
|
|
|
|
// Otherwise, if the variant is public, then the parent is
|
|
|
|
// considered the enclosing enum because the enum will
|
|
|
|
// dictate the privacy visibility of this variant instead.
|
|
|
|
} else {
|
|
|
|
self.parents.insert(variant.node.id, item.id);
|
|
|
|
}
|
2013-03-18 19:20:45 -05:00
|
|
|
}
|
|
|
|
}
|
2013-10-07 15:01:47 -05:00
|
|
|
|
|
|
|
// Trait methods are always considered "public", but if the trait is
|
|
|
|
// private then we need some private item in the chain from the
|
|
|
|
// method to the root. In this case, if the trait is private, then
|
|
|
|
// parent all the methods to the trait to indicate that they're
|
|
|
|
// private.
|
|
|
|
ast::item_trait(_, _, ref methods) if item.vis != ast::public => {
|
|
|
|
for m in methods.iter() {
|
|
|
|
match *m {
|
|
|
|
ast::provided(ref m) => self.parents.insert(m.id, item.id),
|
|
|
|
ast::required(ref m) => self.parents.insert(m.id, item.id),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-03-18 19:20:45 -05:00
|
|
|
_ => {}
|
|
|
|
}
|
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
2013-10-05 16:37:39 -05:00
|
|
|
visit::walk_item(self, item, ());
|
|
|
|
self.curparent = prev;
|
2013-08-13 06:21:45 -05:00
|
|
|
}
|
2013-03-18 19:20:45 -05:00
|
|
|
|
2014-01-06 06:00:46 -06:00
|
|
|
fn visit_foreign_item(&mut self, a: &ast::foreign_item, _: ()) {
|
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
2013-10-05 16:37:39 -05:00
|
|
|
self.parents.insert(a.id, self.curparent);
|
|
|
|
visit::walk_foreign_item(self, a, ());
|
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_fn(&mut self, a: &visit::fn_kind, b: &ast::fn_decl,
|
2014-01-06 06:00:46 -06:00
|
|
|
c: &ast::Block, d: Span, id: ast::NodeId, _: ()) {
|
2013-10-07 15:01:47 -05:00
|
|
|
// We already took care of some trait methods above, otherwise things
|
|
|
|
// like impl methods and pub trait methods are parented to the
|
|
|
|
// containing module, not the containing trait.
|
|
|
|
if !self.parents.contains_key(&id) {
|
|
|
|
self.parents.insert(id, self.curparent);
|
|
|
|
}
|
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
2013-10-05 16:37:39 -05:00
|
|
|
visit::walk_fn(self, a, b, c, d, id, ());
|
|
|
|
}
|
|
|
|
|
2014-01-06 06:00:46 -06:00
|
|
|
fn visit_struct_def(&mut self, s: &ast::struct_def, i: ast::Ident,
|
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
2013-10-05 16:37:39 -05:00
|
|
|
g: &ast::Generics, n: ast::NodeId, _: ()) {
|
|
|
|
// Struct constructors are parented to their struct definitions because
|
|
|
|
// they essentially are the struct definitions.
|
|
|
|
match s.ctor_id {
|
|
|
|
Some(id) => { self.parents.insert(id, n); }
|
|
|
|
None => {}
|
2012-11-30 13:24:16 -06:00
|
|
|
}
|
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
2013-10-05 16:37:39 -05:00
|
|
|
|
|
|
|
// While we have the id of the struct definition, go ahead and parent
|
|
|
|
// all the fields.
|
|
|
|
for field in s.fields.iter() {
|
|
|
|
let vis = match field.node.kind {
|
|
|
|
ast::named_field(_, vis) => vis,
|
|
|
|
ast::unnamed_field => continue
|
|
|
|
};
|
|
|
|
|
|
|
|
// Private fields are scoped to this module, so parent them directly
|
|
|
|
// to the module instead of the struct. This is similar to the case
|
|
|
|
// of private enum variants.
|
|
|
|
if vis == ast::private {
|
|
|
|
self.parents.insert(field.node.id, self.curparent);
|
|
|
|
|
|
|
|
// Otherwise public fields are scoped to the visibility of the
|
|
|
|
// struct itself
|
|
|
|
} else {
|
|
|
|
self.parents.insert(field.node.id, n);
|
|
|
|
}
|
2012-11-30 13:24:16 -06:00
|
|
|
}
|
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
2013-10-05 16:37:39 -05:00
|
|
|
visit::walk_struct_def(self, s, i, g, n, ())
|
2013-08-13 06:21:45 -05:00
|
|
|
}
|
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
2013-10-05 16:37:39 -05:00
|
|
|
}
|
2012-11-30 13:24:16 -06:00
|
|
|
|
2013-11-20 17:15:34 -06:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// The embargo visitor, used to determine the exports of the ast
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2013-12-10 01:16:18 -06:00
|
|
|
struct EmbargoVisitor<'a> {
|
2013-11-11 22:17:47 -06:00
|
|
|
tcx: ty::ctxt,
|
2013-12-10 01:16:18 -06:00
|
|
|
exp_map2: &'a resolve::ExportMap2,
|
2013-03-18 19:20:45 -05:00
|
|
|
|
2013-11-20 17:15:34 -06:00
|
|
|
// This flag is an indicator of whether the previous item in the
|
|
|
|
// hierarchical chain was exported or not. This is the indicator of whether
|
|
|
|
// children should be exported as well. Note that this can flip from false
|
|
|
|
// to true if a reexported module is entered (or an action similar).
|
|
|
|
prev_exported: bool,
|
|
|
|
|
|
|
|
// This is a list of all exported items in the AST. An exported item is any
|
|
|
|
// function/method/item which is usable by external crates. This essentially
|
|
|
|
// means that the result is "public all the way down", but the "path down"
|
|
|
|
// may jump across private boundaries through reexport statements.
|
|
|
|
exported_items: ExportedItems,
|
|
|
|
|
|
|
|
// This sets contains all the destination nodes which are publicly
|
|
|
|
// re-exported. This is *not* a set of all reexported nodes, only a set of
|
|
|
|
// all nodes which are reexported *and* reachable from external crates. This
|
|
|
|
// means that the destination of the reexport is exported, and hence the
|
|
|
|
// destination must also be exported.
|
|
|
|
reexports: HashSet<ast::NodeId>,
|
2013-11-11 22:17:47 -06:00
|
|
|
}
|
|
|
|
|
2013-12-31 14:40:10 -06:00
|
|
|
impl<'a> EmbargoVisitor<'a> {
|
|
|
|
// There are checks inside of privacy which depend on knowing whether a
|
|
|
|
// trait should be exported or not. The two current consumers of this are:
|
|
|
|
//
|
|
|
|
// 1. Should default methods of a trait be exported?
|
|
|
|
// 2. Should the methods of an implementation of a trait be exported?
|
|
|
|
//
|
|
|
|
// The answer to both of these questions partly rely on whether the trait
|
|
|
|
// itself is exported or not. If the trait is somehow exported, then the
|
|
|
|
// answers to both questions must be yes. Right now this question involves
|
|
|
|
// more analysis than is currently done in rustc, so we conservatively
|
|
|
|
// answer "yes" so that all traits need to be exported.
|
|
|
|
fn exported_trait(&self, _id: ast::NodeId) -> bool {
|
|
|
|
true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-10 01:16:18 -06:00
|
|
|
impl<'a> Visitor<()> for EmbargoVisitor<'a> {
|
2014-01-06 06:00:46 -06:00
|
|
|
fn visit_item(&mut self, item: &ast::item, _: ()) {
|
2013-11-20 17:15:34 -06:00
|
|
|
let orig_all_pub = self.prev_exported;
|
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
2013-10-05 16:37:39 -05:00
|
|
|
match item.node {
|
|
|
|
// impls/extern blocks do not break the "public chain" because they
|
|
|
|
// cannot have visibility qualifiers on them anyway
|
2013-11-28 14:22:53 -06:00
|
|
|
ast::item_impl(..) | ast::item_foreign_mod(..) => {}
|
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
2013-10-05 16:37:39 -05:00
|
|
|
|
2013-12-31 14:40:10 -06:00
|
|
|
// Traits are a little special in that even if they themselves are
|
|
|
|
// not public they may still be exported.
|
|
|
|
ast::item_trait(..) => {
|
|
|
|
self.prev_exported = self.exported_trait(item.id);
|
|
|
|
}
|
|
|
|
|
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
2013-10-05 16:37:39 -05:00
|
|
|
// Private by default, hence we only retain the "public chain" if
|
|
|
|
// `pub` is explicitly listed.
|
|
|
|
_ => {
|
2013-11-20 17:15:34 -06:00
|
|
|
self.prev_exported =
|
|
|
|
(orig_all_pub && item.vis == ast::public) ||
|
|
|
|
self.reexports.contains(&item.id);
|
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
2013-10-05 16:37:39 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-20 17:15:34 -06:00
|
|
|
let public_first = self.prev_exported &&
|
|
|
|
self.exported_items.insert(item.id);
|
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
2013-10-05 16:37:39 -05:00
|
|
|
|
|
|
|
match item.node {
|
|
|
|
// Enum variants inherit from their parent, so if the enum is
|
|
|
|
// public all variants are public unless they're explicitly priv
|
2013-11-20 17:15:34 -06:00
|
|
|
ast::item_enum(ref def, _) if public_first => {
|
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
2013-10-05 16:37:39 -05:00
|
|
|
for variant in def.variants.iter() {
|
|
|
|
if variant.node.vis != ast::private {
|
2013-11-20 17:15:34 -06:00
|
|
|
self.exported_items.insert(variant.node.id);
|
2013-03-18 19:20:45 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-20 17:15:34 -06:00
|
|
|
// Implementations are a little tricky to determine what's exported
|
|
|
|
// out of them. Here's a few cases which are currently defined:
|
|
|
|
//
|
|
|
|
// * Impls for private types do not need to export their methods
|
|
|
|
// (either public or private methods)
|
|
|
|
//
|
|
|
|
// * Impls for public types only have public methods exported
|
|
|
|
//
|
|
|
|
// * Public trait impls for public types must have all methods
|
|
|
|
// exported.
|
|
|
|
//
|
|
|
|
// * Private trait impls for public types can be ignored
|
|
|
|
//
|
|
|
|
// * Public trait impls for private types have their methods
|
|
|
|
// exported. I'm not entirely certain that this is the correct
|
|
|
|
// thing to do, but I have seen use cases of where this will cause
|
|
|
|
// undefined symbols at linkage time if this case is not handled.
|
|
|
|
//
|
|
|
|
// * Private trait impls for private types can be completely ignored
|
|
|
|
ast::item_impl(_, _, ref ty, ref methods) => {
|
|
|
|
let public_ty = match ty.node {
|
|
|
|
ast::ty_path(_, _, id) => {
|
2013-12-23 13:15:16 -06:00
|
|
|
let def_map = self.tcx.def_map.borrow();
|
|
|
|
match def_map.get().get_copy(&id) {
|
2013-11-28 14:22:53 -06:00
|
|
|
ast::DefPrimTy(..) => true,
|
2013-11-20 17:15:34 -06:00
|
|
|
def => {
|
|
|
|
let did = def_id_of_def(def);
|
|
|
|
!is_local(did) ||
|
|
|
|
self.exported_items.contains(&did.node)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => true,
|
|
|
|
};
|
|
|
|
let tr = ty::impl_trait_ref(self.tcx, local_def(item.id));
|
2013-11-24 13:44:28 -06:00
|
|
|
let public_trait = tr.map_default(false, |tr| {
|
2013-11-20 17:15:34 -06:00
|
|
|
!is_local(tr.def_id) ||
|
|
|
|
self.exported_items.contains(&tr.def_id.node)
|
2013-11-24 13:44:28 -06:00
|
|
|
});
|
2013-11-20 17:15:34 -06:00
|
|
|
|
|
|
|
if public_ty || public_trait {
|
|
|
|
for method in methods.iter() {
|
|
|
|
let meth_public = match method.explicit_self.node {
|
|
|
|
ast::sty_static => public_ty,
|
|
|
|
_ => true,
|
|
|
|
} && method.vis == ast::public;
|
2013-12-03 17:15:17 -06:00
|
|
|
if meth_public || tr.is_some() {
|
2013-11-20 17:15:34 -06:00
|
|
|
self.exported_items.insert(method.id);
|
|
|
|
}
|
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
2013-10-05 16:37:39 -05:00
|
|
|
}
|
|
|
|
}
|
2013-03-18 19:20:45 -05:00
|
|
|
}
|
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
2013-10-05 16:37:39 -05:00
|
|
|
|
2013-11-20 17:15:34 -06:00
|
|
|
// Default methods on traits are all public so long as the trait
|
|
|
|
// is public
|
|
|
|
ast::item_trait(_, _, ref methods) if public_first => {
|
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
2013-10-05 16:37:39 -05:00
|
|
|
for method in methods.iter() {
|
|
|
|
match *method {
|
|
|
|
ast::provided(ref m) => {
|
2013-10-21 15:08:31 -05:00
|
|
|
debug!("provided {}", m.id);
|
2013-11-20 17:15:34 -06:00
|
|
|
self.exported_items.insert(m.id);
|
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
2013-10-05 16:37:39 -05:00
|
|
|
}
|
|
|
|
ast::required(ref m) => {
|
2013-10-21 15:08:31 -05:00
|
|
|
debug!("required {}", m.id);
|
2013-11-20 17:15:34 -06:00
|
|
|
self.exported_items.insert(m.id);
|
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
2013-10-05 16:37:39 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-03-18 19:20:45 -05:00
|
|
|
}
|
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
2013-10-05 16:37:39 -05:00
|
|
|
|
2013-11-11 22:17:47 -06:00
|
|
|
// Struct constructors are public if the struct is all public.
|
2013-11-20 17:15:34 -06:00
|
|
|
ast::item_struct(ref def, _) if public_first => {
|
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
2013-10-05 16:37:39 -05:00
|
|
|
match def.ctor_id {
|
2013-11-20 17:15:34 -06:00
|
|
|
Some(id) => { self.exported_items.insert(id); }
|
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
2013-10-05 16:37:39 -05:00
|
|
|
None => {}
|
|
|
|
}
|
2013-03-18 19:20:45 -05:00
|
|
|
}
|
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
2013-10-05 16:37:39 -05:00
|
|
|
|
|
|
|
_ => {}
|
2013-03-18 19:20:45 -05:00
|
|
|
}
|
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
2013-10-05 16:37:39 -05:00
|
|
|
|
|
|
|
visit::walk_item(self, item, ());
|
|
|
|
|
2013-11-20 17:15:34 -06:00
|
|
|
self.prev_exported = orig_all_pub;
|
2013-08-13 06:21:45 -05:00
|
|
|
}
|
2013-03-18 19:20:45 -05:00
|
|
|
|
2014-01-06 06:00:46 -06:00
|
|
|
fn visit_foreign_item(&mut self, a: &ast::foreign_item, _: ()) {
|
2013-11-20 17:15:34 -06:00
|
|
|
if self.prev_exported && a.vis == ast::public {
|
|
|
|
self.exported_items.insert(a.id);
|
2013-11-11 22:17:47 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-20 17:15:34 -06:00
|
|
|
fn visit_mod(&mut self, m: &ast::_mod, _sp: Span, id: ast::NodeId, _: ()) {
|
2013-11-11 22:17:47 -06:00
|
|
|
// This code is here instead of in visit_item so that the
|
|
|
|
// crate module gets processed as well.
|
2013-11-20 17:15:34 -06:00
|
|
|
if self.prev_exported {
|
2013-12-20 23:14:25 -06:00
|
|
|
let exp_map2 = self.exp_map2.borrow();
|
|
|
|
assert!(exp_map2.get().contains_key(&id), "wut {:?}", id);
|
|
|
|
for export in exp_map2.get().get(&id).iter() {
|
2013-11-20 17:15:34 -06:00
|
|
|
if is_local(export.def_id) && export.reexport {
|
|
|
|
self.reexports.insert(export.def_id.node);
|
2013-11-11 22:17:47 -06:00
|
|
|
}
|
|
|
|
}
|
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
2013-10-05 16:37:39 -05:00
|
|
|
}
|
2013-11-11 22:17:47 -06:00
|
|
|
visit::walk_mod(self, m, ())
|
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
2013-10-05 16:37:39 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-20 17:15:34 -06:00
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// The privacy visitor, where privacy checks take place (violations reported)
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
2013-12-10 01:16:18 -06:00
|
|
|
struct PrivacyVisitor<'a> {
|
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
2013-10-05 16:37:39 -05:00
|
|
|
tcx: ty::ctxt,
|
|
|
|
curitem: ast::NodeId,
|
2013-11-05 20:06:27 -06:00
|
|
|
in_fn: bool,
|
2013-12-08 13:25:35 -06:00
|
|
|
in_foreign: bool,
|
2013-12-10 01:16:18 -06:00
|
|
|
method_map: &'a method_map,
|
2013-11-20 17:15:34 -06:00
|
|
|
parents: HashMap<ast::NodeId, ast::NodeId>,
|
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
2013-10-05 16:37:39 -05:00
|
|
|
external_exports: resolve::ExternalExports,
|
|
|
|
last_private_map: resolve::LastPrivateMap,
|
|
|
|
}
|
|
|
|
|
2013-10-14 17:12:40 -05:00
|
|
|
enum PrivacyResult {
|
|
|
|
Allowable,
|
|
|
|
ExternallyDenied,
|
|
|
|
DisallowedBy(ast::NodeId),
|
|
|
|
}
|
|
|
|
|
2013-12-10 01:16:18 -06:00
|
|
|
impl<'a> PrivacyVisitor<'a> {
|
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
2013-10-05 16:37:39 -05:00
|
|
|
// used when debugging
|
|
|
|
fn nodestr(&self, id: ast::NodeId) -> ~str {
|
|
|
|
ast_map::node_id_to_str(self.tcx.items, id, token::get_ident_interner())
|
|
|
|
}
|
|
|
|
|
|
|
|
// Determines whether the given definition is public from the point of view
|
|
|
|
// of the current item.
|
2013-10-14 17:12:40 -05:00
|
|
|
fn def_privacy(&self, did: ast::DefId) -> PrivacyResult {
|
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
2013-10-05 16:37:39 -05:00
|
|
|
if !is_local(did) {
|
|
|
|
if self.external_exports.contains(&did) {
|
2013-10-21 15:08:31 -05:00
|
|
|
debug!("privacy - {:?} was externally exported", did);
|
2013-10-14 17:12:40 -05:00
|
|
|
return Allowable;
|
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
2013-10-05 16:37:39 -05:00
|
|
|
}
|
2013-10-21 15:08:31 -05:00
|
|
|
debug!("privacy - is {:?} a public method", did);
|
2013-12-18 17:50:53 -06:00
|
|
|
|
|
|
|
let methods = self.tcx.methods.borrow();
|
|
|
|
return match methods.get().find(&did) {
|
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
2013-10-05 16:37:39 -05:00
|
|
|
Some(meth) => {
|
2013-10-21 15:08:31 -05:00
|
|
|
debug!("privacy - well at least it's a method: {:?}", meth);
|
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
2013-10-05 16:37:39 -05:00
|
|
|
match meth.container {
|
|
|
|
ty::TraitContainer(id) => {
|
2013-10-21 15:08:31 -05:00
|
|
|
debug!("privacy - recursing on trait {:?}", id);
|
2013-10-14 17:12:40 -05:00
|
|
|
self.def_privacy(id)
|
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
2013-10-05 16:37:39 -05:00
|
|
|
}
|
|
|
|
ty::ImplContainer(id) => {
|
|
|
|
match ty::impl_trait_ref(self.tcx, id) {
|
|
|
|
Some(t) => {
|
2013-10-21 15:08:31 -05:00
|
|
|
debug!("privacy - impl of trait {:?}", id);
|
2013-10-14 17:12:40 -05:00
|
|
|
self.def_privacy(t.def_id)
|
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
2013-10-05 16:37:39 -05:00
|
|
|
}
|
|
|
|
None => {
|
2013-10-21 15:08:31 -05:00
|
|
|
debug!("privacy - found a method {:?}",
|
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
2013-10-05 16:37:39 -05:00
|
|
|
meth.vis);
|
2013-10-14 17:12:40 -05:00
|
|
|
if meth.vis == ast::public {
|
|
|
|
Allowable
|
|
|
|
} else {
|
|
|
|
ExternallyDenied
|
|
|
|
}
|
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
2013-10-05 16:37:39 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-03-18 19:20:45 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
None => {
|
2013-10-21 15:08:31 -05:00
|
|
|
debug!("privacy - nope, not even a method");
|
2013-10-14 17:12:40 -05:00
|
|
|
ExternallyDenied
|
2013-03-18 19:20:45 -05:00
|
|
|
}
|
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
2013-10-05 16:37:39 -05:00
|
|
|
};
|
|
|
|
}
|
|
|
|
|
2013-10-21 15:08:31 -05:00
|
|
|
debug!("privacy - local {:?} not public all the way down", did);
|
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
2013-10-05 16:37:39 -05:00
|
|
|
// return quickly for things in the same module
|
|
|
|
if self.parents.find(&did.node) == self.parents.find(&self.curitem) {
|
2013-10-21 15:08:31 -05:00
|
|
|
debug!("privacy - same parent, we're done here");
|
2013-10-14 17:12:40 -05:00
|
|
|
return Allowable;
|
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
2013-10-05 16:37:39 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
// We now know that there is at least one private member between the
|
|
|
|
// destination and the root.
|
|
|
|
let mut closest_private_id = did.node;
|
|
|
|
loop {
|
2013-10-21 15:08:31 -05:00
|
|
|
debug!("privacy - examining {}", self.nodestr(closest_private_id));
|
2013-12-27 18:09:29 -06:00
|
|
|
let items = self.tcx.items.borrow();
|
|
|
|
let vis = match items.get().find(&closest_private_id) {
|
2013-11-20 17:15:34 -06:00
|
|
|
// If this item is a method, then we know for sure that it's an
|
|
|
|
// actual method and not a static method. The reason for this is
|
|
|
|
// that these cases are only hit in the ExprMethodCall
|
|
|
|
// expression, and ExprCall will have its path checked later
|
|
|
|
// (the path of the trait/impl) if it's a static method.
|
|
|
|
//
|
|
|
|
// With this information, then we can completely ignore all
|
|
|
|
// trait methods. The privacy violation would be if the trait
|
|
|
|
// couldn't get imported, not if the method couldn't be used
|
|
|
|
// (all trait methods are public).
|
|
|
|
//
|
|
|
|
// However, if this is an impl method, then we dictate this
|
|
|
|
// decision solely based on the privacy of the method
|
|
|
|
// invocation.
|
|
|
|
// FIXME(#10573) is this the right behavior? Why not consider
|
|
|
|
// where the method was defined?
|
|
|
|
Some(&ast_map::node_method(ref m, imp, _)) => {
|
|
|
|
match ty::impl_trait_ref(self.tcx, imp) {
|
2013-11-28 14:22:53 -06:00
|
|
|
Some(..) => return Allowable,
|
2013-11-20 17:15:34 -06:00
|
|
|
_ if m.vis == ast::public => return Allowable,
|
|
|
|
_ => m.vis
|
|
|
|
}
|
|
|
|
}
|
2013-11-28 14:22:53 -06:00
|
|
|
Some(&ast_map::node_trait_method(..)) => {
|
2013-11-20 17:15:34 -06:00
|
|
|
return Allowable;
|
|
|
|
}
|
|
|
|
|
|
|
|
// This is not a method call, extract the visibility as one
|
|
|
|
// would normally look at it
|
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
2013-10-05 16:37:39 -05:00
|
|
|
Some(&ast_map::node_item(it, _)) => it.vis,
|
|
|
|
Some(&ast_map::node_foreign_item(_, _, v, _)) => v,
|
|
|
|
Some(&ast_map::node_variant(ref v, _, _)) => {
|
|
|
|
// sadly enum variants still inherit visibility, so only
|
|
|
|
// break out of this is explicitly private
|
|
|
|
if v.node.vis == ast::private { break }
|
|
|
|
ast::public // need to move up a level (to the enum)
|
|
|
|
}
|
|
|
|
_ => ast::public,
|
|
|
|
};
|
|
|
|
if vis != ast::public { break }
|
2013-11-20 17:15:34 -06:00
|
|
|
// if we've reached the root, then everything was allowable and this
|
|
|
|
// access is public.
|
|
|
|
if closest_private_id == ast::CRATE_NODE_ID { return Allowable }
|
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
2013-10-05 16:37:39 -05:00
|
|
|
closest_private_id = *self.parents.get(&closest_private_id);
|
|
|
|
|
2013-11-20 17:15:34 -06:00
|
|
|
// If we reached the top, then we were public all the way down and
|
|
|
|
// we can allow this access.
|
|
|
|
if closest_private_id == ast::DUMMY_NODE_ID { return Allowable }
|
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
2013-10-05 16:37:39 -05:00
|
|
|
}
|
2013-10-21 15:08:31 -05:00
|
|
|
debug!("privacy - closest priv {}", self.nodestr(closest_private_id));
|
2013-10-14 17:12:40 -05:00
|
|
|
if self.private_accessible(closest_private_id) {
|
|
|
|
Allowable
|
|
|
|
} else {
|
|
|
|
DisallowedBy(closest_private_id)
|
|
|
|
}
|
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
2013-10-05 16:37:39 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/// For a local private node in the AST, this function will determine
|
|
|
|
/// whether the node is accessible by the current module that iteration is
|
|
|
|
/// inside.
|
|
|
|
fn private_accessible(&self, id: ast::NodeId) -> bool {
|
|
|
|
let parent = *self.parents.get(&id);
|
2013-10-21 15:08:31 -05:00
|
|
|
debug!("privacy - accessible parent {}", self.nodestr(parent));
|
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
2013-10-05 16:37:39 -05:00
|
|
|
|
|
|
|
// After finding `did`'s closest private member, we roll ourselves back
|
|
|
|
// to see if this private member's parent is anywhere in our ancestry.
|
|
|
|
// By the privacy rules, we can access all of our ancestor's private
|
|
|
|
// members, so that's why we test the parent, and not the did itself.
|
|
|
|
let mut cur = self.curitem;
|
|
|
|
loop {
|
2013-10-21 15:08:31 -05:00
|
|
|
debug!("privacy - questioning {}", self.nodestr(cur));
|
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
2013-10-05 16:37:39 -05:00
|
|
|
match cur {
|
|
|
|
// If the relevant parent is in our history, then we're allowed
|
|
|
|
// to look inside any of our ancestor's immediate private items,
|
|
|
|
// so this access is valid.
|
|
|
|
x if x == parent => return true,
|
|
|
|
|
|
|
|
// If we've reached the root, then we couldn't access this item
|
|
|
|
// in the first place
|
|
|
|
ast::DUMMY_NODE_ID => return false,
|
|
|
|
|
|
|
|
// Keep going up
|
|
|
|
_ => {}
|
2013-03-18 19:20:45 -05:00
|
|
|
}
|
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
2013-10-05 16:37:39 -05:00
|
|
|
|
|
|
|
cur = *self.parents.get(&cur);
|
|
|
|
}
|
2013-08-13 06:21:45 -05:00
|
|
|
}
|
2013-03-18 19:20:45 -05:00
|
|
|
|
2013-10-14 17:12:40 -05:00
|
|
|
/// Guarantee that a particular definition is public, possibly emitting an
|
|
|
|
/// error message if it's not.
|
|
|
|
fn ensure_public(&self, span: Span, to_check: ast::DefId,
|
|
|
|
source_did: Option<ast::DefId>, msg: &str) -> bool {
|
|
|
|
match self.def_privacy(to_check) {
|
|
|
|
ExternallyDenied => {
|
|
|
|
self.tcx.sess.span_err(span, format!("{} is private", msg))
|
|
|
|
}
|
|
|
|
DisallowedBy(id) => {
|
|
|
|
if id == source_did.unwrap_or(to_check).node {
|
|
|
|
self.tcx.sess.span_err(span, format!("{} is private", msg));
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
self.tcx.sess.span_err(span, format!("{} is inaccessible",
|
|
|
|
msg));
|
|
|
|
}
|
2013-12-27 18:09:29 -06:00
|
|
|
let items = self.tcx.items.borrow();
|
|
|
|
match items.get().find(&id) {
|
2013-10-14 17:12:40 -05:00
|
|
|
Some(&ast_map::node_item(item, _)) => {
|
|
|
|
let desc = match item.node {
|
2013-11-28 14:22:53 -06:00
|
|
|
ast::item_mod(..) => "module",
|
|
|
|
ast::item_trait(..) => "trait",
|
2013-10-14 17:12:40 -05:00
|
|
|
_ => return false,
|
|
|
|
};
|
|
|
|
let msg = format!("{} `{}` is private", desc,
|
|
|
|
token::ident_to_str(&item.ident));
|
|
|
|
self.tcx.sess.span_note(span, msg);
|
|
|
|
}
|
2013-11-28 14:22:53 -06:00
|
|
|
Some(..) | None => {}
|
2013-10-14 17:12:40 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
Allowable => return true
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
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
2013-10-05 16:37:39 -05:00
|
|
|
// Checks that a field is in scope.
|
2013-09-11 18:21:03 -05:00
|
|
|
// FIXME #6993: change type (and name) from Ident to Name
|
2013-09-01 20:45:37 -05:00
|
|
|
fn check_field(&mut self, span: Span, id: ast::DefId, ident: ast::Ident) {
|
2013-08-13 06:21:45 -05:00
|
|
|
let fields = ty::lookup_struct_fields(self.tcx, id);
|
2013-08-03 11:45:23 -05:00
|
|
|
for field in fields.iter() {
|
2013-10-01 16:31:03 -05:00
|
|
|
if field.name != ident.name { continue; }
|
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
2013-10-05 16:37:39 -05:00
|
|
|
// public fields are public everywhere
|
|
|
|
if field.vis != ast::private { break }
|
|
|
|
if !is_local(field.id) ||
|
|
|
|
!self.private_accessible(field.id.node) {
|
2013-09-28 00:38:08 -05:00
|
|
|
self.tcx.sess.span_err(span, format!("field `{}` is private",
|
2013-06-12 12:02:55 -05:00
|
|
|
token::ident_to_str(&ident)));
|
2012-09-04 20:28:22 -05:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2013-08-13 06:21:45 -05:00
|
|
|
}
|
2012-09-04 20:28:22 -05:00
|
|
|
|
2013-03-18 19:20:45 -05:00
|
|
|
// Given the ID of a method, checks to ensure it's in scope.
|
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
2013-10-05 16:37:39 -05:00
|
|
|
fn check_static_method(&mut self, span: Span, method_id: ast::DefId,
|
|
|
|
name: &ast::Ident) {
|
2013-07-02 16:39:25 -05:00
|
|
|
// If the method is a default method, we need to use the def_id of
|
|
|
|
// the default implementation.
|
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
2013-10-05 16:37:39 -05:00
|
|
|
let method_id = ty::method(self.tcx, method_id).provided_source
|
|
|
|
.unwrap_or(method_id);
|
|
|
|
|
2013-10-14 17:12:40 -05:00
|
|
|
self.ensure_public(span, method_id, None,
|
|
|
|
format!("method `{}`", token::ident_to_str(name)));
|
2013-08-13 06:21:45 -05:00
|
|
|
}
|
2013-03-18 19:20:45 -05:00
|
|
|
|
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
2013-10-05 16:37:39 -05:00
|
|
|
// Checks that a path is in scope.
|
|
|
|
fn check_path(&mut self, span: Span, path_id: ast::NodeId, path: &ast::Path) {
|
2013-10-21 15:08:31 -05:00
|
|
|
debug!("privacy - path {}", self.nodestr(path_id));
|
2013-12-23 13:15:16 -06:00
|
|
|
let def_map = self.tcx.def_map.borrow();
|
|
|
|
let def = def_map.get().get_copy(&path_id);
|
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
2013-10-05 16:37:39 -05:00
|
|
|
let ck = |tyname: &str| {
|
2013-10-14 17:12:40 -05:00
|
|
|
let origdid = def_id_of_def(def);
|
|
|
|
match *self.last_private_map.get(&path_id) {
|
|
|
|
resolve::AllPublic => {},
|
|
|
|
resolve::DependsOn(def) => {
|
|
|
|
let name = token::ident_to_str(&path.segments.last()
|
|
|
|
.identifier);
|
|
|
|
self.ensure_public(span, def, Some(origdid),
|
|
|
|
format!("{} `{}`", tyname, name));
|
|
|
|
}
|
2013-03-18 19:20:45 -05:00
|
|
|
}
|
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
2013-10-05 16:37:39 -05:00
|
|
|
};
|
2013-12-23 13:15:16 -06:00
|
|
|
let def_map = self.tcx.def_map.borrow();
|
|
|
|
match def_map.get().get_copy(&path_id) {
|
2013-11-28 14:22:53 -06:00
|
|
|
ast::DefStaticMethod(..) => ck("static method"),
|
|
|
|
ast::DefFn(..) => ck("function"),
|
|
|
|
ast::DefStatic(..) => ck("static"),
|
|
|
|
ast::DefVariant(..) => ck("variant"),
|
|
|
|
ast::DefTy(..) => ck("type"),
|
|
|
|
ast::DefTrait(..) => ck("trait"),
|
|
|
|
ast::DefStruct(..) => ck("struct"),
|
|
|
|
ast::DefMethod(_, Some(..)) => ck("trait method"),
|
|
|
|
ast::DefMethod(..) => ck("method"),
|
|
|
|
ast::DefMod(..) => ck("module"),
|
2013-03-18 19:20:45 -05:00
|
|
|
_ => {}
|
|
|
|
}
|
2013-08-13 06:21:45 -05:00
|
|
|
}
|
2013-03-18 19:20:45 -05:00
|
|
|
|
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
2013-10-05 16:37:39 -05:00
|
|
|
// Checks that a method is in scope.
|
|
|
|
fn check_method(&mut self, span: Span, origin: &method_origin,
|
|
|
|
ident: ast::Ident) {
|
2012-09-04 20:28:22 -05:00
|
|
|
match *origin {
|
|
|
|
method_static(method_id) => {
|
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
2013-10-05 16:37:39 -05:00
|
|
|
self.check_static_method(span, method_id, &ident)
|
2012-09-04 20:28:22 -05:00
|
|
|
}
|
2013-11-20 17:15:34 -06:00
|
|
|
// Trait methods are always all public. The only controlling factor
|
|
|
|
// is whether the trait itself is accessible or not.
|
2013-11-28 14:22:53 -06:00
|
|
|
method_param(method_param { trait_id: trait_id, .. }) |
|
|
|
|
method_object(method_object { trait_id: trait_id, .. }) => {
|
2013-11-20 17:15:34 -06:00
|
|
|
self.ensure_public(span, trait_id, None, "source trait");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-12-10 01:16:18 -06:00
|
|
|
impl<'a> Visitor<()> for PrivacyVisitor<'a> {
|
2014-01-06 06:00:46 -06:00
|
|
|
fn visit_item(&mut self, item: &ast::item, _: ()) {
|
2013-11-20 17:15:34 -06:00
|
|
|
// Do not check privacy inside items with the resolve_unexported
|
|
|
|
// attribute. This is used for the test runner.
|
|
|
|
if attr::contains_name(item.attrs, "!resolve_unexported") {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
let orig_curitem = util::replace(&mut self.curitem, item.id);
|
|
|
|
visit::walk_item(self, item, ());
|
|
|
|
self.curitem = orig_curitem;
|
|
|
|
}
|
|
|
|
|
2014-01-06 06:00:46 -06:00
|
|
|
fn visit_expr(&mut self, expr: &ast::Expr, _: ()) {
|
2013-11-20 17:15:34 -06:00
|
|
|
match expr.node {
|
|
|
|
ast::ExprField(base, ident, _) => {
|
|
|
|
// Method calls are now a special syntactic form,
|
|
|
|
// so `a.b` should always be a field.
|
2013-12-21 19:04:42 -06:00
|
|
|
let method_map = self.method_map.borrow();
|
|
|
|
assert!(!method_map.get().contains_key(&expr.id));
|
2013-11-20 17:15:34 -06:00
|
|
|
|
|
|
|
// With type_autoderef, make sure we don't
|
|
|
|
// allow pointers to violate privacy
|
2013-11-01 20:06:31 -05:00
|
|
|
let t = ty::type_autoderef(ty::expr_ty(self.tcx, base));
|
2013-11-20 17:15:34 -06:00
|
|
|
match ty::get(t).sty {
|
2013-12-08 13:25:35 -06:00
|
|
|
ty::ty_struct(id, _) => {
|
|
|
|
self.check_field(expr.span, id, ident);
|
|
|
|
}
|
2013-11-20 17:15:34 -06:00
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ast::ExprMethodCall(_, base, ident, _, _, _) => {
|
|
|
|
// see above
|
2013-11-01 20:06:31 -05:00
|
|
|
let t = ty::type_autoderef(ty::expr_ty(self.tcx, base));
|
2013-11-20 17:15:34 -06:00
|
|
|
match ty::get(t).sty {
|
|
|
|
ty::ty_enum(_, _) | ty::ty_struct(_, _) => {
|
2013-12-21 19:04:42 -06:00
|
|
|
let method_map = self.method_map.borrow();
|
|
|
|
let entry = match method_map.get().find(&expr.id) {
|
2013-11-20 17:15:34 -06:00
|
|
|
None => {
|
|
|
|
self.tcx.sess.span_bug(expr.span,
|
|
|
|
"method call not in \
|
|
|
|
method map");
|
|
|
|
}
|
|
|
|
Some(entry) => entry
|
|
|
|
};
|
|
|
|
debug!("(privacy checking) checking impl method");
|
|
|
|
self.check_method(expr.span, &entry.origin, ident);
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ast::ExprStruct(_, ref fields, _) => {
|
|
|
|
match ty::get(ty::expr_ty(self.tcx, expr)).sty {
|
|
|
|
ty::ty_struct(id, _) => {
|
|
|
|
for field in (*fields).iter() {
|
|
|
|
self.check_field(expr.span, id, field.ident.node);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ty::ty_enum(_, _) => {
|
2013-12-23 13:15:16 -06:00
|
|
|
let def_map = self.tcx.def_map.borrow();
|
|
|
|
match def_map.get().get_copy(&expr.id) {
|
2013-11-20 17:15:34 -06:00
|
|
|
ast::DefVariant(_, variant_id, _) => {
|
|
|
|
for field in fields.iter() {
|
|
|
|
self.check_field(expr.span, variant_id,
|
|
|
|
field.ident.node);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => self.tcx.sess.span_bug(expr.span,
|
|
|
|
"resolve didn't \
|
|
|
|
map enum struct \
|
|
|
|
constructor to a \
|
|
|
|
variant def"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => self.tcx.sess.span_bug(expr.span, "struct expr \
|
|
|
|
didn't have \
|
|
|
|
struct type?!"),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
|
|
|
|
visit::walk_expr(self, expr, ());
|
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_view_item(&mut self, a: &ast::view_item, _: ()) {
|
|
|
|
match a.node {
|
2013-11-28 14:22:53 -06:00
|
|
|
ast::view_item_extern_mod(..) => {}
|
2013-11-20 17:15:34 -06:00
|
|
|
ast::view_item_use(ref uses) => {
|
|
|
|
for vpath in uses.iter() {
|
|
|
|
match vpath.node {
|
2013-12-08 13:25:35 -06:00
|
|
|
ast::view_path_simple(..) |
|
|
|
|
ast::view_path_glob(..) => {}
|
2013-11-20 17:15:34 -06:00
|
|
|
ast::view_path_list(_, ref list, _) => {
|
|
|
|
for pid in list.iter() {
|
|
|
|
debug!("privacy - list {}", pid.node.id);
|
|
|
|
let seg = ast::PathSegment {
|
|
|
|
identifier: pid.node.name,
|
|
|
|
lifetimes: opt_vec::Empty,
|
|
|
|
types: opt_vec::Empty,
|
|
|
|
};
|
|
|
|
let segs = ~[seg];
|
|
|
|
let path = ast::Path {
|
|
|
|
global: false,
|
|
|
|
span: pid.span,
|
|
|
|
segments: segs,
|
|
|
|
};
|
|
|
|
self.check_path(pid.span, pid.node.id, &path);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-12-08 13:25:35 -06:00
|
|
|
visit::walk_view_item(self, a, ());
|
2013-11-20 17:15:34 -06:00
|
|
|
}
|
|
|
|
|
2013-11-25 12:22:21 -06:00
|
|
|
fn visit_pat(&mut self, pattern: &ast::Pat, _: ()) {
|
2013-12-08 13:25:35 -06:00
|
|
|
// Foreign functions do not have their patterns mapped in the def_map,
|
|
|
|
// and there's nothing really relevant there anyway, so don't bother
|
|
|
|
// checking privacy. If you can name the type then you can pass it to an
|
|
|
|
// external C function anyway.
|
|
|
|
if self.in_foreign { return }
|
|
|
|
|
2013-11-20 17:15:34 -06:00
|
|
|
match pattern.node {
|
|
|
|
ast::PatStruct(_, ref fields, _) => {
|
|
|
|
match ty::get(ty::pat_ty(self.tcx, pattern)).sty {
|
|
|
|
ty::ty_struct(id, _) => {
|
|
|
|
for field in fields.iter() {
|
|
|
|
self.check_field(pattern.span, id, field.ident);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ty::ty_enum(_, _) => {
|
2013-12-23 13:15:16 -06:00
|
|
|
let def_map = self.tcx.def_map.borrow();
|
|
|
|
match def_map.get().find(&pattern.id) {
|
2013-11-20 17:15:34 -06:00
|
|
|
Some(&ast::DefVariant(_, variant_id, _)) => {
|
|
|
|
for field in fields.iter() {
|
|
|
|
self.check_field(pattern.span, variant_id,
|
|
|
|
field.ident);
|
2012-09-04 20:28:22 -05:00
|
|
|
}
|
|
|
|
}
|
2013-11-20 17:15:34 -06:00
|
|
|
_ => self.tcx.sess.span_bug(pattern.span,
|
|
|
|
"resolve didn't \
|
|
|
|
map enum struct \
|
|
|
|
pattern to a \
|
|
|
|
variant def"),
|
2012-09-04 20:28:22 -05:00
|
|
|
}
|
|
|
|
}
|
2013-11-20 17:15:34 -06:00
|
|
|
_ => self.tcx.sess.span_bug(pattern.span,
|
|
|
|
"struct pattern didn't have \
|
|
|
|
struct type?!"),
|
2012-09-04 20:28:22 -05:00
|
|
|
}
|
|
|
|
}
|
2013-11-20 17:15:34 -06:00
|
|
|
_ => {}
|
2012-09-04 20:28:22 -05:00
|
|
|
}
|
2013-11-20 17:15:34 -06:00
|
|
|
|
|
|
|
visit::walk_pat(self, pattern, ());
|
2013-08-13 06:21:45 -05:00
|
|
|
}
|
2013-12-08 13:25:35 -06:00
|
|
|
|
2014-01-06 06:00:46 -06:00
|
|
|
fn visit_foreign_item(&mut self, fi: &ast::foreign_item, _: ()) {
|
2013-12-08 13:25:35 -06:00
|
|
|
self.in_foreign = true;
|
|
|
|
visit::walk_foreign_item(self, fi, ());
|
|
|
|
self.in_foreign = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_path(&mut self, path: &ast::Path, id: ast::NodeId, _: ()) {
|
|
|
|
self.check_path(path.span, id, path);
|
|
|
|
visit::walk_path(self, path, ());
|
|
|
|
}
|
2013-11-20 17:15:34 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
/// The privacy sanity check visitor, ensures unnecessary visibility isn't here
|
|
|
|
////////////////////////////////////////////////////////////////////////////////
|
|
|
|
|
|
|
|
struct SanePrivacyVisitor {
|
|
|
|
tcx: ty::ctxt,
|
|
|
|
in_fn: bool,
|
|
|
|
}
|
2013-08-13 06:21:45 -05:00
|
|
|
|
2013-11-20 17:15:34 -06:00
|
|
|
impl Visitor<()> for SanePrivacyVisitor {
|
2014-01-06 06:00:46 -06:00
|
|
|
fn visit_item(&mut self, item: &ast::item, _: ()) {
|
2013-11-20 17:15:34 -06:00
|
|
|
if self.in_fn {
|
|
|
|
self.check_all_inherited(item);
|
|
|
|
} else {
|
|
|
|
self.check_sane_privacy(item);
|
|
|
|
}
|
|
|
|
|
|
|
|
let orig_in_fn = util::replace(&mut self.in_fn, match item.node {
|
2013-11-28 14:22:53 -06:00
|
|
|
ast::item_mod(..) => false, // modules turn privacy back on
|
2013-11-20 17:15:34 -06:00
|
|
|
_ => self.in_fn, // otherwise we inherit
|
|
|
|
});
|
|
|
|
visit::walk_item(self, item, ());
|
|
|
|
self.in_fn = orig_in_fn;
|
|
|
|
}
|
|
|
|
|
|
|
|
fn visit_fn(&mut self, fk: &visit::fn_kind, fd: &ast::fn_decl,
|
2014-01-06 06:00:46 -06:00
|
|
|
b: &ast::Block, s: Span, n: ast::NodeId, _: ()) {
|
2013-11-20 17:15:34 -06:00
|
|
|
// This catches both functions and methods
|
|
|
|
let orig_in_fn = util::replace(&mut self.in_fn, true);
|
|
|
|
visit::walk_fn(self, fk, fd, b, s, n, ());
|
|
|
|
self.in_fn = orig_in_fn;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl SanePrivacyVisitor {
|
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
2013-10-05 16:37:39 -05:00
|
|
|
/// Validates all of the visibility qualifers placed on the item given. This
|
|
|
|
/// ensures that there are no extraneous qualifiers that don't actually do
|
|
|
|
/// anything. In theory these qualifiers wouldn't parse, but that may happen
|
|
|
|
/// later on down the road...
|
2014-01-06 06:00:46 -06:00
|
|
|
fn check_sane_privacy(&self, item: &ast::item) {
|
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
2013-10-05 16:37:39 -05:00
|
|
|
let tcx = self.tcx;
|
|
|
|
let check_inherited = |sp: Span, vis: ast::visibility, note: &str| {
|
|
|
|
if vis != ast::inherited {
|
|
|
|
tcx.sess.span_err(sp, "unnecessary visibility qualifier");
|
|
|
|
if note.len() > 0 {
|
|
|
|
tcx.sess.span_note(sp, note);
|
|
|
|
}
|
2012-09-04 16:48:32 -05:00
|
|
|
}
|
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
2013-10-05 16:37:39 -05:00
|
|
|
};
|
|
|
|
let check_not_priv = |sp: Span, vis: ast::visibility, note: &str| {
|
|
|
|
if vis == ast::private {
|
|
|
|
tcx.sess.span_err(sp, "unnecessary `priv` qualifier");
|
|
|
|
if note.len() > 0 {
|
|
|
|
tcx.sess.span_note(sp, note);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2013-10-19 00:43:16 -05:00
|
|
|
let check_struct = |def: &@ast::struct_def| {
|
|
|
|
for f in def.fields.iter() {
|
|
|
|
match f.node.kind {
|
|
|
|
ast::named_field(_, ast::public) => {
|
|
|
|
tcx.sess.span_err(f.span, "unnecessary `pub` \
|
|
|
|
visibility");
|
|
|
|
}
|
|
|
|
ast::named_field(_, ast::private) => {
|
|
|
|
// Fields should really be private by default...
|
|
|
|
}
|
2013-11-28 14:22:53 -06:00
|
|
|
ast::named_field(..) | ast::unnamed_field => {}
|
2013-10-19 00:43:16 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2013-08-07 02:11:34 -05:00
|
|
|
match item.node {
|
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
2013-10-05 16:37:39 -05:00
|
|
|
// implementations of traits don't need visibility qualifiers because
|
|
|
|
// that's controlled by having the trait in scope.
|
2013-11-28 14:22:53 -06:00
|
|
|
ast::item_impl(_, Some(..), _, ref methods) => {
|
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
2013-10-05 16:37:39 -05:00
|
|
|
check_inherited(item.span, item.vis,
|
|
|
|
"visibility qualifiers have no effect on trait \
|
|
|
|
impls");
|
|
|
|
for m in methods.iter() {
|
|
|
|
check_inherited(m.span, m.vis, "");
|
|
|
|
}
|
2013-08-07 02:11:34 -05:00
|
|
|
}
|
|
|
|
|
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
2013-10-05 16:37:39 -05:00
|
|
|
ast::item_impl(_, _, _, ref methods) => {
|
|
|
|
check_inherited(item.span, item.vis,
|
|
|
|
"place qualifiers on individual methods instead");
|
|
|
|
for i in methods.iter() {
|
|
|
|
check_not_priv(i.span, i.vis, "functions are private by \
|
|
|
|
default");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ast::item_foreign_mod(ref fm) => {
|
|
|
|
check_inherited(item.span, item.vis,
|
|
|
|
"place qualifiers on individual functions \
|
|
|
|
instead");
|
|
|
|
for i in fm.items.iter() {
|
|
|
|
check_not_priv(i.span, i.vis, "functions are private by \
|
|
|
|
default");
|
|
|
|
}
|
|
|
|
}
|
2013-08-07 02:11:34 -05:00
|
|
|
|
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
2013-10-05 16:37:39 -05:00
|
|
|
ast::item_enum(ref def, _) => {
|
|
|
|
for v in def.variants.iter() {
|
|
|
|
match v.node.vis {
|
|
|
|
ast::public => {
|
|
|
|
if item.vis == ast::public {
|
|
|
|
tcx.sess.span_err(v.span, "unnecessary `pub` \
|
|
|
|
visibility");
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ast::private => {
|
|
|
|
if item.vis != ast::public {
|
|
|
|
tcx.sess.span_err(v.span, "unnecessary `priv` \
|
|
|
|
visibility");
|
2013-08-07 02:11:34 -05:00
|
|
|
}
|
|
|
|
}
|
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
2013-10-05 16:37:39 -05:00
|
|
|
ast::inherited => {}
|
2013-08-07 02:11:34 -05:00
|
|
|
}
|
2013-08-13 06:21:45 -05:00
|
|
|
|
2013-10-19 00:43:16 -05:00
|
|
|
match v.node.kind {
|
|
|
|
ast::struct_variant_kind(ref s) => check_struct(s),
|
2013-11-28 14:22:53 -06:00
|
|
|
ast::tuple_variant_kind(..) => {}
|
2013-03-18 19:20:45 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-10-19 00:43:16 -05:00
|
|
|
ast::item_struct(ref def, _) => check_struct(def),
|
|
|
|
|
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
2013-10-05 16:37:39 -05:00
|
|
|
ast::item_trait(_, _, ref methods) => {
|
|
|
|
for m in methods.iter() {
|
|
|
|
match *m {
|
|
|
|
ast::provided(ref m) => {
|
|
|
|
check_inherited(m.span, m.vis,
|
|
|
|
"unnecessary visibility");
|
|
|
|
}
|
2013-11-28 14:22:53 -06:00
|
|
|
ast::required(..) => {}
|
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
2013-10-05 16:37:39 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2013-03-18 19:20:45 -05:00
|
|
|
|
2013-11-28 14:22:53 -06:00
|
|
|
ast::item_static(..) |
|
|
|
|
ast::item_fn(..) | ast::item_mod(..) | ast::item_ty(..) |
|
|
|
|
ast::item_mac(..) => {
|
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
2013-10-05 16:37:39 -05:00
|
|
|
check_not_priv(item.span, item.vis, "items are private by \
|
|
|
|
default");
|
2013-03-18 19:20:45 -05:00
|
|
|
}
|
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
2013-10-05 16:37:39 -05:00
|
|
|
}
|
|
|
|
}
|
2013-11-05 20:06:27 -06:00
|
|
|
|
|
|
|
/// When inside of something like a function or a method, visibility has no
|
|
|
|
/// control over anything so this forbids any mention of any visibility
|
2014-01-06 06:00:46 -06:00
|
|
|
fn check_all_inherited(&self, item: &ast::item) {
|
2013-11-05 20:06:27 -06:00
|
|
|
let tcx = self.tcx;
|
|
|
|
let check_inherited = |sp: Span, vis: ast::visibility| {
|
|
|
|
if vis != ast::inherited {
|
|
|
|
tcx.sess.span_err(sp, "visibility has no effect inside functions");
|
|
|
|
}
|
|
|
|
};
|
|
|
|
let check_struct = |def: &@ast::struct_def| {
|
|
|
|
for f in def.fields.iter() {
|
|
|
|
match f.node.kind {
|
|
|
|
ast::named_field(_, p) => check_inherited(f.span, p),
|
|
|
|
ast::unnamed_field => {}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
|
|
|
check_inherited(item.span, item.vis);
|
|
|
|
match item.node {
|
|
|
|
ast::item_impl(_, _, _, ref methods) => {
|
|
|
|
for m in methods.iter() {
|
|
|
|
check_inherited(m.span, m.vis);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ast::item_foreign_mod(ref fm) => {
|
|
|
|
for i in fm.items.iter() {
|
|
|
|
check_inherited(i.span, i.vis);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
ast::item_enum(ref def, _) => {
|
|
|
|
for v in def.variants.iter() {
|
|
|
|
check_inherited(v.span, v.node.vis);
|
|
|
|
|
|
|
|
match v.node.kind {
|
|
|
|
ast::struct_variant_kind(ref s) => check_struct(s),
|
2013-11-28 14:22:53 -06:00
|
|
|
ast::tuple_variant_kind(..) => {}
|
2013-11-05 20:06:27 -06:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
ast::item_struct(ref def, _) => check_struct(def),
|
|
|
|
|
|
|
|
ast::item_trait(_, _, ref methods) => {
|
|
|
|
for m in methods.iter() {
|
|
|
|
match *m {
|
2013-11-28 14:22:53 -06:00
|
|
|
ast::required(..) => {}
|
2013-11-05 20:06:27 -06:00
|
|
|
ast::provided(ref m) => check_inherited(m.span, m.vis),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-11-28 14:22:53 -06:00
|
|
|
ast::item_static(..) |
|
|
|
|
ast::item_fn(..) | ast::item_mod(..) | ast::item_ty(..) |
|
|
|
|
ast::item_mac(..) => {}
|
2013-11-05 20:06:27 -06:00
|
|
|
}
|
|
|
|
}
|
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
2013-10-05 16:37:39 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
pub fn check_crate(tcx: ty::ctxt,
|
|
|
|
method_map: &method_map,
|
|
|
|
exp_map2: &resolve::ExportMap2,
|
|
|
|
external_exports: resolve::ExternalExports,
|
|
|
|
last_private_map: resolve::LastPrivateMap,
|
2013-10-09 23:16:51 -05:00
|
|
|
crate: &ast::Crate) -> ExportedItems {
|
2013-11-20 17:15:34 -06:00
|
|
|
// Figure out who everyone's parent is
|
|
|
|
let mut visitor = ParentVisitor {
|
|
|
|
parents: HashMap::new(),
|
|
|
|
curparent: ast::DUMMY_NODE_ID,
|
|
|
|
};
|
|
|
|
visit::walk_crate(&mut visitor, crate, ());
|
|
|
|
|
|
|
|
// Use the parent map to check the privacy of everything
|
|
|
|
let mut visitor = PrivacyVisitor {
|
|
|
|
curitem: ast::DUMMY_NODE_ID,
|
|
|
|
in_fn: false,
|
2013-12-08 13:25:35 -06:00
|
|
|
in_foreign: false,
|
2013-11-20 17:15:34 -06:00
|
|
|
tcx: tcx,
|
|
|
|
parents: visitor.parents,
|
|
|
|
method_map: method_map,
|
|
|
|
external_exports: external_exports,
|
|
|
|
last_private_map: last_private_map,
|
|
|
|
};
|
|
|
|
visit::walk_crate(&mut visitor, crate, ());
|
|
|
|
|
|
|
|
// Sanity check to make sure that all privacy usage and controls are
|
|
|
|
// reasonable.
|
|
|
|
let mut visitor = SanePrivacyVisitor {
|
|
|
|
in_fn: false,
|
|
|
|
tcx: tcx,
|
|
|
|
};
|
|
|
|
visit::walk_crate(&mut visitor, crate, ());
|
|
|
|
|
|
|
|
tcx.sess.abort_if_errors();
|
|
|
|
|
|
|
|
// Build up a set of all exported items in the AST. This is a set of all
|
|
|
|
// items which are reachable from external crates based on visibility.
|
|
|
|
let mut visitor = EmbargoVisitor {
|
|
|
|
tcx: tcx,
|
|
|
|
exported_items: HashSet::new(),
|
|
|
|
reexports: HashSet::new(),
|
|
|
|
exp_map2: exp_map2,
|
|
|
|
prev_exported: true,
|
|
|
|
};
|
|
|
|
loop {
|
|
|
|
let before = visitor.exported_items.len();
|
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
2013-10-05 16:37:39 -05:00
|
|
|
visit::walk_crate(&mut visitor, crate, ());
|
2013-11-20 17:15:34 -06:00
|
|
|
if before == visitor.exported_items.len() {
|
|
|
|
break
|
|
|
|
}
|
2013-08-09 03:25:24 -05:00
|
|
|
}
|
2013-11-11 22:17:47 -06:00
|
|
|
|
2013-11-20 17:15:34 -06:00
|
|
|
return visitor.exported_items;
|
2013-08-09 03:25:24 -05:00
|
|
|
}
|