about summary refs log tree commit diff
path: root/src/librustdoc
diff options
context:
space:
mode:
authorAlex Crichton <alex@alexcrichton.com>2014-04-28 20:36:08 -0700
committerAlex Crichton <alex@alexcrichton.com>2014-05-07 23:43:39 -0700
commitab92ea526d455b402efbccc7160c8aec0237c88f (patch)
tree92e748f3e3496a48ac68dd290a0a08aa342740a1 /src/librustdoc
parentef6daf9935da103f1b915a5c9904794da79b0b60 (diff)
downloadrust-ab92ea526d455b402efbccc7160c8aec0237c88f.tar.gz
rust-ab92ea526d455b402efbccc7160c8aec0237c88f.zip
std: Modernize the local_data api
This commit brings the local_data api up to modern rust standards with a few key
improvements:

* The `pop` and `set` methods have been combined into one method, `replace`

* The `get_mut` method has been removed. All interior mutability should be done
  through `RefCell`.

* All functionality is now exposed as a method on the keys themselves. Instead
  of importing std::local_data, you now use "key.replace()" and "key.get()".

* All closures have been removed in favor of RAII functionality. This means that
  get() and get_mut() no long require closures, but rather return
  Option<SmartPointer> where the smart pointer takes care of relinquishing the
  borrow and also implements the necessary Deref traits

* The modify() function was removed to cut the local_data interface down to its
  bare essentials (similarly to how RefCell removed set/get).

[breaking-change]
Diffstat (limited to 'src/librustdoc')
-rw-r--r--src/librustdoc/clean.rs15
-rw-r--r--src/librustdoc/core.rs3
-rw-r--r--src/librustdoc/html/format.rs129
-rw-r--r--src/librustdoc/html/markdown.rs23
-rw-r--r--src/librustdoc/html/render.rs154
-rw-r--r--src/librustdoc/lib.rs3
-rw-r--r--src/librustdoc/passes.rs9
-rw-r--r--src/librustdoc/test.rs3
8 files changed, 155 insertions, 184 deletions
diff --git a/src/librustdoc/clean.rs b/src/librustdoc/clean.rs
index 79fc0fbeada..be0fd85525d 100644
--- a/src/librustdoc/clean.rs
+++ b/src/librustdoc/clean.rs
@@ -26,7 +26,6 @@ use rustc::metadata::cstore;
 use rustc::metadata::csearch;
 use rustc::metadata::decoder;
 
-use std::local_data;
 use std::strbuf::StrBuf;
 
 use core;
