1
Fork 0

auto merge of #14068 : alexcrichton/rust/rustdoc-xcrate-links, r=brson

This should improve the libcore experience quite a bit when looking at the
libstd documentation.
This commit is contained in:
bors 2014-05-10 03:36:30 -07:00
commit e850316408
11 changed files with 155 additions and 140 deletions

View file

@ -17,14 +17,13 @@ This document does not serve as a tutorial introduction to the
language. Background familiarity with the language is assumed. A separate language. Background familiarity with the language is assumed. A separate
[tutorial] document is available to help acquire such background familiarity. [tutorial] document is available to help acquire such background familiarity.
This document also does not serve as a reference to the [standard] or [extra] This document also does not serve as a reference to the [standard]
libraries included in the language distribution. Those libraries are library included in the language distribution. Those libraries are
documented separately by extracting documentation attributes from their documented separately by extracting documentation attributes from their
source code. source code.
[tutorial]: tutorial.html [tutorial]: tutorial.html
[standard]: std/index.html [standard]: std/index.html
[extra]: extra/index.html
## Disclaimer ## Disclaimer

View file

@ -24,7 +24,7 @@
//! //!
//! Functions return `Result` whenever errors are expected and //! Functions return `Result` whenever errors are expected and
//! recoverable. In the `std` crate `Result` is most prominently used //! recoverable. In the `std` crate `Result` is most prominently used
//! for [I/O](../io/index.html). //! for [I/O](../../std/io/index.html).
//! //!
//! A simple function returning `Result` might be //! A simple function returning `Result` might be
//! defined and used like so: //! defined and used like so:

View file

