about summary refs log tree commit diff
diff options
context:
space:
mode:
authormitaa <mitaa.ceb@gmail.com>2016-04-07 05:59:02 +0200
committermitaa <mitaa.ceb@gmail.com>2016-04-13 19:39:17 +0200
commitea83349c9f06e13aae4a70e81d5dc470bf051bca (patch)
tree7e4fc83dfa97fcb316d9efdd8a498e21b9d8a2ba
parent6136a86291b12f5441910d56d5bc0dfbc7eecdeb (diff)
downloadrust-ea83349c9f06e13aae4a70e81d5dc470bf051bca.tar.gz
rust-ea83349c9f06e13aae4a70e81d5dc470bf051bca.zip
Retire rustdocs `ANALYSISKEY`
The thread-local isn't needed and consists of mostly empty fields which
were just used to move the data into `html::render::CACHE_KEY`.
-rw-r--r--src/librustc/middle/privacy.rs9
-rw-r--r--src/librustdoc/clean/inline.rs6
-rw-r--r--src/librustdoc/clean/mod.rs21
-rw-r--r--src/librustdoc/core.rs70
-rw-r--r--src/librustdoc/html/render.rs50
-rw-r--r--src/librustdoc/lib.rs21
-rw-r--r--src/librustdoc/passes.rs5
-rw-r--r--src/librustdoc/test.rs9
-rw-r--r--src/librustdoc/visit_ast.rs10
9 files changed, 90 insertions, 111 deletions
diff --git a/src/librustc/middle/privacy.rs b/src/librustc/middle/privacy.rs
index c1dc727449a..478f662d096 100644
--- a/src/librustc/middle/privacy.rs
+++ b/src/librustc/middle/privacy.rs
@@ -15,10 +15,11 @@
 use util::nodemap::{DefIdSet, FnvHashMap};
 
 use std::hash::Hash;
+use std::fmt;
 use syntax::ast::NodeId;
 
 // Accessibility levels, sorted in ascending order
-#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
+#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
 pub enum AccessLevel {
     // Exported items + items participating in various kinds of public interfaces,
     // but not directly nameable. For example, if function `fn f() -> T {...}` is
@@ -56,6 +57,12 @@ impl<Id: Hash + Eq> Default for AccessLevels<Id> {
     }
 }
 
+impl<Id: Hash + Eq + fmt::Debug> fmt::Debug for AccessLevels<Id> {
+    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+        fmt::Debug::fmt(&self.map, f)
+    }
+}
+
 /// A set containing all exported definitions from external crates.
 /// The set does not contain any entries from local crates.
 pub type ExternalExports = DefIdSet;
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index 85097549826..6cca602466a 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -116,7 +116,7 @@ fn try_inline_def(cx: &DocContext, tcx: &TyCtxt,
         }
         _ => return None,
     };
-    cx.inlined.borrow_mut().as_mut().unwrap().insert(did);
+    cx.renderinfo.borrow_mut().inlined.insert(did);
     ret.push(clean::Item {
         source: clean::Span::empty(),
         name: Some(tcx.item_name(did).to_string()),
@@ -146,7 +146,7 @@ pub fn record_extern_fqn(cx: &DocContext, did: DefId, kind: clean::TypeKind) {
             elem.data.to_string()
         });
         let fqn = once(crate_name).chain(relative).collect();
-        cx.external_paths.borrow_mut().as_mut().unwrap().insert(did, (fqn, kind));
+        cx.renderinfo.borrow_mut().external_paths.insert(did, (fqn, kind));
     }
 }
 
