summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2014-07-26 06:56:23 +0000
committerbors <bors@rust-lang.org>2014-07-26 06:56:23 +0000
commitc0fa8764efa53ef2c6383ddedf90ee9804a02c68 (patch)
treeae0bf25823cc8e9b812d594ea27c5bc2525d2108 /src
parent34a6a8fc59343fca718a4d7d908012d1fdc83a80 (diff)
parent98f48630fc511c66b830571b028ebebe3911fa6f (diff)
downloadrust-c0fa8764efa53ef2c6383ddedf90ee9804a02c68.tar.gz
rust-c0fa8764efa53ef2c6383ddedf90ee9804a02c68.zip
auto merge of #15982 : alexcrichton/rust/rustdoc-fixes, r=brson
Sadly there's still a lot of open issues, but this tackles some of the more pressing ones. Each commit has its own description along with the issues it closes.
Diffstat (limited to 'src')
-rw-r--r--src/libcore/fmt/num.rs1
-rw-r--r--src/librustdoc/clean/inline.rs95
-rw-r--r--src/librustdoc/clean/mod.rs95
-rw-r--r--src/librustdoc/core.rs9
-rw-r--r--src/librustdoc/html/format.rs6
-rw-r--r--src/librustdoc/html/static/main.js4
-rw-r--r--src/librustdoc/lib.rs5
-rw-r--r--src/librustdoc/visit_ast.rs26
8 files changed, 158 insertions, 83 deletions
diff --git a/src/libcore/fmt/num.rs b/src/libcore/fmt/num.rs
index a4fd5bb92e6..2ed32b3388f 100644
--- a/src/libcore/fmt/num.rs
+++ b/src/libcore/fmt/num.rs
@@ -26,6 +26,7 @@ use iter::Iterator;         // NOTE(stage0): Remove after snapshot.
 use option::{Some, None};   // NOTE(stage0): Remove after snapshot.
 
 /// A type that represents a specific radix
+#[doc(hidden)]
 trait GenericRadix {
     /// The number of digits.
     fn base(&self) -> u8;
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index b3891432e21..2f7d766c28f 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -18,6 +18,7 @@ use rustc::metadata::csearch;
 use rustc::metadata::decoder;
 use rustc::middle::def;
 use rustc::middle::ty;
+use rustc::middle::subst;
 use rustc::middle::stability;
 
 use core;
@@ -38,7 +39,8 @@ use super::Clean;
 ///
 /// The returned value is `None` if the `id` could not be inlined, and `Some`
 /// of a vector of items if it was successfully expanded.
-pub fn try_inline(id: ast::NodeId) -> Option<Vec<clean::Item>> {
+pub fn try_inline(id: ast::NodeId, into: Option<ast::Ident>)
+                  -> Option<Vec<clean::Item>> {
     let cx = ::ctxtkey.get().unwrap();
     let tcx = match cx.maybe_typed {
         core::Typed(ref tycx) => tycx,
@@ -50,7 +52,17 @@ pub fn try_inline(id: ast::NodeId) -> Option<Vec<clean::Item>> {
     };
     let did = def.def_id();
     if ast_util::is_local(did) { return None }
-    try_inline_def(&**cx, tcx, def)
+    try_inline_def(&**cx, tcx, def).map(|vec| {
+        vec.move_iter().map(|mut item| {
+            match into {
+                Some(into) if item.name.is_some() => {
+                    item.name = Some(into.clean());
+                }
+                _ => {}
+            }
+            item
+        }).collect()
+    })
 }
 
 fn try_inline_def(cx: &core::DocContext,
@@ -163,7 +175,7 @@ pub fn build_external_trait(tcx: &ty::ctxt, did: ast::DefId) -> clean::Trait {
     });
 
     clean::Trait {
-        generics: def.generics.clean(),
+        generics: (&def.generics, subst::TypeSpace).clean(),
         methods: methods.collect(),
         parents: parents.collect()
     }
@@ -178,7 +190,7 @@ fn build_external_function(tcx: &ty::ctxt,
             ty::ty_bare_fn(ref f) => (did, &f.sig).clean(),
             _ => fail!("bad function"),
         },
-        generics: t.generics.clean(),
+        generics: (&t.generics, subst::FnSpace).clean(),
         fn_style: style,
     }
 }
@@ -196,7 +208,7 @@ fn build_struct(tcx: &ty::ctxt, did: ast::DefId) -> clean::Struct {
             [ref f, ..] if f.name == unnamed_field.name => doctree::Tuple,
             _ => doctree::Plain,
         },
-        generics: t.generics.clean(),
+        generics: (&t.generics, subst::TypeSpace).clean(),
         fields: fields.iter().map(|f| f.clean()).collect(),
         fields_stripped: false,
     }