@ -670,15 +670,7 @@ pub enum Type {
ResolvedPath { ResolvedPath {
pub path: Path, pub path: Path,
pub typarams: Option<Vec<TyParamBound>>, pub typarams: Option<Vec<TyParamBound>>,
pub id: ast::NodeId, pub did: ast::DefId,
},
/// Same as above, but only external variants
ExternalPath {
pub path: Path,
pub typarams: Option<Vec<TyParamBound>>,
pub fqn: Vec<~str>,
pub kind: TypeKind,
pub krate: ast::CrateNum,
}, },
// I have no idea how to usefully use this. // I have no idea how to usefully use this.
TyParamBinder(ast::NodeId), TyParamBinder(ast::NodeId),
@ -715,19 +707,18 @@ pub enum Type {
#[deriving(Clone, Encodable, Decodable)] #[deriving(Clone, Encodable, Decodable)]
pub enum TypeKind { pub enum TypeKind {
TypeStruct,
TypeEnum, TypeEnum,
TypeTrait,
TypeFunction, TypeFunction,
TypeModule,
TypeStatic,
TypeStruct,
TypeTrait,
TypeVariant,
} }
impl Clean<Type> for ast::Ty { impl Clean<Type> for ast::Ty {
fn clean(&self) -> Type { fn clean(&self) -> Type {
use syntax::ast::*; use syntax::ast::*;
debug!("cleaning type `{:?}`", self);
let ctxt = super::ctxtkey.get().unwrap();
let codemap = ctxt.sess().codemap();
debug!("span corresponds to `{}`", codemap.span_to_str(self.span));
match self.node { match self.node {
TyNil => Unit, TyNil => Unit,
TyPtr(ref m) => RawPointer(m.mutbl.clean(), box m.ty.clean()), TyPtr(ref m) => RawPointer(m.mutbl.clean(), box m.ty.clean()),
@ -1153,7 +1144,7 @@ pub enum ViewPath {
// use source::*; // use source::*;
GlobImport(ImportSource), GlobImport(ImportSource),
// use source::{a, b, c}; // use source::{a, b, c};
ImportList(ImportSource, Vec<ViewListIdent> ), ImportList(ImportSource, Vec<ViewListIdent>),
} }
#[deriving(Clone, Encodable, Decodable)] #[deriving(Clone, Encodable, Decodable)]
@ -1298,48 +1289,47 @@ fn resolve_type(path: Path, tpbs: Option<Vec<TyParamBound> >,
core::NotTyped(_) => return Bool core::NotTyped(_) => return Bool
}; };
debug!("searching for {:?} in defmap", id); debug!("searching for {:?} in defmap", id);
let d = match tycx.def_map.borrow().find(&id) { let def = match tycx.def_map.borrow().find(&id) {
Some(&k) => k, Some(&k) => k,
None => { None => fail!("unresolved id not in defmap")
debug!("could not find {:?} in defmap (`{}`)", id, tycx.map.node_to_str(id));
fail!("Unexpected failure: unresolved id not in defmap (this is a bug!)")
}
}; };
let (def_id, kind) = match d { match def {
ast::DefFn(i, _) => (i, TypeFunction),
ast::DefSelfTy(i) => return Self(i), ast::DefSelfTy(i) => return Self(i),
ast::DefTy(i) => (i, TypeEnum),
ast::DefTrait(i) => {
debug!("saw DefTrait in def_to_id");
(i, TypeTrait)
},
ast::DefPrimTy(p) => match p { ast::DefPrimTy(p) => match p {
ast::TyStr => return String, ast::TyStr => return String,
ast::TyBool => return Bool, ast::TyBool => return Bool,
_ => return Primitive(p) _ => return Primitive(p)
}, },
ast::DefTyParam(i, _) => return Generic(i.node), ast::DefTyParam(i, _) => return Generic(i.node),
ast::DefStruct(i) => (i, TypeStruct), ast::DefTyParamBinder(i) => return TyParamBinder(i),
ast::DefTyParamBinder(i) => { _ => {}
debug!("found a typaram_binder, what is it? {}", i);
return TyParamBinder(i);
},
x => fail!("resolved type maps to a weird def {:?}", x),
}; };
if ast_util::is_local(def_id) { let did = register_def(&**cx, def);
ResolvedPath{ path: path, typarams: tpbs, id: def_id.node } ResolvedPath { path: path, typarams: tpbs, did: did }
} else { }
let fqn = csearch::get_item_path(tycx, def_id);
fn register_def(cx: &core::DocContext, def: ast::Def) -> ast::DefId {
let (did, kind) = match def {
ast::DefFn(i, _) => (i, TypeFunction),
ast::DefTy(i) => (i, TypeEnum),
ast::DefTrait(i) => (i, TypeTrait),
ast::DefStruct(i) => (i, TypeStruct),
ast::DefMod(i) => (i, TypeModule),
ast::DefStatic(i, _) => (i, TypeStatic),
ast::DefVariant(i, _, _) => (i, TypeEnum),
_ => return ast_util::def_id_of_def(def),
};
if ast_util::is_local(did) { return did }
let tcx = match cx.maybe_typed {
core::Typed(ref t) => t,
core::NotTyped(_) => return did
};
let fqn = csearch::get_item_path(tcx, did);
let fqn = fqn.move_iter().map(|i| i.to_str()).collect(); let fqn = fqn.move_iter().map(|i| i.to_str()).collect();
ExternalPath { debug!("recording {} => {}", did, fqn);
path: path, cx.external_paths.borrow_mut().get_mut_ref().insert(did, (fqn, kind));
typarams: tpbs, return did;
fqn: fqn,
kind: kind,
krate: def_id.krate,
}
}
} }
fn resolve_use_source(path: Path, id: ast::NodeId) -> ImportSource { fn resolve_use_source(path: Path, id: ast::NodeId) -> ImportSource {
@ -1353,7 +1343,7 @@ fn resolve_def(id: ast::NodeId) -> Option<ast::DefId> {
let cx = super::ctxtkey.get().unwrap(); let cx = super::ctxtkey.get().unwrap();
match cx.maybe_typed { match cx.maybe_typed {
core::Typed(ref tcx) => { core::Typed(ref tcx) => {
tcx.def_map.borrow().find(&id).map(|&d| ast_util::def_id_of_def(d)) tcx.def_map.borrow().find(&id).map(|&def| register_def(&**cx, def))
} }
core::NotTyped(_) => None core::NotTyped(_) => None
} }

View file

@ -20,7 +20,7 @@ use syntax;
use std::cell::RefCell; use std::cell::RefCell;
use std::os; use std::os;
use collections::HashSet; use collections::{HashSet, HashMap};
use visit_ast::RustdocVisitor; use visit_ast::RustdocVisitor;
use clean; use clean;
@ -31,10 +31,14 @@ pub enum MaybeTyped {
NotTyped(driver::session::Session) NotTyped(driver::session::Session)
} }
pub type ExternalPaths = RefCell<Option<HashMap<ast::DefId,
(Vec<~str>, clean::TypeKind)>>>;
pub struct DocContext { pub struct DocContext {
pub krate: ast::Crate, pub krate: ast::Crate,
pub maybe_typed: MaybeTyped, pub maybe_typed: MaybeTyped,
pub src: Path, pub src: Path,
pub external_paths: ExternalPaths,
} }
impl DocContext { impl DocContext {
@ -49,6 +53,7 @@ impl DocContext {
pub struct CrateAnalysis { pub struct CrateAnalysis {
pub exported_items: privacy::ExportedItems, pub exported_items: privacy::ExportedItems,
pub public_items: privacy::PublicItems, pub public_items: privacy::PublicItems,
pub external_paths: ExternalPaths,
} }
/// Parses, resolves, and typechecks the given crate /// Parses, resolves, and typechecks the given crate
@ -98,9 +103,11 @@ fn get_ast_and_resolve(cpath: &Path, libs: HashSet<Path>, cfgs: Vec<~str>)
krate: krate, krate: krate,
maybe_typed: Typed(ty_cx), maybe_typed: Typed(ty_cx),
src: cpath.clone(), src: cpath.clone(),
external_paths: RefCell::new(Some(HashMap::new())),
}, CrateAnalysis { }, CrateAnalysis {
exported_items: exported_items, exported_items: exported_items,
public_items: public_items, public_items: public_items,
external_paths: RefCell::new(None),
}) })
} }
@ -116,5 +123,7 @@ pub fn run_core(libs: HashSet<Path>, cfgs: Vec<~str>, path: &Path)
v.clean() v.clean()
}; };
let external_paths = ctxt.external_paths.borrow_mut().take();
*analysis.external_paths.borrow_mut() = external_paths;
(krate, analysis) (krate, analysis)
} }

