about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2016-03-09 07:14:05 -0800
committerbors <bors@rust-lang.org>2016-03-09 07:14:05 -0800
commitef3d0516303f82ebfbcc4c250ebfc783aaadad72 (patch)
tree876c8b3173020b881509d514d2d70ff2fb0ef434
parentcbbd3d9b927e4dc73b071e7bce70e1a3fc119946 (diff)
parentb06a1cc760cfb09e4eeae6d40244be9fcf048d8a (diff)
downloadrust-ef3d0516303f82ebfbcc4c250ebfc783aaadad72.tar.gz
rust-ef3d0516303f82ebfbcc4c250ebfc783aaadad72.zip
Auto merge of #32073 - jseyfried:fix_another_trait_privacy_error, r=nikomatsakis
Fix incorrect trait privacy error

This PR fixes #21670 by using the crate metadata instead of `ExternalExports` to determine if an external item is public.

r? @nikomatsakis
-rw-r--r--src/librustc/middle/cstore.rs2
-rw-r--r--src/librustc_driver/driver.rs5
-rw-r--r--src/librustc_metadata/csearch.rs5
-rw-r--r--src/librustc_metadata/decoder.rs4
-rw-r--r--src/librustc_privacy/lib.rs11
-rw-r--r--src/librustc_resolve/build_reduced_graph.rs14
-rw-r--r--src/librustc_resolve/lib.rs7
-rw-r--r--src/test/compile-fail/trait-privacy.rs7
8 files changed, 22 insertions, 33 deletions
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs
index 3af987df3a8..193492ee7e1 100644
--- a/src/librustc/middle/cstore.rs
+++ b/src/librustc/middle/cstore.rs
@@ -137,6 +137,7 @@ pub trait CrateStore<'tcx> : Any {
     // item info
     fn stability(&self, def: DefId) -> Option<attr::Stability>;
     fn deprecation(&self, def: DefId) -> Option<attr::Deprecation>;