@@ -295,7 +295,7 @@ pub fn build_impl(cx: &DocContext,
                   tcx: &TyCtxt,
                   did: DefId,
                   ret: &mut Vec<clean::Item>) {
-    if !cx.inlined.borrow_mut().as_mut().unwrap().insert(did) {
+    if !cx.renderinfo.borrow_mut().inlined.insert(did) {
         return
     }
 
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index d8d1472560d..bba394bb90d 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -35,6 +35,7 @@ use syntax::ptr::P;
 
 use rustc_trans::back::link;
 use rustc::middle::cstore::{self, CrateStore};
+use rustc::middle::privacy::AccessLevels;
 use rustc::hir::def::Def;
 use rustc::hir::def_id::{DefId, DefIndex};
 use rustc::ty::subst::{self, ParamSpace, VecPerParamSpace};
@@ -46,8 +47,10 @@ use rustc::hir;
 use std::collections::{HashMap, HashSet};
 use std::path::PathBuf;
 use std::rc::Rc;
+use std::sync::Arc;
 use std::u32;
 use std::env::current_dir;
+use std::mem;
 
 use core::DocContext;
 use doctree;
@@ -112,13 +115,16 @@ impl<T: Clean<U>, U> Clean<Vec<U>> for P<[T]> {
     }
 }
 
-#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
+#[derive(Clone, Debug)]
 pub struct Crate {
     pub name: String,
     pub src: PathBuf,
     pub module: Option<Item>,
     pub externs: Vec<(ast::CrateNum, ExternalCrate)>,
     pub primitives: Vec<PrimitiveType>,
+    pub access_levels: Arc<AccessLevels<DefId>>,
+    // These are later on moved into `CACHEKEY`, leaving the map empty.
+    // Only here so that they can be filtered through the rustdoc passes.
     pub external_traits: HashMap<DefId, Trait>,
 }
 
@@ -130,6 +136,7 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
 
         if let Some(t) = cx.tcx_opt() {
             cx.deref_trait_did.set(t.lang_items.deref_trait());
+            cx.renderinfo.borrow_mut().deref_trait_did = cx.deref_trait_did.get();
         }
 
         let mut externs = Vec::new();
@@ -204,14 +211,17 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
             Input::Str { ref name, .. } => PathBuf::from(name.clone()),
         };
 
+        let mut access_levels = cx.access_levels.borrow_mut();
+        let mut external_traits = cx.external_traits.borrow_mut();
+
         Crate {
             name: name.to_string(),
             src: src,
             module: Some(module),
             externs: externs,
             primitives: primitives,
-            external_traits: cx.external_traits.borrow_mut().take()
-                               .unwrap_or(HashMap::new()),
+            access_levels: Arc::new(mem::replace(&mut access_levels, Default::default())),
+            external_traits: mem::replace(&mut external_traits, Default::default()),
         }
     }
 }
