From 81e549cc76813acd718497e357e0f15ab73463cf Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Tue, 3 Dec 2019 22:14:48 +0100 Subject: [PATCH] remove code that doesn't belong in clean/types.rs --- src/librustdoc/clean/types.rs | 2975 --------------------------------- 1 file changed, 2975 deletions(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 4d8d0040cdc..94c6f2a66b7 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -67,61 +67,6 @@ thread_local!(pub static MAX_DEF_ID: RefCell> = Defau const FN_OUTPUT_NAME: &'static str = "Output"; -// extract the stability index for a node from tcx, if possible -fn get_stability(cx: &DocContext<'_>, def_id: DefId) -> Option { - cx.tcx.lookup_stability(def_id).clean(cx) -} - -fn get_deprecation(cx: &DocContext<'_>, def_id: DefId) -> Option { - cx.tcx.lookup_deprecation(def_id).clean(cx) -} - -pub trait Clean { - fn clean(&self, cx: &DocContext<'_>) -> T; -} - -impl, U> Clean> for [T] { - fn clean(&self, cx: &DocContext<'_>) -> Vec { - self.iter().map(|x| x.clean(cx)).collect() - } -} - -impl, U, V: Idx> Clean> for IndexVec { - fn clean(&self, cx: &DocContext<'_>) -> IndexVec { - self.iter().map(|x| x.clean(cx)).collect() - } -} - -impl, U> Clean for P { - fn clean(&self, cx: &DocContext<'_>) -> U { - (**self).clean(cx) - } -} - -impl, U> Clean for Rc { - fn clean(&self, cx: &DocContext<'_>) -> U { - (**self).clean(cx) - } -} - -impl, U> Clean> for Option { - fn clean(&self, cx: &DocContext<'_>) -> Option { - self.as_ref().map(|v| v.clean(cx)) - } -} - -impl Clean for ty::Binder where T: Clean { - fn clean(&self, cx: &DocContext<'_>) -> U { - self.skip_binder().clean(cx) - } -} - -impl, U> Clean> for P<[T]> { - fn clean(&self, cx: &DocContext<'_>) -> Vec { - self.iter().map(|x| x.clean(cx)).collect() - } -} - #[derive(Clone, Debug)] pub struct Crate { pub name: String, @@ -137,91 +82,6 @@ pub struct Crate { pub collapsed: bool, } -pub fn krate(mut cx: &mut DocContext<'_>) -> Crate { - use crate::visit_lib::LibEmbargoVisitor; - - let krate = cx.tcx.hir().krate(); - let module = crate::visit_ast::RustdocVisitor::new(&mut cx).visit(krate); - - let mut r = cx.renderinfo.get_mut(); - r.deref_trait_did = cx.tcx.lang_items().deref_trait(); - r.deref_mut_trait_did = cx.tcx.lang_items().deref_mut_trait(); - r.owned_box_did = cx.tcx.lang_items().owned_box(); - - let mut externs = Vec::new(); - for &cnum in cx.tcx.crates().iter() { - externs.push((cnum, cnum.clean(cx))); - // Analyze doc-reachability for extern items - LibEmbargoVisitor::new(&mut cx).visit_lib(cnum); - } - externs.sort_by(|&(a, _), &(b, _)| a.cmp(&b)); - - // Clean the crate, translating the entire libsyntax AST to one that is - // understood by rustdoc. - let mut module = module.clean(cx); - let mut masked_crates = FxHashSet::default(); - - match module.inner { - ModuleItem(ref module) => { - for it in &module.items { - // `compiler_builtins` should be masked too, but we can't apply - // `#[doc(masked)]` to the injected `extern crate` because it's unstable. - if it.is_extern_crate() - && (it.attrs.has_doc_flag(sym::masked) - || cx.tcx.is_compiler_builtins(it.def_id.krate)) - { - masked_crates.insert(it.def_id.krate); - } - } - } - _ => unreachable!(), - } - - let ExternalCrate { name, src, primitives, keywords, .. } = LOCAL_CRATE.clean(cx); - { - let m = match module.inner { - ModuleItem(ref mut m) => m, - _ => unreachable!(), - }; - m.items.extend(primitives.iter().map(|&(def_id, prim, ref attrs)| { - Item { - source: Span::empty(), - name: Some(prim.to_url_str().to_string()), - attrs: attrs.clone(), - visibility: Public, - stability: get_stability(cx, def_id), - deprecation: get_deprecation(cx, def_id), - def_id, - inner: PrimitiveItem(prim), - } - })); - m.items.extend(keywords.into_iter().map(|(def_id, kw, attrs)| { - Item { - source: Span::empty(), - name: Some(kw.clone()), - attrs, - visibility: Public, - stability: get_stability(cx, def_id), - deprecation: get_deprecation(cx, def_id), - def_id, - inner: KeywordItem(kw), - } - })); - } - - Crate { - name, - version: None, - src, - module: Some(module), - externs, - primitives, - external_traits: cx.external_traits.clone(), - masked_crates, - collapsed: false, - } -} - #[derive(Clone, Debug)] pub struct ExternalCrate { pub name: String, @@ -231,126 +91,6 @@ pub struct ExternalCrate { pub keywords: Vec<(DefId, String, Attributes)>, } -impl Clean for CrateNum { - fn clean(&self, cx: &DocContext<'_>) -> ExternalCrate { - let root = DefId { krate: *self, index: CRATE_DEF_INDEX }; - let krate_span = cx.tcx.def_span(root); - let krate_src = cx.sess().source_map().span_to_filename(krate_span); - - // Collect all inner modules which are tagged as implementations of - // primitives. - // - // Note that this loop only searches the top-level items of the crate, - // and this is intentional. If we were to search the entire crate for an - // item tagged with `#[doc(primitive)]` then we would also have to - // search the entirety of external modules for items tagged - // `#[doc(primitive)]`, which is a pretty inefficient process (decoding - // all that metadata unconditionally). - // - // In order to keep the metadata load under control, the - // `#[doc(primitive)]` feature is explicitly designed to only allow the - // primitive tags to show up as the top level items in a crate. - // - // Also note that this does not attempt to deal with modules tagged - // duplicately for the same primitive. This is handled later on when - // rendering by delegating everything to a hash map. - let as_primitive = |res: Res| { - if let Res::Def(DefKind::Mod, def_id) = res { - let attrs = cx.tcx.get_attrs(def_id).clean(cx); - let mut prim = None; - for attr in attrs.lists(sym::doc) { - if let Some(v) = attr.value_str() { - if attr.check_name(sym::primitive) { - prim = PrimitiveType::from_str(&v.as_str()); - if prim.is_some() { - break; - } - // FIXME: should warn on unknown primitives? - } - } - } - return prim.map(|p| (def_id, p, attrs)); - } - None - }; - let primitives = if root.is_local() { - cx.tcx.hir().krate().module.item_ids.iter().filter_map(|&id| { - let item = cx.tcx.hir().expect_item(id.id); - match item.kind { - hir::ItemKind::Mod(_) => { - as_primitive(Res::Def( - DefKind::Mod, - cx.tcx.hir().local_def_id(id.id), - )) - } - hir::ItemKind::Use(ref path, hir::UseKind::Single) - if item.vis.node.is_pub() => { - as_primitive(path.res).map(|(_, prim, attrs)| { - // Pretend the primitive is local. - (cx.tcx.hir().local_def_id(id.id), prim, attrs) - }) - } - _ => None - } - }).collect() - } else { - cx.tcx.item_children(root).iter().map(|item| item.res) - .filter_map(as_primitive).collect() - }; - - let as_keyword = |res: Res| { - if let Res::Def(DefKind::Mod, def_id) = res { - let attrs = cx.tcx.get_attrs(def_id).clean(cx); - let mut keyword = None; - for attr in attrs.lists(sym::doc) { - if let Some(v) = attr.value_str() { - if attr.check_name(sym::keyword) { - if v.is_doc_keyword() { - keyword = Some(v.to_string()); - break; - } - // FIXME: should warn on unknown keywords? - } - } - } - return keyword.map(|p| (def_id, p, attrs)); - } - None - }; - let keywords = if root.is_local() { - cx.tcx.hir().krate().module.item_ids.iter().filter_map(|&id| { - let item = cx.tcx.hir().expect_item(id.id); - match item.kind { - hir::ItemKind::Mod(_) => { - as_keyword(Res::Def( - DefKind::Mod, - cx.tcx.hir().local_def_id(id.id), - )) - } - hir::ItemKind::Use(ref path, hir::UseKind::Single) - if item.vis.node.is_pub() => { - as_keyword(path.res).map(|(_, prim, attrs)| { - (cx.tcx.hir().local_def_id(id.id), prim, attrs) - }) - } - _ => None - } - }).collect() - } else { - cx.tcx.item_children(root).iter().map(|item| item.res) - .filter_map(as_keyword).collect() - }; - - ExternalCrate { - name: cx.tcx.crate_name(*self).to_string(), - src: krate_src, - attrs: cx.tcx.get_attrs(root).clean(cx), - primitives, - keywords, - } - } -} - /// 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. @@ -582,69 +322,6 @@ pub struct Module { pub is_crate: bool, } -impl Clean for doctree::Module<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Item { - let name = if self.name.is_some() { - self.name.expect("No name provided").clean(cx) - } else { - String::new() - }; - - // maintain a stack of mod ids, for doc comment path resolution - // but we also need to resolve the module's own docs based on whether its docs were written - // inside or outside the module, so check for that - let attrs = self.attrs.clean(cx); - - let mut items: Vec = vec![]; - items.extend(self.extern_crates.iter().flat_map(|x| x.clean(cx))); - items.extend(self.imports.iter().flat_map(|x| x.clean(cx))); - items.extend(self.structs.iter().map(|x| x.clean(cx))); - items.extend(self.unions.iter().map(|x| x.clean(cx))); - items.extend(self.enums.iter().map(|x| x.clean(cx))); - items.extend(self.fns.iter().map(|x| x.clean(cx))); - items.extend(self.foreigns.iter().map(|x| x.clean(cx))); - items.extend(self.mods.iter().map(|x| x.clean(cx))); - items.extend(self.typedefs.iter().map(|x| x.clean(cx))); - items.extend(self.opaque_tys.iter().map(|x| x.clean(cx))); - items.extend(self.statics.iter().map(|x| x.clean(cx))); - items.extend(self.constants.iter().map(|x| x.clean(cx))); - items.extend(self.traits.iter().map(|x| x.clean(cx))); - items.extend(self.impls.iter().flat_map(|x| x.clean(cx))); - items.extend(self.macros.iter().map(|x| x.clean(cx))); - items.extend(self.proc_macros.iter().map(|x| x.clean(cx))); - items.extend(self.trait_aliases.iter().map(|x| x.clean(cx))); - - // determine if we should display the inner contents or - // the outer `mod` item for the source code. - let whence = { - let cm = cx.sess().source_map(); - let outer = cm.lookup_char_pos(self.where_outer.lo()); - let inner = cm.lookup_char_pos(self.where_inner.lo()); - if outer.file.start_pos == inner.file.start_pos { - // mod foo { ... } - self.where_outer - } else { - // mod foo; (and a separate SourceFile for the contents) - self.where_inner - } - }; - - Item { - name: Some(name), - attrs, - source: whence.clean(cx), - visibility: self.vis.clean(cx), - stability: cx.stability(self.id).clean(cx), - deprecation: cx.deprecation(self.id).clean(cx), - def_id: cx.tcx.hir().local_def_id(self.id), - inner: ModuleItem(Module { - is_crate: self.is_crate, - items, - }) - } - } -} - pub struct ListAttributesIter<'a> { attrs: slice::Iter<'a, ast::Attribute>, current_list: vec::IntoIter, @@ -1048,12 +725,6 @@ impl AttributesExt for Attributes { } } -impl Clean for [ast::Attribute] { - fn clean(&self, cx: &DocContext<'_>) -> Attributes { - Attributes::from_ast(cx.sess().diagnostic(), self) - } -} - #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub enum GenericBound { TraitBound(PolyTrait, hir::TraitBoundModifier), @@ -1104,139 +775,6 @@ impl GenericBound { } } -impl Clean for hir::GenericBound { - fn clean(&self, cx: &DocContext<'_>) -> GenericBound { - match *self { - hir::GenericBound::Outlives(lt) => GenericBound::Outlives(lt.clean(cx)), - hir::GenericBound::Trait(ref t, modifier) => { - GenericBound::TraitBound(t.clean(cx), modifier) - } - } - } -} - -fn external_generic_args( - cx: &DocContext<'_>, - trait_did: Option, - has_self: bool, - bindings: Vec, - substs: SubstsRef<'_>, -) -> GenericArgs { - let mut skip_self = has_self; - let mut ty_kind = None; - let args: Vec<_> = substs.iter().filter_map(|kind| match kind.unpack() { - GenericArgKind::Lifetime(lt) => { - lt.clean(cx).and_then(|lt| Some(GenericArg::Lifetime(lt))) - } - GenericArgKind::Type(_) if skip_self => { - skip_self = false; - None - } - GenericArgKind::Type(ty) => { - ty_kind = Some(&ty.kind); - Some(GenericArg::Type(ty.clean(cx))) - } - GenericArgKind::Const(ct) => Some(GenericArg::Const(ct.clean(cx))), - }).collect(); - - match trait_did { - // Attempt to sugar an external path like Fn<(A, B,), C> to Fn(A, B) -> C - Some(did) if cx.tcx.lang_items().fn_trait_kind(did).is_some() => { - assert!(ty_kind.is_some()); - let inputs = match ty_kind { - Some(ty::Tuple(ref tys)) => tys.iter().map(|t| t.expect_ty().clean(cx)).collect(), - _ => return GenericArgs::AngleBracketed { args, bindings }, - }; - let output = None; - // FIXME(#20299) return type comes from a projection now - // match types[1].kind { - // ty::Tuple(ref v) if v.is_empty() => None, // -> () - // _ => Some(types[1].clean(cx)) - // }; - GenericArgs::Parenthesized { inputs, output } - }, - _ => { - GenericArgs::AngleBracketed { args, bindings } - } - } -} - -// trait_did should be set to a trait's DefId if called on a TraitRef, in order to sugar -// from Fn<(A, B,), C> to Fn(A, B) -> C -fn external_path(cx: &DocContext<'_>, name: Symbol, trait_did: Option, has_self: bool, - bindings: Vec, substs: SubstsRef<'_>) -> Path { - Path { - global: false, - res: Res::Err, - segments: vec![PathSegment { - name: name.to_string(), - args: external_generic_args(cx, trait_did, has_self, bindings, substs) - }], - } -} - -impl<'a, 'tcx> Clean for (&'a ty::TraitRef<'tcx>, Vec) { - fn clean(&self, cx: &DocContext<'_>) -> GenericBound { - let (trait_ref, ref bounds) = *self; - inline::record_extern_fqn(cx, trait_ref.def_id, TypeKind::Trait); - let path = external_path(cx, cx.tcx.item_name(trait_ref.def_id), - Some(trait_ref.def_id), true, bounds.clone(), trait_ref.substs); - - debug!("ty::TraitRef\n subst: {:?}\n", trait_ref.substs); - - // collect any late bound regions - let mut late_bounds = vec![]; - for ty_s in trait_ref.input_types().skip(1) { - if let ty::Tuple(ts) = ty_s.kind { - for &ty_s in ts { - if let ty::Ref(ref reg, _, _) = ty_s.expect_ty().kind { - if let &ty::RegionKind::ReLateBound(..) = *reg { - debug!(" hit an ReLateBound {:?}", reg); - if let Some(Lifetime(name)) = reg.clean(cx) { - late_bounds.push(GenericParamDef { - name, - kind: GenericParamDefKind::Lifetime, - }); - } - } - } - } - } - } - - GenericBound::TraitBound( - PolyTrait { - trait_: ResolvedPath { - path, - param_names: None, - did: trait_ref.def_id, - is_generic: false, - }, - generic_params: late_bounds, - }, - hir::TraitBoundModifier::None - ) - } -} - -impl<'tcx> Clean for ty::TraitRef<'tcx> { - fn clean(&self, cx: &DocContext<'_>) -> GenericBound { - (self, vec![]).clean(cx) - } -} - -impl<'tcx> Clean>> for InternalSubsts<'tcx> { - fn clean(&self, cx: &DocContext<'_>) -> Option> { - let mut v = Vec::new(); - v.extend(self.regions().filter_map(|r| r.clean(cx)).map(GenericBound::Outlives)); - v.extend(self.types().map(|t| GenericBound::TraitBound(PolyTrait { - trait_: t.clean(cx), - generic_params: Vec::new(), - }, hir::TraitBoundModifier::None))); - if !v.is_empty() {Some(v)} else {None} - } -} - #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub struct Lifetime(String); @@ -1252,86 +790,6 @@ impl Lifetime { } } -impl Clean for hir::Lifetime { - fn clean(&self, cx: &DocContext<'_>) -> Lifetime { - if self.hir_id != hir::DUMMY_HIR_ID { - let def = cx.tcx.named_region(self.hir_id); - match def { - Some(rl::Region::EarlyBound(_, node_id, _)) | - Some(rl::Region::LateBound(_, node_id, _)) | - Some(rl::Region::Free(_, node_id)) => { - if let Some(lt) = cx.lt_substs.borrow().get(&node_id).cloned() { - return lt; - } - } - _ => {} - } - } - Lifetime(self.name.ident().to_string()) - } -} - -impl Clean for hir::GenericParam { - fn clean(&self, _: &DocContext<'_>) -> Lifetime { - match self.kind { - hir::GenericParamKind::Lifetime { .. } => { - if self.bounds.len() > 0 { - let mut bounds = self.bounds.iter().map(|bound| match bound { - hir::GenericBound::Outlives(lt) => lt, - _ => panic!(), - }); - let name = bounds.next().expect("no more bounds").name.ident(); - let mut s = format!("{}: {}", self.name.ident(), name); - for bound in bounds { - s.push_str(&format!(" + {}", bound.name.ident())); - } - Lifetime(s) - } else { - Lifetime(self.name.ident().to_string()) - } - } - _ => panic!(), - } - } -} - -impl Clean for hir::ConstArg { - fn clean(&self, cx: &DocContext<'_>) -> Constant { - Constant { - type_: cx.tcx.type_of(cx.tcx.hir().body_owner_def_id(self.value.body)).clean(cx), - expr: print_const_expr(cx, self.value.body), - } - } -} - -impl Clean for ty::GenericParamDef { - fn clean(&self, _cx: &DocContext<'_>) -> Lifetime { - Lifetime(self.name.to_string()) - } -} - -impl Clean> for ty::RegionKind { - fn clean(&self, cx: &DocContext<'_>) -> Option { - match *self { - ty::ReStatic => Some(Lifetime::statik()), - ty::ReLateBound(_, ty::BrNamed(_, name)) => Some(Lifetime(name.to_string())), - ty::ReEarlyBound(ref data) => Some(Lifetime(data.name.clean(cx))), - - ty::ReLateBound(..) | - ty::ReFree(..) | - ty::ReScope(..) | - ty::ReVar(..) | - ty::RePlaceholder(..) | - ty::ReEmpty | - ty::ReClosureBound(_) | - ty::ReErased => { - debug!("cannot clean region {:?}", self); - None - } - } - } -} - #[derive(Clone, Debug)] pub enum WherePredicate { BoundPredicate { ty: Type, bounds: Vec }, @@ -1349,127 +807,6 @@ impl WherePredicate { } } -impl Clean for hir::WherePredicate { - fn clean(&self, cx: &DocContext<'_>) -> WherePredicate { - match *self { - hir::WherePredicate::BoundPredicate(ref wbp) => { - WherePredicate::BoundPredicate { - ty: wbp.bounded_ty.clean(cx), - bounds: wbp.bounds.clean(cx) - } - } - - hir::WherePredicate::RegionPredicate(ref wrp) => { - WherePredicate::RegionPredicate { - lifetime: wrp.lifetime.clean(cx), - bounds: wrp.bounds.clean(cx) - } - } - - hir::WherePredicate::EqPredicate(ref wrp) => { - WherePredicate::EqPredicate { - lhs: wrp.lhs_ty.clean(cx), - rhs: wrp.rhs_ty.clean(cx) - } - } - } - } -} - -impl<'a> Clean> for ty::Predicate<'a> { - fn clean(&self, cx: &DocContext<'_>) -> Option { - use rustc::ty::Predicate; - - match *self { - Predicate::Trait(ref pred) => Some(pred.clean(cx)), - Predicate::Subtype(ref pred) => Some(pred.clean(cx)), - Predicate::RegionOutlives(ref pred) => pred.clean(cx), - Predicate::TypeOutlives(ref pred) => pred.clean(cx), - Predicate::Projection(ref pred) => Some(pred.clean(cx)), - - Predicate::WellFormed(..) | - Predicate::ObjectSafe(..) | - Predicate::ClosureKind(..) | - Predicate::ConstEvaluatable(..) => panic!("not user writable"), - } - } -} - -impl<'a> Clean for ty::TraitPredicate<'a> { - fn clean(&self, cx: &DocContext<'_>) -> WherePredicate { - WherePredicate::BoundPredicate { - ty: self.trait_ref.self_ty().clean(cx), - bounds: vec![self.trait_ref.clean(cx)] - } - } -} - -impl<'tcx> Clean for ty::SubtypePredicate<'tcx> { - fn clean(&self, _cx: &DocContext<'_>) -> WherePredicate { - panic!("subtype predicates are an internal rustc artifact \ - and should not be seen by rustdoc") - } -} - -impl<'tcx> Clean> for - ty::OutlivesPredicate,ty::Region<'tcx>> { - - fn clean(&self, cx: &DocContext<'_>) -> Option { - let ty::OutlivesPredicate(ref a, ref b) = *self; - - match (a, b) { - (ty::ReEmpty, ty::ReEmpty) => { - return None; - }, - _ => {} - } - - Some(WherePredicate::RegionPredicate { - lifetime: a.clean(cx).expect("failed to clean lifetime"), - bounds: vec![GenericBound::Outlives(b.clean(cx).expect("failed to clean bounds"))] - }) - } -} - -impl<'tcx> Clean> for ty::OutlivesPredicate, ty::Region<'tcx>> { - fn clean(&self, cx: &DocContext<'_>) -> Option { - let ty::OutlivesPredicate(ref ty, ref lt) = *self; - - match lt { - ty::ReEmpty => return None, - _ => {} - } - - Some(WherePredicate::BoundPredicate { - ty: ty.clean(cx), - bounds: vec![GenericBound::Outlives(lt.clean(cx).expect("failed to clean lifetimes"))] - }) - } -} - -impl<'tcx> Clean for ty::ProjectionPredicate<'tcx> { - fn clean(&self, cx: &DocContext<'_>) -> WherePredicate { - WherePredicate::EqPredicate { - lhs: self.projection_ty.clean(cx), - rhs: self.ty.clean(cx) - } - } -} - -impl<'tcx> Clean for ty::ProjectionTy<'tcx> { - fn clean(&self, cx: &DocContext<'_>) -> Type { - let trait_ = match self.trait_ref(cx.tcx).clean(cx) { - GenericBound::TraitBound(t, _) => t.trait_, - GenericBound::Outlives(_) => panic!("cleaning a trait got a lifetime"), - }; - Type::QPath { - name: cx.tcx.associated_item(self.item_def_id).ident.name.clean(cx), - self_type: box self.self_ty().clean(cx), - trait_: box trait_ - } - } -} - #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub enum GenericParamDefKind { Lifetime, @@ -1537,83 +874,6 @@ impl GenericParamDef { } } -impl Clean for ty::GenericParamDef { - fn clean(&self, cx: &DocContext<'_>) -> GenericParamDef { - let (name, kind) = match self.kind { - ty::GenericParamDefKind::Lifetime => { - (self.name.to_string(), GenericParamDefKind::Lifetime) - } - ty::GenericParamDefKind::Type { has_default, synthetic, .. } => { - let default = if has_default { - Some(cx.tcx.type_of(self.def_id).clean(cx)) - } else { - None - }; - (self.name.clean(cx), GenericParamDefKind::Type { - did: self.def_id, - bounds: vec![], // These are filled in from the where-clauses. - default, - synthetic, - }) - } - ty::GenericParamDefKind::Const { .. } => { - (self.name.clean(cx), GenericParamDefKind::Const { - did: self.def_id, - ty: cx.tcx.type_of(self.def_id).clean(cx), - }) - } - }; - - GenericParamDef { - name, - kind, - } - } -} - -impl Clean for hir::GenericParam { - fn clean(&self, cx: &DocContext<'_>) -> GenericParamDef { - let (name, kind) = match self.kind { - hir::GenericParamKind::Lifetime { .. } => { - let name = if self.bounds.len() > 0 { - let mut bounds = self.bounds.iter().map(|bound| match bound { - hir::GenericBound::Outlives(lt) => lt, - _ => panic!(), - }); - let name = bounds.next().expect("no more bounds").name.ident(); - let mut s = format!("{}: {}", self.name.ident(), name); - for bound in bounds { - s.push_str(&format!(" + {}", bound.name.ident())); - } - s - } else { - self.name.ident().to_string() - }; - (name, GenericParamDefKind::Lifetime) - } - hir::GenericParamKind::Type { ref default, synthetic } => { - (self.name.ident().name.clean(cx), GenericParamDefKind::Type { - did: cx.tcx.hir().local_def_id(self.hir_id), - bounds: self.bounds.clean(cx), - default: default.clean(cx), - synthetic, - }) - } - hir::GenericParamKind::Const { ref ty } => { - (self.name.ident().name.clean(cx), GenericParamDefKind::Const { - did: cx.tcx.hir().local_def_id(self.hir_id), - ty: ty.clean(cx), - }) - } - }; - - GenericParamDef { - name, - kind, - } - } -} - // maybe use a Generic enum and use Vec? #[derive(Clone, Debug, Default)] pub struct Generics { @@ -1621,360 +881,6 @@ pub struct Generics { pub where_predicates: Vec, } -impl Clean for hir::Generics { - fn clean(&self, cx: &DocContext<'_>) -> Generics { - // Synthetic type-parameters are inserted after normal ones. - // In order for normal parameters to be able to refer to synthetic ones, - // scans them first. - fn is_impl_trait(param: &hir::GenericParam) -> bool { - match param.kind { - hir::GenericParamKind::Type { synthetic, .. } => { - synthetic == Some(hir::SyntheticTyParamKind::ImplTrait) - } - _ => false, - } - } - let impl_trait_params = self.params - .iter() - .filter(|param| is_impl_trait(param)) - .map(|param| { - let param: GenericParamDef = param.clean(cx); - match param.kind { - GenericParamDefKind::Lifetime => unreachable!(), - GenericParamDefKind::Type { did, ref bounds, .. } => { - cx.impl_trait_bounds.borrow_mut().insert(did.into(), bounds.clone()); - } - GenericParamDefKind::Const { .. } => unreachable!(), - } - param - }) - .collect::>(); - - let mut params = Vec::with_capacity(self.params.len()); - for p in self.params.iter().filter(|p| !is_impl_trait(p)) { - let p = p.clean(cx); - params.push(p); - } - params.extend(impl_trait_params); - - let mut generics = Generics { - params, - where_predicates: self.where_clause.predicates.clean(cx), - }; - - // Some duplicates are generated for ?Sized bounds between type params and where - // predicates. The point in here is to move the bounds definitions from type params - // to where predicates when such cases occur. - for where_pred in &mut generics.where_predicates { - match *where_pred { - WherePredicate::BoundPredicate { ty: Generic(ref name), ref mut bounds } => { - if bounds.is_empty() { - for param in &mut generics.params { - match param.kind { - GenericParamDefKind::Lifetime => {} - GenericParamDefKind::Type { bounds: ref mut ty_bounds, .. } => { - if ¶m.name == name { - mem::swap(bounds, ty_bounds); - break - } - } - GenericParamDefKind::Const { .. } => {} - } - } - } - } - _ => continue, - } - } - generics - } -} - -impl<'a, 'tcx> Clean for (&'a ty::Generics, ty::GenericPredicates<'tcx>) { - fn clean(&self, cx: &DocContext<'_>) -> Generics { - use self::WherePredicate as WP; - use std::collections::BTreeMap; - - let (gens, preds) = *self; - - // Don't populate `cx.impl_trait_bounds` before `clean`ning `where` clauses, - // since `Clean for ty::Predicate` would consume them. - let mut impl_trait = BTreeMap::>::default(); - - // Bounds in the type_params and lifetimes fields are repeated in the - // predicates field (see rustc_typeck::collect::ty_generics), so remove - // them. - let stripped_typarams = gens.params.iter() - .filter_map(|param| match param.kind { - ty::GenericParamDefKind::Lifetime => None, - ty::GenericParamDefKind::Type { synthetic, .. } => { - if param.name == kw::SelfUpper { - assert_eq!(param.index, 0); - return None; - } - if synthetic == Some(hir::SyntheticTyParamKind::ImplTrait) { - impl_trait.insert(param.index.into(), vec![]); - return None; - } - Some(param.clean(cx)) - } - ty::GenericParamDefKind::Const { .. } => None, - }).collect::>(); - - // param index -> [(DefId of trait, associated type name, type)] - let mut impl_trait_proj = - FxHashMap::)>>::default(); - - let where_predicates = preds.predicates.iter() - .flat_map(|(p, _)| { - let mut projection = None; - let param_idx = (|| { - if let Some(trait_ref) = p.to_opt_poly_trait_ref() { - if let ty::Param(param) = trait_ref.self_ty().kind { - return Some(param.index); - } - } else if let Some(outlives) = p.to_opt_type_outlives() { - if let ty::Param(param) = outlives.skip_binder().0.kind { - return Some(param.index); - } - } else if let ty::Predicate::Projection(p) = p { - if let ty::Param(param) = p.skip_binder().projection_ty.self_ty().kind { - projection = Some(p); - return Some(param.index); - } - } - - None - })(); - - if let Some(param_idx) = param_idx { - if let Some(b) = impl_trait.get_mut(¶m_idx.into()) { - let p = p.clean(cx)?; - - b.extend( - p.get_bounds() - .into_iter() - .flatten() - .cloned() - .filter(|b| !b.is_sized_bound(cx)) - ); - - let proj = projection - .map(|p| (p.skip_binder().projection_ty.clean(cx), p.skip_binder().ty)); - if let Some(((_, trait_did, name), rhs)) = - proj.as_ref().and_then(|(lhs, rhs)| Some((lhs.projection()?, rhs))) - { - impl_trait_proj - .entry(param_idx) - .or_default() - .push((trait_did, name.to_string(), rhs)); - } - - return None; - } - } - - Some(p) - }) - .collect::>(); - - for (param, mut bounds) in impl_trait { - // Move trait bounds to the front. - bounds.sort_by_key(|b| if let GenericBound::TraitBound(..) = b { - false - } else { - true - }); - - if let crate::core::ImplTraitParam::ParamIndex(idx) = param { - if let Some(proj) = impl_trait_proj.remove(&idx) { - for (trait_did, name, rhs) in proj { - simplify::merge_bounds( - cx, - &mut bounds, - trait_did, - &name, - &rhs.clean(cx), - ); - } - } - } else { - unreachable!(); - } - - cx.impl_trait_bounds.borrow_mut().insert(param, bounds); - } - - // Now that `cx.impl_trait_bounds` is populated, we can process - // remaining predicates which could contain `impl Trait`. - let mut where_predicates = where_predicates - .into_iter() - .flat_map(|p| p.clean(cx)) - .collect::>(); - - // Type parameters and have a Sized bound by default unless removed with - // ?Sized. Scan through the predicates and mark any type parameter with - // a Sized bound, removing the bounds as we find them. - // - // Note that associated types also have a sized bound by default, but we - // don't actually know the set of associated types right here so that's - // handled in cleaning associated types - let mut sized_params = FxHashSet::default(); - where_predicates.retain(|pred| { - match *pred { - WP::BoundPredicate { ty: Generic(ref g), ref bounds } => { - if bounds.iter().any(|b| b.is_sized_bound(cx)) { - sized_params.insert(g.clone()); - false - } else { - true - } - } - _ => true, - } - }); - - // Run through the type parameters again and insert a ?Sized - // unbound for any we didn't find to be Sized. - for tp in &stripped_typarams { - if !sized_params.contains(&tp.name) { - where_predicates.push(WP::BoundPredicate { - ty: Type::Generic(tp.name.clone()), - bounds: vec![GenericBound::maybe_sized(cx)], - }) - } - } - - // It would be nice to collect all of the bounds on a type and recombine - // them if possible, to avoid e.g., `where T: Foo, T: Bar, T: Sized, T: 'a` - // and instead see `where T: Foo + Bar + Sized + 'a` - - Generics { - params: gens.params - .iter() - .flat_map(|param| match param.kind { - ty::GenericParamDefKind::Lifetime => Some(param.clean(cx)), - ty::GenericParamDefKind::Type { .. } => None, - ty::GenericParamDefKind::Const { .. } => Some(param.clean(cx)), - }).chain(simplify::ty_params(stripped_typarams).into_iter()) - .collect(), - where_predicates: simplify::where_clauses(cx, where_predicates), - } - } -} - -/// The point of this function is to replace bounds with types. -/// -/// i.e. `[T, U]` when you have the following bounds: `T: Display, U: Option` will return -/// `[Display, Option]` (we just returns the list of the types, we don't care about the -/// wrapped types in here). -fn get_real_types( - generics: &Generics, - arg: &Type, - cx: &DocContext<'_>, - recurse: i32, -) -> FxHashSet { - let arg_s = arg.print().to_string(); - let mut res = FxHashSet::default(); - if recurse >= 10 { // FIXME: remove this whole recurse thing when the recursion bug is fixed - return res; - } - if arg.is_full_generic() { - if let Some(where_pred) = generics.where_predicates.iter().find(|g| { - match g { - &WherePredicate::BoundPredicate { ref ty, .. } => ty.def_id() == arg.def_id(), - _ => false, - } - }) { - let bounds = where_pred.get_bounds().unwrap_or_else(|| &[]); - for bound in bounds.iter() { - match *bound { - GenericBound::TraitBound(ref poly_trait, _) => { - for x in poly_trait.generic_params.iter() { - if !x.is_type() { - continue - } - if let Some(ty) = x.get_type() { - let adds = get_real_types(generics, &ty, cx, recurse + 1); - if !adds.is_empty() { - res.extend(adds); - } else if !ty.is_full_generic() { - res.insert(ty); - } - } - } - } - _ => {} - } - } - } - if let Some(bound) = generics.params.iter().find(|g| { - g.is_type() && g.name == arg_s - }) { - for bound in bound.get_bounds().unwrap_or_else(|| &[]) { - if let Some(ty) = bound.get_trait_type() { - let adds = get_real_types(generics, &ty, cx, recurse + 1); - if !adds.is_empty() { - res.extend(adds); - } else if !ty.is_full_generic() { - res.insert(ty.clone()); - } - } - } - } - } else { - res.insert(arg.clone()); - if let Some(gens) = arg.generics() { - for gen in gens.iter() { - if gen.is_full_generic() { - let adds = get_real_types(generics, gen, cx, recurse + 1); - if !adds.is_empty() { - res.extend(adds); - } - } else { - res.insert(gen.clone()); - } - } - } - } - res -} - -/// Return the full list of types when bounds have been resolved. -/// -/// i.e. `fn foo>(x: u32, y: B)` will return -/// `[u32, Display, Option]`. -pub fn get_all_types( - generics: &Generics, - decl: &FnDecl, - cx: &DocContext<'_>, -) -> (Vec, Vec) { - let mut all_types = FxHashSet::default(); - for arg in decl.inputs.values.iter() { - if arg.type_.is_self_type() { - continue; - } - let args = get_real_types(generics, &arg.type_, cx, 0); - if !args.is_empty() { - all_types.extend(args); - } else { - all_types.insert(arg.type_.clone()); - } - } - - let ret_types = match decl.output { - FunctionRetTy::Return(ref return_type) => { - let mut ret = get_real_types(generics, &return_type, cx, 0); - if ret.is_empty() { - ret.insert(return_type.clone()); - } - ret.into_iter().collect() - } - _ => Vec::new(), - }; - (all_types.into_iter().collect(), ret_types) -} - #[derive(Clone, Debug)] pub struct Method { pub generics: Generics, @@ -1985,24 +891,6 @@ pub struct Method { pub ret_types: Vec, } -impl<'a> Clean for (&'a hir::FnSig, &'a hir::Generics, hir::BodyId, - Option) { - fn clean(&self, cx: &DocContext<'_>) -> Method { - let (generics, decl) = enter_impl_trait(cx, || { - (self.1.clean(cx), (&*self.0.decl, self.2).clean(cx)) - }); - let (all_types, ret_types) = get_all_types(&generics, &decl, cx); - Method { - decl, - generics, - header: self.0.header, - defaultness: self.3, - all_types, - ret_types, - } - } -} - #[derive(Clone, Debug)] pub struct TyMethod { pub header: hir::FnHeader, @@ -2021,38 +909,6 @@ pub struct Function { pub ret_types: Vec, } -impl Clean for doctree::Function<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Item { - let (generics, decl) = enter_impl_trait(cx, || { - (self.generics.clean(cx), (self.decl, self.body).clean(cx)) - }); - - let did = cx.tcx.hir().local_def_id(self.id); - let constness = if cx.tcx.is_min_const_fn(did) { - hir::Constness::Const - } else { - hir::Constness::NotConst - }; - let (all_types, ret_types) = get_all_types(&generics, &decl, cx); - Item { - name: Some(self.name.clean(cx)), - attrs: self.attrs.clean(cx), - source: self.whence.clean(cx), - visibility: self.vis.clean(cx), - stability: cx.stability(self.id).clean(cx), - deprecation: cx.deprecation(self.id).clean(cx), - def_id: did, - inner: FunctionItem(Function { - decl, - generics, - header: hir::FnHeader { constness, ..self.header }, - all_types, - ret_types, - }), - } - } -} - #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub struct FnDecl { pub inputs: Arguments, @@ -2096,77 +952,6 @@ pub struct Arguments { pub values: Vec, } -impl<'a> Clean for (&'a [hir::Ty], &'a [ast::Ident]) { - fn clean(&self, cx: &DocContext<'_>) -> Arguments { - Arguments { - values: self.0.iter().enumerate().map(|(i, ty)| { - let mut name = self.1.get(i).map(|ident| ident.to_string()) - .unwrap_or(String::new()); - if name.is_empty() { - name = "_".to_string(); - } - Argument { - name, - type_: ty.clean(cx), - } - }).collect() - } - } -} - -impl<'a> Clean for (&'a [hir::Ty], hir::BodyId) { - fn clean(&self, cx: &DocContext<'_>) -> Arguments { - let body = cx.tcx.hir().body(self.1); - - Arguments { - values: self.0.iter().enumerate().map(|(i, ty)| { - Argument { - name: name_from_pat(&body.params[i].pat), - type_: ty.clean(cx), - } - }).collect() - } - } -} - -impl<'a, A: Copy> Clean for (&'a hir::FnDecl, A) - where (&'a [hir::Ty], A): Clean -{ - fn clean(&self, cx: &DocContext<'_>) -> FnDecl { - FnDecl { - inputs: (&self.0.inputs[..], self.1).clean(cx), - output: self.0.output.clean(cx), - c_variadic: self.0.c_variadic, - attrs: Attributes::default(), - } - } -} - -impl<'tcx> Clean for (DefId, ty::PolyFnSig<'tcx>) { - fn clean(&self, cx: &DocContext<'_>) -> FnDecl { - let (did, sig) = *self; - let mut names = if cx.tcx.hir().as_local_hir_id(did).is_some() { - vec![].into_iter() - } else { - cx.tcx.fn_arg_names(did).into_iter() - }; - - FnDecl { - output: Return(sig.skip_binder().output().clean(cx)), - attrs: Attributes::default(), - c_variadic: sig.skip_binder().c_variadic, - inputs: Arguments { - values: sig.skip_binder().inputs().iter().map(|t| { - Argument { - type_: t.clean(cx), - name: names.next().map_or(String::new(), |name| name.to_string()), - } - }).collect(), - }, - } - } -} - #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub struct Argument { pub type_: Type, @@ -2203,15 +988,6 @@ pub enum FunctionRetTy { DefaultReturn, } -impl Clean for hir::FunctionRetTy { - fn clean(&self, cx: &DocContext<'_>) -> FunctionRetTy { - match *self { - hir::Return(ref typ) => Return(typ.clean(cx)), - hir::DefaultReturn(..) => DefaultReturn, - } - } -} - impl GetDefId for FunctionRetTy { fn def_id(&self) -> Option { match *self { @@ -2232,315 +1008,12 @@ pub struct Trait { pub is_auto: bool, } -impl Clean for doctree::Trait<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Item { - let attrs = self.attrs.clean(cx); - let is_spotlight = attrs.has_doc_flag(sym::spotlight); - Item { - name: Some(self.name.clean(cx)), - attrs, - source: self.whence.clean(cx), - def_id: cx.tcx.hir().local_def_id(self.id), - visibility: self.vis.clean(cx), - stability: cx.stability(self.id).clean(cx), - deprecation: cx.deprecation(self.id).clean(cx), - inner: TraitItem(Trait { - auto: self.is_auto.clean(cx), - unsafety: self.unsafety, - items: self.items.iter().map(|ti| ti.clean(cx)).collect(), - generics: self.generics.clean(cx), - bounds: self.bounds.clean(cx), - is_spotlight, - is_auto: self.is_auto.clean(cx), - }), - } - } -} - #[derive(Clone, Debug)] pub struct TraitAlias { pub generics: Generics, pub bounds: Vec, } -impl Clean for doctree::TraitAlias<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Item { - let attrs = self.attrs.clean(cx); - Item { - name: Some(self.name.clean(cx)), - attrs, - source: self.whence.clean(cx), - def_id: cx.tcx.hir().local_def_id(self.id), - visibility: self.vis.clean(cx), - stability: cx.stability(self.id).clean(cx), - deprecation: cx.deprecation(self.id).clean(cx), - inner: TraitAliasItem(TraitAlias { - generics: self.generics.clean(cx), - bounds: self.bounds.clean(cx), - }), - } - } -} - -impl Clean for hir::IsAuto { - fn clean(&self, _: &DocContext<'_>) -> bool { - match *self { - hir::IsAuto::Yes => true, - hir::IsAuto::No => false, - } - } -} - -impl Clean for hir::TraitRef { - fn clean(&self, cx: &DocContext<'_>) -> Type { - resolve_type(cx, self.path.clean(cx), self.hir_ref_id) - } -} - -impl Clean for hir::PolyTraitRef { - fn clean(&self, cx: &DocContext<'_>) -> PolyTrait { - PolyTrait { - trait_: self.trait_ref.clean(cx), - generic_params: self.bound_generic_params.clean(cx) - } - } -} - -impl Clean for hir::TraitItem { - fn clean(&self, cx: &DocContext<'_>) -> Item { - let inner = match self.kind { - hir::TraitItemKind::Const(ref ty, default) => { - AssocConstItem(ty.clean(cx), - default.map(|e| print_const_expr(cx, e))) - } - hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) => { - MethodItem((sig, &self.generics, body, None).clean(cx)) - } - hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Required(ref names)) => { - let (generics, decl) = enter_impl_trait(cx, || { - (self.generics.clean(cx), (&*sig.decl, &names[..]).clean(cx)) - }); - let (all_types, ret_types) = get_all_types(&generics, &decl, cx); - TyMethodItem(TyMethod { - header: sig.header, - decl, - generics, - all_types, - ret_types, - }) - } - hir::TraitItemKind::Type(ref bounds, ref default) => { - AssocTypeItem(bounds.clean(cx), default.clean(cx)) - } - }; - let local_did = cx.tcx.hir().local_def_id(self.hir_id); - Item { - name: Some(self.ident.name.clean(cx)), - attrs: self.attrs.clean(cx), - source: self.span.clean(cx), - def_id: local_did, - visibility: Visibility::Inherited, - stability: get_stability(cx, local_did), - deprecation: get_deprecation(cx, local_did), - inner, - } - } -} - -impl Clean for hir::ImplItem { - fn clean(&self, cx: &DocContext<'_>) -> Item { - let inner = match self.kind { - hir::ImplItemKind::Const(ref ty, expr) => { - AssocConstItem(ty.clean(cx), - Some(print_const_expr(cx, expr))) - } - hir::ImplItemKind::Method(ref sig, body) => { - MethodItem((sig, &self.generics, body, Some(self.defaultness)).clean(cx)) - } - hir::ImplItemKind::TyAlias(ref ty) => TypedefItem(Typedef { - type_: ty.clean(cx), - generics: Generics::default(), - }, true), - hir::ImplItemKind::OpaqueTy(ref bounds) => OpaqueTyItem(OpaqueTy { - bounds: bounds.clean(cx), - generics: Generics::default(), - }, true), - }; - let local_did = cx.tcx.hir().local_def_id(self.hir_id); - Item { - name: Some(self.ident.name.clean(cx)), - source: self.span.clean(cx), - attrs: self.attrs.clean(cx), - def_id: local_did, - visibility: self.vis.clean(cx), - stability: get_stability(cx, local_did), - deprecation: get_deprecation(cx, local_did), - inner, - } - } -} - -impl Clean for ty::AssocItem { - fn clean(&self, cx: &DocContext<'_>) -> Item { - let inner = match self.kind { - ty::AssocKind::Const => { - let ty = cx.tcx.type_of(self.def_id); - let default = if self.defaultness.has_value() { - Some(inline::print_inlined_const(cx, self.def_id)) - } else { - None - }; - AssocConstItem(ty.clean(cx), default) - } - ty::AssocKind::Method => { - let generics = (cx.tcx.generics_of(self.def_id), - cx.tcx.explicit_predicates_of(self.def_id)).clean(cx); - let sig = cx.tcx.fn_sig(self.def_id); - let mut decl = (self.def_id, sig).clean(cx); - - if self.method_has_self_argument { - let self_ty = match self.container { - ty::ImplContainer(def_id) => { - cx.tcx.type_of(def_id) - } - ty::TraitContainer(_) => cx.tcx.types.self_param, - }; - let self_arg_ty = *sig.input(0).skip_binder(); - if self_arg_ty == self_ty { - decl.inputs.values[0].type_ = Generic(String::from("Self")); - } else if let ty::Ref(_, ty, _) = self_arg_ty.kind { - if ty == self_ty { - match decl.inputs.values[0].type_ { - BorrowedRef{ref mut type_, ..} => { - **type_ = Generic(String::from("Self")) - } - _ => unreachable!(), - } - } - } - } - - let provided = match self.container { - ty::ImplContainer(_) => true, - ty::TraitContainer(_) => self.defaultness.has_value() - }; - let (all_types, ret_types) = get_all_types(&generics, &decl, cx); - if provided { - let constness = if cx.tcx.is_min_const_fn(self.def_id) { - hir::Constness::Const - } else { - hir::Constness::NotConst - }; - let asyncness = cx.tcx.asyncness(self.def_id); - let defaultness = match self.container { - ty::ImplContainer(_) => Some(self.defaultness), - ty::TraitContainer(_) => None, - }; - MethodItem(Method { - generics, - decl, - header: hir::FnHeader { - unsafety: sig.unsafety(), - abi: sig.abi(), - constness, - asyncness, - }, - defaultness, - all_types, - ret_types, - }) - } else { - TyMethodItem(TyMethod { - generics, - decl, - header: hir::FnHeader { - unsafety: sig.unsafety(), - abi: sig.abi(), - constness: hir::Constness::NotConst, - asyncness: hir::IsAsync::NotAsync, - }, - all_types, - ret_types, - }) - } - } - ty::AssocKind::Type => { - let my_name = self.ident.name.clean(cx); - - if let ty::TraitContainer(did) = self.container { - // When loading a cross-crate associated type, the bounds for this type - // are actually located on the trait/impl itself, so we need to load - // all of the generics from there and then look for bounds that are - // applied to this associated type in question. - let predicates = cx.tcx.explicit_predicates_of(did); - let generics = (cx.tcx.generics_of(did), predicates).clean(cx); - let mut bounds = generics.where_predicates.iter().filter_map(|pred| { - let (name, self_type, trait_, bounds) = match *pred { - WherePredicate::BoundPredicate { - ty: QPath { ref name, ref self_type, ref trait_ }, - ref bounds - } => (name, self_type, trait_, bounds), - _ => return None, - }; - if *name != my_name { return None } - match **trait_ { - ResolvedPath { did, .. } if did == self.container.id() => {} - _ => return None, - } - match **self_type { - Generic(ref s) if *s == "Self" => {} - _ => return None, - } - Some(bounds) - }).flat_map(|i| i.iter().cloned()).collect::>(); - // Our Sized/?Sized bound didn't get handled when creating the generics - // because we didn't actually get our whole set of bounds until just now - // (some of them may have come from the trait). If we do have a sized - // bound, we remove it, and if we don't then we add the `?Sized` bound - // at the end. - match bounds.iter().position(|b| b.is_sized_bound(cx)) { - Some(i) => { bounds.remove(i); } - None => bounds.push(GenericBound::maybe_sized(cx)), - } - - let ty = if self.defaultness.has_value() { - Some(cx.tcx.type_of(self.def_id)) - } else { - None - }; - - AssocTypeItem(bounds, ty.clean(cx)) - } else { - TypedefItem(Typedef { - type_: cx.tcx.type_of(self.def_id).clean(cx), - generics: Generics { - params: Vec::new(), - where_predicates: Vec::new(), - }, - }, true) - } - } - ty::AssocKind::OpaqueTy => unimplemented!(), - }; - - let visibility = match self.container { - ty::ImplContainer(_) => self.vis.clean(cx), - ty::TraitContainer(_) => Inherited, - }; - - Item { - name: Some(self.ident.name.clean(cx)), - visibility, - stability: get_stability(cx, self.def_id), - deprecation: get_deprecation(cx, self.def_id), - def_id: self.def_id, - attrs: inline::load_attrs(cx, self.def_id).clean(cx), - source: cx.tcx.def_span(self.def_id).clean(cx), - inner, - } - } -} - /// A trait reference, which may have higher ranked lifetimes. #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub struct PolyTrait { @@ -2856,460 +1329,6 @@ impl From for PrimitiveType { } } -impl Clean for hir::Ty { - fn clean(&self, cx: &DocContext<'_>) -> Type { - use rustc::hir::*; - - match self.kind { - TyKind::Never => Never, - TyKind::Ptr(ref m) => RawPointer(m.mutbl.clean(cx), box m.ty.clean(cx)), - TyKind::Rptr(ref l, ref m) => { - let lifetime = if l.is_elided() { - None - } else { - Some(l.clean(cx)) - }; - BorrowedRef {lifetime, mutability: m.mutbl.clean(cx), - type_: box m.ty.clean(cx)} - } - TyKind::Slice(ref ty) => Slice(box ty.clean(cx)), - TyKind::Array(ref ty, ref length) => { - let def_id = cx.tcx.hir().local_def_id(length.hir_id); - let param_env = cx.tcx.param_env(def_id); - let substs = InternalSubsts::identity_for_item(cx.tcx, def_id); - let cid = GlobalId { - instance: ty::Instance::new(def_id, substs), - promoted: None - }; - let length = match cx.tcx.const_eval(param_env.and(cid)) { - Ok(length) => print_const(cx, length), - Err(_) => cx.sess() - .source_map() - .span_to_snippet(cx.tcx.def_span(def_id)) - .unwrap_or_else(|_| "_".to_string()), - }; - Array(box ty.clean(cx), length) - }, - TyKind::Tup(ref tys) => Tuple(tys.clean(cx)), - TyKind::Def(item_id, _) => { - let item = cx.tcx.hir().expect_item(item_id.id); - if let hir::ItemKind::OpaqueTy(ref ty) = item.kind { - ImplTrait(ty.bounds.clean(cx)) - } else { - unreachable!() - } - } - TyKind::Path(hir::QPath::Resolved(None, ref path)) => { - if let Res::Def(DefKind::TyParam, did) = path.res { - if let Some(new_ty) = cx.ty_substs.borrow().get(&did).cloned() { - return new_ty; - } - if let Some(bounds) = cx.impl_trait_bounds.borrow_mut().remove(&did.into()) { - return ImplTrait(bounds); - } - } - - let mut alias = None; - if let Res::Def(DefKind::TyAlias, def_id) = path.res { - // Substitute private type aliases - if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(def_id) { - if !cx.renderinfo.borrow().access_levels.is_exported(def_id) { - alias = Some(&cx.tcx.hir().expect_item(hir_id).kind); - } - } - }; - - if let Some(&hir::ItemKind::TyAlias(ref ty, ref generics)) = alias { - let provided_params = &path.segments.last().expect("segments were empty"); - let mut ty_substs = FxHashMap::default(); - let mut lt_substs = FxHashMap::default(); - let mut ct_substs = FxHashMap::default(); - let generic_args = provided_params.generic_args(); - { - let mut indices: GenericParamCount = Default::default(); - for param in generics.params.iter() { - match param.kind { - hir::GenericParamKind::Lifetime { .. } => { - let mut j = 0; - let lifetime = generic_args.args.iter().find_map(|arg| { - match arg { - hir::GenericArg::Lifetime(lt) => { - if indices.lifetimes == j { - return Some(lt); - } - j += 1; - None - } - _ => None, - } - }); - if let Some(lt) = lifetime.cloned() { - if !lt.is_elided() { - let lt_def_id = - cx.tcx.hir().local_def_id(param.hir_id); - lt_substs.insert(lt_def_id, lt.clean(cx)); - } - } - indices.lifetimes += 1; - } - hir::GenericParamKind::Type { ref default, .. } => { - let ty_param_def_id = - cx.tcx.hir().local_def_id(param.hir_id); - let mut j = 0; - let type_ = generic_args.args.iter().find_map(|arg| { - match arg { - hir::GenericArg::Type(ty) => { - if indices.types == j { - return Some(ty); - } - j += 1; - None - } - _ => None, - } - }); - if let Some(ty) = type_ { - ty_substs.insert(ty_param_def_id, ty.clean(cx)); - } else if let Some(default) = default.clone() { - ty_substs.insert(ty_param_def_id, - default.clean(cx)); - } - indices.types += 1; - } - hir::GenericParamKind::Const { .. } => { - let const_param_def_id = - cx.tcx.hir().local_def_id(param.hir_id); - let mut j = 0; - let const_ = generic_args.args.iter().find_map(|arg| { - match arg { - hir::GenericArg::Const(ct) => { - if indices.consts == j { - return Some(ct); - } - j += 1; - None - } - _ => None, - } - }); - if let Some(ct) = const_ { - ct_substs.insert(const_param_def_id, ct.clean(cx)); - } - // FIXME(const_generics:defaults) - indices.consts += 1; - } - } - } - } - return cx.enter_alias(ty_substs, lt_substs, ct_substs, || ty.clean(cx)); - } - resolve_type(cx, path.clean(cx), self.hir_id) - } - TyKind::Path(hir::QPath::Resolved(Some(ref qself), ref p)) => { - let segments = if p.is_global() { &p.segments[1..] } else { &p.segments }; - let trait_segments = &segments[..segments.len() - 1]; - let trait_path = self::Path { - global: p.is_global(), - res: Res::Def( - DefKind::Trait, - cx.tcx.associated_item(p.res.def_id()).container.id(), - ), - segments: trait_segments.clean(cx), - }; - Type::QPath { - name: p.segments.last().expect("segments were empty").ident.name.clean(cx), - self_type: box qself.clean(cx), - trait_: box resolve_type(cx, trait_path, self.hir_id) - } - } - TyKind::Path(hir::QPath::TypeRelative(ref qself, ref segment)) => { - let mut res = Res::Err; - let ty = hir_ty_to_ty(cx.tcx, self); - if let ty::Projection(proj) = ty.kind { - res = Res::Def(DefKind::Trait, proj.trait_ref(cx.tcx).def_id); - } - let trait_path = hir::Path { - span: self.span, - res, - segments: vec![].into(), - }; - Type::QPath { - name: segment.ident.name.clean(cx), - self_type: box qself.clean(cx), - trait_: box resolve_type(cx, trait_path.clean(cx), self.hir_id) - } - } - TyKind::TraitObject(ref bounds, ref lifetime) => { - match bounds[0].clean(cx).trait_ { - ResolvedPath { path, param_names: None, did, is_generic } => { - let mut bounds: Vec = bounds[1..].iter().map(|bound| { - self::GenericBound::TraitBound(bound.clean(cx), - hir::TraitBoundModifier::None) - }).collect(); - if !lifetime.is_elided() { - bounds.push(self::GenericBound::Outlives(lifetime.clean(cx))); - } - ResolvedPath { path, param_names: Some(bounds), did, is_generic, } - } - _ => Infer, // shouldn't happen - } - } - TyKind::BareFn(ref barefn) => BareFunction(box barefn.clean(cx)), - TyKind::Infer | TyKind::Err => Infer, - TyKind::Typeof(..) => panic!("unimplemented type {:?}", self.kind), - } - } -} - -impl<'tcx> Clean for Ty<'tcx> { - fn clean(&self, cx: &DocContext<'_>) -> Type { - debug!("cleaning type: {:?}", self); - match self.kind { - ty::Never => Never, - ty::Bool => Primitive(PrimitiveType::Bool), - ty::Char => Primitive(PrimitiveType::Char), - ty::Int(int_ty) => Primitive(int_ty.into()), - ty::Uint(uint_ty) => Primitive(uint_ty.into()), - ty::Float(float_ty) => Primitive(float_ty.into()), - ty::Str => Primitive(PrimitiveType::Str), - ty::Slice(ty) => Slice(box ty.clean(cx)), - ty::Array(ty, n) => { - let mut n = cx.tcx.lift(&n).expect("array lift failed"); - if let ty::ConstKind::Unevaluated(def_id, substs) = n.val { - let param_env = cx.tcx.param_env(def_id); - let cid = GlobalId { - instance: ty::Instance::new(def_id, substs), - promoted: None - }; - if let Ok(new_n) = cx.tcx.const_eval(param_env.and(cid)) { - n = new_n; - } - }; - let n = print_const(cx, n); - Array(box ty.clean(cx), n) - } - ty::RawPtr(mt) => RawPointer(mt.mutbl.clean(cx), box mt.ty.clean(cx)), - ty::Ref(r, ty, mutbl) => BorrowedRef { - lifetime: r.clean(cx), - mutability: mutbl.clean(cx), - type_: box ty.clean(cx), - }, - ty::FnDef(..) | - ty::FnPtr(_) => { - let ty = cx.tcx.lift(self).expect("FnPtr lift failed"); - let sig = ty.fn_sig(cx.tcx); - let local_def_id = cx.tcx.hir().local_def_id_from_node_id(ast::CRATE_NODE_ID); - BareFunction(box BareFunctionDecl { - unsafety: sig.unsafety(), - generic_params: Vec::new(), - decl: (local_def_id, sig).clean(cx), - abi: sig.abi(), - }) - } - ty::Adt(def, substs) => { - let did = def.did; - let kind = match def.adt_kind() { - AdtKind::Struct => TypeKind::Struct, - AdtKind::Union => TypeKind::Union, - AdtKind::Enum => TypeKind::Enum, - }; - inline::record_extern_fqn(cx, did, kind); - let path = external_path(cx, cx.tcx.item_name(did), None, false, vec![], substs); - ResolvedPath { - path, - param_names: None, - did, - is_generic: false, - } - } - ty::Foreign(did) => { - inline::record_extern_fqn(cx, did, TypeKind::Foreign); - let path = external_path(cx, cx.tcx.item_name(did), - None, false, vec![], InternalSubsts::empty()); - ResolvedPath { - path, - param_names: None, - did, - is_generic: false, - } - } - ty::Dynamic(ref obj, ref reg) => { - // HACK: pick the first `did` as the `did` of the trait object. Someone - // might want to implement "native" support for marker-trait-only - // trait objects. - let mut dids = obj.principal_def_id().into_iter().chain(obj.auto_traits()); - let did = dids.next().unwrap_or_else(|| { - panic!("found trait object `{:?}` with no traits?", self) - }); - let substs = match obj.principal() { - Some(principal) => principal.skip_binder().substs, - // marker traits have no substs. - _ => cx.tcx.intern_substs(&[]) - }; - - inline::record_extern_fqn(cx, did, TypeKind::Trait); - - let mut param_names = vec![]; - reg.clean(cx).map(|b| param_names.push(GenericBound::Outlives(b))); - for did in dids { - let empty = cx.tcx.intern_substs(&[]); - let path = external_path(cx, cx.tcx.item_name(did), - Some(did), false, vec![], empty); - inline::record_extern_fqn(cx, did, TypeKind::Trait); - let bound = GenericBound::TraitBound(PolyTrait { - trait_: ResolvedPath { - path, - param_names: None, - did, - is_generic: false, - }, - generic_params: Vec::new(), - }, hir::TraitBoundModifier::None); - param_names.push(bound); - } - - let mut bindings = vec![]; - for pb in obj.projection_bounds() { - bindings.push(TypeBinding { - name: cx.tcx.associated_item(pb.item_def_id()).ident.name.clean(cx), - kind: TypeBindingKind::Equality { - ty: pb.skip_binder().ty.clean(cx) - }, - }); - } - - let path = external_path(cx, cx.tcx.item_name(did), Some(did), - false, bindings, substs); - ResolvedPath { - path, - param_names: Some(param_names), - did, - is_generic: false, - } - } - ty::Tuple(ref t) => { - Tuple(t.iter().map(|t| t.expect_ty()).collect::>().clean(cx)) - } - - ty::Projection(ref data) => data.clean(cx), - - ty::Param(ref p) => { - if let Some(bounds) = cx.impl_trait_bounds.borrow_mut().remove(&p.index.into()) { - ImplTrait(bounds) - } else { - Generic(p.name.to_string()) - } - } - - ty::Opaque(def_id, substs) => { - // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`, - // by looking up the projections associated with the def_id. - let predicates_of = cx.tcx.explicit_predicates_of(def_id); - let substs = cx.tcx.lift(&substs).expect("Opaque lift failed"); - let bounds = predicates_of.instantiate(cx.tcx, substs); - let mut regions = vec![]; - let mut has_sized = false; - let mut bounds = bounds.predicates.iter().filter_map(|predicate| { - let trait_ref = if let Some(tr) = predicate.to_opt_poly_trait_ref() { - tr - } else if let ty::Predicate::TypeOutlives(pred) = *predicate { - // these should turn up at the end - pred.skip_binder().1.clean(cx).map(|r| { - regions.push(GenericBound::Outlives(r)) - }); - return None; - } else { - return None; - }; - - if let Some(sized) = cx.tcx.lang_items().sized_trait() { - if trait_ref.def_id() == sized { - has_sized = true; - return None; - } - } - - let bounds = bounds.predicates.iter().filter_map(|pred| - if let ty::Predicate::Projection(proj) = *pred { - let proj = proj.skip_binder(); - if proj.projection_ty.trait_ref(cx.tcx) == *trait_ref.skip_binder() { - Some(TypeBinding { - name: cx.tcx.associated_item(proj.projection_ty.item_def_id) - .ident.name.clean(cx), - kind: TypeBindingKind::Equality { - ty: proj.ty.clean(cx), - }, - }) - } else { - None - } - } else { - None - } - ).collect(); - - Some((trait_ref.skip_binder(), bounds).clean(cx)) - }).collect::>(); - bounds.extend(regions); - if !has_sized && !bounds.is_empty() { - bounds.insert(0, GenericBound::maybe_sized(cx)); - } - ImplTrait(bounds) - } - - ty::Closure(..) | ty::Generator(..) => Tuple(vec![]), // FIXME(pcwalton) - - ty::Bound(..) => panic!("Bound"), - ty::Placeholder(..) => panic!("Placeholder"), - ty::UnnormalizedProjection(..) => panic!("UnnormalizedProjection"), - ty::GeneratorWitness(..) => panic!("GeneratorWitness"), - ty::Infer(..) => panic!("Infer"), - ty::Error => panic!("Error"), - } - } -} - -impl<'tcx> Clean for ty::Const<'tcx> { - fn clean(&self, cx: &DocContext<'_>) -> Constant { - Constant { - type_: self.ty.clean(cx), - expr: format!("{}", self), - } - } -} - -impl Clean for hir::StructField { - fn clean(&self, cx: &DocContext<'_>) -> Item { - let local_did = cx.tcx.hir().local_def_id(self.hir_id); - - Item { - name: Some(self.ident.name).clean(cx), - attrs: self.attrs.clean(cx), - source: self.span.clean(cx), - visibility: self.vis.clean(cx), - stability: get_stability(cx, local_did), - deprecation: get_deprecation(cx, local_did), - def_id: local_did, - inner: StructFieldItem(self.ty.clean(cx)), - } - } -} - -impl Clean for ty::FieldDef { - fn clean(&self, cx: &DocContext<'_>) -> Item { - Item { - name: Some(self.ident.name).clean(cx), - attrs: cx.tcx.get_attrs(self.did).clean(cx), - source: cx.tcx.def_span(self.did).clean(cx), - visibility: self.vis.clean(cx), - stability: get_stability(cx, self.did), - deprecation: get_deprecation(cx, self.did), - def_id: self.did, - inner: StructFieldItem(cx.tcx.type_of(self.did).clean(cx)), - } - } -} - #[derive(Clone, PartialEq, Eq, Debug)] pub enum Visibility { Public, @@ -3318,27 +1337,6 @@ pub enum Visibility { Restricted(DefId, Path), } -impl Clean for hir::Visibility { - fn clean(&self, cx: &DocContext<'_>) -> Visibility { - match self.node { - hir::VisibilityKind::Public => Visibility::Public, - hir::VisibilityKind::Inherited => Visibility::Inherited, - hir::VisibilityKind::Crate(_) => Visibility::Crate, - hir::VisibilityKind::Restricted { ref path, .. } => { - let path = path.clean(cx); - let did = register_res(cx, path.res); - Visibility::Restricted(did, path) - } - } - } -} - -impl Clean for ty::Visibility { - fn clean(&self, _: &DocContext<'_>) -> Visibility { - if *self == ty::Visibility::Public { Public } else { Inherited } - } -} - #[derive(Clone, Debug)] pub struct Struct { pub struct_type: doctree::StructType, @@ -3355,46 +1353,6 @@ pub struct Union { pub fields_stripped: bool, } -impl Clean for doctree::Struct<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Item { - Item { - name: Some(self.name.clean(cx)), - attrs: self.attrs.clean(cx), - source: self.whence.clean(cx), - def_id: cx.tcx.hir().local_def_id(self.id), - visibility: self.vis.clean(cx), - stability: cx.stability(self.id).clean(cx), - deprecation: cx.deprecation(self.id).clean(cx), - inner: StructItem(Struct { - struct_type: self.struct_type, - generics: self.generics.clean(cx), - fields: self.fields.clean(cx), - fields_stripped: false, - }), - } - } -} - -impl Clean for doctree::Union<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Item { - Item { - name: Some(self.name.clean(cx)), - attrs: self.attrs.clean(cx), - source: self.whence.clean(cx), - def_id: cx.tcx.hir().local_def_id(self.id), - visibility: self.vis.clean(cx), - stability: cx.stability(self.id).clean(cx), - deprecation: cx.deprecation(self.id).clean(cx), - inner: UnionItem(Union { - struct_type: self.struct_type, - generics: self.generics.clean(cx), - fields: self.fields.clean(cx), - fields_stripped: false, - }), - } - } -} - /// 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. @@ -3405,16 +1363,6 @@ pub struct VariantStruct { pub fields_stripped: bool, } -impl Clean for ::rustc::hir::VariantData { - fn clean(&self, cx: &DocContext<'_>) -> VariantStruct { - VariantStruct { - struct_type: doctree::struct_type_from_def(self), - fields: self.fields().iter().map(|x| x.clean(cx)).collect(), - fields_stripped: false, - } - } -} - #[derive(Clone, Debug)] pub struct Enum { pub variants: IndexVec, @@ -3422,88 +1370,11 @@ pub struct Enum { pub variants_stripped: bool, } -impl Clean for doctree::Enum<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Item { - Item { - name: Some(self.name.clean(cx)), - attrs: self.attrs.clean(cx), - source: self.whence.clean(cx), - def_id: cx.tcx.hir().local_def_id(self.id), - visibility: self.vis.clean(cx), - stability: cx.stability(self.id).clean(cx), - deprecation: cx.deprecation(self.id).clean(cx), - inner: EnumItem(Enum { - variants: self.variants.iter().map(|v| v.clean(cx)).collect(), - generics: self.generics.clean(cx), - variants_stripped: false, - }), - } - } -} - #[derive(Clone, Debug)] pub struct Variant { pub kind: VariantKind, } -impl Clean for doctree::Variant<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Item { - Item { - name: Some(self.name.clean(cx)), - attrs: self.attrs.clean(cx), - source: self.whence.clean(cx), - visibility: Inherited, - stability: cx.stability(self.id).clean(cx), - deprecation: cx.deprecation(self.id).clean(cx), - def_id: cx.tcx.hir().local_def_id(self.id), - inner: VariantItem(Variant { - kind: self.def.clean(cx), - }), - } - } -} - -impl Clean for ty::VariantDef { - fn clean(&self, cx: &DocContext<'_>) -> Item { - let kind = match self.ctor_kind { - CtorKind::Const => VariantKind::CLike, - CtorKind::Fn => { - VariantKind::Tuple( - self.fields.iter().map(|f| cx.tcx.type_of(f.did).clean(cx)).collect() - ) - } - CtorKind::Fictive => { - VariantKind::Struct(VariantStruct { - struct_type: doctree::Plain, - fields_stripped: false, - fields: self.fields.iter().map(|field| { - Item { - source: cx.tcx.def_span(field.did).clean(cx), - name: Some(field.ident.name.clean(cx)), - attrs: cx.tcx.get_attrs(field.did).clean(cx), - visibility: field.vis.clean(cx), - def_id: field.did, - stability: get_stability(cx, field.did), - deprecation: get_deprecation(cx, field.did), - inner: StructFieldItem(cx.tcx.type_of(field.did).clean(cx)) - } - }).collect() - }) - } - }; - Item { - name: Some(self.ident.clean(cx)), - attrs: inline::load_attrs(cx, self.def_id).clean(cx), - source: cx.tcx.def_span(self.def_id).clean(cx), - visibility: Inherited, - def_id: self.def_id, - inner: VariantItem(Variant { kind }), - stability: get_stability(cx, self.def_id), - deprecation: get_deprecation(cx, self.def_id), - } - } -} - #[derive(Clone, Debug)] pub enum VariantKind { CLike, @@ -3511,17 +1382,6 @@ pub enum VariantKind { Struct(VariantStruct), } -impl Clean for hir::VariantData { - fn clean(&self, cx: &DocContext<'_>) -> VariantKind { - match self { - hir::VariantData::Struct(..) => VariantKind::Struct(self.clean(cx)), - hir::VariantData::Tuple(..) => - VariantKind::Tuple(self.fields().iter().map(|x| x.ty.clean(cx)).collect()), - hir::VariantData::Unit(..) => VariantKind::CLike, - } - } -} - #[derive(Clone, Debug)] pub struct Span { pub filename: FileName, @@ -3547,27 +1407,6 @@ impl Span { } } -impl Clean for syntax_pos::Span { - fn clean(&self, cx: &DocContext<'_>) -> Span { - if self.is_dummy() { - return Span::empty(); - } - - let cm = cx.sess().source_map(); - let filename = cm.span_to_filename(*self); - let lo = cm.lookup_char_pos(self.lo()); - let hi = cm.lookup_char_pos(self.hi()); - Span { - filename, - loline: lo.line, - locol: lo.col.to_usize(), - hiline: hi.line, - hicol: hi.col.to_usize(), - original: *self, - } - } -} - #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub struct Path { pub global: bool, @@ -3581,16 +1420,6 @@ impl Path { } } -impl Clean for hir::Path { - fn clean(&self, cx: &DocContext<'_>) -> Path { - Path { - global: self.is_global(), - res: self.res, - segments: if self.is_global() { &self.segments[1..] } else { &self.segments }.clean(cx), - } - } -} - #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub enum GenericArg { Lifetime(Lifetime), @@ -3610,171 +1439,24 @@ pub enum GenericArgs { } } -impl Clean for hir::GenericArgs { - fn clean(&self, cx: &DocContext<'_>) -> GenericArgs { - if self.parenthesized { - let output = self.bindings[0].ty().clean(cx); - GenericArgs::Parenthesized { - inputs: self.inputs().clean(cx), - output: if output != Type::Tuple(Vec::new()) { Some(output) } else { None } - } - } else { - let elide_lifetimes = self.args.iter().all(|arg| match arg { - hir::GenericArg::Lifetime(lt) => lt.is_elided(), - _ => true, - }); - GenericArgs::AngleBracketed { - args: self.args.iter().filter_map(|arg| match arg { - hir::GenericArg::Lifetime(lt) if !elide_lifetimes => { - Some(GenericArg::Lifetime(lt.clean(cx))) - } - hir::GenericArg::Lifetime(_) => None, - hir::GenericArg::Type(ty) => Some(GenericArg::Type(ty.clean(cx))), - hir::GenericArg::Const(ct) => Some(GenericArg::Const(ct.clean(cx))), - }).collect(), - bindings: self.bindings.clean(cx), - } - } - } -} - #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub struct PathSegment { pub name: String, pub args: GenericArgs, } -impl Clean for hir::PathSegment { - fn clean(&self, cx: &DocContext<'_>) -> PathSegment { - PathSegment { - name: self.ident.name.clean(cx), - args: self.generic_args().clean(cx), - } - } -} - -fn strip_type(ty: Type) -> Type { - match ty { - Type::ResolvedPath { path, param_names, did, is_generic } => { - Type::ResolvedPath { path: strip_path(&path), param_names, did, is_generic } - } - Type::Tuple(inner_tys) => { - Type::Tuple(inner_tys.iter().map(|t| strip_type(t.clone())).collect()) - } - Type::Slice(inner_ty) => Type::Slice(Box::new(strip_type(*inner_ty))), - Type::Array(inner_ty, s) => Type::Array(Box::new(strip_type(*inner_ty)), s), - Type::RawPointer(m, inner_ty) => Type::RawPointer(m, Box::new(strip_type(*inner_ty))), - Type::BorrowedRef { lifetime, mutability, type_ } => { - Type::BorrowedRef { lifetime, mutability, type_: Box::new(strip_type(*type_)) } - } - Type::QPath { name, self_type, trait_ } => { - Type::QPath { - name, - self_type: Box::new(strip_type(*self_type)), trait_: Box::new(strip_type(*trait_)) - } - } - _ => ty - } -} - -fn strip_path(path: &Path) -> Path { - let segments = path.segments.iter().map(|s| { - PathSegment { - name: s.name.clone(), - args: GenericArgs::AngleBracketed { - args: vec![], - bindings: vec![], - } - } - }).collect(); - - Path { - global: path.global, - res: path.res.clone(), - segments, - } -} - -fn qpath_to_string(p: &hir::QPath) -> String { - let segments = match *p { - hir::QPath::Resolved(_, ref path) => &path.segments, - hir::QPath::TypeRelative(_, ref segment) => return segment.ident.to_string(), - }; - - let mut s = String::new(); - for (i, seg) in segments.iter().enumerate() { - if i > 0 { - s.push_str("::"); - } - if seg.ident.name != kw::PathRoot { - s.push_str(&seg.ident.as_str()); - } - } - s -} - -impl Clean for Ident { - #[inline] - fn clean(&self, cx: &DocContext<'_>) -> String { - self.name.clean(cx) - } -} - -impl Clean for ast::Name { - #[inline] - fn clean(&self, _: &DocContext<'_>) -> String { - self.to_string() - } -} - #[derive(Clone, Debug)] pub struct Typedef { pub type_: Type, pub generics: Generics, } -impl Clean for doctree::Typedef<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Item { - Item { - name: Some(self.name.clean(cx)), - attrs: self.attrs.clean(cx), - source: self.whence.clean(cx), - def_id: cx.tcx.hir().local_def_id(self.id), - visibility: self.vis.clean(cx), - stability: cx.stability(self.id).clean(cx), - deprecation: cx.deprecation(self.id).clean(cx), - inner: TypedefItem(Typedef { - type_: self.ty.clean(cx), - generics: self.gen.clean(cx), - }, false), - } - } -} - #[derive(Clone, Debug)] pub struct OpaqueTy { pub bounds: Vec, pub generics: Generics, } -impl Clean for doctree::OpaqueTy<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Item { - Item { - name: Some(self.name.clean(cx)), - attrs: self.attrs.clean(cx), - source: self.whence.clean(cx), - def_id: cx.tcx.hir().local_def_id(self.id), - visibility: self.vis.clean(cx), - stability: cx.stability(self.id).clean(cx), - deprecation: cx.deprecation(self.id).clean(cx), - inner: OpaqueTyItem(OpaqueTy { - bounds: self.opaque_ty.bounds.clean(cx), - generics: self.opaque_ty.generics.clean(cx), - }, false), - } - } -} - #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub struct BareFunctionDecl { pub unsafety: hir::Unsafety, @@ -3783,20 +1465,6 @@ pub struct BareFunctionDecl { pub abi: Abi, } -impl Clean for hir::BareFnTy { - fn clean(&self, cx: &DocContext<'_>) -> BareFunctionDecl { - let (generic_params, decl) = enter_impl_trait(cx, || { - (self.generic_params.clean(cx), (&*self.decl, &self.param_names[..]).clean(cx)) - }); - BareFunctionDecl { - unsafety: self.unsafety, - abi: self.abi, - decl, - generic_params, - } - } -} - #[derive(Clone, Debug)] pub struct Static { pub type_: Type, @@ -3807,82 +1475,24 @@ pub struct Static { pub expr: String, } -impl Clean for doctree::Static<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Item { - debug!("cleaning static {}: {:?}", self.name.clean(cx), self); - Item { - name: Some(self.name.clean(cx)), - attrs: self.attrs.clean(cx), - source: self.whence.clean(cx), - def_id: cx.tcx.hir().local_def_id(self.id), - visibility: self.vis.clean(cx), - stability: cx.stability(self.id).clean(cx), - deprecation: cx.deprecation(self.id).clean(cx), - inner: StaticItem(Static { - type_: self.type_.clean(cx), - mutability: self.mutability.clean(cx), - expr: print_const_expr(cx, self.expr), - }), - } - } -} - #[derive(Clone, PartialEq, Eq, Hash, Debug)] pub struct Constant { pub type_: Type, pub expr: String, } -impl Clean for doctree::Constant<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Item { - Item { - name: Some(self.name.clean(cx)), - attrs: self.attrs.clean(cx), - source: self.whence.clean(cx), - def_id: cx.tcx.hir().local_def_id(self.id), - visibility: self.vis.clean(cx), - stability: cx.stability(self.id).clean(cx), - deprecation: cx.deprecation(self.id).clean(cx), - inner: ConstantItem(Constant { - type_: self.type_.clean(cx), - expr: print_const_expr(cx, self.expr), - }), - } - } -} - #[derive(Debug, Clone, PartialEq, Eq, Copy, Hash)] pub enum Mutability { Mutable, Immutable, } -impl Clean for hir::Mutability { - fn clean(&self, _: &DocContext<'_>) -> Mutability { - match self { - &hir::Mutability::Mutable => Mutable, - &hir::Mutability::Immutable => Immutable, - } - } -} - #[derive(Clone, PartialEq, Debug)] pub enum ImplPolarity { Positive, Negative, } -impl Clean for ty::ImplPolarity { - fn clean(&self, _: &DocContext<'_>) -> ImplPolarity { - match self { - &ty::ImplPolarity::Positive | - // FIXME: do we want to do something else here? - &ty::ImplPolarity::Reservation => ImplPolarity::Positive, - &ty::ImplPolarity::Negative => ImplPolarity::Negative, - } - } -} - #[derive(Clone, Debug)] pub struct Impl { pub unsafety: hir::Unsafety, @@ -3896,225 +1506,6 @@ pub struct Impl { pub blanket_impl: Option, } -pub fn get_auto_trait_and_blanket_impls( - cx: &DocContext<'tcx>, - ty: Ty<'tcx>, - param_env_def_id: DefId, -) -> impl Iterator { - AutoTraitFinder::new(cx).get_auto_trait_impls(ty, param_env_def_id).into_iter() - .chain(BlanketImplFinder::new(cx).get_blanket_impls(ty, param_env_def_id)) -} - -impl Clean> for doctree::Impl<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Vec { - let mut ret = Vec::new(); - let trait_ = self.trait_.clean(cx); - let items = self.items.iter().map(|ii| ii.clean(cx)).collect::>(); - let def_id = cx.tcx.hir().local_def_id(self.id); - - // If this impl block is an implementation of the Deref trait, then we - // need to try inlining the target's inherent impl blocks as well. - if trait_.def_id() == cx.tcx.lang_items().deref_trait() { - build_deref_target_impls(cx, &items, &mut ret); - } - - let provided = trait_.def_id().map(|did| { - cx.tcx.provided_trait_methods(did) - .into_iter() - .map(|meth| meth.ident.to_string()) - .collect() - }).unwrap_or_default(); - - ret.push(Item { - name: None, - attrs: self.attrs.clean(cx), - source: self.whence.clean(cx), - def_id, - visibility: self.vis.clean(cx), - stability: cx.stability(self.id).clean(cx), - deprecation: cx.deprecation(self.id).clean(cx), - inner: ImplItem(Impl { - unsafety: self.unsafety, - generics: self.generics.clean(cx), - provided_trait_methods: provided, - trait_, - for_: self.for_.clean(cx), - items, - polarity: Some(cx.tcx.impl_polarity(def_id).clean(cx)), - synthetic: false, - blanket_impl: None, - }) - }); - ret - } -} - -fn build_deref_target_impls(cx: &DocContext<'_>, - items: &[Item], - ret: &mut Vec) { - use self::PrimitiveType::*; - let tcx = cx.tcx; - - for item in items { - let target = match item.inner { - TypedefItem(ref t, true) => &t.type_, - _ => continue, - }; - let primitive = match *target { - ResolvedPath { did, .. } if did.is_local() => continue, - ResolvedPath { did, .. } => { - ret.extend(inline::build_impls(cx, did, None)); - continue - } - _ => match target.primitive_type() { - Some(prim) => prim, - None => continue, - } - }; - let did = match primitive { - Isize => tcx.lang_items().isize_impl(), - I8 => tcx.lang_items().i8_impl(), - I16 => tcx.lang_items().i16_impl(), - I32 => tcx.lang_items().i32_impl(), - I64 => tcx.lang_items().i64_impl(), - I128 => tcx.lang_items().i128_impl(), - Usize => tcx.lang_items().usize_impl(), - U8 => tcx.lang_items().u8_impl(), - U16 => tcx.lang_items().u16_impl(), - U32 => tcx.lang_items().u32_impl(), - U64 => tcx.lang_items().u64_impl(), - U128 => tcx.lang_items().u128_impl(), - F32 => tcx.lang_items().f32_impl(), - F64 => tcx.lang_items().f64_impl(), - Char => tcx.lang_items().char_impl(), - Bool => tcx.lang_items().bool_impl(), - Str => tcx.lang_items().str_impl(), - Slice => tcx.lang_items().slice_impl(), - Array => tcx.lang_items().slice_impl(), - Tuple => None, - Unit => None, - RawPointer => tcx.lang_items().const_ptr_impl(), - Reference => None, - Fn => None, - Never => None, - }; - if let Some(did) = did { - if !did.is_local() { - inline::build_impl(cx, did, None, ret); - } - } - } -} - -impl Clean> for doctree::ExternCrate<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Vec { - - let please_inline = self.vis.node.is_pub() && self.attrs.iter().any(|a| { - a.check_name(sym::doc) && match a.meta_item_list() { - Some(l) => attr::list_contains_name(&l, sym::inline), - None => false, - } - }); - - if please_inline { - let mut visited = FxHashSet::default(); - - let res = Res::Def( - DefKind::Mod, - DefId { - krate: self.cnum, - index: CRATE_DEF_INDEX, - }, - ); - - if let Some(items) = inline::try_inline( - cx, res, self.name, - Some(rustc::ty::Attributes::Borrowed(self.attrs)), - &mut visited - ) { - return items; - } - } - - vec![Item { - name: None, - attrs: self.attrs.clean(cx), - source: self.whence.clean(cx), - def_id: DefId { krate: self.cnum, index: CRATE_DEF_INDEX }, - visibility: self.vis.clean(cx), - stability: None, - deprecation: None, - inner: ExternCrateItem(self.name.clean(cx), self.path.clone()) - }] - } -} - -impl Clean> for doctree::Import<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Vec { - // We consider inlining the documentation of `pub use` statements, but we - // forcefully don't inline if this is not public or if the - // #[doc(no_inline)] attribute is present. - // Don't inline doc(hidden) imports so they can be stripped at a later stage. - let mut denied = !self.vis.node.is_pub() || self.attrs.iter().any(|a| { - a.check_name(sym::doc) && match a.meta_item_list() { - Some(l) => attr::list_contains_name(&l, sym::no_inline) || - attr::list_contains_name(&l, sym::hidden), - None => false, - } - }); - // Also check whether imports were asked to be inlined, in case we're trying to re-export a - // crate in Rust 2018+ - let please_inline = self.attrs.lists(sym::doc).has_word(sym::inline); - let path = self.path.clean(cx); - let inner = if self.glob { - if !denied { - let mut visited = FxHashSet::default(); - if let Some(items) = inline::try_inline_glob(cx, path.res, &mut visited) { - return items; - } - } - - Import::Glob(resolve_use_source(cx, path)) - } else { - let name = self.name; - if !please_inline { - match path.res { - Res::Def(DefKind::Mod, did) => { - if !did.is_local() && did.index == CRATE_DEF_INDEX { - // if we're `pub use`ing an extern crate root, don't inline it unless we - // were specifically asked for it - denied = true; - } - } - _ => {} - } - } - if !denied { - let mut visited = FxHashSet::default(); - if let Some(items) = inline::try_inline( - cx, path.res, name, - Some(rustc::ty::Attributes::Borrowed(self.attrs)), - &mut visited - ) { - return items; - } - } - Import::Simple(name.clean(cx), resolve_use_source(cx, path)) - }; - - vec![Item { - name: None, - attrs: self.attrs.clean(cx), - source: self.whence.clean(cx), - def_id: cx.tcx.hir().local_def_id_from_node_id(ast::CRATE_NODE_ID), - visibility: self.vis.clean(cx), - stability: None, - deprecation: None, - inner: ImportItem(inner) - }] - } -} - #[derive(Clone, Debug)] pub enum Import { // use source as str; @@ -4129,270 +1520,18 @@ pub struct ImportSource { pub did: Option, } -impl Clean for doctree::ForeignItem<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Item { - let inner = match self.kind { - hir::ForeignItemKind::Fn(ref decl, ref names, ref generics) => { - let abi = cx.tcx.hir().get_foreign_abi(self.id); - let (generics, decl) = enter_impl_trait(cx, || { - (generics.clean(cx), (&**decl, &names[..]).clean(cx)) - }); - let (all_types, ret_types) = get_all_types(&generics, &decl, cx); - ForeignFunctionItem(Function { - decl, - generics, - header: hir::FnHeader { - unsafety: hir::Unsafety::Unsafe, - abi, - constness: hir::Constness::NotConst, - asyncness: hir::IsAsync::NotAsync, - }, - all_types, - ret_types, - }) - } - hir::ForeignItemKind::Static(ref ty, mutbl) => { - ForeignStaticItem(Static { - type_: ty.clean(cx), - mutability: mutbl.clean(cx), - expr: String::new(), - }) - } - hir::ForeignItemKind::Type => { - ForeignTypeItem - } - }; - - Item { - name: Some(self.name.clean(cx)), - attrs: self.attrs.clean(cx), - source: self.whence.clean(cx), - def_id: cx.tcx.hir().local_def_id(self.id), - visibility: self.vis.clean(cx), - stability: cx.stability(self.id).clean(cx), - deprecation: cx.deprecation(self.id).clean(cx), - inner, - } - } -} - -// Utilities - -pub trait ToSource { - fn to_src(&self, cx: &DocContext<'_>) -> String; -} - -impl ToSource for syntax_pos::Span { - fn to_src(&self, cx: &DocContext<'_>) -> String { - debug!("converting span {:?} to snippet", self.clean(cx)); - let sn = match cx.sess().source_map().span_to_snippet(*self) { - Ok(x) => x, - Err(_) => String::new() - }; - debug!("got snippet {}", sn); - sn - } -} - -fn name_from_pat(p: &hir::Pat) -> String { - use rustc::hir::*; - debug!("trying to get a name from pattern: {:?}", p); - - match p.kind { - PatKind::Wild => "_".to_string(), - PatKind::Binding(_, _, ident, _) => ident.to_string(), - PatKind::TupleStruct(ref p, ..) | PatKind::Path(ref p) => qpath_to_string(p), - PatKind::Struct(ref name, ref fields, etc) => { - format!("{} {{ {}{} }}", qpath_to_string(name), - fields.iter().map(|fp| format!("{}: {}", fp.ident, name_from_pat(&fp.pat))) - .collect::>().join(", "), - if etc { ", .." } else { "" } - ) - } - PatKind::Or(ref pats) => { - pats.iter().map(|p| name_from_pat(&**p)).collect::>().join(" | ") - } - PatKind::Tuple(ref elts, _) => format!("({})", elts.iter().map(|p| name_from_pat(&**p)) - .collect::>().join(", ")), - PatKind::Box(ref p) => name_from_pat(&**p), - PatKind::Ref(ref p, _) => name_from_pat(&**p), - PatKind::Lit(..) => { - warn!("tried to get argument name from PatKind::Lit, \ - which is silly in function arguments"); - "()".to_string() - }, - PatKind::Range(..) => panic!("tried to get argument name from PatKind::Range, \ - which is not allowed in function arguments"), - PatKind::Slice(ref begin, ref mid, ref end) => { - let begin = begin.iter().map(|p| name_from_pat(&**p)); - let mid = mid.as_ref().map(|p| format!("..{}", name_from_pat(&**p))).into_iter(); - let end = end.iter().map(|p| name_from_pat(&**p)); - format!("[{}]", begin.chain(mid).chain(end).collect::>().join(", ")) - }, - } -} - -fn print_const(cx: &DocContext<'_>, n: &ty::Const<'_>) -> String { - match n.val { - ty::ConstKind::Unevaluated(def_id, _) => { - if let Some(hir_id) = cx.tcx.hir().as_local_hir_id(def_id) { - print_const_expr(cx, cx.tcx.hir().body_owned_by(hir_id)) - } else { - inline::print_inlined_const(cx, def_id) - } - }, - _ => { - let mut s = n.to_string(); - // array lengths are obviously usize - if s.ends_with("usize") { - let n = s.len() - "usize".len(); - s.truncate(n); - if s.ends_with(": ") { - let n = s.len() - ": ".len(); - s.truncate(n); - } - } - s - }, - } -} - -fn print_const_expr(cx: &DocContext<'_>, body: hir::BodyId) -> String { - cx.tcx.hir().hir_to_pretty_string(body.hir_id) -} - -/// Given a type Path, resolve it to a Type using the TyCtxt -fn resolve_type(cx: &DocContext<'_>, - path: Path, - id: hir::HirId) -> Type { - if id == hir::DUMMY_HIR_ID { - debug!("resolve_type({:?})", path); - } else { - debug!("resolve_type({:?},{:?})", path, id); - } - - let is_generic = match path.res { - Res::PrimTy(p) => match p { - hir::Str => return Primitive(PrimitiveType::Str), - hir::Bool => return Primitive(PrimitiveType::Bool), - hir::Char => return Primitive(PrimitiveType::Char), - hir::Int(int_ty) => return Primitive(int_ty.into()), - hir::Uint(uint_ty) => return Primitive(uint_ty.into()), - hir::Float(float_ty) => return Primitive(float_ty.into()), - }, - Res::SelfTy(..) if path.segments.len() == 1 => { - return Generic(kw::SelfUpper.to_string()); - } - Res::Def(DefKind::TyParam, _) if path.segments.len() == 1 => { - return Generic(format!("{:#}", path.print())); - } - Res::SelfTy(..) - | Res::Def(DefKind::TyParam, _) - | Res::Def(DefKind::AssocTy, _) => true, - _ => false, - }; - let did = register_res(&*cx, path.res); - ResolvedPath { path, param_names: None, did, is_generic } -} - -pub fn register_res(cx: &DocContext<'_>, res: Res) -> DefId { - debug!("register_res({:?})", res); - - let (did, kind) = match res { - Res::Def(DefKind::Fn, i) => (i, TypeKind::Function), - Res::Def(DefKind::TyAlias, i) => (i, TypeKind::Typedef), - Res::Def(DefKind::Enum, i) => (i, TypeKind::Enum), - Res::Def(DefKind::Trait, i) => (i, TypeKind::Trait), - Res::Def(DefKind::Struct, i) => (i, TypeKind::Struct), - Res::Def(DefKind::Union, i) => (i, TypeKind::Union), - Res::Def(DefKind::Mod, i) => (i, TypeKind::Module), - Res::Def(DefKind::ForeignTy, i) => (i, TypeKind::Foreign), - Res::Def(DefKind::Const, i) => (i, TypeKind::Const), - Res::Def(DefKind::Static, i) => (i, TypeKind::Static), - Res::Def(DefKind::Variant, i) => (cx.tcx.parent(i).expect("cannot get parent def id"), - TypeKind::Enum), - Res::Def(DefKind::Macro(mac_kind), i) => match mac_kind { - MacroKind::Bang => (i, TypeKind::Macro), - MacroKind::Attr => (i, TypeKind::Attr), - MacroKind::Derive => (i, TypeKind::Derive), - }, - Res::Def(DefKind::TraitAlias, i) => (i, TypeKind::TraitAlias), - Res::SelfTy(Some(def_id), _) => (def_id, TypeKind::Trait), - Res::SelfTy(_, Some(impl_def_id)) => return impl_def_id, - _ => return res.def_id() - }; - if did.is_local() { return did } - inline::record_extern_fqn(cx, did, kind); - if let TypeKind::Trait = kind { - inline::record_extern_trait(cx, did); - } - did -} - -fn resolve_use_source(cx: &DocContext<'_>, path: Path) -> ImportSource { - ImportSource { - did: if path.res.opt_def_id().is_none() { - None - } else { - Some(register_res(cx, path.res)) - }, - path, - } -} - #[derive(Clone, Debug)] pub struct Macro { pub source: String, pub imported_from: Option, } -impl Clean for doctree::Macro<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Item { - let name = self.name.clean(cx); - Item { - name: Some(name.clone()), - attrs: self.attrs.clean(cx), - source: self.whence.clean(cx), - visibility: Public, - stability: cx.stability(self.hid).clean(cx), - deprecation: cx.deprecation(self.hid).clean(cx), - def_id: self.def_id, - inner: MacroItem(Macro { - source: format!("macro_rules! {} {{\n{}}}", - name, - self.matchers.iter().map(|span| { - format!(" {} => {{ ... }};\n", span.to_src(cx)) - }).collect::()), - imported_from: self.imported_from.clean(cx), - }), - } - } -} - #[derive(Clone, Debug)] pub struct ProcMacro { pub kind: MacroKind, pub helpers: Vec, } -impl Clean for doctree::ProcMacro<'_> { - fn clean(&self, cx: &DocContext<'_>) -> Item { - Item { - name: Some(self.name.clean(cx)), - attrs: self.attrs.clean(cx), - source: self.whence.clean(cx), - visibility: Public, - stability: cx.stability(self.id).clean(cx), - deprecation: cx.deprecation(self.id).clean(cx), - def_id: cx.tcx.hir().local_def_id(self.id), - inner: ProcMacroItem(ProcMacro { - kind: self.kind, - helpers: self.helpers.clean(cx), - }), - } - } -} - #[derive(Clone, Debug)] pub struct Stability { pub level: stability::StabilityLevel, @@ -4409,48 +1548,6 @@ pub struct Deprecation { pub note: Option, } -impl Clean for attr::Stability { - fn clean(&self, _: &DocContext<'_>) -> Stability { - Stability { - level: stability::StabilityLevel::from_attr_level(&self.level), - feature: Some(self.feature.to_string()).filter(|f| !f.is_empty()), - since: match self.level { - attr::Stable {ref since} => since.to_string(), - _ => String::new(), - }, - deprecation: self.rustc_depr.as_ref().map(|d| { - Deprecation { - note: Some(d.reason.to_string()).filter(|r| !r.is_empty()), - since: Some(d.since.to_string()).filter(|d| !d.is_empty()), - } - }), - unstable_reason: match self.level { - attr::Unstable { reason: Some(ref reason), .. } => Some(reason.to_string()), - _ => None, - }, - issue: match self.level { - attr::Unstable {issue, ..} => issue, - _ => None, - } - } - } -} - -impl<'a> Clean for &'a attr::Stability { - fn clean(&self, dc: &DocContext<'_>) -> Stability { - (**self).clean(dc) - } -} - -impl Clean for attr::Deprecation { - fn clean(&self, _: &DocContext<'_>) -> Deprecation { - Deprecation { - since: self.since.map(|s| s.to_string()).filter(|s| !s.is_empty()), - note: self.note.map(|n| n.to_string()).filter(|n| !n.is_empty()), - } - } -} - /// An type binding on an associated type (e.g., `A = Bar` in `Foo` or /// `A: Send + Sync` in `Foo`). #[derive(Clone, PartialEq, Eq, Debug, Hash)] @@ -4477,75 +1574,3 @@ impl TypeBinding { } } } - -impl Clean for hir::TypeBinding { - fn clean(&self, cx: &DocContext<'_>) -> TypeBinding { - TypeBinding { - name: self.ident.name.clean(cx), - kind: self.kind.clean(cx), - } - } -} - -impl Clean for hir::TypeBindingKind { - fn clean(&self, cx: &DocContext<'_>) -> TypeBindingKind { - match *self { - hir::TypeBindingKind::Equality { ref ty } => - TypeBindingKind::Equality { - ty: ty.clean(cx), - }, - hir::TypeBindingKind::Constraint { ref bounds } => - TypeBindingKind::Constraint { - bounds: bounds.into_iter().map(|b| b.clean(cx)).collect(), - }, - } - } -} - -pub fn enter_impl_trait(cx: &DocContext<'_>, f: F) -> R -where - F: FnOnce() -> R, -{ - let old_bounds = mem::take(&mut *cx.impl_trait_bounds.borrow_mut()); - let r = f(); - assert!(cx.impl_trait_bounds.borrow().is_empty()); - *cx.impl_trait_bounds.borrow_mut() = old_bounds; - r -} - -#[derive(Eq, PartialEq, Hash, Copy, Clone, Debug)] -enum RegionTarget<'tcx> { - Region(Region<'tcx>), - RegionVid(RegionVid) -} - -#[derive(Default, Debug, Clone)] -struct RegionDeps<'tcx> { - larger: FxHashSet>, - smaller: FxHashSet> -} - -enum SimpleBound { - TraitBound(Vec, Vec, Vec, hir::TraitBoundModifier), - Outlives(Lifetime), -} - -impl From for SimpleBound { - fn from(bound: GenericBound) -> Self { - match bound.clone() { - GenericBound::Outlives(l) => SimpleBound::Outlives(l), - GenericBound::TraitBound(t, mod_) => match t.trait_ { - Type::ResolvedPath { path, param_names, .. } => { - SimpleBound::TraitBound(path.segments, - param_names - .map_or_else(|| Vec::new(), |v| v.iter() - .map(|p| SimpleBound::from(p.clone())) - .collect()), - t.generic_params, - mod_) - } - _ => panic!("Unexpected bound {:?}", bound), - } - } - } -}