@@ -77,7 +76,7 @@ pub struct Crate {
 
 impl<'a> Clean<Crate> for visit_ast::RustdocVisitor<'a> {
     fn clean(&self) -> Crate {
-        let cx = local_data::get(super::ctxtkey, |x| *x.unwrap());
+        let cx = super::ctxtkey.get().unwrap();
 
         let mut externs = Vec::new();
         cx.sess().cstore.iter_crate_data(|n, meta| {
@@ -251,7 +250,7 @@ impl Clean<Item> for doctree::Module {
         // determine if we should display the inner contents or
         // the outer `mod` item for the source code.
         let where = {
-            let ctxt = local_data::get(super::ctxtkey, |x| *x.unwrap());
+            let ctxt = super::ctxtkey.get().unwrap();
             let cm = ctxt.sess().codemap();
             let outer = cm.lookup_char_pos(self.where_outer.lo);
             let inner = cm.lookup_char_pos(self.where_inner.lo);
@@ -726,7 +725,7 @@ impl Clean<Type> for ast::Ty {
     fn clean(&self) -> Type {
         use syntax::ast::*;
         debug!("cleaning type `{:?}`", self);
-        let ctxt = local_data::get(super::ctxtkey, |x| *x.unwrap());
+        let ctxt = super::ctxtkey.get().unwrap();
         let codemap = ctxt.sess().codemap();
         debug!("span corresponds to `{}`", codemap.span_to_str(self.span));
         match self.node {
@@ -909,7 +908,7 @@ pub struct Span {
 
 impl Clean<Span> for syntax::codemap::Span {
     fn clean(&self) -> Span {
-        let ctxt = local_data::get(super::ctxtkey, |x| *x.unwrap());
+        let ctxt = super::ctxtkey.get().unwrap();
         let cm = ctxt.sess().codemap();
         let filename = cm.span_to_filename(*self);
         let lo = cm.lookup_char_pos(self.lo);
@@ -1237,7 +1236,7 @@ trait ToSource {
 impl ToSource for syntax::codemap::Span {
     fn to_src(&self) -> ~str {
         debug!("converting span {:?} to snippet", self.clean());
-        let ctxt = local_data::get(super::ctxtkey, |x| x.unwrap().clone());
+        let ctxt = super::ctxtkey.get().unwrap();
         let cm = ctxt.sess().codemap().clone();
         let sn = match cm.span_to_snippet(*self) {
             Some(x) => x,
@@ -1292,7 +1291,7 @@ fn name_from_pat(p: &ast::Pat) -> ~str {
 /// Given a Type, resolve it using the def_map
 fn resolve_type(path: Path, tpbs: Option<Vec<TyParamBound> >,
                 id: ast::NodeId) -> Type {
-    let cx = local_data::get(super::ctxtkey, |x| *x.unwrap());
+    let cx = super::ctxtkey.get().unwrap();
     let tycx = match cx.maybe_typed {
         core::Typed(ref tycx) => tycx,
         // If we're extracting tests, this return value doesn't matter.
@@ -1351,7 +1350,7 @@ fn resolve_use_source(path: Path, id: ast::NodeId) -> ImportSource {
 }
 
 fn resolve_def(id: ast::NodeId) -> Option<ast::DefId> {
-    let cx = local_data::get(super::ctxtkey, |x| *x.unwrap());
+    let cx = super::ctxtkey.get().unwrap();
     match cx.maybe_typed {
         core::Typed(ref tcx) => {
             tcx.def_map.borrow().find(&id).map(|&d| ast_util::def_id_of_def(d))
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 9f89da563cc..1916e053e98 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -20,7 +20,6 @@ use syntax;
 
 use std::cell::RefCell;
 use std::os;
-use std::local_data;
 use collections::HashSet;
 
 use visit_ast::RustdocVisitor;
@@ -109,7 +108,7 @@ pub fn run_core(libs: HashSet<Path>, cfgs: Vec<~str>, path: &Path)
                 -> (clean::Crate, CrateAnalysis) {
     let (ctxt, analysis) = get_ast_and_resolve(path, libs, cfgs);
     let ctxt = @ctxt;
-    local_data::set(super::ctxtkey, ctxt);
+    super::ctxtkey.replace(Some(ctxt));
 
     let krate = {
         let mut v = RustdocVisitor::new(ctxt, Some(&analysis));
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index 1e2f89659cd..223f9341b73 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -17,7 +17,6 @@
 
 use std::fmt;
 use std::io;
-use std::local_data;
 use std::strbuf::StrBuf;
 
 use syntax::ast;
@@ -206,78 +205,72 @@ fn path(w: &mut io::Writer, path: &clean::Path, print_all: bool,
         generics.push_str("&gt;");
     }
 
-    // Did someone say rightward-drift?
-    local_data::get(current_location_key, |loc| {
-        let loc = loc.unwrap();
-
-        local_data::get(cache_key, |cache| {
-            let cache = cache.unwrap();
-            let abs_root = root(&**cache, loc.as_slice());
-            let rel_root = match path.segments.get(0).name.as_slice() {
-                "self" => Some("./".to_owned()),
-                _ => None,
-            };
-
-            if print_all {
-                let amt = path.segments.len() - 1;
-                match rel_root {
-                    Some(root) => {
-                        let mut root = StrBuf::from_str(root);
-                        for seg in path.segments.slice_to(amt).iter() {
-                            if "super" == seg.name || "self" == seg.name {
-                                try!(write!(w, "{}::", seg.name));
-                            } else {
-                                root.push_str(seg.name);
-                                root.push_str("/");
-                                try!(write!(w, "<a class='mod'
-                                                    href='{}index.html'>{}</a>::",
-                                              root.as_slice(),
-                                              seg.name));
-                            }
-                        }
-                    }
-                    None => {
-                        for seg in path.segments.slice_to(amt).iter() {
-                            try!(write!(w, "{}::", seg.name));
-                        }
+    let loc = current_location_key.get().unwrap();
+    let cache = cache_key.get().unwrap();
+    let abs_root = root(&**cache, loc.as_slice());
+    let rel_root = match path.segments.get(0).name.as_slice() {
+        "self" => Some("./".to_owned()),
+        _ => None,
+    };
+
+    if print_all {
+        let amt = path.segments.len() - 1;
+        match rel_root {
+            Some(root) => {
+                let mut root = StrBuf::from_str(root);
+                for seg in path.segments.slice_to(amt).iter() {
+                    if "super" == seg.name || "self" == seg.name {
+                        try!(write!(w, "{}::", seg.name));
+                    } else {
+                        root.push_str(seg.name);
+                        root.push_str("/");
+                        try!(write!(w, "<a class='mod'
+                                            href='{}index.html'>{}</a>::",
+                                      root.as_slice(),
+                                      seg.name));
                     }
                 }
             }
-
-            match info(&**cache) {
-                // This is a documented path, link to it!
-                Some((ref fqp, shortty)) if abs_root.is_some() => {
-                    let mut url = StrBuf::from_str(abs_root.unwrap());
-                    let to_link = fqp.slice_to(fqp.len() - 1);
-                    for component in to_link.iter() {
-                        url.push_str(*component);
-                        url.push_str("/");
-                    }
-                    match shortty {
-                        item_type::Module => {
-                            url.push_str(*fqp.last().unwrap());
-                            url.push_str("/index.html");
-                        }
-                        _ => {
-                            url.push_str(shortty.to_static_str());
-                            url.push_str(".");
-                            url.push_str(*fqp.last().unwrap());
-                            url.push_str(".html");
-                        }
-                    }
-
-                    try!(write!(w, "<a class='{}' href='{}' title='{}'>{}</a>",
-                                  shortty, url, fqp.connect("::"), last.name));
+            None => {
+                for seg in path.segments.slice_to(amt).iter() {
+                    try!(write!(w, "{}::", seg.name));
                 }
+            }
+        }
+    }
 
+    match info(&**cache) {
+        // This is a documented path, link to it!
+        Some((ref fqp, shortty)) if abs_root.is_some() => {
+            let mut url = StrBuf::from_str(abs_root.unwrap());
+            let to_link = fqp.slice_to(fqp.len() - 1);
+            for component in to_link.iter() {
+                url.push_str(*component);
+                url.push_str("/");
+            }
+            match shortty {
+                item_type::Module => {
+                    url.push_str(*fqp.last().unwrap());
+                    url.push_str("/index.html");
+                }
                 _ => {
-                    try!(write!(w, "{}", last.name));
+                    url.push_str(shortty.to_static_str());
+                    url.push_str(".");
+                    url.push_str(*fqp.last().unwrap());
+                    url.push_str(".html");
                 }
             }
-            try!(write!(w, "{}", generics.as_slice()));
-            Ok(())
-        })
-    })
+
+            try!(write!(w, "<a class='{}' href='{}' title='{}'>{}</a>",
+                          shortty, url, fqp.connect("::"), last.name));
+        }
+
+        _ => {
+            try!(write!(w, "{}", last.name));
+        }
+    }
+    try!(write!(w, "{}", generics.as_slice()));
+    Ok(())
 }
 
 /// Helper to render type parameters
@@ -302,10 +295,8 @@ impl fmt::Show for clean::Type {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match *self {
             clean::TyParamBinder(id) | clean::Generic(id) => {
-                local_data::get(cache_key, |cache| {
-                    let m = cache.unwrap();
-                    f.buf.write(m.typarams.get(&id).as_bytes())
-                })
+                let m = cache_key.get().unwrap();
+                f.buf.write(m.typarams.get(&id).as_bytes())
             }
             clean::ResolvedPath{id, typarams: ref tp, path: ref path} => {
                 try!(resolved_path(f.buf, id, path, false));
diff --git a/src/librustdoc/html/markdown.rs b/src/librustdoc/html/markdown.rs
index 9d6b0ec5517..0141df34a6c 100644
--- a/src/librustdoc/html/markdown.rs
+++ b/src/librustdoc/html/markdown.rs
@@ -27,11 +27,11 @@
 #![allow(non_camel_case_types)]
 
 use libc;
+use std::cell::RefCell;
 use std::fmt;
 use std::io;
-use std::local_data;
-use std::str;
 use std::slice;
+use std::str;
 use collections::HashMap;
 
 use html::toc::TocBuilder;
@@ -139,7 +139,7 @@ fn stripped_filtered_line<'a>(s: &'a str) -> Option<&'a str> {
     }
 }
 
-local_data_key!(used_header_map: HashMap<~str, uint>)
+local_data_key!(used_header_map: RefCell<HashMap<~str, uint>>)
 
 pub fn render(w: &mut io::Writer, s: &str, print_toc: bool) -> fmt::Result {
     extern fn block(ob: *mut hoedown_buffer, text: *hoedown_buffer,
@@ -216,15 +216,12 @@ pub fn render(w: &mut io::Writer, s: &str, print_toc: bool) -> fmt::Result {
         let opaque = unsafe { &mut *((*opaque).opaque as *mut MyOpaque) };
 
         // Make sure our hyphenated ID is unique for this page
-        let id = local_data::get_mut(used_header_map, |map| {
-            let map = map.unwrap();
-            match map.find_mut(&id) {
-                None => {}
-                Some(a) => { *a += 1; return format!("{}-{}", id, *a - 1) }
-            }
-            map.insert(id.clone(), 1);
-            id.clone()
-        });
+        let map = used_header_map.get().unwrap();
+        let id = match map.borrow_mut().find_mut(&id) {
+            None => id,
+            Some(a) => { *a += 1; format!("{}-{}", id, *a - 1) }
+        };
+        map.borrow_mut().insert(id.clone(), 1);
 
         let sec = match opaque.toc_builder {
             Some(ref mut builder) => {
@@ -348,7 +345,7 @@ pub fn find_testable_code(doc: &str, tests: &mut ::test::Collector) {
 /// used at the beginning of rendering an entire HTML page to reset from the
 /// previous state (if any).
 pub fn reset_headers() {
-    local_data::set(used_header_map, HashMap::new())
+    used_header_map.replace(Some(RefCell::new(HashMap::new())));
 }
 
 impl<'a> fmt::Show for Markdown<'a> {
diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs
index a0d21bbf149..fe80d26d109 100644
--- a/src/librustdoc/html/render.rs
+++ b/src/librustdoc/html/render.rs
@@ -37,7 +37,6 @@ use collections::{HashMap, HashSet};
 use std::fmt;
 use std::io::{fs, File, BufferedWriter, MemWriter, BufferedReader};
 use std::io;
-use std::local_data;
 use std::str;
 use std::strbuf::StrBuf;
 
@@ -243,24 +242,22 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
     }
 
     // Crawl the crate to build various caches used for the output
-    let mut cache = local_data::get(::analysiskey, |analysis| {
-        let public_items = analysis.map(|a| a.public_items.clone());
-        let public_items = public_items.unwrap_or(NodeSet::new());
-        Cache {
-            impls: HashMap::new(),
-            typarams: HashMap::new(),
-            paths: HashMap::new(),
-            traits: HashMap::new(),
-            implementors: HashMap::new(),
-            stack: Vec::new(),
-            parent_stack: Vec::new(),
-            search_index: Vec::new(),
-            extern_locations: HashMap::new(),
-            privmod: false,
-            public_items: public_items,
-            orphan_methods: Vec::new(),
-        }
-    });
+    let public_items = ::analysiskey.get().map(|a| a.public_items.clone());
+    let public_items = public_items.unwrap_or(NodeSet::new());
+    let mut cache = Cache {
+        impls: HashMap::new(),
+        typarams: HashMap::new(),
+        paths: HashMap::new(),
+        traits: HashMap::new(),
+        implementors: HashMap::new(),
+        stack: Vec::new(),
+        parent_stack: Vec::new(),
+        search_index: Vec::new(),
+        extern_locations: HashMap::new(),
+        privmod: false,
+        public_items: public_items,
+        orphan_methods: Vec::new(),
+    };
     cache.stack.push(krate.name.clone());
     krate = cache.fold_crate(krate);
 
@@ -833,7 +830,7 @@ impl Context {
         item.name = Some(krate.name);
 
         // using a rwarc makes this parallelizable in the future
-        local_data::set(cache_key, Arc::new(cache));
+        cache_key.replace(Some(Arc::new(cache)));
 
         let mut work = vec!((self, item));
         loop {
@@ -859,7 +856,7 @@ impl Context {
             info!("Rendering an item to {}", w.path().display());
             // A little unfortunate that this is done like this, but it sure
             // does make formatting *a lot* nicer.
-            local_data::set(current_location_key, cx.current.clone());
+            current_location_key.replace(Some(cx.current.clone()));
 
             let mut title = StrBuf::from_str(cx.current.connect("::"));
             if pushname {
@@ -1299,31 +1296,28 @@ fn item_trait(w: &mut Writer, it: &clean::Item,
         try!(write!(w, "</div>"));
     }
 
-    local_data::get(cache_key, |cache| {
-        let cache = cache.unwrap();
-        match cache.implementors.find(&it.id) {
-            Some(implementors) => {
-                try!(write!(w, "
-                    <h2 id='implementors'>Implementors</h2>
-                    <ul class='item-list'>
-                "));
-                for i in implementors.iter() {
-                    match *i {
-                        PathType(ref ty) => {
-                            try!(write!(w, "<li><code>{}</code></li>", *ty));
-                        }
-                        OtherType(ref generics, ref trait_, ref for_) => {
-                            try!(write!(w, "<li><code>impl{} {} for {}</code></li>",
-                                          *generics, *trait_, *for_));
-                        }
+    match cache_key.get().unwrap().implementors.find(&it.id) {
+        Some(implementors) => {
+            try!(write!(w, "
+                <h2 id='implementors'>Implementors</h2>
+                <ul class='item-list'>
+            "));
+            for i in implementors.iter() {
+                match *i {
+                    PathType(ref ty) => {
+                        try!(write!(w, "<li><code>{}</code></li>", *ty));
+                    }
+                    OtherType(ref generics, ref trait_, ref for_) => {
+                        try!(write!(w, "<li><code>impl{} {} for {}</code></li>",
+                                      *generics, *trait_, *for_));
                     }
                 }
-                try!(write!(w, "</ul>"));
             }
-            None => {}
+            try!(write!(w, "</ul>"));
         }
-        Ok(())
-    })
+        None => {}
+    }
+    Ok(())
 }
 
 fn render_method(w: &mut Writer, meth: &clean::Item) -> fmt::Result {
@@ -1550,51 +1544,48 @@ fn render_struct(w: &mut Writer, it: &clean::Item,
 }
 
 fn render_methods(w: &mut Writer, it: &clean::Item) -> fmt::Result {
-    local_data::get(cache_key, |cache| {
-        let c = cache.unwrap();
-        match c.impls.find(&it.id) {
-            Some(v) => {
-                let mut non_trait = v.iter().filter(|p| {
-                    p.ref0().trait_.is_none()
-                });
-                let non_trait = non_trait.collect::<Vec<&(clean::Impl, Option<~str>)>>();
-                let mut traits = v.iter().filter(|p| {
-                    p.ref0().trait_.is_some()
-                });
-                let traits = traits.collect::<Vec<&(clean::Impl, Option<~str>)>>();
-
-                if non_trait.len() > 0 {
-                    try!(write!(w, "<h2 id='methods'>Methods</h2>"));
-                    for &(ref i, ref dox) in non_trait.move_iter() {
+    match cache_key.get().unwrap().impls.find(&it.id) {
+        Some(v) => {
+            let mut non_trait = v.iter().filter(|p| {
+                p.ref0().trait_.is_none()
+            });
+            let non_trait = non_trait.collect::<Vec<&(clean::Impl, Option<~str>)>>();
+            let mut traits = v.iter().filter(|p| {
+                p.ref0().trait_.is_some()
+            });
+            let traits = traits.collect::<Vec<&(clean::Impl, Option<~str>)>>();
+
+            if non_trait.len() > 0 {
+                try!(write!(w, "<h2 id='methods'>Methods</h2>"));
+                for &(ref i, ref dox) in non_trait.move_iter() {
+                    try!(render_impl(w, i, dox));
+                }
+            }
+            if traits.len() > 0 {
+                try!(write!(w, "<h2 id='implementations'>Trait \
+                                  Implementations</h2>"));
+                let mut any_derived = false;
+                for & &(ref i, ref dox) in traits.iter() {
+                    if !i.derived {
                         try!(render_impl(w, i, dox));
+                    } else {
+                        any_derived = true;
                     }
                 }
-                if traits.len() > 0 {
-                    try!(write!(w, "<h2 id='implementations'>Trait \
-                                      Implementations</h2>"));
-                    let mut any_derived = false;
-                    for & &(ref i, ref dox) in traits.iter() {
-                        if !i.derived {
+                if any_derived {
+                    try!(write!(w, "<h3 id='derived_implementations'>Derived Implementations \
+                                </h3>"));
+                    for &(ref i, ref dox) in traits.move_iter() {
+                        if i.derived {
                             try!(render_impl(w, i, dox));
-                        } else {
-                            any_derived = true;
-                        }
-                    }
-                    if any_derived {
-                        try!(write!(w, "<h3 id='derived_implementations'>Derived Implementations \
-                                    </h3>"));
-                        for &(ref i, ref dox) in traits.move_iter() {
-                            if i.derived {
-                                try!(render_impl(w, i, dox));
-                            }
                         }
                     }
                 }
             }
-            None => {}
         }
-        Ok(())
-    })
+        None => {}
+    }
+    Ok(())
 }
 
 fn render_impl(w: &mut Writer, i: &clean::Impl,
@@ -1644,9 +1635,8 @@ fn render_impl(w: &mut Writer, i: &clean::Impl,
     match trait_id {
         None => {}
         Some(id) => {
-            try!(local_data::get(cache_key, |cache| {
-                let cache = cache.unwrap();
-                match cache.traits.find(&id) {
+            try!({
+                match cache_key.get().unwrap().traits.find(&id) {
                     Some(t) => {
                         for method in t.methods.iter() {
                             let n = method.item().name.clone();
@@ -1661,7 +1651,7 @@ fn render_impl(w: &mut Writer, i: &clean::Impl,
                     None => {}
                 }
                 Ok(())
-            }))
+            })
         }
     }
     try!(write!(w, "</div>"));
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 24b3e1128ea..a79c8b30bba 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -28,7 +28,6 @@ extern crate time;
 extern crate log;
 extern crate libc;
 
-use std::local_data;
 use std::io;
 use std::io::{File, MemWriter};
 use std::str;
@@ -276,7 +275,7 @@ fn rust_input(cratefile: &str, matches: &getopts::Matches) -> Output {
                        &cr)
     }).unwrap();
     info!("finished with rustc");
-    local_data::set(analysiskey, analysis);
+    analysiskey.replace(Some(analysis));
 
     // Process all of the crate attributes, extracting plugin metadata along
     // with the passes which we are supposed to run.
diff --git a/src/librustdoc/passes.rs b/src/librustdoc/passes.rs
index f8a2382c028..38d1b2a14e1 100644
--- a/src/librustdoc/passes.rs
+++ b/src/librustdoc/passes.rs
@@ -11,7 +11,6 @@
 use collections::HashSet;
 use rustc::util::nodemap::NodeSet;
 use std::cmp;
-use std::local_data;
 use std::strbuf::StrBuf;
 use std::uint;
 use syntax::ast;
@@ -86,13 +85,11 @@ pub fn strip_hidden(krate: clean::Crate) -> plugins::PluginResult {
 
 /// Strip private items from the point of view of a crate or externally from a
 /// crate, specified by the `xcrate` flag.
-pub fn strip_private(krate: clean::Crate) -> plugins::PluginResult {
+pub fn strip_private(mut krate: clean::Crate) -> plugins::PluginResult {
     // This stripper collects all *retained* nodes.
     let mut retained = HashSet::new();
-    let exported_items = local_data::get(super::analysiskey, |analysis| {
-        analysis.unwrap().exported_items.clone()
-    });
-    let mut krate = krate;
+    let analysis = super::analysiskey.get().unwrap();
+    let exported_items = analysis.exported_items.clone();
 
     // strip all private items
     {
diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs
index 0b8434d7d17..898f5856694 100644
--- a/src/librustdoc/test.rs
+++ b/src/librustdoc/test.rs
@@ -12,7 +12,6 @@ use std::cell::RefCell;
 use std::char;
 use std::io;
 use std::io::{Process, TempDir};
-use std::local_data;
 use std::os;
 use std::str;
 use std::strbuf::StrBuf;
@@ -75,7 +74,7 @@ pub fn run(input: &str,
         maybe_typed: core::NotTyped(sess),
         src: input_path,
     };
-    local_data::set(super::ctxtkey, ctx);
+    super::ctxtkey.replace(Some(ctx));
 
     let mut v = RustdocVisitor::new(ctx, None);
     v.visit(&ctx.krate);