@@ -540,8 +550,7 @@ impl Clean<TyParam> for hir::TyParam {
 
 impl<'tcx> Clean<TyParam> for ty::TypeParameterDef<'tcx> {
     fn clean(&self, cx: &DocContext) -> TyParam {
-        cx.external_typarams.borrow_mut().as_mut().unwrap()
-          .insert(self.def_id, self.name.clean(cx));
+        cx.renderinfo.borrow_mut().external_typarams.insert(self.def_id, self.name.clean(cx));
         TyParam {
             name: self.name.clean(cx),
             did: self.def_id,
@@ -2668,7 +2677,7 @@ fn register_def(cx: &DocContext, def: Def) -> DefId {
     inline::record_extern_fqn(cx, did, kind);
     if let TypeTrait = kind {
         let t = inline::build_external_trait(cx, tcx, did);
-        cx.external_traits.borrow_mut().as_mut().unwrap().insert(did, t);
+        cx.external_traits.borrow_mut().insert(did, t);
     }
     did
 }
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 6b7aa103e1d..c9773ebccb4 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -29,12 +29,13 @@ use syntax::feature_gate::UnstableFeatures;
 use syntax::parse::token;
 
 use std::cell::{RefCell, Cell};
-use std::collections::{HashMap, HashSet};
+use std::collections::HashMap;
 use std::rc::Rc;
 
 use visit_ast::RustdocVisitor;
 use clean;
 use clean::Clean;
+use html::render::RenderInfo;
 
 pub use rustc::session::config::Input;
 pub use rustc::session::search_paths::SearchPaths;
@@ -45,19 +46,20 @@ pub enum MaybeTyped<'a, 'tcx: 'a> {
     NotTyped(&'a session::Session)
 }
 
-pub type ExternalPaths = RefCell<Option<HashMap<DefId,
-                                                (Vec<String>, clean::TypeKind)>>>;
+pub type ExternalPaths = HashMap<DefId, (Vec<String>, clean::TypeKind)>;
 
 pub struct DocContext<'a, 'tcx: 'a> {
     pub map: &'a hir_map::Map<'tcx>,
     pub maybe_typed: MaybeTyped<'a, 'tcx>,
     pub input: Input,
-    pub external_paths: ExternalPaths,
-    pub external_traits: RefCell<Option<HashMap<DefId, clean::Trait>>>,
-    pub external_typarams: RefCell<Option<HashMap<DefId, String>>>,
-    pub inlined: RefCell<Option<HashSet<DefId>>>,
     pub all_crate_impls: RefCell<HashMap<ast::CrateNum, Vec<clean::Item>>>,
+    // Later on moved into `clean::Crate`
+    pub access_levels: RefCell<AccessLevels<DefId>>,
+    // Later on moved into `html::render::CACHE_KEY`
+    pub renderinfo: RefCell<RenderInfo>,
     pub deref_trait_did: Cell<Option<DefId>>,
+    // Later on moved through `clean::Crate` into `html::render::CACHE_KEY`
+    pub external_traits: RefCell<HashMap<DefId, clean::Trait>>,
 }
 
 impl<'b, 'tcx> DocContext<'b, 'tcx> {
@@ -81,20 +83,14 @@ impl<'b, 'tcx> DocContext<'b, 'tcx> {
     }
 }
 
-pub struct CrateAnalysis {
-    pub access_levels: AccessLevels<DefId>,
-    pub external_paths: ExternalPaths,
-    pub external_typarams: RefCell<Option<HashMap<DefId, String>>>,
-    pub inlined: RefCell<Option<HashSet<DefId>>>,
-    pub deref_trait_did: Option<DefId>,
-}
-
 pub type Externs = HashMap<String, Vec<String>>;
 
-pub fn run_core(search_paths: SearchPaths, cfgs: Vec<String>, externs: Externs,
-                input: Input, triple: Option<String>)
-                -> (clean::Crate, CrateAnalysis) {
-
+pub fn run_core(search_paths: SearchPaths,
+                cfgs: Vec<String>,
+                externs: Externs,
+                input: Input,
+                triple: Option<String>) -> (clean::Crate, RenderInfo)
+{
     // Parse, resolve, and typecheck the given crate.
 
     let cpath = match input {
@@ -148,7 +144,7 @@ pub fn run_core(search_paths: SearchPaths, cfgs: Vec<String>, externs: Externs,
     let arenas = ty::CtxtArenas::new();
     let hir_map = driver::make_map(&sess, &mut hir_forest);
 
-    let krate_and_analysis = abort_on_err(driver::phase_3_run_analysis_passes(&sess,
+    abort_on_err(driver::phase_3_run_analysis_passes(&sess,
                                                      &cstore,
                                                      hir_map,
                                                      &arenas,
@@ -175,42 +171,20 @@ pub fn run_core(search_paths: SearchPaths, cfgs: Vec<String>, externs: Externs,
             map: &tcx.map,
             maybe_typed: Typed(tcx),
             input: input,
-            external_traits: RefCell::new(Some(HashMap::new())),
-            external_typarams: RefCell::new(Some(HashMap::new())),
-            external_paths: RefCell::new(Some(HashMap::new())),
-            inlined: RefCell::new(Some(HashSet::new())),
             all_crate_impls: RefCell::new(HashMap::new()),
             deref_trait_did: Cell::new(None),
+            access_levels: RefCell::new(access_levels),
+            external_traits: RefCell::new(HashMap::new()),
+            renderinfo: RefCell::new(Default::default()),
         };
         debug!("crate: {:?}", ctxt.map.krate());
 
-        let mut analysis = CrateAnalysis {
-            access_levels: access_levels,
-            external_paths: RefCell::new(None),
-            external_typarams: RefCell::new(None),
-            inlined: RefCell::new(None),
-            deref_trait_did: None,
-        };
-
         let krate = {
-            let mut v = RustdocVisitor::new(&ctxt, Some(&analysis));
+            let mut v = RustdocVisitor::new(&ctxt);
             v.visit(ctxt.map.krate());
             v.clean(&ctxt)
         };
 
-        let external_paths = ctxt.external_paths.borrow_mut().take();
-        *analysis.external_paths.borrow_mut() = external_paths;
-
-        let map = ctxt.external_typarams.borrow_mut().take();
-        *analysis.external_typarams.borrow_mut() = map;
-
-        let map = ctxt.inlined.borrow_mut().take();
-        *analysis.inlined.borrow_mut() = map;
-
-        analysis.deref_trait_did = ctxt.deref_trait_did.get();
-
-        Some((krate, analysis))
-    }), &sess);
-
-    krate_and_analysis.unwrap()
+        Some((krate, ctxt.renderinfo.into_inner()))
+    }), &sess).unwrap()
 }
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index c5850089578..2d59747d00c 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -253,7 +253,7 @@ pub struct Cache {
     parent_is_trait_impl: bool,
     search_index: Vec<IndexItem>,
     stripped_mod: bool,
-    access_levels: AccessLevels<DefId>,
+    access_levels: Arc<AccessLevels<DefId>>,
     deref_trait_did: Option<DefId>,
 
     // In rare case where a structure is defined in one module but implemented
@@ -264,6 +264,16 @@ pub struct Cache {
     orphan_methods: Vec<(DefId, clean::Item)>,
 }
 
+/// Temporary storage for data obtained during `RustdocVisitor::clean()`.
+/// Later on moved into `CACHE_KEY`.
+#[derive(Default)]
+pub struct RenderInfo {
+    pub inlined: HashSet<DefId>,
+    pub external_paths: ::core::ExternalPaths,
+    pub external_typarams: HashMap<DefId, String>,
+    pub deref_trait_did: Option<DefId>,
+}
+
 /// Helper struct to render all source code to HTML pages
 struct SourceCollector<'a> {
     scx: &'a mut SharedContext,
@@ -415,7 +425,8 @@ pub fn run(mut krate: clean::Crate,
            external_html: &ExternalHtml,
            dst: PathBuf,
            passes: HashSet<String>,
-           css_file_extension: Option<PathBuf>) -> Result<(), Error> {
+           css_file_extension: Option<PathBuf>,
+           renderinfo: RenderInfo) -> Result<(), Error> {
     let src_root = match krate.src.parent() {
         Some(p) => p.to_path_buf(),
         None => PathBuf::new(),
@@ -482,19 +493,20 @@ pub fn run(mut krate: clean::Crate,
     };
 
     // Crawl the crate to build various caches used for the output
-    let analysis = ::ANALYSISKEY.with(|a| a.clone());
-    let analysis = analysis.borrow();
-    let access_levels = analysis.as_ref().map(|a| a.access_levels.clone());
-    let access_levels = access_levels.unwrap_or(Default::default());
-    let paths: HashMap<DefId, (Vec<String>, ItemType)> =
-      analysis.as_ref().map(|a| {
-        let paths = a.external_paths.borrow_mut().take().unwrap();
-        paths.into_iter().map(|(k, (v, t))| (k, (v, ItemType::from_type_kind(t)))).collect()
-      }).unwrap_or(HashMap::new());
+    let RenderInfo {
+        inlined,
+        external_paths,
+        external_typarams,
+        deref_trait_did,
+    } = renderinfo;
+
+    let paths = external_paths.into_iter()
+                              .map(|(k, (v, t))| (k, (v, ItemType::from_type_kind(t))))
+                              .collect::<HashMap<_, _>>();
+
     let mut cache = Cache {
         impls: HashMap::new(),
-        external_paths: paths.iter().map(|(&k, v)| (k, v.0.clone()))
-                             .collect(),
+        external_paths: paths.iter().map(|(&k, v)| (k, v.0.clone())).collect(),
         paths: paths,
         implementors: HashMap::new(),
         stack: Vec::new(),
@@ -504,16 +516,12 @@ pub fn run(mut krate: clean::Crate,
         extern_locations: HashMap::new(),
         primitive_locations: HashMap::new(),
         stripped_mod: false,
-        access_levels: access_levels,
+        access_levels: krate.access_levels.clone(),
         orphan_methods: Vec::new(),
         traits: mem::replace(&mut krate.external_traits, HashMap::new()),
-        deref_trait_did: analysis.as_ref().and_then(|a| a.deref_trait_did),
-        typarams: analysis.as_ref().map(|a| {
-            a.external_typarams.borrow_mut().take().unwrap()
-        }).unwrap_or(HashMap::new()),
-        inlined: analysis.as_ref().map(|a| {
-            a.inlined.borrow_mut().take().unwrap()
-        }).unwrap_or(HashSet::new()),
+        deref_trait_did: deref_trait_did,
+        typarams: external_typarams,
+        inlined: inlined,
     };
 
     // Cache where all our extern crates are located
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index bc7c7c5e0ca..0d80e702816 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -48,14 +48,11 @@ extern crate rustc_unicode;
 
 extern crate serialize as rustc_serialize; // used by deriving
 
-use std::cell::RefCell;
 use std::collections::HashMap;
 use std::default::Default;
 use std::env;
-use std::io::Read;
 use std::path::PathBuf;
 use std::process;
-use std::rc::Rc;
 use std::sync::mpsc::channel;
 
 use externalfiles::ExternalHtml;
@@ -113,12 +110,9 @@ const DEFAULT_PASSES: &'static [&'static str] = &[
     "unindent-comments",
 ];
 
-thread_local!(pub static ANALYSISKEY: Rc<RefCell<Option<core::CrateAnalysis>>> = {
-    Rc::new(RefCell::new(None))
-});
-
 struct Output {
     krate: clean::Crate,
+    renderinfo: html::render::RenderInfo,
     passes: Vec<String>,
 }
 
@@ -302,14 +296,15 @@ pub fn main_args(args: &[String]) -> isize {
             return 1;
         }
     };
-    let Output { krate, passes, } = out;
+    let Output { krate, passes, renderinfo } = out;
     info!("going to format");
     match matches.opt_str("w").as_ref().map(|s| &**s) {
         Some("html") | None => {
             html::render::run(krate, &external_html,
                               output.unwrap_or(PathBuf::from("doc")),
                               passes.into_iter().collect(),
-                              css_file_extension)
+                              css_file_extension,
+                              renderinfo)
                 .expect("failed to generate documentation")
         }
         Some(s) => {
@@ -380,12 +375,8 @@ fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matche
         tx.send(core::run_core(paths, cfgs, externs, Input::File(cr),
                                triple)).unwrap();
     });
-    let (mut krate, analysis) = rx.recv().unwrap();
+    let (mut krate, renderinfo) = rx.recv().unwrap();
     info!("finished with rustc");
-    let mut analysis = Some(analysis);
-    ANALYSISKEY.with(|s| {
-        *s.borrow_mut() = analysis.take();
-    });
 
     if let Some(name) = matches.opt_str("crate-name") {
         krate.name = name
@@ -443,5 +434,5 @@ fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matche
     // Run everything!
     info!("Executing passes/plugins");
     let krate = pm.run_plugins(krate);
-    Output { krate: krate, passes: passes }
+    Output { krate: krate, renderinfo: renderinfo, passes: passes }
 }
diff --git a/src/librustdoc/passes.rs b/src/librustdoc/passes.rs
index adc39b69986..b9a2acb02e8 100644
--- a/src/librustdoc/passes.rs
+++ b/src/librustdoc/passes.rs
@@ -88,10 +88,7 @@ pub fn strip_hidden(krate: clean::Crate) -> plugins::PluginResult {
 pub fn strip_private(mut krate: clean::Crate) -> plugins::PluginResult {
     // This stripper collects all *retained* nodes.
     let mut retained = DefIdSet();
-    let analysis = super::ANALYSISKEY.with(|a| a.clone());
-    let analysis = analysis.borrow();
-    let analysis = analysis.as_ref().unwrap();
-    let access_levels = analysis.access_levels.clone();
+    let access_levels = krate.access_levels.clone();
 
     // strip all private items
     {
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 982f477fc4a..5a7050fb42f 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -108,15 +108,14 @@ pub fn run(input: &str,
         map: &map,
         maybe_typed: core::NotTyped(&sess),
         input: input,
-        external_paths: RefCell::new(Some(HashMap::new())),
-        external_traits: RefCell::new(None),
-        external_typarams: RefCell::new(None),
-        inlined: RefCell::new(None),
+        external_traits: RefCell::new(HashMap::new()),
         all_crate_impls: RefCell::new(HashMap::new()),
         deref_trait_did: Cell::new(None),
+        access_levels: Default::default(),
+        renderinfo: Default::default(),
     };
 
-    let mut v = RustdocVisitor::new(&ctx, None);
+    let mut v = RustdocVisitor::new(&ctx);
     v.visit(ctx.map.krate());
     let mut krate = v.clean(&ctx);
     if let Some(name) = crate_name {
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 5c36c38abc5..a406c843b82 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -41,14 +41,12 @@ pub struct RustdocVisitor<'a, 'tcx: 'a> {
     pub module: Module,
     pub attrs: hir::HirVec<ast::Attribute>,
     pub cx: &'a core::DocContext<'a, 'tcx>,
-    pub analysis: Option<&'a core::CrateAnalysis>,
     view_item_stack: HashSet<ast::NodeId>,
     inlining_from_glob: bool,
 }
 
 impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
-    pub fn new(cx: &'a core::DocContext<'a, 'tcx>,
-               analysis: Option<&'a core::CrateAnalysis>) -> RustdocVisitor<'a, 'tcx> {
+    pub fn new(cx: &'a core::DocContext<'a, 'tcx>) -> RustdocVisitor<'a, 'tcx> {
         // If the root is reexported, terminate all recursion.
         let mut stack = HashSet::new();
         stack.insert(ast::CRATE_NODE_ID);
@@ -56,7 +54,6 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
             module: Module::new(None),
             attrs: hir::HirVec::new(),
             cx: cx,
-            analysis: analysis,
             view_item_stack: stack,
             inlining_from_glob: false,
         }
@@ -247,13 +244,10 @@ impl<'a, 'tcx> RustdocVisitor<'a, 'tcx> {
         let def_node_id = match tcx.map.as_local_node_id(def) {
             Some(n) => n, None => return false
         };
-        let analysis = match self.analysis {
-            Some(analysis) => analysis, None => return false
-        };
 
         let use_attrs = tcx.map.attrs(id).clean(self.cx);
 
-        let is_private = !analysis.access_levels.is_public(def);
+        let is_private = !self.cx.access_levels.borrow().is_public(def);
         let is_hidden = inherits_doc_hidden(self.cx, def_node_id);
         let is_no_inline = use_attrs.list("doc").has_word("no_inline");