+    fn visibility(&self, def: DefId) -> hir::Visibility;
     fn closure_kind(&self, tcx: &TyCtxt<'tcx>, def_id: DefId)
                     -> ty::ClosureKind;
     fn closure_ty(&self, tcx: &TyCtxt<'tcx>, def_id: DefId)
@@ -302,6 +303,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
     // item info
     fn stability(&self, def: DefId) -> Option<attr::Stability> { unimplemented!() }
     fn deprecation(&self, def: DefId) -> Option<attr::Deprecation> { unimplemented!() }
+    fn visibility(&self, def: DefId) -> hir::Visibility { unimplemented!() }
     fn closure_kind(&self, tcx: &TyCtxt<'tcx>, def_id: DefId)
                     -> ty::ClosureKind  { unimplemented!() }
     fn closure_ty(&self, tcx: &TyCtxt<'tcx>, def_id: DefId)
diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs
index 43160ab3558..55ec9d82a2e 100644
--- a/src/librustc_driver/driver.rs
+++ b/src/librustc_driver/driver.rs
@@ -768,7 +768,6 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
         freevars,
         export_map,
         trait_map,
-        external_exports,
         glob_map,
     } = time(time_passes,
              "resolution",
@@ -829,9 +828,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>(sess: &'tcx Session,
 
         analysis.access_levels =
             time(time_passes, "privacy checking", || {
-                rustc_privacy::check_crate(tcx,
-                                           &analysis.export_map,
-                                           external_exports)
+                rustc_privacy::check_crate(tcx, &analysis.export_map)
             });
 
         // Do not move this check past lint
diff --git a/src/librustc_metadata/csearch.rs b/src/librustc_metadata/csearch.rs
index 63db3d3c870..b3f24b8f16b 100644
--- a/src/librustc_metadata/csearch.rs
+++ b/src/librustc_metadata/csearch.rs
@@ -49,6 +49,11 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
         decoder::get_deprecation(&cdata, def.index)
     }
 
+    fn visibility(&self, def: DefId) -> hir::Visibility {
+        let cdata = self.get_crate_data(def.krate);
+        decoder::get_visibility(&cdata, def.index)
+    }
+
     fn closure_kind(&self, _tcx: &TyCtxt<'tcx>, def_id: DefId) -> ty::ClosureKind
     {
         assert!(!def_id.is_local());
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index e286e028f33..96e4f8a72f1 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -545,6 +545,10 @@ pub fn get_deprecation(cdata: Cmd, id: DefIndex) -> Option<attr::Deprecation> {
     })
 }
 
+pub fn get_visibility(cdata: Cmd, id: DefIndex) -> hir::Visibility {
+    item_visibility(cdata.lookup_item(id))
+}
+
 pub fn get_repr_attrs(cdata: Cmd, id: DefIndex) -> Vec<attr::ReprAttr> {
     let item = cdata.lookup_item(id);
     match reader::maybe_get_doc(item, tag_items_data_item_repr).map(|doc| {
diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs
index 214ac81ee50..82f4ad1d746 100644
--- a/src/librustc_privacy/lib.rs
+++ b/src/librustc_privacy/lib.rs
@@ -38,10 +38,10 @@ use rustc_front::intravisit::{self, Visitor};
 
 use rustc::dep_graph::DepNode;
 use rustc::lint;
+use rustc::middle::cstore::CrateStore;
 use rustc::middle::def::{self, Def};
 use rustc::middle::def_id::DefId;
 use rustc::middle::privacy::{AccessLevel, AccessLevels};
-use rustc::middle::privacy::ExternalExports;
 use rustc::middle::ty::{self, TyCtxt};
 use rustc::util::nodemap::{NodeMap, NodeSet};
 use rustc::front::map as ast_map;
@@ -476,7 +476,6 @@ struct PrivacyVisitor<'a, 'tcx: 'a> {
     curitem: ast::NodeId,
     in_foreign: bool,
     parents: NodeMap<ast::NodeId>,
-    external_exports: ExternalExports,
 }
 
 #[derive(Debug)]
@@ -498,7 +497,7 @@ impl<'a, 'tcx> PrivacyVisitor<'a, 'tcx> {
         let node_id = if let Some(node_id) = self.tcx.map.as_local_node_id(did) {
             node_id
         } else {
-            if self.external_exports.contains(&did) {
+            if self.tcx.sess.cstore.visibility(did) == hir::Public {
                 debug!("privacy - {:?} was externally exported", did);
                 return Allowable;
             }
@@ -1567,10 +1566,7 @@ impl<'a, 'tcx, 'v> Visitor<'v> for PrivateItemsInPublicInterfacesVisitor<'a, 'tc
     }
 }
 
-pub fn check_crate(tcx: &TyCtxt,
-                   export_map: &def::ExportMap,
-                   external_exports: ExternalExports)
-                   -> AccessLevels {
+pub fn check_crate(tcx: &TyCtxt, export_map: &def::ExportMap) -> AccessLevels {
     let _task = tcx.dep_graph.in_task(DepNode::Privacy);
 
     let krate = tcx.map.krate();
@@ -1593,7 +1589,6 @@ pub fn check_crate(tcx: &TyCtxt,
         in_foreign: false,
         tcx: tcx,
         parents: visitor.parents,
-        external_exports: external_exports,
     };
     intravisit::walk_crate(&mut visitor, krate);
 
diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs
index b3d7be4775e..884196a97af 100644
--- a/src/librustc_resolve/build_reduced_graph.rs
+++ b/src/librustc_resolve/build_reduced_graph.rs
@@ -289,7 +289,6 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                         krate: crate_id,
                         index: CRATE_DEF_INDEX,
                     };
-                    self.external_exports.insert(def_id);
                     let parent_link = ModuleParentLink(parent, name);
                     let def = Def::Mod(def_id);
                     let module = self.new_extern_crate_module(parent_link, def, is_public, item.id);
@@ -495,15 +494,6 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
             modifiers = modifiers | DefModifiers::IMPORTABLE;
         }
 
-        let is_exported = is_public &&
-                          match new_parent.def_id() {
-            None => true,
-            Some(did) => self.external_exports.contains(&did),
-        };
-        if is_exported {
-            self.external_exports.insert(def.def_id());
-        }
-
         match def {
             Def::Mod(_) | Def::ForeignMod(_) | Def::Enum(..) | Def::TyAlias(..) => {
                 debug!("(building reduced graph for external crate) building module {} {}",
@@ -552,10 +542,6 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
                            trait_item_name);
 
                     self.trait_item_map.insert((trait_item_name, def_id), trait_item_def.def_id());
-
-                    if is_exported {
-                        self.external_exports.insert(trait_item_def.def_id());
-                    }
                 }
 
                 let parent_link = ModuleParentLink(new_parent, name);
diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs
index a205bfb98ac..970f54207ba 100644
--- a/src/librustc_resolve/lib.rs
+++ b/src/librustc_resolve/lib.rs
@@ -55,10 +55,9 @@ use rustc::middle::cstore::{CrateStore, DefLike, DlDef};
 use rustc::middle::def::*;
 use rustc::middle::def_id::DefId;
 use rustc::middle::pat_util::pat_bindings;
-use rustc::middle::privacy::ExternalExports;
 use rustc::middle::subst::{ParamSpace, FnSpace, TypeSpace};
 use rustc::middle::ty::{Freevar, FreevarMap, TraitMap, GlobMap};
-use rustc::util::nodemap::{NodeMap, DefIdSet, FnvHashMap};
+use rustc::util::nodemap::{NodeMap, FnvHashMap};
 
 use syntax::ast::{self, FloatTy};
 use syntax::ast::{CRATE_NODE_ID, Name, NodeId, CrateNum, IntTy, UintTy};
@@ -1093,7 +1092,6 @@ pub struct Resolver<'a, 'tcx: 'a> {
     freevars_seen: NodeMap<NodeMap<usize>>,
     export_map: ExportMap,
     trait_map: TraitMap,
-    external_exports: ExternalExports,
 
     // Whether or not to print error messages. Can be set to true
     // when getting additional info for error message suggestions,
@@ -1184,7 +1182,6 @@ impl<'a, 'tcx> Resolver<'a, 'tcx> {
             trait_map: NodeMap(),
             used_imports: HashSet::new(),
             used_crates: HashSet::new(),
-            external_exports: DefIdSet(),
 
             emit_errors: true,
             make_glob_map: make_glob_map == MakeGlobMap::Yes,
@@ -3716,7 +3713,6 @@ pub struct CrateMap {
     pub freevars: FreevarMap,
     pub export_map: ExportMap,
     pub trait_map: TraitMap,
-    pub external_exports: ExternalExports,
     pub glob_map: Option<GlobMap>,
 }
 
@@ -3754,7 +3750,6 @@ pub fn resolve_crate<'a, 'tcx>(session: &'a Session,
         freevars: resolver.freevars,
         export_map: resolver.export_map,
         trait_map: resolver.trait_map,
-        external_exports: resolver.external_exports,
         glob_map: if resolver.make_glob_map {
             Some(resolver.glob_map)
         } else {
diff --git a/src/test/compile-fail/trait-privacy.rs b/src/test/compile-fail/trait-privacy.rs
index a0d0014a064..5f9e8ba6c0a 100644
--- a/src/test/compile-fail/trait-privacy.rs
+++ b/src/test/compile-fail/trait-privacy.rs
@@ -8,7 +8,7 @@
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
-#![feature(rustc_attrs)]
+#![feature(rustc_attrs, get_type_id)]
 #![allow(dead_code)]
 
 mod foo {
@@ -26,5 +26,10 @@ fn g() {
     ().f(); // Check that this does not trigger a privacy error
 }
 
+fn f() {
+    let error = ::std::thread::spawn(|| {}).join().unwrap_err();
+    error.get_type_id(); // Regression test for #21670
+}
+
 #[rustc_error]
 fn main() {} //~ ERROR compilation successful