Prohibit access to private statics from other crates through macros 2.0
This commit is contained in:
parent
190adc0e19
commit
020961d880
4 changed files with 13 additions and 2 deletions
|
@ -783,11 +783,16 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
|
|||
}
|
||||
|
||||
// Prohibit access to associated items with insufficient nominal visibility.
|
||||
//
|
||||
// Additionally, until better reachability analysis for macros 2.0 is available,
|
||||
// we prohibit access to private statics from other crates, this allows to give
|
||||
// more code internal visibility at link time. (Access to private functions
|
||||
// is already prohibited by type privacy for funciton types.)
|
||||
fn visit_qpath(&mut self, qpath: &'tcx hir::QPath, id: ast::NodeId, span: Span) {
|
||||
let def = match *qpath {
|
||||
hir::QPath::Resolved(_, ref path) => match path.def {
|
||||
Def::Method(..) | Def::AssociatedConst(..) |
|
||||
Def::AssociatedTy(..) => Some(path.def),
|
||||
Def::AssociatedTy(..) | Def::Static(..) => Some(path.def),
|
||||
_ => None,
|
||||
}
|
||||
hir::QPath::TypeRelative(..) => {
|
||||
|
@ -797,7 +802,8 @@ impl<'a, 'tcx> Visitor<'tcx> for TypePrivacyVisitor<'a, 'tcx> {
|
|||
};
|
||||
if let Some(def) = def {
|
||||
let def_id = def.def_id();
|
||||
if !self.item_is_accessible(def_id) {
|
||||
let is_local_static = if let Def::Static(..) = def { def_id.is_local() } else { false };
|
||||
if !self.item_is_accessible(def_id) && !is_local_static {
|
||||
let name = match *qpath {
|
||||
hir::QPath::Resolved(_, ref path) => format!("{}", path),
|
||||
hir::QPath::TypeRelative(_, ref segment) => segment.name.to_string(),
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#![feature(decl_macro)]
|
||||
|
||||
fn priv_fn() {}
|
||||
static PRIV_STATIC: u8 = 0;
|
||||
enum PrivEnum { Variant }
|
||||
pub enum PubEnum { Variant }
|
||||
trait PrivTrait { fn method() {} }
|
||||
|
@ -34,6 +35,7 @@ impl Pub<u8> {
|
|||
|
||||
pub macro m() {
|
||||
priv_fn;
|
||||
PRIV_STATIC;
|
||||
PrivEnum::Variant;
|
||||
PubEnum::Variant;
|
||||
<u8 as PrivTrait>::method;
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
// aux-build:private-inferred-type.rs
|
||||
|
||||
// error-pattern:type `fn() {ext::priv_fn}` is private
|
||||
// error-pattern:static `PRIV_STATIC` is private
|
||||
// error-pattern:type `ext::PrivEnum` is private
|
||||
// error-pattern:type `fn() {<u8 as ext::PrivTrait>::method}` is private
|
||||
// error-pattern:type `fn(u8) -> ext::PrivTupleStruct {ext::PrivTupleStruct::{{constructor}}}` is pr
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
|
||||
mod m {
|
||||
fn priv_fn() {}
|
||||
static PRIV_STATIC: u8 = 0;
|
||||
enum PrivEnum { Variant }
|
||||
pub enum PubEnum { Variant }
|
||||
trait PrivTrait { fn method() {} }
|
||||
|
@ -47,6 +48,7 @@ mod m {
|
|||
|
||||
pub macro m() {
|
||||
priv_fn; //~ ERROR type `fn() {m::priv_fn}` is private
|
||||
PRIV_STATIC; // OK, not cross-crate
|
||||
PrivEnum::Variant; //~ ERROR type `m::PrivEnum` is private
|
||||
PubEnum::Variant; // OK
|
||||
<u8 as PrivTrait>::method; //~ ERROR type `fn() {<u8 as m::PrivTrait>::method}` is private
|
||||
|
|
Loading…
Reference in a new issue