about summary refs log tree commit diff
diff options
context:
space:
mode:
authorVadim Petrochenkov <vadim.petrochenkov@gmail.com>2017-11-18 19:15:16 +0300
committerVadim Petrochenkov <vadim.petrochenkov@gmail.com>2017-12-21 03:17:19 +0300
commit020961d88027faf901c533634f07bb5bf3bb64d3 (patch)
tree2529299f3a90506d2918cc18c413fcf93b3e92eb
parent190adc0e193d9b7154b54b4800e2059acb72448b (diff)
downloadrust-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.rs10
-rw-r--r--src/test/compile-fail/auxiliary/private-inferred-type.rs2
-rw-r--r--src/test/compile-fail/private-inferred-type-3.rs1
-rw-r--r--src/test/compile-fail/private-inferred-type.rs2
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