diff options
| author | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2017-11-18 19:15:16 +0300 |
|---|---|---|
| committer | Vadim Petrochenkov <vadim.petrochenkov@gmail.com> | 2017-12-21 03:17:19 +0300 |
| commit | 020961d88027faf901c533634f07bb5bf3bb64d3 (patch) | |
| tree | 2529299f3a90506d2918cc18c413fcf93b3e92eb | |
| parent | 190adc0e193d9b7154b54b4800e2059acb72448b (diff) | |
| download | rust-020961d88027faf901c533634f07bb5bf3bb64d3.tar.gz rust-020961d88027faf901c533634f07bb5bf3bb64d3.zip | |
Prohibit access to private statics from other crates through macros 2.0
| -rw-r--r-- | src/librustc_privacy/lib.rs | 10 | ||||
| -rw-r--r-- | src/test/compile-fail/auxiliary/private-inferred-type.rs | 2 | ||||
| -rw-r--r-- | src/test/compile-fail/private-inferred-type-3.rs | 1 | ||||
| -rw-r--r-- | src/test/compile-fail/private-inferred-type.rs | 2 |
4 files changed, 13 insertions, 2 deletions
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 906e584e0ec..fc2e2ca6620 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -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(), diff --git a/src/test/compile-fail/auxiliary/private-inferred-type.rs b/src/test/compile-fail/auxiliary/private-inferred-type.rs index 7627f5dc0cd..fc43765f63c 100644 --- a/src/test/compile-fail/auxiliary/private-inferred-type.rs +++ b/src/test/compile-fail/auxiliary/private-inferred-type.rs @@ -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; diff --git a/src/test/compile-fail/private-inferred-type-3.rs b/src/test/compile-fail/private-inferred-type-3.rs index c0ba38b2402..0c393f02323 100644 --- a/src/test/compile-fail/private-inferred-type-3.rs +++ b/src/test/compile-fail/private-inferred-type-3.rs @@ -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 diff --git a/src/test/compile-fail/private-inferred-type.rs b/src/test/compile-fail/private-inferred-type.rs index 95e3732d613..c50d7f59b8e 100644 --- a/src/test/compile-fail/private-inferred-type.rs +++ b/src/test/compile-fail/private-inferred-type.rs @@ -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 |
