From 7b4c50821a62bd6cd0df6810cd07db363bd003ac Mon Sep 17 00:00:00 2001 From: Tom Jakubowski Date: Wed, 14 Jan 2015 05:51:56 -0800 Subject: [PATCH 1/6] rustdoc: Add Show impls to more clean types --- src/librustdoc/clean/mod.rs | 58 ++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 29 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 8dc3adad3b27..c3cd81d3a95f 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -116,7 +116,7 @@ impl, U> Clean> for syntax::owned_slice::OwnedSlice { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct Crate { pub name: String, pub src: FsPath, @@ -198,7 +198,7 @@ impl<'a, 'tcx> Clean for visit_ast::RustdocVisitor<'a, 'tcx> { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct ExternalCrate { pub name: String, pub attrs: Vec, @@ -231,7 +231,7 @@ impl Clean for cstore::crate_metadata { /// Anything with a source location and set of attributes and, optionally, a /// name. That is, anything that can be documented. This doesn't correspond /// directly to the AST's concept of an item; it's a strict superset. -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct Item { /// Stringified span pub source: Span, @@ -307,7 +307,7 @@ impl Item { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub enum ItemEnum { StructItem(Struct), EnumItem(Enum), @@ -336,7 +336,7 @@ pub enum ItemEnum { AssociatedTypeItem(TyParam), } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct Module { pub items: Vec, pub is_crate: bool, @@ -938,7 +938,7 @@ impl<'a, 'tcx> Clean for (&'a ty::Generics<'tcx>, subst::ParamSpace) { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct Method { pub generics: Generics, pub self_: SelfTy, @@ -977,7 +977,7 @@ impl Clean for ast::Method { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct TyMethod { pub unsafety: ast::Unsafety, pub decl: FnDecl, @@ -1015,7 +1015,7 @@ impl Clean for ast::TypeMethod { } } -#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq)] +#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Show)] pub enum SelfTy { SelfStatic, SelfValue, @@ -1036,7 +1036,7 @@ impl Clean for ast::ExplicitSelf_ { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct Function { pub decl: FnDecl, pub generics: Generics, @@ -1153,7 +1153,7 @@ impl Clean for ast::FunctionRetTy { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct Trait { pub unsafety: ast::Unsafety, pub items: Vec, @@ -1197,11 +1197,11 @@ impl Clean for ast::PolyTraitRef { /// An item belonging to a trait, whether a method or associated. Could be named /// TraitItem except that's already taken by an exported enum variant. -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub enum TraitMethod { RequiredMethod(Item), ProvidedMethod(Item), - TypeTraitItem(Item), + TypeTraitItem(Item), // an associated type } impl TraitMethod { @@ -1242,7 +1242,7 @@ impl Clean for ast::TraitItem { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub enum ImplMethod { MethodImplItem(Item), TypeImplItem(Item), @@ -1378,7 +1378,7 @@ pub enum PrimitiveType { PrimitiveTuple, } -#[derive(Clone, RustcEncodable, RustcDecodable, Copy)] +#[derive(Clone, RustcEncodable, RustcDecodable, Copy, Show)] pub enum TypeKind { TypeEnum, TypeFunction, @@ -1621,7 +1621,7 @@ impl Clean for ast::QPath { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub enum StructField { HiddenStructField, // inserted later by strip passes TypedStructField(Type), @@ -1680,7 +1680,7 @@ impl Clean> for ast::Visibility { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct Struct { pub struct_type: doctree::StructType, pub generics: Generics, @@ -1710,7 +1710,7 @@ impl Clean for doctree::Struct { /// This is a more limited form of the standard Struct, different in that /// it lacks the things most items have (name, id, parameterization). Found /// only as a variant in an enum. -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct VariantStruct { pub struct_type: doctree::StructType, pub fields: Vec, @@ -1727,7 +1727,7 @@ impl Clean for syntax::ast::StructDef { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct Enum { pub variants: Vec, pub generics: Generics, @@ -1752,7 +1752,7 @@ impl Clean for doctree::Enum { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct Variant { pub kind: VariantKind, } @@ -1820,7 +1820,7 @@ impl<'tcx> Clean for ty::VariantInfo<'tcx> { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub enum VariantKind { CLikeVariant, TupleVariant(Vec), @@ -1967,7 +1967,7 @@ impl Clean for ast::Name { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct Typedef { pub type_: Type, pub generics: Generics, @@ -2080,7 +2080,7 @@ impl Clean for ast::Mutability { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct Impl { pub generics: Generics, pub trait_: Option, @@ -2118,7 +2118,7 @@ impl Clean for doctree::Impl { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct ViewItem { pub inner: ViewItemInner, } @@ -2184,7 +2184,7 @@ impl Clean> for ast::ViewItem { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub enum ViewItemInner { ExternCrate(String, Option, ast::NodeId), Import(ViewPath) @@ -2207,7 +2207,7 @@ impl Clean for ast::ViewItem_ { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub enum ViewPath { // use source as str; SimpleImport(String, ImportSource), @@ -2217,7 +2217,7 @@ pub enum ViewPath { ImportList(ImportSource, Vec), } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct ImportSource { pub path: Path, pub did: Option, @@ -2238,7 +2238,7 @@ impl Clean for ast::ViewPath { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct ViewListIdent { pub name: String, pub source: Option, @@ -2457,7 +2457,7 @@ fn resolve_def(cx: &DocContext, id: ast::NodeId) -> Option { }) } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct Macro { pub source: String, } @@ -2478,7 +2478,7 @@ impl Clean for doctree::Macro { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct Stability { pub level: attr::StabilityLevel, pub text: String From d47a11353d2c254d4644b998b81779887e525bee Mon Sep 17 00:00:00 2001 From: Tom Jakubowski Date: Wed, 14 Jan 2015 06:32:43 -0800 Subject: [PATCH 2/6] Remove some dead code from rustc::middle::ty --- src/librustc/middle/ty.rs | 21 +-------------------- 1 file changed, 1 insertion(+), 20 deletions(-) diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index c72fbc745651..e3b57b781906 100644 --- a/src/librustc/middle/ty.rs +++ b/src/librustc/middle/ty.rs @@ -70,7 +70,7 @@ use util::nodemap::{FnvHashMap}; use arena::TypedArena; use std::borrow::{BorrowFrom, Cow}; use std::cell::{Cell, RefCell}; -use std::cmp::{self, Ordering}; +use std::cmp; use std::fmt::{self, Show}; use std::hash::{Hash, Writer, SipHasher, Hasher}; use std::mem; @@ -5096,25 +5096,6 @@ pub fn associated_type_parameter_index(cx: &ctxt, cx.sess.bug("couldn't find associated type parameter index") } -#[derive(Copy, PartialEq, Eq)] -pub struct AssociatedTypeInfo { - pub def_id: ast::DefId, - pub index: uint, - pub name: ast::Name, -} - -impl PartialOrd for AssociatedTypeInfo { - fn partial_cmp(&self, other: &AssociatedTypeInfo) -> Option { - Some(self.index.cmp(&other.index)) - } -} - -impl Ord for AssociatedTypeInfo { - fn cmp(&self, other: &AssociatedTypeInfo) -> Ordering { - self.index.cmp(&other.index) - } -} - pub fn trait_item_def_ids(cx: &ctxt, id: ast::DefId) -> Rc> { lookup_locally_or_in_crate_store("trait_item_def_ids", From aaf595eab9e57c7c2f301fb0e4054a03df23324d Mon Sep 17 00:00:00 2001 From: Tom Jakubowski Date: Wed, 14 Jan 2015 07:28:37 -0800 Subject: [PATCH 3/6] rustdoc: Separate associated types from methods Fix #21142 --- src/librustdoc/clean/inline.rs | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index ccaefadc1fcd..432748b40e43 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -147,14 +147,22 @@ pub fn record_extern_fqn(cx: &DocContext, did: ast::DefId, kind: clean::TypeKind pub fn build_external_trait(cx: &DocContext, tcx: &ty::ctxt, did: ast::DefId) -> clean::Trait { + use clean::TraitMethod; + let def = ty::lookup_trait_def(tcx, did); let trait_items = ty::trait_items(tcx, did).clean(cx); let provided = ty::provided_trait_methods(tcx, did); let items = trait_items.into_iter().map(|trait_item| { - if provided.iter().any(|a| a.def_id == trait_item.def_id) { - clean::ProvidedMethod(trait_item) - } else { - clean::RequiredMethod(trait_item) + match trait_item.inner { + clean::TyMethodItem(_) => { + if provided.iter().any(|a| a.def_id == trait_item.def_id) { + TraitMethod::ProvidedMethod(trait_item) + } else { + TraitMethod::RequiredMethod(trait_item) + } + }, + clean::AssociatedTypeItem(_) => TraitMethod::TypeTraitItem(trait_item), + _ => unreachable!() } }); let trait_def = ty::lookup_trait_def(tcx, did); From e930aeb32b82181e3941c1c9f149057ac3a56537 Mon Sep 17 00:00:00 2001 From: Tom Jakubowski Date: Sat, 17 Jan 2015 21:02:31 -0800 Subject: [PATCH 4/6] rustdoc: Accept string source in core::run_core This is wanted by external tooling that uses rustdoc. There are likely some bugs when actually generating HTML output (which may expect to be able to read the source) but all I need for now is the cleaned crate and analysis. --- src/librustdoc/clean/mod.rs | 14 ++++++++++---- src/librustdoc/core.rs | 16 +++++++++------- src/librustdoc/lib.rs | 4 +++- src/librustdoc/test.rs | 2 +- 4 files changed, 23 insertions(+), 13 deletions(-) diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index c3cd81d3a95f..a522cbf72fa9 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -45,7 +45,6 @@ use rustc::middle::def; use rustc::middle::subst::{self, ParamSpace, VecPerParamSpace}; use rustc::middle::ty; use rustc::middle::stability; -use rustc::session::config; use std::rc::Rc; use std::u32; @@ -127,6 +126,8 @@ pub struct Crate { impl<'a, 'tcx> Clean for visit_ast::RustdocVisitor<'a, 'tcx> { fn clean(&self, cx: &DocContext) -> Crate { + use rustc::session::config::Input; + let mut externs = Vec::new(); cx.sess().cstore.iter_crate_data(|n, meta| { externs.push((n, meta.clean(cx))); @@ -134,8 +135,8 @@ impl<'a, 'tcx> Clean for visit_ast::RustdocVisitor<'a, 'tcx> { externs.sort_by(|&(a, _), &(b, _)| a.cmp(&b)); // Figure out the name of this crate - let input = config::Input::File(cx.src.clone()); - let name = link::find_crate_name(None, self.attrs.as_slice(), &input); + let input = &cx.input; + let name = link::find_crate_name(None, self.attrs.as_slice(), input); // Clean the crate, translating the entire libsyntax AST to one that is // understood by rustdoc. @@ -188,9 +189,14 @@ impl<'a, 'tcx> Clean for visit_ast::RustdocVisitor<'a, 'tcx> { m.items.extend(tmp.into_iter()); } + let src = match cx.input { + Input::File(ref path) => path.clone(), + Input::Str(_) => FsPath::new("") // FIXME: this is wrong + }; + Crate { name: name.to_string(), - src: cx.src.clone(), + src: src, module: Some(module), externs: externs, primitives: primitives, diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 5bef0195874b..437ff6664978 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -11,7 +11,7 @@ pub use self::MaybeTyped::*; use rustc_driver::driver; use rustc::session::{self, config}; -use rustc::session::config::UnstableFeatures; +use rustc::session::config::{Input, UnstableFeatures}; use rustc::session::search_paths::SearchPaths; use rustc::middle::{privacy, ty}; use rustc::lint; @@ -39,7 +39,7 @@ pub type ExternalPaths = RefCell { pub krate: &'tcx ast::Crate, pub maybe_typed: MaybeTyped<'tcx>, - pub src: Path, + pub input: Input, pub external_paths: ExternalPaths, pub external_traits: RefCell>>, pub external_typarams: RefCell>>, @@ -80,12 +80,15 @@ pub struct CrateAnalysis { pub type Externs = HashMap>; pub fn run_core(search_paths: SearchPaths, cfgs: Vec, externs: Externs, - cpath: &Path, triple: Option) + input: Input, triple: Option) -> (clean::Crate, CrateAnalysis) { // Parse, resolve, and typecheck the given crate. - let input = config::Input::File(cpath.clone()); + let cpath = match input { + Input::File(ref p) => Some(p.clone()), + _ => None + }; let warning_lint = lint::builtin::WARNINGS.name_lower(); @@ -107,8 +110,7 @@ pub fn run_core(search_paths: SearchPaths, cfgs: Vec, externs: Externs, let span_diagnostic_handler = diagnostic::mk_span_handler(diagnostic_handler, codemap); - let sess = session::build_session_(sessopts, - Some(cpath.clone()), + let sess = session::build_session_(sessopts, cpath, span_diagnostic_handler); let cfg = config::build_configuration(&sess); @@ -136,7 +138,7 @@ pub fn run_core(search_paths: SearchPaths, cfgs: Vec, externs: Externs, let ctxt = DocContext { krate: ty_cx.map.krate(), maybe_typed: Typed(ty_cx), - src: cpath.clone(), + input: input, external_traits: RefCell::new(Some(HashMap::new())), external_typarams: RefCell::new(Some(HashMap::new())), external_paths: RefCell::new(Some(HashMap::new())), diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index e6eed4806338..11135ed436ea 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -350,8 +350,10 @@ fn rust_input(cratefile: &str, externs: core::Externs, matches: &getopts::Matche info!("starting to run rustc"); let (mut krate, analysis) = std::thread::Thread::scoped(move |:| { + use rustc::session::config::Input; + let cr = cr; - core::run_core(paths, cfgs, externs, &cr, triple) + core::run_core(paths, cfgs, externs, Input::File(cr), triple) }).join().map_err(|_| "rustc failed").unwrap(); info!("finished with rustc"); let mut analysis = Some(analysis); diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 9b8d220acc39..7f1bd9e6d596 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -79,7 +79,7 @@ pub fn run(input: &str, let ctx = core::DocContext { krate: &krate, maybe_typed: core::NotTyped(sess), - src: input_path, + input: input, external_paths: RefCell::new(Some(HashMap::new())), external_traits: RefCell::new(None), external_typarams: RefCell::new(None), From 8224e0ed3d65748df4e3a89a1076ffae629e2acb Mon Sep 17 00:00:00 2001 From: Tom Jakubowski Date: Sat, 17 Jan 2015 21:23:05 -0800 Subject: [PATCH 5/6] rustdoc: Add some re-exports --- src/librustdoc/core.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 437ff6664978..04947e41663e 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -11,8 +11,7 @@ pub use self::MaybeTyped::*; use rustc_driver::driver; use rustc::session::{self, config}; -use rustc::session::config::{Input, UnstableFeatures}; -use rustc::session::search_paths::SearchPaths; +use rustc::session::config::UnstableFeatures; use rustc::middle::{privacy, ty}; use rustc::lint; use rustc_trans::back::link; @@ -27,6 +26,9 @@ use visit_ast::RustdocVisitor; use clean; use clean::Clean; +pub use rustc::session::config::Input; +pub use rustc::session::search_paths::SearchPaths; + /// Are we generating documentation (`Typed`) or tests (`NotTyped`)? pub enum MaybeTyped<'tcx> { Typed(ty::ctxt<'tcx>), From 159236a63b64fec9aec6e1d36ee4e1c811747240 Mon Sep 17 00:00:00 2001 From: Tom Jakubowski Date: Sat, 17 Jan 2015 22:39:01 -0800 Subject: [PATCH 6/6] rustdoc: Handle associated types on inlined impls Fix #21348 --- src/librustdoc/clean/inline.rs | 18 +++++++++++++++--- src/librustdoc/clean/mod.rs | 14 ++++++++++++-- 2 files changed, 27 insertions(+), 5 deletions(-) diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 432748b40e43..21e0fee33dda 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -319,9 +319,21 @@ fn build_impl(cx: &DocContext, tcx: &ty::ctxt, }; Some(item) } - ty::TypeTraitItem(_) => { - // FIXME(pcwalton): Implement. - None + ty::TypeTraitItem(ref assoc_ty) => { + let did = assoc_ty.def_id; + let type_scheme = ty::lookup_item_type(tcx, did); + // Not sure the choice of ParamSpace actually matters here, because an + // associated type won't have generics on the LHS + let typedef = (type_scheme, subst::ParamSpace::TypeSpace).clean(cx); + Some(clean::Item { + name: Some(assoc_ty.name.clean(cx)), + inner: clean::TypedefItem(typedef), + source: clean::Span::empty(), + attrs: vec![], + visibility: None, + stability: stability::lookup(tcx, did).clean(cx), + def_id: did + }) } } }).collect(); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index a522cbf72fa9..0d82efbdbdea 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -2520,14 +2520,14 @@ impl Clean for ty::AssociatedType { source: DUMMY_SP.clean(cx), name: Some(self.name.clean(cx)), attrs: Vec::new(), - // FIXME(#18048): this is wrong, but cross-crate associated types are broken - // anyway, for the time being. inner: AssociatedTypeItem(TyParam { name: self.name.clean(cx), did: ast::DefId { krate: 0, node: ast::DUMMY_NODE_ID }, + // FIXME(#20727): bounds are missing and need to be filled in from the + // predicates on the trait itself bounds: vec![], default: None, }), @@ -2559,6 +2559,16 @@ impl Clean for ast::Typedef { } } +impl<'a> Clean for (ty::TypeScheme<'a>, ParamSpace) { + fn clean(&self, cx: &DocContext) -> Typedef { + let (ref ty_scheme, ps) = *self; + Typedef { + type_: ty_scheme.ty.clean(cx), + generics: (&ty_scheme.generics, ps).clean(cx) + } + } +} + fn lang_struct(cx: &DocContext, did: Option, t: ty::Ty, name: &str, fallback: fn(Box) -> Type) -> Type {