View file

@ -146,38 +146,25 @@ impl fmt::Show for clean::Path {
/// Used when rendering a `ResolvedPath` structure. This invokes the `path` /// Used when rendering a `ResolvedPath` structure. This invokes the `path`
/// rendering function with the necessary arguments for linking to a local path. /// rendering function with the necessary arguments for linking to a local path.
fn resolved_path(w: &mut io::Writer, id: ast::NodeId, p: &clean::Path, fn resolved_path(w: &mut io::Writer, did: ast::DefId, p: &clean::Path,
print_all: bool) -> fmt::Result { print_all: bool) -> fmt::Result {
path(w, p, print_all,
|_cache, loc| { Some("../".repeat(loc.len())) },
|cache| {
match cache.paths.find(&id) {
None => None,
Some(&(ref fqp, shortty)) => Some((fqp.clone(), shortty))
}
})
}
/// Used when rendering an `ExternalPath` structure. Like `resolved_path` this
/// will invoke `path` with proper linking-style arguments.
fn external_path(w: &mut io::Writer, p: &clean::Path, print_all: bool,
fqn: &[~str], kind: clean::TypeKind,
krate: ast::CrateNum) -> fmt::Result {
path(w, p, print_all, path(w, p, print_all,
|cache, loc| { |cache, loc| {
match *cache.extern_locations.get(&krate) { if ast_util::is_local(did) {
Some("../".repeat(loc.len()))
} else {
match *cache.extern_locations.get(&did.krate) {
render::Remote(ref s) => Some(s.clone()), render::Remote(ref s) => Some(s.clone()),
render::Local => Some("../".repeat(loc.len())), render::Local => Some("../".repeat(loc.len())),
render::Unknown => None, render::Unknown => None,
} }
}
}, },
|_cache| { |cache| {
Some((Vec::from_slice(fqn), match kind { match cache.paths.find(&did) {
clean::TypeStruct => item_type::Struct, None => None,
clean::TypeEnum => item_type::Enum, Some(&(ref fqp, shortty)) => Some((fqp.clone(), shortty))
clean::TypeFunction => item_type::Function, }
clean::TypeTrait => item_type::Trait,
}))
}) })
} }
@ -298,15 +285,9 @@ impl fmt::Show for clean::Type {
let m = cache_key.get().unwrap(); let m = cache_key.get().unwrap();
f.buf.write(m.typarams.get(&id).as_bytes()) f.buf.write(m.typarams.get(&id).as_bytes())
} }
clean::ResolvedPath{id, typarams: ref tp, path: ref path} => { clean::ResolvedPath{ did, ref typarams, ref path} => {
try!(resolved_path(f.buf, id, path, false)); try!(resolved_path(f.buf, did, path, false));
tybounds(f.buf, tp) tybounds(f.buf, typarams)
}
clean::ExternalPath{path: ref path, typarams: ref tp,
fqn: ref fqn, kind, krate} => {
try!(external_path(f.buf, path, false, fqn.as_slice(), kind,
krate))
tybounds(f.buf, tp)
} }
clean::Self(..) => f.buf.write("Self".as_bytes()), clean::Self(..) => f.buf.write("Self".as_bytes()),
clean::Primitive(prim) => { clean::Primitive(prim) => {
@ -543,10 +524,7 @@ impl fmt::Show for clean::ViewPath {
impl fmt::Show for clean::ImportSource { impl fmt::Show for clean::ImportSource {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.did { match self.did {
// FIXME: shouldn't be restricted to just local imports Some(did) => resolved_path(f.buf, did, &self.path, true),
Some(did) if ast_util::is_local(did) => {
resolved_path(f.buf, did.node, &self.path, true)
}
_ => { _ => {
for (i, seg) in self.path.segments.iter().enumerate() { for (i, seg) in self.path.segments.iter().enumerate() {
if i > 0 { if i > 0 {
@ -563,8 +541,7 @@ impl fmt::Show for clean::ImportSource {
impl fmt::Show for clean::ViewListIdent { impl fmt::Show for clean::ViewListIdent {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match self.source { match self.source {
// FIXME: shouldn't be limited to just local imports Some(did) => {
Some(did) if ast_util::is_local(did) => {
let path = clean::Path { let path = clean::Path {
global: false, global: false,
segments: vec!(clean::PathSegment { segments: vec!(clean::PathSegment {
@ -573,7 +550,7 @@ impl fmt::Show for clean::ViewListIdent {
types: Vec::new(), types: Vec::new(),
}) })
}; };
resolved_path(f.buf, did.node, &path, false) resolved_path(f.buf, did, &path, false)
} }
_ => write!(f.buf, "{}", self.name), _ => write!(f.buf, "{}", self.name),
} }

View file

@ -44,9 +44,9 @@ impl ItemType {
match *self { match *self {
Module => "mod", Module => "mod",
Struct => "struct", Struct => "struct",
Enum => "enum", Enum => "type",
Function => "fn", Function => "fn",
Typedef => "typedef", Typedef => "type",
Static => "static", Static => "static",
Trait => "trait", Trait => "trait",
Impl => "impl", Impl => "impl",

View file

@ -43,6 +43,7 @@ use std::strbuf::StrBuf;
use sync::Arc; use sync::Arc;
use serialize::json::ToJson; use serialize::json::ToJson;
use syntax::ast; use syntax::ast;
use syntax::ast_util;
use syntax::attr; use syntax::attr;
use syntax::parse::token::InternedString; use syntax::parse::token::InternedString;
use rustc::util::nodemap::NodeSet; use rustc::util::nodemap::NodeSet;
@ -50,13 +51,13 @@ use rustc::util::nodemap::NodeSet;
use clean; use clean;
use doctree; use doctree;
use fold::DocFolder; use fold::DocFolder;
use html::item_type;
use html::item_type::{ItemType, shortty};
use html::format::{VisSpace, Method, FnStyleSpace}; use html::format::{VisSpace, Method, FnStyleSpace};
use html::layout;
use html::markdown;
use html::markdown::Markdown;
use html::highlight; use html::highlight;
use html::item_type::{ItemType, shortty};
use html::item_type;
use html::layout;
use html::markdown::Markdown;
use html::markdown;
/// Major driving force in all rustdoc rendering. This contains information /// Major driving force in all rustdoc rendering. This contains information
/// about where in the tree-like hierarchy rendering is occurring and controls /// about where in the tree-like hierarchy rendering is occurring and controls
@ -138,7 +139,7 @@ pub struct Cache {
/// URLs when a type is being linked to. External paths are not located in /// URLs when a type is being linked to. External paths are not located in
/// this map because the `External` type itself has all the information /// this map because the `External` type itself has all the information
/// necessary. /// necessary.
pub paths: HashMap<ast::NodeId, (Vec<~str> , ItemType)>, pub paths: HashMap<ast::DefId, (Vec<~str>, ItemType)>,
/// This map contains information about all known traits of this crate. /// This map contains information about all known traits of this crate.
/// Implementations of a crate should inherit the documentation of the /// Implementations of a crate should inherit the documentation of the
@ -242,12 +243,26 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
} }
// Crawl the crate to build various caches used for the output // Crawl the crate to build various caches used for the output
let public_items = ::analysiskey.get().map(|a| a.public_items.clone()); let analysis = ::analysiskey.get();
let public_items = public_items.unwrap_or(NodeSet::new()); let public_items = analysis.as_ref().map(|a| a.public_items.clone());
let paths = analysis.as_ref().map(|a| {
let paths = a.external_paths.borrow_mut().take_unwrap();
paths.move_iter().map(|(k, (v, t))| {
(k, (v, match t {
clean::TypeStruct => item_type::Struct,
clean::TypeEnum => item_type::Enum,
clean::TypeFunction => item_type::Function,
clean::TypeTrait => item_type::Trait,
clean::TypeModule => item_type::Module,
clean::TypeStatic => item_type::Static,
clean::TypeVariant => item_type::Variant,
}))
}).collect()
}).unwrap_or(HashMap::new());
let mut cache = Cache { let mut cache = Cache {
impls: HashMap::new(), impls: HashMap::new(),
typarams: HashMap::new(), typarams: HashMap::new(),
paths: HashMap::new(), paths: paths,
traits: HashMap::new(), traits: HashMap::new(),
implementors: HashMap::new(), implementors: HashMap::new(),
stack: Vec::new(), stack: Vec::new(),
@ -255,7 +270,7 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
search_index: Vec::new(), search_index: Vec::new(),
extern_locations: HashMap::new(), extern_locations: HashMap::new(),
privmod: false, privmod: false,
public_items: public_items, public_items: public_items.unwrap_or(NodeSet::new()),
orphan_methods: Vec::new(), orphan_methods: Vec::new(),
}; };
cache.stack.push(krate.name.clone()); cache.stack.push(krate.name.clone());
@ -269,15 +284,16 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
// Attach all orphan methods to the type's definition if the type // Attach all orphan methods to the type's definition if the type
// has since been learned. // has since been learned.
for &(ref pid, ref item) in meths.iter() { for &(pid, ref item) in meths.iter() {
match paths.find(pid) { let did = ast_util::local_def(pid);
match paths.find(&did) {
Some(&(ref fqp, _)) => { Some(&(ref fqp, _)) => {
index.push(IndexItem { index.push(IndexItem {
ty: shortty(item), ty: shortty(item),
name: item.name.clone().unwrap(), name: item.name.clone().unwrap(),
path: fqp.slice_to(fqp.len() - 1).connect("::"), path: fqp.slice_to(fqp.len() - 1).connect("::"),
desc: shorter(item.doc_value()).to_owned(), desc: shorter(item.doc_value()).to_owned(),
parent: Some(*pid), parent: Some(pid),
}); });
}, },
None => {} None => {}
@ -336,7 +352,8 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
try!(write!(&mut w, r#"],"paths":["#)); try!(write!(&mut w, r#"],"paths":["#));
for (i, &nodeid) in pathid_to_nodeid.iter().enumerate() { for (i, &nodeid) in pathid_to_nodeid.iter().enumerate() {
let &(ref fqp, short) = cache.paths.find(&nodeid).unwrap(); let def = ast_util::local_def(nodeid);
let &(ref fqp, short) = cache.paths.find(&def).unwrap();
if i > 0 { if i > 0 {
try!(write!(&mut w, ",")); try!(write!(&mut w, ","));
} }
@ -414,6 +431,8 @@ pub fn run(mut krate: clean::Crate, dst: Path) -> io::IoResult<()> {
for &(n, ref e) in krate.externs.iter() { for &(n, ref e) in krate.externs.iter() {
cache.extern_locations.insert(n, extern_location(e, &cx.dst)); cache.extern_locations.insert(n, extern_location(e, &cx.dst));
let did = ast::DefId { krate: n, node: ast::CRATE_NODE_ID };
cache.paths.insert(did, (Vec::new(), item_type::Module));
} }
// And finally render the whole crate's documentation // And finally render the whole crate's documentation
@ -606,7 +625,12 @@ impl DocFolder for Cache {
match item.inner { match item.inner {
clean::ImplItem(ref i) => { clean::ImplItem(ref i) => {
match i.trait_ { match i.trait_ {
Some(clean::ResolvedPath{ id, .. }) => { // FIXME: this is_local() check seems to be losing
// information
Some(clean::ResolvedPath{ did, .. })
if ast_util::is_local(did) =>
{
let id = did.node;
let v = self.implementors.find_or_insert_with(id, |_|{ let v = self.implementors.find_or_insert_with(id, |_|{
Vec::new() Vec::new()
}); });
@ -643,7 +667,8 @@ impl DocFolder for Cache {
(None, None) (None, None)
} else { } else {
let last = self.parent_stack.last().unwrap(); let last = self.parent_stack.last().unwrap();
let path = match self.paths.find(last) { let did = ast_util::local_def(*last);
let path = match self.paths.find(&did) {
Some(&(_, item_type::Trait)) => Some(&(_, item_type::Trait)) =>
Some(self.stack.slice_to(self.stack.len() - 1)), Some(self.stack.slice_to(self.stack.len() - 1)),
// The current stack not necessarily has correlation for // The current stack not necessarily has correlation for
@ -699,10 +724,11 @@ impl DocFolder for Cache {
// a reexported item doesn't show up in the `public_items` map, // a reexported item doesn't show up in the `public_items` map,
// so we can skip inserting into the paths map if there was // so we can skip inserting into the paths map if there was
// already an entry present and we're not a public item. // already an entry present and we're not a public item.
if !self.paths.contains_key(&item.id) || let did = ast_util::local_def(item.id);
if !self.paths.contains_key(&did) ||
self.public_items.contains(&item.id) { self.public_items.contains(&item.id) {
self.paths.insert(item.id, self.paths.insert(did, (self.stack.clone(),
(self.stack.clone(), shortty(&item))); shortty(&item)));
} }
} }
// link variants to their parent enum because pages aren't emitted // link variants to their parent enum because pages aren't emitted
@ -710,7 +736,8 @@ impl DocFolder for Cache {
clean::VariantItem(..) => { clean::VariantItem(..) => {
let mut stack = self.stack.clone(); let mut stack = self.stack.clone();
stack.pop(); stack.pop();
self.paths.insert(item.id, (stack, item_type::Enum)); self.paths.insert(ast_util::local_def(item.id),
(stack, item_type::Enum));
} }
_ => {} _ => {}
} }
@ -722,8 +749,13 @@ impl DocFolder for Cache {
} }
clean::ImplItem(ref i) => { clean::ImplItem(ref i) => {
match i.for_ { match i.for_ {
clean::ResolvedPath{ id, .. } => { clean::ResolvedPath{ did, .. } => {
self.parent_stack.push(id); true if ast_util::is_local(did) {
self.parent_stack.push(did.node);
true
} else {
false
}
} }
_ => false _ => false
} }
@ -738,8 +770,10 @@ impl DocFolder for Cache {
match item { match item {
clean::Item{ attrs, inner: clean::ImplItem(i), .. } => { clean::Item{ attrs, inner: clean::ImplItem(i), .. } => {
match i.for_ { match i.for_ {
clean::ResolvedPath { id, .. } => { clean::ResolvedPath { did, .. }
let v = self.impls.find_or_insert_with(id, |_| { if ast_util::is_local(did) =>
{
let v = self.impls.find_or_insert_with(did.node, |_| {
Vec::new() Vec::new()
}); });
// extract relevant documentation for this impl // extract relevant documentation for this impl
@ -1596,7 +1630,7 @@ fn render_impl(w: &mut Writer, i: &clean::Impl,
Some(ref ty) => { Some(ref ty) => {
try!(write!(w, "{} for ", *ty)); try!(write!(w, "{} for ", *ty));
match *ty { match *ty {
clean::ResolvedPath { id, .. } => Some(id), clean::ResolvedPath { did, .. } => Some(did),
_ => None, _ => None,
} }
} }
@ -1635,9 +1669,10 @@ fn render_impl(w: &mut Writer, i: &clean::Impl,
// default methods which weren't overridden in the implementation block. // default methods which weren't overridden in the implementation block.
match trait_id { match trait_id {
None => {} None => {}
Some(id) => { // FIXME: this should work for non-local traits
Some(did) if ast_util::is_local(did) => {
try!({ try!({
match cache_key.get().unwrap().traits.find(&id) { match cache_key.get().unwrap().traits.find(&did.node) {
Some(t) => { Some(t) => {
for method in t.methods.iter() { for method in t.methods.iter() {
let n = method.item().name.clone(); let n = method.item().name.clone();
@ -1654,6 +1689,7 @@ fn render_impl(w: &mut Writer, i: &clean::Impl,
Ok(()) Ok(())
}) })
} }
Some(..) => {}
} }
try!(write!(w, "</div>")); try!(write!(w, "</div>"));
Ok(()) Ok(())

View file

@ -65,9 +65,10 @@ pub fn strip_hidden(krate: clean::Crate) -> plugins::PluginResult {
impl<'a> fold::DocFolder for ImplStripper<'a> { impl<'a> fold::DocFolder for ImplStripper<'a> {
fn fold_item(&mut self, i: Item) -> Option<Item> { fn fold_item(&mut self, i: Item) -> Option<Item> {
match i.inner { match i.inner {
clean::ImplItem(clean::Impl{ for_: clean::ResolvedPath{ id: for_id, .. }, clean::ImplItem(clean::Impl{
.. }) => { for_: clean::ResolvedPath{ did, .. }, ..
if self.stripped.contains(&for_id) { }) => {
if self.stripped.contains(&did.node) {
return None; return None;
} }
} }
@ -146,8 +147,10 @@ impl<'a> fold::DocFolder for Stripper<'a> {
clean::ModuleItem(..) => {} clean::ModuleItem(..) => {}
// trait impls for private items should be stripped // trait impls for private items should be stripped
clean::ImplItem(clean::Impl{ for_: clean::ResolvedPath{ id: ref for_id, .. }, .. }) => { clean::ImplItem(clean::Impl{
if !self.exported_items.contains(for_id) { for_: clean::ResolvedPath{ did, .. }, ..
}) => {
if !self.exported_items.contains(&did.node) {
return None; return None;
} }
} }
@ -201,9 +204,9 @@ impl<'a> fold::DocFolder for ImplStripper<'a> {
match i.inner { match i.inner {
clean::ImplItem(ref imp) => { clean::ImplItem(ref imp) => {
match imp.trait_ { match imp.trait_ {
Some(clean::ResolvedPath{ id, .. }) => { Some(clean::ResolvedPath{ did, .. }) => {
let ImplStripper(s) = *self; let ImplStripper(s) = *self;
if !s.contains(&id) { if !s.contains(&did.node) {
return None; return None;
} }
} }

View file

@ -16,7 +16,7 @@ use std::os;
use std::str; use std::str;
use std::strbuf::StrBuf; use std::strbuf::StrBuf;
use collections::HashSet; use collections::{HashSet, HashMap};
use testing; use testing;
use rustc::back::link; use rustc::back::link;
use rustc::driver::driver; use rustc::driver::driver;
@ -73,6 +73,7 @@ pub fn run(input: &str,
krate: krate, krate: krate,
maybe_typed: core::NotTyped(sess), maybe_typed: core::NotTyped(sess),
src: input_path, src: input_path,
external_paths: RefCell::new(Some(HashMap::new())),
}; };
super::ctxtkey.replace(Some(ctx)); super::ctxtkey.replace(Some(ctx));

View file

@ -16,11 +16,11 @@
//! //!
//! ## Intrinsic types and operations //! ## Intrinsic types and operations
//! //!
//! The [`ptr`](ptr/index.html), [`mem`](mem/index.html), //! The [`ptr`](../core/ptr/index.html), [`mem`](../core/mem/index.html),
//! and [`cast`](cast/index.html) modules deal with unsafe pointers, //! and [`cast`](../core/cast/index.html) modules deal with unsafe pointers,
//! memory manipulation, and coercion. //! memory manipulation, and coercion.
//! [`kinds`](kinds/index.html) defines the special built-in traits, //! [`kinds`](../core/kinds/index.html) defines the special built-in traits,
//! and [`raw`](raw/index.html) the runtime representation of Rust types. //! and [`raw`](../core/raw/index.html) the runtime representation of Rust types.
//! These are some of the lowest-level building blocks of Rust //! These are some of the lowest-level building blocks of Rust
//! abstractions. //! abstractions.
//! //!
@ -35,9 +35,9 @@
//! //!
//! The [`option`](option/index.html) and [`result`](result/index.html) //! The [`option`](option/index.html) and [`result`](result/index.html)
//! modules define optional and error-handling types, `Option` and `Result`. //! modules define optional and error-handling types, `Option` and `Result`.
//! [`iter`](iter/index.html) defines Rust's iterator protocol //! [`iter`](../core/iter/index.html) defines Rust's iterator protocol
//! along with a wide variety of iterators. //! along with a wide variety of iterators.
//! [`Cell` and `RefCell`](cell/index.html) are for creating types that //! [`Cell` and `RefCell`](../core/cell/index.html) are for creating types that
//! manage their own mutability. //! manage their own mutability.
//! //!
//! ## Vectors, slices and strings //! ## Vectors, slices and strings

View file

@ -226,8 +226,8 @@
//! similar and complementary: they are often employed to indicate a //! similar and complementary: they are often employed to indicate a
//! lack of a return value; and they are trivially converted between //! lack of a return value; and they are trivially converted between
//! each other, so `Result`s are often handled by first converting to //! each other, so `Result`s are often handled by first converting to
//! `Option` with the [`ok`](enum.Result.html#method.ok) and //! `Option` with the [`ok`](../../core/result/enum.Result.html#method.ok) and
//! [`err`](enum.Result.html#method.ok) methods. //! [`err`](../../core/result/enum.Result.html#method.ok) methods.
//! //!
//! Whereas `Option` only indicates the lack of a value, `Result` is //! Whereas `Option` only indicates the lack of a value, `Result` is
//! specifically for error reporting, and carries with it an error //! specifically for error reporting, and carries with it an error