diff --git a/src/librustc/middle/ty.rs b/src/librustc/middle/ty.rs index e5bbd01dde6..06fb9106b19 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; @@ -5089,25 +5089,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", diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 519292fa9e0..6e79bd9bebd 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); @@ -311,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 e1090391236..7c7db97951e 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; @@ -116,7 +115,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, @@ -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, @@ -198,7 +204,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 +237,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 +313,7 @@ impl Item { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub enum ItemEnum { StructItem(Struct), EnumItem(Enum), @@ -336,7 +342,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 +944,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 +983,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 +1021,7 @@ impl Clean for ast::TypeMethod { } } -#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq)] +#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Show)] pub enum SelfTy { SelfStatic, SelfValue, @@ -1036,7 +1042,7 @@ impl Clean for ast::ExplicitSelf_ { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct Function { pub decl: FnDecl, pub generics: Generics, @@ -1155,7 +1161,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, @@ -1199,11 +1205,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 { @@ -1244,7 +1250,7 @@ impl Clean for ast::TraitItem { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub enum ImplMethod { MethodImplItem(Item), TypeImplItem(Item), @@ -1380,7 +1386,7 @@ pub enum PrimitiveType { PrimitiveTuple, } -#[derive(Clone, RustcEncodable, RustcDecodable, Copy)] +#[derive(Clone, RustcEncodable, RustcDecodable, Copy, Show)] pub enum TypeKind { TypeEnum, TypeFunction, @@ -1623,7 +1629,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), @@ -1682,7 +1688,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, @@ -1712,7 +1718,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, @@ -1729,7 +1735,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, @@ -1754,7 +1760,7 @@ impl Clean for doctree::Enum { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct Variant { pub kind: VariantKind, } @@ -1822,7 +1828,7 @@ impl<'tcx> Clean for ty::VariantInfo<'tcx> { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub enum VariantKind { CLikeVariant, TupleVariant(Vec), @@ -1969,7 +1975,7 @@ impl Clean for ast::Name { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct Typedef { pub type_: Type, pub generics: Generics, @@ -2082,7 +2088,7 @@ impl Clean for ast::Mutability { } } -#[derive(Show, Clone, RustcEncodable, RustcDecodable, PartialEq, Copy)] +#[derive(Show, Clone, RustcEncodable, RustcDecodable, PartialEq, Copy, Show)] pub enum ImplPolarity { Positive, Negative, @@ -2097,7 +2103,7 @@ impl Clean for ast::ImplPolarity { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct Impl { pub generics: Generics, pub trait_: Option, @@ -2137,7 +2143,7 @@ impl Clean for doctree::Impl { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct ViewItem { pub inner: ViewItemInner, } @@ -2203,7 +2209,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) @@ -2226,7 +2232,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), @@ -2236,7 +2242,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, @@ -2257,7 +2263,7 @@ impl Clean for ast::ViewPath { } } -#[derive(Clone, RustcEncodable, RustcDecodable)] +#[derive(Clone, RustcEncodable, RustcDecodable, Show)] pub struct ViewListIdent { pub name: String, pub source: Option, @@ -2476,7 +2482,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, } @@ -2497,7 +2503,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 @@ -2533,14 +2539,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, }), @@ -2572,6 +2578,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 { diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 5bef0195874..04947e41663 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -12,7 +12,6 @@ pub use self::MaybeTyped::*; use rustc_driver::driver; use rustc::session::{self, config}; use rustc::session::config::UnstableFeatures; -use rustc::session::search_paths::SearchPaths; 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>), @@ -39,7 +41,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 +82,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 +112,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 +140,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 71bd53009af..db17c7014c2 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -351,8 +351,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 9b8d220acc3..7f1bd9e6d59 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),