@@ -207,7 +219,7 @@ fn build_type(tcx: &ty::ctxt, did: ast::DefId) -> clean::ItemEnum {
     match ty::get(t.ty).sty {
         ty::ty_enum(edid, _) if !csearch::is_typedef(&tcx.sess.cstore, did) => {
             return clean::EnumItem(clean::Enum {
-                generics: t.generics.clean(),
+                generics: (&t.generics, subst::TypeSpace).clean(),
                 variants_stripped: false,
                 variants: ty::enum_variants(tcx, edid).clean(),
             })
@@ -217,7 +229,7 @@ fn build_type(tcx: &ty::ctxt, did: ast::DefId) -> clean::ItemEnum {
 
     clean::TypedefItem(clean::Typedef {
         type_: t.ty.clean(),
-        generics: t.generics.clean(),
+        generics: (&t.generics, subst::TypeSpace).clean(),
     })
 }
 
@@ -278,6 +290,17 @@ fn build_impl(cx: &core::DocContext,
     }
 
     let associated_trait = csearch::get_impl_trait(tcx, did);
+    // If this is an impl for a #[doc(hidden)] trait, be sure to not inline it.
+    match associated_trait {
+        Some(ref t) => {
+            let trait_attrs = load_attrs(tcx, t.def_id);
+            if trait_attrs.iter().any(|a| is_doc_hidden(a)) {
+                return None
+            }
+        }
+        None => {}
+    }
+
     let attrs = load_attrs(tcx, did);
     let ty = ty::lookup_item_type(tcx, did);
     let methods = csearch::get_impl_methods(&tcx.sess.cstore,
@@ -302,7 +325,7 @@ fn build_impl(cx: &core::DocContext,
         };
         Some(item)
     }).collect();
-    Some(clean::Item {
+    return Some(clean::Item {
         inner: clean::ImplItem(clean::Impl {
             derived: clean::detect_derived(attrs.as_slice()),
             trait_: associated_trait.clean().map(|bound| {
@@ -312,7 +335,7 @@ fn build_impl(cx: &core::DocContext,
                 }
             }),
             for_: ty.ty.clean(),
-            generics: ty.generics.clean(),
+            generics: (&ty.generics, subst::TypeSpace).clean(),
             methods: methods,
         }),
         source: clean::Span::empty(),
@@ -321,33 +344,53 @@ fn build_impl(cx: &core::DocContext,
         visibility: Some(ast::Inherited),
         stability: stability::lookup(tcx, did).clean(),
         def_id: did,
-    })
+    });
+
+    fn is_doc_hidden(a: &clean::Attribute) -> bool {
+        match *a {
+            clean::List(ref name, ref inner) if name.as_slice() == "doc" => {
+                inner.iter().any(|a| {
+                    match *a {
+                        clean::Word(ref s) => s.as_slice() == "hidden",
+                        _ => false,
+                    }
+                })
+            }
+            _ => false
+        }
+    }
 }
 
 fn build_module(cx: &core::DocContext, tcx: &ty::ctxt,
                 did: ast::DefId) -> clean::Module {
     let mut items = Vec::new();
+    fill_in(cx, tcx, did, &mut items);
+    return clean::Module {
+        items: items,
+        is_crate: false,
+    };
 
     // FIXME: this doesn't handle reexports inside the module itself.
     //        Should they be handled?
-    csearch::each_child_of_item(&tcx.sess.cstore, did, |def, _, vis| {
-        if vis != ast::Public { return }
-        match def {
-            decoder::DlDef(def) => {
-                match try_inline_def(cx, tcx, def) {
-                    Some(i) => items.extend(i.move_iter()),
-                    None => {}
+    fn fill_in(cx: &core::DocContext, tcx: &ty::ctxt, did: ast::DefId,
+               items: &mut Vec<clean::Item>) {
+        csearch::each_child_of_item(&tcx.sess.cstore, did, |def, _, vis| {
+            match def {
+                decoder::DlDef(def::DefForeignMod(did)) => {
+                    fill_in(cx, tcx, did, items);
                 }
+                decoder::DlDef(def) if vis == ast::Public => {
+                    match try_inline_def(cx, tcx, def) {
+                        Some(i) => items.extend(i.move_iter()),
+                        None => {}
+                    }
+                }
+                decoder::DlDef(..) => {}
+                // All impls were inlined above
+                decoder::DlImpl(..) => {}
+                decoder::DlField => fail!("unimplemented field"),
             }
-            // All impls were inlined above
-            decoder::DlImpl(..) => {}
-            decoder::DlField => fail!("unimplemented field"),
-        }
-    });
-
-    clean::Module {
-        items: items,
-        is_crate: false,
+        });
     }
 }
 
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index 57cda6c4817..953b736f38b 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -653,35 +653,12 @@ impl Clean<Generics> for ast::Generics {
     }
 }
 
-impl Clean<Generics> for ty::Generics {
+impl<'a> Clean<Generics> for (&'a ty::Generics, subst::ParamSpace) {
     fn clean(&self) -> Generics {
-        // In the type space, generics can come in one of multiple
-        // namespaces.  This means that e.g. for fn items the type
-        // parameters will live in FnSpace, but for types the
-        // parameters will live in TypeSpace (trait definitions also
-        // define a parameter in SelfSpace). *Method* definitions are
-        // the one exception: they combine the TypeSpace parameters
-        // from the enclosing impl/trait with their own FnSpace
-        // parameters.
-        //
-        // In general, when we clean, we are trying to produce the
-        // "user-facing" generics. Hence we select the most specific
-        // namespace that is occupied, ignoring SelfSpace because it
-        // is implicit.
-
-        let space = {
-            if !self.types.is_empty_in(subst::FnSpace) ||
-                !self.regions.is_empty_in(subst::FnSpace)
-            {
-                subst::FnSpace
-            } else {
-                subst::TypeSpace
-            }
-        };
-
+        let (me, space) = *self;
         Generics {
-            type_params: Vec::from_slice(self.types.get_slice(space)).clean(),
-            lifetimes: Vec::from_slice(self.regions.get_slice(space)).clean(),
+            type_params: Vec::from_slice(me.types.get_slice(space)).clean(),
+            lifetimes: Vec::from_slice(me.regions.get_slice(space)).clean(),
         }
     }
 }
@@ -770,7 +747,6 @@ pub enum SelfTy {
     SelfStatic,
     SelfValue,
     SelfBorrowed(Option<Lifetime>, Mutability),
-    SelfOwned,
     SelfExplicit(Type),
 }
 
@@ -994,28 +970,27 @@ impl Clean<Item> for ty::Method {
     fn clean(&self) -> Item {
         let cx = get_cx();
         let (self_, sig) = match self.explicit_self {
-            ty::StaticExplicitSelfCategory => (ast::SelfStatic.clean(), self.fty.sig.clone()),
+            ty::StaticExplicitSelfCategory => (ast::SelfStatic.clean(),
+                                               self.fty.sig.clone()),
             s => {
                 let sig = ty::FnSig {
                     inputs: Vec::from_slice(self.fty.sig.inputs.slice_from(1)),
                     ..self.fty.sig.clone()
                 };
                 let s = match s {
+                    ty::ByValueExplicitSelfCategory => SelfValue,
                     ty::ByReferenceExplicitSelfCategory(..) => {
                         match ty::get(self.fty.sig.inputs[0]).sty {
                             ty::ty_rptr(r, mt) => {
                                 SelfBorrowed(r.clean(), mt.mutbl.clean())
                             }
-                            _ => {
-                                // FIXME(pcwalton): This is wrong.
-                                SelfStatic
-                            }
+                            _ => unreachable!(),
                         }
                     }
-                    _ => {
-                        // FIXME(pcwalton): This is wrong.
-                        SelfStatic
+                    ty::ByBoxExplicitSelfCategory => {
+                        SelfExplicit(self.fty.sig.inputs[0].clean())
                     }
+                    ty::StaticExplicitSelfCategory => unreachable!(),
                 };
                 (s, sig)
             }
@@ -1030,7 +1005,7 @@ impl Clean<Item> for ty::Method {
             source: Span::empty(),
             inner: TyMethodItem(TyMethod {
                 fn_style: self.fty.fn_style,
-                generics: self.generics.clean(),
+                generics: (&self.generics, subst::FnSpace).clean(),
                 self_: self_,
                 decl: (self.def_id, &sig).clean(),
             })
@@ -1236,8 +1211,18 @@ impl Clean<Type> for ty::t {
             ty::ty_float(ast::TyF32) => Primitive(F32),
             ty::ty_float(ast::TyF64) => Primitive(F64),
             ty::ty_str => Primitive(Str),
-            ty::ty_box(t) => Managed(box t.clean()),
-            ty::ty_uniq(t) => Unique(box t.clean()),
+            ty::ty_box(t) => {
+                let gc_did = get_cx().tcx_opt().and_then(|tcx| {
+                    tcx.lang_items.gc()
+                });
+                lang_struct(gc_did, t, "Gc", Managed)
+            }
+            ty::ty_uniq(t) => {
+                let box_did = get_cx().tcx_opt().and_then(|tcx| {
+                    tcx.lang_items.owned_box()
+                });
+                lang_struct(box_did, t, "Box", Unique)
+            }
             ty::ty_vec(mt, None) => Vector(box mt.ty.clean()),
             ty::ty_vec(mt, Some(i)) => FixedVector(box mt.ty.clean(),
                                                    format!("{}", i)),
@@ -1778,7 +1763,7 @@ impl Clean<Vec<Item>> for ast::ViewItem {
                         // to keep any non-inlineable reexports so they can be
                         // listed in the documentation.
                         let remaining = list.iter().filter(|path| {
-                            match inline::try_inline(path.node.id()) {
+                            match inline::try_inline(path.node.id(), None) {
                                 Some(items) => {
                                     ret.extend(items.move_iter()); false
                                 }
@@ -1793,8 +1778,8 @@ impl Clean<Vec<Item>> for ast::ViewItem {
                             ret.push(convert(&ast::ViewItemUse(box(GC) path)));
                         }
                     }
-                    ast::ViewPathSimple(_, _, id) => {
-                        match inline::try_inline(id) {
+                    ast::ViewPathSimple(ident, _, id) => {
+                        match inline::try_inline(id, Some(ident)) {
                             Some(items) => ret.extend(items.move_iter()),
                             None => ret.push(convert(&self.node)),
                         }
@@ -2117,3 +2102,29 @@ impl Clean<Stability> for attr::Stability {
         }
     }
 }
+
+fn lang_struct(did: Option<ast::DefId>, t: ty::t, name: &str,
+               fallback: fn(Box<Type>) -> Type) -> Type {
+    let did = match did {
+        Some(did) => did,
+        None => return fallback(box t.clean()),
+    };
+    let fqn = csearch::get_item_path(get_cx().tcx(), did);
+    let fqn: Vec<String> = fqn.move_iter().map(|i| {
+        i.to_string()
+    }).collect();
+    get_cx().external_paths.borrow_mut().get_mut_ref()
+                           .insert(did, (fqn, TypeStruct));
+    ResolvedPath {
+        typarams: None,
+        did: did,
+        path: Path {
+            global: false,
+            segments: vec![PathSegment {
+                name: name.to_string(),
+                lifetimes: vec![],
+                types: vec![t.clean()],
+            }],
+        },
+    }
+}
diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs
index 7f021510f4a..032189dca48 100644
--- a/src/librustdoc/core.rs
+++ b/src/librustdoc/core.rs
@@ -80,7 +80,8 @@ pub struct CrateAnalysis {
 pub type Externs = HashMap<String, Vec<String>>;
 
 /// Parses, resolves, and typechecks the given crate
-fn get_ast_and_resolve(cpath: &Path, libs: HashSet<Path>, cfgs: Vec<String>, externs: Externs)
+fn get_ast_and_resolve(cpath: &Path, libs: HashSet<Path>, cfgs: Vec<String>,
+                       externs: Externs, triple: Option<String>)
                        -> (DocContext, CrateAnalysis) {
     use syntax::codemap::dummy_spanned;
     use rustc::driver::driver::{FileInput,
@@ -99,6 +100,7 @@ fn get_ast_and_resolve(cpath: &Path, libs: HashSet<Path>, cfgs: Vec<String>, ext
         crate_types: vec!(driver::config::CrateTypeRlib),
         lint_opts: vec!((warning_lint, lint::Allow)),
         externs: externs,
+        target_triple: triple.unwrap_or(driver::driver::host_triple().to_string()),
         ..rustc::driver::config::basic_options().clone()
     };
 
@@ -151,9 +153,10 @@ fn get_ast_and_resolve(cpath: &Path, libs: HashSet<Path>, cfgs: Vec<String>, ext
     })
 }
 
-pub fn run_core(libs: HashSet<Path>, cfgs: Vec<String>, externs: Externs, path: &Path)
+pub fn run_core(libs: HashSet<Path>, cfgs: Vec<String>, externs: Externs,
+                path: &Path, triple: Option<String>)
                 -> (clean::Crate, CrateAnalysis) {
-    let (ctxt, analysis) = get_ast_and_resolve(path, libs, cfgs, externs);
+    let (ctxt, analysis) = get_ast_and_resolve(path, libs, cfgs, externs, triple);
     let ctxt = box(GC) ctxt;
     super::ctxtkey.replace(Some(ctxt));
 
diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs
index e7f93703399..c6d6843db5f 100644
--- a/src/librustdoc/html/format.rs
+++ b/src/librustdoc/html/format.rs
@@ -444,8 +444,6 @@ impl fmt::Show for clean::Type {
                                format!("[{}, ..{}]", **t, *s).as_slice())
             }
             clean::Bottom => f.write("!".as_bytes()),
-            clean::Unique(ref t) => write!(f, "Box<{}>", **t),
-            clean::Managed(ref t) => write!(f, "Gc<{}>", **t),
             clean::RawPointer(m, ref t) => {
                 write!(f, "*{}{}", RawMutableSpace(m), **t)
             }
@@ -456,6 +454,9 @@ impl fmt::Show for clean::Type {
                 };
                 write!(f, "&amp;{}{}{}", lt, MutableSpace(mutability), **ty)
             }
+            clean::Unique(..) | clean::Managed(..) => {
+                fail!("should have been cleaned")
+            }
         }
     }
 }
@@ -491,7 +492,6 @@ impl<'a> fmt::Show for Method<'a> {
         match *selfty {
             clean::SelfStatic => {},
             clean::SelfValue => args.push_str("self"),
-            clean::SelfOwned => args.push_str("self: Box<Self>"),
             clean::SelfBorrowed(Some(ref lt), mtbl) => {
                 args.push_str(format!("&amp;{} {}self", *lt,
                                       MutableSpace(mtbl)).as_slice());
diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js
index fc1e480f6af..1869031dab3 100644
--- a/src/librustdoc/html/static/main.js
+++ b/src/librustdoc/html/static/main.js
@@ -357,8 +357,8 @@
                 }, 20);
             });
 
-            $(document).off('keypress.searchnav');
-            $(document).on('keypress.searchnav', function(e) {
+            $(document).off('keydown.searchnav');
+            $(document).on('keydown.searchnav', function(e) {
                 var $active = $results.filter('.highlighted');
 
                 if (e.which === 38) { // up
diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs
index 39b2511fde4..a89b7657287 100644
--- a/src/librustdoc/lib.rs
+++ b/src/librustdoc/lib.rs
@@ -117,6 +117,7 @@ pub fn opts() -> Vec<getopts::OptGroup> {
         optflag("", "test", "run code examples as tests"),
         optmulti("", "test-args", "arguments to pass to the test runner",
                  "ARGS"),
+        optopt("", "target", "target triple to document", "TRIPLE"),
         optmulti("", "markdown-css", "CSS files to include via <link> in a rendered Markdown file",
                  "FILES"),
         optmulti("", "html-in-header",
@@ -321,6 +322,7 @@ fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matche
                                  .map(|s| Path::new(s.as_slice()))
                                  .collect();
     let cfgs = matches.opt_strs("cfg");
+    let triple = matches.opt_str("target");
 
     let cr = Path::new(cratefile);
     info!("starting to run rustc");
@@ -329,7 +331,8 @@ fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matche
         core::run_core(libs.move_iter().collect(),
                        cfgs,
                        externs,
-                       &cr)
+                       &cr,
+                       triple)
     }).map_err(|boxed_any|format!("{:?}", boxed_any)).unwrap();
     info!("finished with rustc");
     analysiskey.replace(Some(analysis));
diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs
index 594a2353396..d28069da6ba 100644
--- a/src/librustdoc/visit_ast.rs
+++ b/src/librustdoc/visit_ast.rs
@@ -192,13 +192,16 @@ impl<'a> RustdocVisitor<'a> {
                        om: &mut Module,
                        please_inline: bool) -> Option<Gc<ast::ViewPath>> {
         match path.node {
-            ast::ViewPathSimple(_, _, id) => {
-                if self.resolve_id(id, false, om, please_inline) { return None }
+            ast::ViewPathSimple(dst, _, id) => {
+                if self.resolve_id(id, Some(dst), false, om, please_inline) {
+                    return None
+                }
             }
             ast::ViewPathList(ref p, ref paths, ref b) => {
                 let mut mine = Vec::new();
                 for path in paths.iter() {
-                    if !self.resolve_id(path.node.id(), false, om, please_inline) {
+                    if !self.resolve_id(path.node.id(), None, false, om,
+                                        please_inline) {
                         mine.push(path.clone());
                     }
                 }
@@ -212,14 +215,16 @@ impl<'a> RustdocVisitor<'a> {
 
             // these are feature gated anyway
             ast::ViewPathGlob(_, id) => {
-                if self.resolve_id(id, true, om, please_inline) { return None }
+                if self.resolve_id(id, None, true, om, please_inline) {
+                    return None
+                }
             }
         }
         return Some(path);
     }
 
-    fn resolve_id(&mut self, id: ast::NodeId, glob: bool,
-                  om: &mut Module, please_inline: bool) -> bool {
+    fn resolve_id(&mut self, id: ast::NodeId, renamed: Option<ast::Ident>,
+                  glob: bool, om: &mut Module, please_inline: bool) -> bool {
         let tcx = match self.cx.maybe_typed {
             core::Typed(ref tcx) => tcx,
             core::NotTyped(_) => return false
@@ -235,6 +240,15 @@ impl<'a> RustdocVisitor<'a> {
 
         match tcx.map.get(def.node) {
             ast_map::NodeItem(it) => {
+                let it = match renamed {
+                    Some(ident) => {
+                        box(GC) ast::Item {
+                            ident: ident,
+                            ..(*it).clone()
+                        }
+                    }
+                    None => it,
+                };
                 if glob {
                     match it.node {
                         ast::ItemMod(ref m) => {