2013-09-12 21:10:51 -04:00
|
|
|
// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
|
|
|
|
// file at the top-level directory of this distribution and at
|
|
|
|
// http://rust-lang.org/COPYRIGHT.
|
|
|
|
//
|
|
|
|
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
|
|
|
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
|
|
|
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
|
|
|
// option. This file may not be copied, modified, or distributed
|
|
|
|
// except according to those terms.
|
|
|
|
|
2013-08-15 16:28:54 -04:00
|
|
|
//! This module contains the "cleaned" pieces of the AST, and the functions
|
|
|
|
//! that clean them.
|
|
|
|
|
2014-11-06 00:05:53 -08:00
|
|
|
pub use self::Type::*;
|
|
|
|
pub use self::Mutability::*;
|
|
|
|
pub use self::ItemEnum::*;
|
|
|
|
pub use self::TyParamBound::*;
|
|
|
|
pub use self::SelfTy::*;
|
|
|
|
pub use self::FunctionRetTy::*;
|
2016-04-11 08:15:14 +00:00
|
|
|
pub use self::Visibility::*;
|
2014-11-06 00:05:53 -08:00
|
|
|
|
2016-02-05 13:13:36 +01:00
|
|
|
use syntax::abi::Abi;
|
2013-08-15 16:28:54 -04:00
|
|
|
use syntax::ast;
|
2015-09-14 21:58:20 +12:00
|
|
|
use syntax::attr;
|
2016-06-21 19:57:03 -04:00
|
|
|
use syntax::codemap::Spanned;
|
2014-05-18 16:56:13 +03:00
|
|
|
use syntax::ptr::P;
|
2016-11-17 14:04:36 +00:00
|
|
|
use syntax::symbol::keywords;
|
2016-06-21 18:08:13 -04:00
|
|
|
use syntax_pos::{self, DUMMY_SP, Pos};
|
2013-08-15 16:28:54 -04:00
|
|
|
|
2017-08-05 16:11:24 +03:00
|
|
|
use rustc::middle::const_val::ConstVal;
|
2016-04-07 05:59:02 +02:00
|
|
|
use rustc::middle::privacy::AccessLevels;
|
2017-01-08 22:40:04 +02:00
|
|
|
use rustc::middle::resolve_lifetime as rl;
|
2016-11-13 19:42:15 -07:00
|
|
|
use rustc::middle::lang_items;
|
2016-09-15 00:51:46 +03:00
|
|
|
use rustc::hir::def::{Def, CtorKind};
|
2016-11-29 08:15:16 +02:00
|
|
|
use rustc::hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX, LOCAL_CRATE};
|
2017-08-07 08:08:53 +03:00
|
|
|
use rustc::traits::Reveal;
|
2016-08-17 06:32:00 +03:00
|
|
|
use rustc::ty::subst::Substs;
|
2017-09-14 21:44:23 -04:00
|
|
|
use rustc::ty::{self, Ty, AdtKind};
|
2014-06-26 11:37:39 -07:00
|
|
|
use rustc::middle::stability;
|
2016-11-08 14:02:55 +11:00
|
|
|
use rustc::util::nodemap::{FxHashMap, FxHashSet};
|
2017-05-03 11:53:06 -04:00
|
|
|
use rustc_typeck::hir_ty_to_ty;
|
2013-10-02 15:39:32 -07:00
|
|
|
|
2016-03-29 08:50:44 +03:00
|
|
|
use rustc::hir;
|
2015-07-31 00:04:06 -07:00
|
|
|
|
2017-08-05 16:11:24 +03:00
|
|
|
use rustc_const_math::ConstInt;
|
2017-03-03 09:23:59 +00:00
|
|
|
use std::{mem, slice, vec};
|
2015-04-06 15:10:55 -07:00
|
|
|
use std::path::PathBuf;
|
2014-05-23 00:42:33 -07:00
|
|
|
use std::rc::Rc;
|
2016-04-07 05:59:02 +02:00
|
|
|
use std::sync::Arc;
|
2014-05-28 19:53:37 -07:00
|
|
|
use std::u32;
|
2013-10-02 15:39:32 -07:00
|
|
|
|
2014-09-06 19:13:40 +03:00
|
|
|
use core::DocContext;
|
2013-08-15 16:28:54 -04:00
|
|
|
use doctree;
|
|
|
|
use visit_ast;
|
2016-03-31 18:15:54 +02:00
|
|
|
use html::item_type::ItemType;
|
2013-08-15 16:28:54 -04:00
|
|
|
|
2016-04-15 16:34:48 +02:00
|
|
|
pub mod inline;
|
2017-08-05 14:38:52 +08:00
|
|
|
pub mod cfg;
|
2015-04-06 21:17:51 -07:00
|
|
|
mod simplify;
|
2014-05-24 11:56:38 -07:00
|
|
|
|
2017-08-05 14:38:52 +08:00
|
|
|
use self::cfg::Cfg;
|
|
|
|
|
2014-09-06 19:13:40 +03:00
|
|
|
// extract the stability index for a node from tcx, if possible
|
2015-08-16 06:32:28 -04:00
|
|
|
fn get_stability(cx: &DocContext, def_id: DefId) -> Option<Stability> {
|
2016-11-20 03:42:54 +02:00
|
|
|
cx.tcx.lookup_stability(def_id).clean(cx)
|
2014-06-26 11:37:39 -07:00
|
|
|
}
|
|
|
|
|
2015-12-12 23:01:27 +03:00
|
|
|
fn get_deprecation(cx: &DocContext, def_id: DefId) -> Option<Deprecation> {
|
2016-11-20 03:42:54 +02:00
|
|
|
cx.tcx.lookup_deprecation(def_id).clean(cx)
|
2015-12-12 23:01:27 +03:00
|
|
|
}
|
|
|
|
|
2013-08-15 16:28:54 -04:00
|
|
|
pub trait Clean<T> {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> T;
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
|
2015-03-10 12:28:44 +02:00
|
|
|
impl<T: Clean<U>, U> Clean<Vec<U>> for [T] {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> Vec<U> {
|
|
|
|
self.iter().map(|x| x.clean(cx)).collect()
|
2014-02-28 17:46:09 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-18 16:56:13 +03:00
|
|
|
impl<T: Clean<U>, U> Clean<U> for P<T> {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> U {
|
|
|
|
(**self).clean(cx)
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-05-23 00:42:33 -07:00
|
|
|
impl<T: Clean<U>, U> Clean<U> for Rc<T> {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> U {
|
|
|
|
(**self).clean(cx)
|
2014-05-23 00:42:33 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-15 16:28:54 -04:00
|
|
|
impl<T: Clean<U>, U> Clean<Option<U>> for Option<T> {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> Option<U> {
|
2016-02-28 12:11:13 +01:00
|
|
|
self.as_ref().map(|v| v.clean(cx))
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-10 23:50:46 -08:00
|
|
|
impl<T, U> Clean<U> for ty::Binder<T> where T: Clean<U> {
|
|
|
|
fn clean(&self, cx: &DocContext) -> U {
|
|
|
|
self.0.clean(cx)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-12-16 21:44:33 +03:00
|
|
|
impl<T: Clean<U>, U> Clean<Vec<U>> for P<[T]> {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> Vec<U> {
|
|
|
|
self.iter().map(|x| x.clean(cx)).collect()
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-07 05:59:02 +02:00
|
|
|
#[derive(Clone, Debug)]
|
2013-08-15 16:28:54 -04:00
|
|
|
pub struct Crate {
|
2014-05-22 16:57:53 -07:00
|
|
|
pub name: String,
|
2017-10-02 18:29:03 -05:00
|
|
|
pub version: Option<String>,
|
2015-02-26 21:00:43 -08:00
|
|
|
pub src: PathBuf,
|
2014-03-28 10:27:24 -07:00
|
|
|
pub module: Option<Item>,
|
2016-11-29 08:15:16 +02:00
|
|
|
pub externs: Vec<(CrateNum, ExternalCrate)>,
|
|
|
|
pub primitives: Vec<(DefId, PrimitiveType, Attributes)>,
|
2016-04-07 05:59:02 +02:00
|
|
|
pub access_levels: Arc<AccessLevels<DefId>>,
|
|
|
|
// These are later on moved into `CACHEKEY`, leaving the map empty.
|
|
|
|
// Only here so that they can be filtered through the rustdoc passes.
|
2016-11-08 14:02:55 +11:00
|
|
|
pub external_traits: FxHashMap<DefId, Trait>,
|
2017-08-21 13:43:45 -05:00
|
|
|
pub masked_crates: FxHashSet<CrateNum>,
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
|
2014-09-06 19:13:40 +03:00
|
|
|
impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
|
|
|
|
fn clean(&self, cx: &DocContext) -> Crate {
|
2016-04-17 08:54:48 +02:00
|
|
|
use ::visit_lib::LibEmbargoVisitor;
|
2015-01-17 21:02:31 -08:00
|
|
|
|
2016-11-20 03:42:54 +02:00
|
|
|
{
|
|
|
|
let mut r = cx.renderinfo.borrow_mut();
|
2017-08-31 09:19:33 -07:00
|
|
|
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();
|
2015-04-13 16:23:32 -07:00
|
|
|
}
|
|
|
|
|
2014-03-05 15:28:08 -08:00
|
|
|
let mut externs = Vec::new();
|
2017-09-07 08:13:41 -07:00
|
|
|
for &cnum in cx.tcx.crates().iter() {
|
2016-11-29 08:15:16 +02:00
|
|
|
externs.push((cnum, cnum.clean(cx)));
|
2016-11-20 03:42:54 +02:00
|
|
|
// Analyze doc-reachability for extern items
|
|
|
|
LibEmbargoVisitor::new(cx).visit_lib(cnum);
|
2015-11-22 21:02:04 +02:00
|
|
|
}
|
2014-06-03 17:55:30 -07:00
|
|
|
externs.sort_by(|&(a, _), &(b, _)| a.cmp(&b));
|
2013-08-15 16:28:54 -04:00
|
|
|
|
2014-05-29 13:50:47 -07:00
|
|
|
// Clean the crate, translating the entire libsyntax AST to one that is
|
2014-05-28 19:53:37 -07:00
|
|
|
// understood by rustdoc.
|
2014-09-06 19:13:40 +03:00
|
|
|
let mut module = self.module.clean(cx);
|
2017-08-21 13:43:45 -05:00
|
|
|
let mut masked_crates = FxHashSet();
|
|
|
|
|
|
|
|
match module.inner {
|
|
|
|
ModuleItem(ref module) => {
|
|
|
|
for it in &module.items {
|
2017-10-04 15:51:35 -05:00
|
|
|
if it.is_extern_crate() && it.attrs.has_doc_flag("masked") {
|
2017-08-21 13:43:45 -05:00
|
|
|
masked_crates.insert(it.def_id.krate);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
_ => unreachable!(),
|
|
|
|
}
|
2014-05-28 19:53:37 -07:00
|
|
|
|
2016-11-29 08:15:16 +02:00
|
|
|
let ExternalCrate { name, src, primitives, .. } = LOCAL_CRATE.clean(cx);
|
2014-05-28 19:53:37 -07:00
|
|
|
{
|
|
|
|
let m = match module.inner {
|
|
|
|
ModuleItem(ref mut m) => m,
|
|
|
|
_ => unreachable!(),
|
|
|
|
};
|
2016-11-29 08:15:16 +02:00
|
|
|
m.items.extend(primitives.iter().map(|&(def_id, prim, ref attrs)| {
|
|
|
|
Item {
|
2014-05-28 19:53:37 -07:00
|
|
|
source: Span::empty(),
|
|
|
|
name: Some(prim.to_url_str().to_string()),
|
2016-11-29 08:15:16 +02:00
|
|
|
attrs: attrs.clone(),
|
2016-04-11 08:15:14 +00:00
|
|
|
visibility: Some(Public),
|
2017-01-15 09:08:29 +00:00
|
|
|
stability: get_stability(cx, def_id),
|
|
|
|
deprecation: get_deprecation(cx, def_id),
|
2017-08-06 22:54:09 -07:00
|
|
|
def_id,
|
2014-05-28 19:53:37 -07:00
|
|
|
inner: PrimitiveItem(prim),
|
2016-02-23 07:52:43 +01:00
|
|
|
}
|
2016-11-29 08:15:16 +02:00
|
|
|
}));
|
|
|
|
}
|
2015-01-17 21:02:31 -08:00
|
|
|
|
2016-04-07 05:59:02 +02:00
|
|
|
let mut access_levels = cx.access_levels.borrow_mut();
|
|
|
|
let mut external_traits = cx.external_traits.borrow_mut();
|
|
|
|
|
2013-08-15 16:28:54 -04:00
|
|
|
Crate {
|
2017-08-06 22:54:09 -07:00
|
|
|
name,
|
2017-10-02 18:29:03 -05:00
|
|
|
version: None,
|
2017-08-06 22:54:09 -07:00
|
|
|
src,
|
2014-05-28 19:53:37 -07:00
|
|
|
module: Some(module),
|
2017-08-06 22:54:09 -07:00
|
|
|
externs,
|
|
|
|
primitives,
|
2016-04-07 05:59:02 +02:00
|
|
|
access_levels: Arc::new(mem::replace(&mut access_levels, Default::default())),
|
|
|
|
external_traits: mem::replace(&mut external_traits, Default::default()),
|
2017-08-21 13:43:45 -05:00
|
|
|
masked_crates,
|
2013-10-02 15:39:32 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
2013-10-02 15:39:32 -07:00
|
|
|
pub struct ExternalCrate {
|
2014-05-22 16:57:53 -07:00
|
|
|
pub name: String,
|
2016-11-29 08:15:16 +02:00
|
|
|
pub src: PathBuf,
|
2016-11-24 01:40:52 +02:00
|
|
|
pub attrs: Attributes,
|
2016-11-29 08:15:16 +02:00
|
|
|
pub primitives: Vec<(DefId, PrimitiveType, Attributes)>,
|
2013-10-02 15:39:32 -07:00
|
|
|
}
|
|
|
|
|
2015-11-22 21:02:04 +02:00
|
|
|
impl Clean<ExternalCrate> for CrateNum {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> ExternalCrate {
|
2016-11-29 08:15:16 +02:00
|
|
|
let root = DefId { krate: *self, index: CRATE_DEF_INDEX };
|
|
|
|
let krate_span = cx.tcx.def_span(root);
|
|
|
|
let krate_src = cx.sess().codemap().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 = |def: Def| {
|
|
|
|
if let Def::Mod(def_id) = def {
|
|
|
|
let attrs = cx.tcx.get_attrs(def_id).clean(cx);
|
|
|
|
let mut prim = None;
|
|
|
|
for attr in attrs.lists("doc") {
|
|
|
|
if let Some(v) = attr.value_str() {
|
|
|
|
if attr.check_name("primitive") {
|
|
|
|
prim = PrimitiveType::from_str(&v.as_str());
|
|
|
|
if prim.is_some() {
|
|
|
|
break;
|
|
|
|
}
|
2017-10-17 23:03:50 -07:00
|
|
|
// FIXME: should warn on unknown primitives?
|
2016-11-29 08:15:16 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return prim.map(|p| (def_id, p, attrs));
|
|
|
|
}
|
|
|
|
None
|
|
|
|
};
|
|
|
|
let primitives = if root.is_local() {
|
2017-01-26 02:41:06 +02:00
|
|
|
cx.tcx.hir.krate().module.item_ids.iter().filter_map(|&id| {
|
|
|
|
let item = cx.tcx.hir.expect_item(id.id);
|
2016-11-29 08:15:16 +02:00
|
|
|
match item.node {
|
|
|
|
hir::ItemMod(_) => {
|
2017-01-26 02:41:06 +02:00
|
|
|
as_primitive(Def::Mod(cx.tcx.hir.local_def_id(id.id)))
|
2016-11-29 08:15:16 +02:00
|
|
|
}
|
|
|
|
hir::ItemUse(ref path, hir::UseKind::Single)
|
|
|
|
if item.vis == hir::Visibility::Public => {
|
|
|
|
as_primitive(path.def).map(|(_, prim, attrs)| {
|
|
|
|
// Pretend the primitive is local.
|
2017-01-26 02:41:06 +02:00
|
|
|
(cx.tcx.hir.local_def_id(id.id), prim, attrs)
|
2016-11-29 08:15:16 +02:00
|
|
|
})
|
|
|
|
}
|
|
|
|
_ => None
|
|
|
|
}
|
|
|
|
}).collect()
|
|
|
|
} else {
|
2017-08-31 08:07:39 -07:00
|
|
|
cx.tcx.item_children(root).iter().map(|item| item.def)
|
2016-11-29 08:15:16 +02:00
|
|
|
.filter_map(as_primitive).collect()
|
|
|
|
};
|
|
|
|
|
2013-10-02 15:39:32 -07:00
|
|
|
ExternalCrate {
|
2016-11-29 08:15:16 +02:00
|
|
|
name: cx.tcx.crate_name(*self).to_string(),
|
|
|
|
src: PathBuf::from(krate_src),
|
|
|
|
attrs: cx.tcx.get_attrs(root).clean(cx),
|
2017-08-06 22:54:09 -07:00
|
|
|
primitives,
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
/// 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.
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
2013-08-15 16:28:54 -04:00
|
|
|
pub struct Item {
|
|
|
|
/// Stringified span
|
2014-03-28 10:27:24 -07:00
|
|
|
pub source: Span,
|
2013-08-15 16:28:54 -04:00
|
|
|
/// Not everything has a name. E.g., impls
|
2014-05-22 16:57:53 -07:00
|
|
|
pub name: Option<String>,
|
2016-11-24 01:40:52 +02:00
|
|
|
pub attrs: Attributes,
|
2014-03-28 10:27:24 -07:00
|
|
|
pub inner: ItemEnum,
|
|
|
|
pub visibility: Option<Visibility>,
|
2015-08-16 06:32:28 -04:00
|
|
|
pub def_id: DefId,
|
2014-06-26 11:37:39 -07:00
|
|
|
pub stability: Option<Stability>,
|
2015-12-12 23:01:27 +03:00
|
|
|
pub deprecation: Option<Deprecation>,
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
|
2013-09-18 22:18:38 -07:00
|
|
|
impl Item {
|
|
|
|
/// Finds the `doc` attribute as a NameValue and returns the corresponding
|
|
|
|
/// value found.
|
|
|
|
pub fn doc_value<'a>(&'a self) -> Option<&'a str> {
|
2016-11-24 01:40:52 +02:00
|
|
|
self.attrs.doc_value()
|
2014-04-29 03:59:48 +09:00
|
|
|
}
|
2016-02-28 12:23:07 +01:00
|
|
|
pub fn is_crate(&self) -> bool {
|
|
|
|
match self.inner {
|
2016-03-31 18:15:54 +02:00
|
|
|
StrippedItem(box ModuleItem(Module { is_crate: true, ..})) |
|
|
|
|
ModuleItem(Module { is_crate: true, ..}) => true,
|
|
|
|
_ => false,
|
2016-02-28 12:23:07 +01:00
|
|
|
}
|
|
|
|
}
|
2013-09-18 22:18:38 -07:00
|
|
|
pub fn is_mod(&self) -> bool {
|
2016-09-28 22:53:35 -04:00
|
|
|
self.type_() == ItemType::Module
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
|
|
|
pub fn is_trait(&self) -> bool {
|
2016-09-28 22:53:35 -04:00
|
|
|
self.type_() == ItemType::Trait
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
|
|
|
pub fn is_struct(&self) -> bool {
|
2016-09-28 22:53:35 -04:00
|
|
|
self.type_() == ItemType::Struct
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
|
|
|
pub fn is_enum(&self) -> bool {
|
2016-11-21 15:52:51 -06:00
|
|
|
self.type_() == ItemType::Enum
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
|
|
|
pub fn is_fn(&self) -> bool {
|
2016-09-28 22:53:35 -04:00
|
|
|
self.type_() == ItemType::Function
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
2016-02-28 12:23:07 +01:00
|
|
|
pub fn is_associated_type(&self) -> bool {
|
2016-09-28 22:53:35 -04:00
|
|
|
self.type_() == ItemType::AssociatedType
|
2016-02-28 12:23:07 +01:00
|
|
|
}
|
|
|
|
pub fn is_associated_const(&self) -> bool {
|
2016-09-28 22:53:35 -04:00
|
|
|
self.type_() == ItemType::AssociatedConst
|
2016-02-28 12:23:07 +01:00
|
|
|
}
|
|
|
|
pub fn is_method(&self) -> bool {
|
2016-09-28 22:53:35 -04:00
|
|
|
self.type_() == ItemType::Method
|
2016-02-28 12:23:07 +01:00
|
|
|
}
|
|
|
|
pub fn is_ty_method(&self) -> bool {
|
2016-09-28 22:53:35 -04:00
|
|
|
self.type_() == ItemType::TyMethod
|
2016-03-31 18:15:54 +02:00
|
|
|
}
|
Document direct implementations on type aliases.
This improves #32077, but is not a complete fix. For a type alias `type
NewType = AliasedType`, it will include any `impl NewType` and `impl
Trait for NewType` blocks in the documentation for `NewType`.
A complete fix would include the implementations from the aliased type
in the type alias' documentation, so that users have a complete
picture of methods that are available on the alias. However, to do this
properly would require a fix for #14072, as the alias may affect the
type parameters of the type alias, making the documentation difficult to
understand. (That is, for `type Result = std::result::Result<(), ()>` we
would ideally show documentation for `impl Result<(), ()>`, rather than
generic documentation for `impl<T, E> Result<T, E>`).
I think this improvement is worthwhile, as it exposes implementations
which are not currently documented by rustdoc. The documentation for the
implementations on the aliased type are still accessible by clicking
through to the docs for that type. (Although perhaps it's now less
obvious to the user that they should click-through to get there).
2017-05-16 13:16:44 +07:00
|
|
|
pub fn is_typedef(&self) -> bool {
|
|
|
|
self.type_() == ItemType::Typedef
|
|
|
|
}
|
2016-06-30 23:16:44 +01:00
|
|
|
pub fn is_primitive(&self) -> bool {
|
2016-09-28 22:53:35 -04:00
|
|
|
self.type_() == ItemType::Primitive
|
2016-06-30 23:16:44 +01:00
|
|
|
}
|
2016-11-21 15:52:51 -06:00
|
|
|
pub fn is_union(&self) -> bool {
|
|
|
|
self.type_() == ItemType::Union
|
|
|
|
}
|
2017-08-18 00:08:12 +02:00
|
|
|
pub fn is_import(&self) -> bool {
|
|
|
|
self.type_() == ItemType::Import
|
|
|
|
}
|
2017-08-21 13:43:45 -05:00
|
|
|
pub fn is_extern_crate(&self) -> bool {
|
|
|
|
self.type_() == ItemType::ExternCrate
|
|
|
|
}
|
2017-08-18 00:08:12 +02:00
|
|
|
|
2016-03-31 18:15:54 +02:00
|
|
|
pub fn is_stripped(&self) -> bool {
|
|
|
|
match self.inner { StrippedItem(..) => true, _ => false }
|
2016-02-28 12:23:07 +01:00
|
|
|
}
|
2016-04-02 08:17:59 +02:00
|
|
|
pub fn has_stripped_fields(&self) -> Option<bool> {
|
|
|
|
match self.inner {
|
|
|
|
StructItem(ref _struct) => Some(_struct.fields_stripped),
|
2016-08-10 21:00:17 +03:00
|
|
|
UnionItem(ref union) => Some(union.fields_stripped),
|
2016-10-02 20:07:18 -04:00
|
|
|
VariantItem(Variant { kind: VariantKind::Struct(ref vstruct)} ) => {
|
2016-04-02 08:17:59 +02:00
|
|
|
Some(vstruct.fields_stripped)
|
|
|
|
},
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
2015-04-13 11:55:00 -07:00
|
|
|
|
2017-02-11 04:16:13 -08:00
|
|
|
pub fn stability_class(&self) -> Option<String> {
|
2017-02-11 10:00:56 -08:00
|
|
|
self.stability.as_ref().and_then(|ref s| {
|
|
|
|
let mut classes = Vec::with_capacity(2);
|
2017-02-11 04:16:13 -08:00
|
|
|
|
2017-02-11 10:00:56 -08:00
|
|
|
if s.level == stability::Unstable {
|
|
|
|
classes.push("unstable");
|
|
|
|
}
|
2017-02-11 04:16:13 -08:00
|
|
|
|
2017-02-11 10:00:56 -08:00
|
|
|
if !s.deprecated_since.is_empty() {
|
|
|
|
classes.push("deprecated");
|
|
|
|
}
|
2017-02-11 04:16:13 -08:00
|
|
|
|
2017-02-11 10:00:56 -08:00
|
|
|
if classes.len() != 0 {
|
|
|
|
Some(classes.join(" "))
|
|
|
|
} else {
|
|
|
|
None
|
2015-04-13 11:55:00 -07:00
|
|
|
}
|
2017-02-11 10:00:56 -08:00
|
|
|
})
|
2015-04-13 11:55:00 -07:00
|
|
|
}
|
2016-02-09 21:15:29 -05:00
|
|
|
|
|
|
|
pub fn stable_since(&self) -> Option<&str> {
|
2016-02-28 12:11:13 +01:00
|
|
|
self.stability.as_ref().map(|s| &s.since[..])
|
2016-02-09 21:15:29 -05:00
|
|
|
}
|
2016-09-28 22:53:35 -04:00
|
|
|
|
|
|
|
/// Returns a documentation-level item type from the item.
|
|
|
|
pub fn type_(&self) -> ItemType {
|
|
|
|
ItemType::from(self)
|
|
|
|
}
|
2013-09-18 22:18:38 -07:00
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
2013-08-15 16:28:54 -04:00
|
|
|
pub enum ItemEnum {
|
2014-12-26 10:55:16 +02:00
|
|
|
ExternCrateItem(String, Option<String>),
|
|
|
|
ImportItem(Import),
|
2013-08-15 16:28:54 -04:00
|
|
|
StructItem(Struct),
|
2016-08-10 21:00:17 +03:00
|
|
|
UnionItem(Union),
|
2013-08-15 16:28:54 -04:00
|
|
|
EnumItem(Enum),
|
|
|
|
FunctionItem(Function),
|
|
|
|
ModuleItem(Module),
|
2015-05-21 14:17:37 +02:00
|
|
|
TypedefItem(Typedef, bool /* is associated type */),
|
2013-08-15 16:28:54 -04:00
|
|
|
StaticItem(Static),
|
2014-10-06 17:41:15 -07:00
|
|
|
ConstantItem(Constant),
|
2013-08-15 16:28:54 -04:00
|
|
|
TraitItem(Trait),
|
|
|
|
ImplItem(Impl),
|
2014-03-16 19:12:00 -04:00
|
|
|
/// A method signature only. Used for required methods in traits (ie,
|
|
|
|
/// non-default-methods).
|
2013-08-15 16:28:54 -04:00
|
|
|
TyMethodItem(TyMethod),
|
2014-03-16 19:12:00 -04:00
|
|
|
/// A method with a body.
|
2013-08-15 16:28:54 -04:00
|
|
|
MethodItem(Method),
|
2016-04-02 08:17:59 +02:00
|
|
|
StructFieldItem(Type),
|
2013-08-15 16:28:54 -04:00
|
|
|
VariantItem(Variant),
|
2014-03-16 19:12:00 -04:00
|
|
|
/// `fn`s from an extern block
|
2013-09-26 11:57:25 -07:00
|
|
|
ForeignFunctionItem(Function),
|
2014-03-16 19:12:00 -04:00
|
|
|
/// `static`s from an extern block
|
2013-09-26 11:57:25 -07:00
|
|
|
ForeignStaticItem(Static),
|
2017-09-03 19:53:58 +01:00
|
|
|
/// `type`s from an extern block
|
|
|
|
ForeignTypeItem,
|
2014-02-16 21:40:26 -08:00
|
|
|
MacroItem(Macro),
|
2014-09-11 17:07:49 +12:00
|
|
|
PrimitiveItem(PrimitiveType),
|
2015-03-14 12:05:00 -06:00
|
|
|
AssociatedConstItem(Type, Option<String>),
|
2015-03-10 12:28:44 +02:00
|
|
|
AssociatedTypeItem(Vec<TyParamBound>, Option<Type>),
|
2017-10-09 13:59:20 -03:00
|
|
|
AutoImplItem(AutoImpl),
|
2016-03-31 18:15:54 +02:00
|
|
|
/// An item that has been stripped by a rustdoc pass
|
|
|
|
StrippedItem(Box<ItemEnum>),
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
|
2016-08-20 13:36:52 -04:00
|
|
|
impl ItemEnum {
|
|
|
|
pub fn generics(&self) -> Option<&Generics> {
|
|
|
|
Some(match *self {
|
|
|
|
ItemEnum::StructItem(ref s) => &s.generics,
|
|
|
|
ItemEnum::EnumItem(ref e) => &e.generics,
|
|
|
|
ItemEnum::FunctionItem(ref f) => &f.generics,
|
|
|
|
ItemEnum::TypedefItem(ref t, _) => &t.generics,
|
|
|
|
ItemEnum::TraitItem(ref t) => &t.generics,
|
|
|
|
ItemEnum::ImplItem(ref i) => &i.generics,
|
|
|
|
ItemEnum::TyMethodItem(ref i) => &i.generics,
|
|
|
|
ItemEnum::MethodItem(ref i) => &i.generics,
|
|
|
|
ItemEnum::ForeignFunctionItem(ref f) => &f.generics,
|
|
|
|
_ => return None,
|
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
2013-08-15 16:28:54 -04:00
|
|
|
pub struct Module {
|
2014-03-28 10:27:24 -07:00
|
|
|
pub items: Vec<Item>,
|
|
|
|
pub is_crate: bool,
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Clean<Item> for doctree::Module {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> Item {
|
2013-08-15 16:28:54 -04:00
|
|
|
let name = if self.name.is_some() {
|
2014-09-06 19:13:40 +03:00
|
|
|
self.name.unwrap().clean(cx)
|
2013-08-15 16:28:54 -04:00
|
|
|
} else {
|
2014-05-25 03:17:19 -07:00
|
|
|
"".to_string()
|
2013-08-15 16:28:54 -04:00
|
|
|
};
|
2015-02-02 18:33:24 +09:00
|
|
|
|
|
|
|
let mut items: Vec<Item> = vec![];
|
|
|
|
items.extend(self.extern_crates.iter().map(|x| x.clean(cx)));
|
2015-06-10 17:22:20 +01:00
|
|
|
items.extend(self.imports.iter().flat_map(|x| x.clean(cx)));
|
2015-02-02 18:33:24 +09:00
|
|
|
items.extend(self.structs.iter().map(|x| x.clean(cx)));
|
2016-08-10 21:00:17 +03:00
|
|
|
items.extend(self.unions.iter().map(|x| x.clean(cx)));
|
2015-02-02 18:33:24 +09:00
|
|
|
items.extend(self.enums.iter().map(|x| x.clean(cx)));
|
|
|
|
items.extend(self.fns.iter().map(|x| x.clean(cx)));
|
2015-06-10 17:22:20 +01:00
|
|
|
items.extend(self.foreigns.iter().flat_map(|x| x.clean(cx)));
|
2015-02-02 18:33:24 +09:00
|
|
|
items.extend(self.mods.iter().map(|x| x.clean(cx)));
|
|
|
|
items.extend(self.typedefs.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)));
|
2015-06-10 17:22:20 +01:00
|
|
|
items.extend(self.impls.iter().flat_map(|x| x.clean(cx)));
|
2015-02-02 18:33:24 +09:00
|
|
|
items.extend(self.macros.iter().map(|x| x.clean(cx)));
|
2015-03-12 19:15:52 -07:00
|
|
|
items.extend(self.def_traits.iter().map(|x| x.clean(cx)));
|
2014-04-27 05:08:36 +09:00
|
|
|
|
|
|
|
// determine if we should display the inner contents or
|
|
|
|
// the outer `mod` item for the source code.
|
2014-08-11 09:32:26 -07:00
|
|
|
let whence = {
|
2014-09-06 19:13:40 +03:00
|
|
|
let cm = cx.sess().codemap();
|
2017-07-31 23:04:34 +03:00
|
|
|
let outer = cm.lookup_char_pos(self.where_outer.lo());
|
|
|
|
let inner = cm.lookup_char_pos(self.where_inner.lo());
|
2014-04-27 05:08:36 +09:00
|
|
|
if outer.file.start_pos == inner.file.start_pos {
|
|
|
|
// mod foo { ... }
|
|
|
|
self.where_outer
|
|
|
|
} else {
|
|
|
|
// mod foo; (and a separate FileMap for the contents)
|
|
|
|
self.where_inner
|
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2013-08-15 16:28:54 -04:00
|
|
|
Item {
|
|
|
|
name: Some(name),
|
2014-09-06 19:13:40 +03:00
|
|
|
attrs: self.attrs.clean(cx),
|
|
|
|
source: whence.clean(cx),
|
|
|
|
visibility: self.vis.clean(cx),
|
|
|
|
stability: self.stab.clean(cx),
|
2015-12-12 23:01:27 +03:00
|
|
|
deprecation: self.depr.clean(cx),
|
2017-01-26 02:41:06 +02:00
|
|
|
def_id: cx.tcx.hir.local_def_id(self.id),
|
2013-08-15 16:28:54 -04:00
|
|
|
inner: ModuleItem(Module {
|
2014-02-28 22:33:45 +01:00
|
|
|
is_crate: self.is_crate,
|
2017-08-06 22:54:09 -07:00
|
|
|
items,
|
2013-08-15 16:28:54 -04:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-24 01:40:52 +02:00
|
|
|
pub struct ListAttributesIter<'a> {
|
|
|
|
attrs: slice::Iter<'a, ast::Attribute>,
|
2017-03-03 09:23:59 +00:00
|
|
|
current_list: vec::IntoIter<ast::NestedMetaItem>,
|
2016-11-24 01:40:52 +02:00
|
|
|
name: &'a str
|
2016-02-28 10:12:41 +01:00
|
|
|
}
|
|
|
|
|
2016-11-24 01:40:52 +02:00
|
|
|
impl<'a> Iterator for ListAttributesIter<'a> {
|
2017-03-03 09:23:59 +00:00
|
|
|
type Item = ast::NestedMetaItem;
|
2016-11-24 01:40:52 +02:00
|
|
|
|
|
|
|
fn next(&mut self) -> Option<Self::Item> {
|
|
|
|
if let Some(nested) = self.current_list.next() {
|
|
|
|
return Some(nested);
|
2016-02-28 10:12:41 +01:00
|
|
|
}
|
|
|
|
|
2016-11-24 01:40:52 +02:00
|
|
|
for attr in &mut self.attrs {
|
2017-03-03 09:23:59 +00:00
|
|
|
if let Some(list) = attr.meta_item_list() {
|
2016-11-24 01:40:52 +02:00
|
|
|
if attr.check_name(self.name) {
|
2017-03-03 09:23:59 +00:00
|
|
|
self.current_list = list.into_iter();
|
2016-11-24 01:40:52 +02:00
|
|
|
if let Some(nested) = self.current_list.next() {
|
|
|
|
return Some(nested);
|
|
|
|
}
|
2016-02-28 10:12:41 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-11-24 01:40:52 +02:00
|
|
|
|
2016-02-28 10:12:41 +01:00
|
|
|
None
|
|
|
|
}
|
2016-11-24 01:40:52 +02:00
|
|
|
}
|
2016-02-28 10:12:41 +01:00
|
|
|
|
2016-11-24 01:40:52 +02:00
|
|
|
pub trait AttributesExt {
|
2016-02-28 10:12:41 +01:00
|
|
|
/// Finds an attribute as List and returns the list of attributes nested inside.
|
2017-05-02 05:55:20 +02:00
|
|
|
fn lists<'a>(&'a self, name: &'a str) -> ListAttributesIter<'a>;
|
2016-11-24 01:40:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
impl AttributesExt for [ast::Attribute] {
|
|
|
|
fn lists<'a>(&'a self, name: &'a str) -> ListAttributesIter<'a> {
|
|
|
|
ListAttributesIter {
|
|
|
|
attrs: self.iter(),
|
2017-03-03 09:23:59 +00:00
|
|
|
current_list: Vec::new().into_iter(),
|
2017-08-06 22:54:09 -07:00
|
|
|
name,
|
2016-02-28 10:12:41 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-24 01:40:52 +02:00
|
|
|
pub trait NestedAttributesExt {
|
|
|
|
/// Returns whether the attribute list contains a specific `Word`
|
2017-05-02 05:55:20 +02:00
|
|
|
fn has_word(self, word: &str) -> bool;
|
2016-11-24 01:40:52 +02:00
|
|
|
}
|
|
|
|
|
2017-03-03 09:23:59 +00:00
|
|
|
impl<I: IntoIterator<Item=ast::NestedMetaItem>> NestedAttributesExt for I {
|
2016-11-24 01:40:52 +02:00
|
|
|
fn has_word(self, word: &str) -> bool {
|
|
|
|
self.into_iter().any(|attr| attr.is_word() && attr.check_name(word))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug, Default)]
|
|
|
|
pub struct Attributes {
|
|
|
|
pub doc_strings: Vec<String>,
|
2017-01-17 23:54:51 +01:00
|
|
|
pub other_attrs: Vec<ast::Attribute>,
|
2017-08-05 14:38:52 +08:00
|
|
|
pub cfg: Option<Rc<Cfg>>,
|
2017-01-17 23:54:51 +01:00
|
|
|
pub span: Option<syntax_pos::Span>,
|
2016-11-24 01:40:52 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Attributes {
|
2017-08-05 14:38:52 +08:00
|
|
|
/// Extracts the content from an attribute `#[doc(cfg(content))]`.
|
|
|
|
fn extract_cfg(mi: &ast::MetaItem) -> Option<&ast::MetaItem> {
|
|
|
|
use syntax::ast::NestedMetaItemKind::MetaItem;
|
|
|
|
|
|
|
|
if let ast::MetaItemKind::List(ref nmis) = mi.node {
|
|
|
|
if nmis.len() == 1 {
|
|
|
|
if let MetaItem(ref cfg_mi) = nmis[0].node {
|
|
|
|
if cfg_mi.check_name("cfg") {
|
|
|
|
if let ast::MetaItemKind::List(ref cfg_nmis) = cfg_mi.node {
|
|
|
|
if cfg_nmis.len() == 1 {
|
|
|
|
if let MetaItem(ref content_mi) = cfg_nmis[0].node {
|
|
|
|
return Some(content_mi);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
None
|
|
|
|
}
|
|
|
|
|
2017-10-04 15:51:35 -05:00
|
|
|
pub fn has_doc_flag(&self, flag: &str) -> bool {
|
2017-08-21 13:43:45 -05:00
|
|
|
for attr in &self.other_attrs {
|
|
|
|
if !attr.check_name("doc") { continue; }
|
|
|
|
|
|
|
|
if let Some(items) = attr.meta_item_list() {
|
2017-10-04 15:51:35 -05:00
|
|
|
if items.iter().filter_map(|i| i.meta_item()).any(|it| it.check_name(flag)) {
|
2017-08-21 13:43:45 -05:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
false
|
|
|
|
}
|
|
|
|
|
2017-08-05 14:38:52 +08:00
|
|
|
pub fn from_ast(diagnostic: &::errors::Handler, attrs: &[ast::Attribute]) -> Attributes {
|
2016-11-24 01:40:52 +02:00
|
|
|
let mut doc_strings = vec![];
|
2017-01-17 23:54:51 +01:00
|
|
|
let mut sp = None;
|
2017-08-05 14:38:52 +08:00
|
|
|
let mut cfg = Cfg::True;
|
|
|
|
|
2016-11-24 01:40:52 +02:00
|
|
|
let other_attrs = attrs.iter().filter_map(|attr| {
|
|
|
|
attr.with_desugared_doc(|attr| {
|
2017-08-05 14:38:52 +08:00
|
|
|
if attr.check_name("doc") {
|
|
|
|
if let Some(mi) = attr.meta() {
|
|
|
|
if let Some(value) = mi.value_str() {
|
|
|
|
// Extracted #[doc = "..."]
|
|
|
|
doc_strings.push(value.to_string());
|
|
|
|
if sp.is_none() {
|
|
|
|
sp = Some(attr.span);
|
|
|
|
}
|
|
|
|
return None;
|
|
|
|
} else if let Some(cfg_mi) = Attributes::extract_cfg(&mi) {
|
|
|
|
// Extracted #[doc(cfg(...))]
|
|
|
|
match Cfg::parse(cfg_mi) {
|
|
|
|
Ok(new_cfg) => cfg &= new_cfg,
|
|
|
|
Err(e) => diagnostic.span_err(e.span, e.msg),
|
|
|
|
}
|
|
|
|
return None;
|
2017-01-17 23:54:51 +01:00
|
|
|
}
|
2016-11-24 01:40:52 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
Some(attr.clone())
|
|
|
|
})
|
|
|
|
}).collect();
|
|
|
|
Attributes {
|
2017-08-05 14:38:52 +08:00
|
|
|
doc_strings,
|
|
|
|
other_attrs,
|
|
|
|
cfg: if cfg == Cfg::True { None } else { Some(Rc::new(cfg)) },
|
2017-01-17 23:54:51 +01:00
|
|
|
span: sp,
|
2016-08-19 18:58:14 -07:00
|
|
|
}
|
|
|
|
}
|
2016-11-24 01:40:52 +02:00
|
|
|
|
|
|
|
/// Finds the `doc` attribute as a NameValue and returns the corresponding
|
|
|
|
/// value found.
|
|
|
|
pub fn doc_value<'a>(&'a self) -> Option<&'a str> {
|
|
|
|
self.doc_strings.first().map(|s| &s[..])
|
|
|
|
}
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
|
2016-11-24 01:40:52 +02:00
|
|
|
impl AttributesExt for Attributes {
|
|
|
|
fn lists<'a>(&'a self, name: &'a str) -> ListAttributesIter<'a> {
|
|
|
|
self.other_attrs.lists(name)
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-24 01:40:52 +02:00
|
|
|
impl Clean<Attributes> for [ast::Attribute] {
|
2017-08-05 14:38:52 +08:00
|
|
|
fn clean(&self, cx: &DocContext) -> Attributes {
|
|
|
|
Attributes::from_ast(cx.sess().diagnostic(), self)
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
|
2013-08-15 16:28:54 -04:00
|
|
|
pub struct TyParam {
|
2014-05-22 16:57:53 -07:00
|
|
|
pub name: String,
|
2015-08-16 06:32:28 -04:00
|
|
|
pub did: DefId,
|
2014-03-28 10:27:24 -07:00
|
|
|
pub bounds: Vec<TyParamBound>,
|
2014-11-24 10:14:46 -08:00
|
|
|
pub default: Option<Type>,
|
2014-03-28 10:27:24 -07:00
|
|
|
}
|
2013-08-15 16:28:54 -04:00
|
|
|
|
2015-07-31 00:04:06 -07:00
|
|
|
impl Clean<TyParam> for hir::TyParam {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> TyParam {
|
2013-08-15 16:28:54 -04:00
|
|
|
TyParam {
|
2015-09-20 16:47:24 +03:00
|
|
|
name: self.name.clean(cx),
|
2017-01-26 02:41:06 +02:00
|
|
|
did: cx.tcx.hir.local_def_id(self.id),
|
2014-09-06 19:13:40 +03:00
|
|
|
bounds: self.bounds.clean(cx),
|
2014-11-24 10:14:46 -08:00
|
|
|
default: self.default.clean(cx),
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-25 22:01:11 +02:00
|
|
|
impl<'tcx> Clean<TyParam> for ty::TypeParameterDef {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> TyParam {
|
2016-04-07 05:59:02 +02:00
|
|
|
cx.renderinfo.borrow_mut().external_typarams.insert(self.def_id, self.name.clean(cx));
|
2014-05-03 02:08:58 -07:00
|
|
|
TyParam {
|
2014-09-30 19:11:34 -05:00
|
|
|
name: self.name.clean(cx),
|
2014-05-03 02:08:58 -07:00
|
|
|
did: self.def_id,
|
2015-02-18 11:50:51 -05:00
|
|
|
bounds: vec![], // these are filled in from the where-clauses
|
2017-01-25 22:01:11 +02:00
|
|
|
default: if self.has_default {
|
2017-04-24 15:20:46 +03:00
|
|
|
Some(cx.tcx.type_of(self.def_id).clean(cx))
|
2017-01-25 22:01:11 +02:00
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
2014-05-03 02:08:58 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
|
2013-08-15 16:28:54 -04:00
|
|
|
pub enum TyParamBound {
|
2014-10-05 07:35:04 -07:00
|
|
|
RegionBound(Lifetime),
|
2015-07-31 00:04:06 -07:00
|
|
|
TraitBound(PolyTrait, hir::TraitBoundModifier)
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
|
2015-04-07 00:16:35 -07:00
|
|
|
impl TyParamBound {
|
|
|
|
fn maybe_sized(cx: &DocContext) -> TyParamBound {
|
2016-11-25 21:21:03 -07:00
|
|
|
let did = cx.tcx.require_lang_item(lang_items::SizedTraitLangItem);
|
2016-11-16 09:21:49 -07:00
|
|
|
let empty = cx.tcx.intern_substs(&[]);
|
2017-09-01 09:24:02 -07:00
|
|
|
let path = external_path(cx, &cx.tcx.item_name(did),
|
2016-11-13 19:42:15 -07:00
|
|
|
Some(did), false, vec![], empty);
|
|
|
|
inline::record_extern_fqn(cx, did, TypeKind::Trait);
|
|
|
|
TraitBound(PolyTrait {
|
|
|
|
trait_: ResolvedPath {
|
2017-08-06 22:54:09 -07:00
|
|
|
path,
|
2016-11-13 19:42:15 -07:00
|
|
|
typarams: None,
|
2017-08-06 22:54:09 -07:00
|
|
|
did,
|
2016-11-13 19:42:15 -07:00
|
|
|
is_generic: false,
|
|
|
|
},
|
|
|
|
lifetimes: vec![]
|
|
|
|
}, hir::TraitBoundModifier::Maybe)
|
2015-04-07 00:16:35 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
fn is_sized_bound(&self, cx: &DocContext) -> bool {
|
2016-03-29 08:50:44 +03:00
|
|
|
use rustc::hir::TraitBoundModifier as TBM;
|
2016-11-20 03:42:54 +02:00
|
|
|
if let TyParamBound::TraitBound(PolyTrait { ref trait_, .. }, TBM::None) = *self {
|
2017-08-31 09:19:33 -07:00
|
|
|
if trait_.def_id() == cx.tcx.lang_items().sized_trait() {
|
2016-11-20 03:42:54 +02:00
|
|
|
return true;
|
2015-04-07 00:16:35 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
false
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-31 00:04:06 -07:00
|
|
|
impl Clean<TyParamBound> for hir::TyParamBound {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> TyParamBound {
|
2013-08-15 16:28:54 -04:00
|
|
|
match *self {
|
2015-07-31 00:04:06 -07:00
|
|
|
hir::RegionTyParamBound(lt) => RegionBound(lt.clean(cx)),
|
|
|
|
hir::TraitTyParamBound(ref t, modifier) => TraitBound(t.clean(cx), modifier),
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-15 01:07:09 +03:00
|
|
|
fn external_path_params(cx: &DocContext, trait_did: Option<DefId>, has_self: bool,
|
2016-08-08 23:39:49 +03:00
|
|
|
bindings: Vec<TypeBinding>, substs: &Substs) -> PathParameters {
|
2016-08-18 08:32:50 +03:00
|
|
|
let lifetimes = substs.regions().filter_map(|v| v.clean(cx)).collect();
|
2016-08-27 01:13:48 +03:00
|
|
|
let types = substs.types().skip(has_self as usize).collect::<Vec<_>>();
|
2014-12-17 02:39:10 -08:00
|
|
|
|
2016-11-20 03:42:54 +02:00
|
|
|
match trait_did {
|
2014-12-17 02:39:10 -08:00
|
|
|
// Attempt to sugar an external path like Fn<(A, B,), C> to Fn(A, B) -> C
|
2017-08-31 09:19:33 -07:00
|
|
|
Some(did) if cx.tcx.lang_items().fn_trait_kind(did).is_some() => {
|
2015-01-12 10:24:19 -05:00
|
|
|
assert_eq!(types.len(), 1);
|
2014-12-17 02:39:10 -08:00
|
|
|
let inputs = match types[0].sty {
|
2017-01-11 15:58:37 +08:00
|
|
|
ty::TyTuple(ref tys, _) => tys.iter().map(|t| t.clean(cx)).collect(),
|
2014-12-17 02:39:10 -08:00
|
|
|
_ => {
|
|
|
|
return PathParameters::AngleBracketed {
|
2017-08-06 22:54:09 -07:00
|
|
|
lifetimes,
|
2015-01-07 16:10:40 -08:00
|
|
|
types: types.clean(cx),
|
2017-08-06 22:54:09 -07:00
|
|
|
bindings,
|
2014-12-17 02:39:10 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
};
|
2015-01-12 10:24:19 -05:00
|
|
|
let output = None;
|
|
|
|
// FIXME(#20299) return type comes from a projection now
|
|
|
|
// match types[1].sty {
|
2017-01-11 15:58:37 +08:00
|
|
|
// ty::TyTuple(ref v, _) if v.is_empty() => None, // -> ()
|
2015-01-12 10:24:19 -05:00
|
|
|
// _ => Some(types[1].clean(cx))
|
|
|
|
// };
|
2014-12-17 02:39:10 -08:00
|
|
|
PathParameters::Parenthesized {
|
2017-08-06 22:54:09 -07:00
|
|
|
inputs,
|
|
|
|
output,
|
2014-12-17 02:39:10 -08:00
|
|
|
}
|
|
|
|
},
|
2016-11-20 03:42:54 +02:00
|
|
|
_ => {
|
2014-12-17 02:39:10 -08:00
|
|
|
PathParameters::AngleBracketed {
|
2017-08-06 22:54:09 -07:00
|
|
|
lifetimes,
|
2014-12-17 02:39:10 -08:00
|
|
|
types: types.clean(cx),
|
2017-08-06 22:54:09 -07:00
|
|
|
bindings,
|
2014-12-17 02:39:10 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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
|
2016-08-15 01:07:09 +03:00
|
|
|
fn external_path(cx: &DocContext, name: &str, trait_did: Option<DefId>, has_self: bool,
|
2016-08-08 23:39:49 +03:00
|
|
|
bindings: Vec<TypeBinding>, substs: &Substs) -> Path {
|
2014-05-03 02:08:58 -07:00
|
|
|
Path {
|
|
|
|
global: false,
|
2016-11-25 13:21:19 +02:00
|
|
|
def: Def::Err,
|
2014-05-03 02:08:58 -07:00
|
|
|
segments: vec![PathSegment {
|
2014-05-25 03:17:19 -07:00
|
|
|
name: name.to_string(),
|
2016-08-15 01:07:09 +03:00
|
|
|
params: external_path_params(cx, trait_did, has_self, bindings, substs)
|
2014-05-28 23:14:08 -07:00
|
|
|
}],
|
2014-05-03 02:08:58 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-11-06 09:20:16 +02:00
|
|
|
impl<'tcx> Clean<TyParamBound> for ty::TraitRef<'tcx> {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> TyParamBound {
|
2016-10-01 00:34:00 -04:00
|
|
|
inline::record_extern_fqn(cx, self.def_id, TypeKind::Trait);
|
2017-09-01 09:24:02 -07:00
|
|
|
let path = external_path(cx, &cx.tcx.item_name(self.def_id),
|
2016-08-15 01:07:09 +03:00
|
|
|
Some(self.def_id), true, vec![], self.substs);
|
2014-12-16 08:50:52 -08:00
|
|
|
|
2016-08-18 08:32:50 +03:00
|
|
|
debug!("ty::TraitRef\n subst: {:?}\n", self.substs);
|
2014-12-16 08:50:52 -08:00
|
|
|
|
|
|
|
// collect any late bound regions
|
|
|
|
let mut late_bounds = vec![];
|
2016-08-27 01:13:48 +03:00
|
|
|
for ty_s in self.input_types().skip(1) {
|
2017-01-11 15:58:37 +08:00
|
|
|
if let ty::TyTuple(ts, _) = ty_s.sty {
|
2015-01-31 12:20:46 -05:00
|
|
|
for &ty_s in ts {
|
2015-06-11 16:21:46 -07:00
|
|
|
if let ty::TyRef(ref reg, _) = ty_s.sty {
|
2017-04-20 04:45:53 -04:00
|
|
|
if let &ty::RegionKind::ReLateBound(..) = *reg {
|
2014-12-20 00:09:35 -08:00
|
|
|
debug!(" hit an ReLateBound {:?}", reg);
|
2014-12-16 08:50:52 -08:00
|
|
|
if let Some(lt) = reg.clean(cx) {
|
2016-02-28 12:11:13 +01:00
|
|
|
late_bounds.push(lt);
|
2014-12-16 08:50:52 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-03-24 06:10:52 +01:00
|
|
|
TraitBound(
|
|
|
|
PolyTrait {
|
|
|
|
trait_: ResolvedPath {
|
2017-08-06 22:54:09 -07:00
|
|
|
path,
|
2016-03-24 06:10:52 +01:00
|
|
|
typarams: None,
|
|
|
|
did: self.def_id,
|
|
|
|
is_generic: false,
|
|
|
|
},
|
|
|
|
lifetimes: late_bounds,
|
2015-05-25 15:06:38 +02:00
|
|
|
},
|
2016-03-24 06:10:52 +01:00
|
|
|
hir::TraitBoundModifier::None
|
|
|
|
)
|
2014-05-03 02:08:58 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-08 23:39:49 +03:00
|
|
|
impl<'tcx> Clean<Option<Vec<TyParamBound>>> for Substs<'tcx> {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> Option<Vec<TyParamBound>> {
|
2014-05-03 02:08:58 -07:00
|
|
|
let mut v = Vec::new();
|
2016-08-18 08:32:50 +03:00
|
|
|
v.extend(self.regions().filter_map(|r| r.clean(cx))
|
2016-06-13 20:46:08 +03:00
|
|
|
.map(RegionBound));
|
2016-08-18 08:32:50 +03:00
|
|
|
v.extend(self.types().map(|t| TraitBound(PolyTrait {
|
2014-12-16 08:50:52 -08:00
|
|
|
trait_: t.clean(cx),
|
|
|
|
lifetimes: vec![]
|
2015-07-31 00:04:06 -07:00
|
|
|
}, hir::TraitBoundModifier::None)));
|
2015-03-24 16:54:09 -07:00
|
|
|
if !v.is_empty() {Some(v)} else {None}
|
2014-05-03 02:08:58 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
|
2014-05-22 16:57:53 -07:00
|
|
|
pub struct Lifetime(String);
|
2013-08-15 16:28:54 -04:00
|
|
|
|
2013-11-01 18:06:31 -07:00
|
|
|
impl Lifetime {
|
|
|
|
pub fn get_ref<'a>(&'a self) -> &'a str {
|
|
|
|
let Lifetime(ref s) = *self;
|
2015-02-01 21:53:25 -05:00
|
|
|
let s: &'a str = s;
|
2016-10-01 16:47:43 -04:00
|
|
|
s
|
2013-11-01 18:06:31 -07:00
|
|
|
}
|
2014-10-05 07:35:04 -07:00
|
|
|
|
|
|
|
pub fn statik() -> Lifetime {
|
|
|
|
Lifetime("'static".to_string())
|
|
|
|
}
|
2013-11-01 18:06:31 -07:00
|
|
|
}
|
|
|
|
|
2015-07-31 00:04:06 -07:00
|
|
|
impl Clean<Lifetime> for hir::Lifetime {
|
2016-09-01 10:21:12 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> Lifetime {
|
2017-08-30 09:31:14 -07:00
|
|
|
let hir_id = cx.tcx.hir.node_to_hir_id(self.id);
|
|
|
|
let def = cx.tcx.named_region(hir_id);
|
2016-11-20 03:42:54 +02:00
|
|
|
match def {
|
2017-01-08 22:40:04 +02:00
|
|
|
Some(rl::Region::EarlyBound(_, node_id)) |
|
|
|
|
Some(rl::Region::LateBound(_, node_id)) |
|
|
|
|
Some(rl::Region::Free(_, node_id)) => {
|
2016-11-20 03:42:54 +02:00
|
|
|
if let Some(lt) = cx.lt_substs.borrow().get(&node_id).cloned() {
|
|
|
|
return lt;
|
2016-09-01 10:21:12 +03:00
|
|
|
}
|
|
|
|
}
|
2016-11-20 03:42:54 +02:00
|
|
|
_ => {}
|
2016-09-01 10:21:12 +03:00
|
|
|
}
|
2017-09-19 16:36:54 -07:00
|
|
|
Lifetime(self.name.name().to_string())
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-31 00:04:06 -07:00
|
|
|
impl Clean<Lifetime> for hir::LifetimeDef {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, _: &DocContext) -> Lifetime {
|
2016-05-15 15:29:44 +02:00
|
|
|
if self.bounds.len() > 0 {
|
|
|
|
let mut s = format!("{}: {}",
|
2017-09-19 16:36:54 -07:00
|
|
|
self.lifetime.name.name(),
|
|
|
|
self.bounds[0].name.name());
|
2016-05-15 15:29:44 +02:00
|
|
|
for bound in self.bounds.iter().skip(1) {
|
2017-09-19 16:36:54 -07:00
|
|
|
s.push_str(&format!(" + {}", bound.name.name()));
|
2016-05-15 15:29:44 +02:00
|
|
|
}
|
|
|
|
Lifetime(s)
|
|
|
|
} else {
|
2017-09-19 16:36:54 -07:00
|
|
|
Lifetime(self.lifetime.name.name().to_string())
|
2016-05-15 15:29:44 +02:00
|
|
|
}
|
2014-08-05 22:59:24 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-25 18:39:21 +02:00
|
|
|
impl Clean<Lifetime> for ty::RegionParameterDef {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, _: &DocContext) -> Lifetime {
|
2015-07-28 18:07:20 +02:00
|
|
|
Lifetime(self.name.to_string())
|
2014-05-03 02:08:58 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-05-11 16:10:47 +03:00
|
|
|
impl Clean<Option<Lifetime>> for ty::RegionKind {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> Option<Lifetime> {
|
2014-05-03 02:08:58 -07:00
|
|
|
match *self {
|
2014-10-05 07:35:04 -07:00
|
|
|
ty::ReStatic => Some(Lifetime::statik()),
|
2017-01-06 14:35:23 -05:00
|
|
|
ty::ReLateBound(_, ty::BrNamed(_, name)) => Some(Lifetime(name.to_string())),
|
2015-04-17 10:05:25 -04:00
|
|
|
ty::ReEarlyBound(ref data) => Some(Lifetime(data.name.clean(cx))),
|
2014-05-03 02:08:58 -07:00
|
|
|
|
|
|
|
ty::ReLateBound(..) |
|
|
|
|
ty::ReFree(..) |
|
|
|
|
ty::ReScope(..) |
|
2015-08-18 23:21:29 +03:00
|
|
|
ty::ReVar(..) |
|
|
|
|
ty::ReSkolemized(..) |
|
2016-06-01 15:10:44 +03:00
|
|
|
ty::ReEmpty |
|
|
|
|
ty::ReErased => None
|
2014-05-03 02:08:58 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
|
2014-12-23 01:08:00 -08:00
|
|
|
pub enum WherePredicate {
|
|
|
|
BoundPredicate { ty: Type, bounds: Vec<TyParamBound> },
|
|
|
|
RegionPredicate { lifetime: Lifetime, bounds: Vec<Lifetime>},
|
2017-04-11 17:11:05 -04:00
|
|
|
EqPredicate { lhs: Type, rhs: Type },
|
2014-09-25 02:01:42 -07:00
|
|
|
}
|
|
|
|
|
2015-07-31 00:04:06 -07:00
|
|
|
impl Clean<WherePredicate> for hir::WherePredicate {
|
2014-09-25 02:01:42 -07:00
|
|
|
fn clean(&self, cx: &DocContext) -> WherePredicate {
|
2014-12-02 15:03:02 -08:00
|
|
|
match *self {
|
2015-07-31 00:04:06 -07:00
|
|
|
hir::WherePredicate::BoundPredicate(ref wbp) => {
|
2014-12-23 01:08:00 -08:00
|
|
|
WherePredicate::BoundPredicate {
|
2014-12-20 02:29:19 -08:00
|
|
|
ty: wbp.bounded_ty.clean(cx),
|
2014-12-02 15:03:02 -08:00
|
|
|
bounds: wbp.bounds.clean(cx)
|
|
|
|
}
|
|
|
|
}
|
2014-12-23 01:08:00 -08:00
|
|
|
|
2015-07-31 00:04:06 -07:00
|
|
|
hir::WherePredicate::RegionPredicate(ref wrp) => {
|
2014-12-23 01:08:00 -08:00
|
|
|
WherePredicate::RegionPredicate {
|
|
|
|
lifetime: wrp.lifetime.clean(cx),
|
|
|
|
bounds: wrp.bounds.clean(cx)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-17 21:18:29 +03:00
|
|
|
hir::WherePredicate::EqPredicate(ref wrp) => {
|
|
|
|
WherePredicate::EqPredicate {
|
|
|
|
lhs: wrp.lhs_ty.clean(cx),
|
|
|
|
rhs: wrp.rhs_ty.clean(cx)
|
|
|
|
}
|
2014-12-02 15:03:02 -08:00
|
|
|
}
|
2014-09-25 02:01:42 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-10 23:50:46 -08:00
|
|
|
impl<'a> Clean<WherePredicate> for ty::Predicate<'a> {
|
|
|
|
fn clean(&self, cx: &DocContext) -> WherePredicate {
|
2016-03-22 17:30:57 +02:00
|
|
|
use rustc::ty::Predicate;
|
2015-01-10 23:50:46 -08:00
|
|
|
|
|
|
|
match *self {
|
|
|
|
Predicate::Trait(ref pred) => pred.clean(cx),
|
|
|
|
Predicate::Equate(ref pred) => pred.clean(cx),
|
2017-03-09 21:47:09 -05:00
|
|
|
Predicate::Subtype(ref pred) => pred.clean(cx),
|
2015-01-10 23:50:46 -08:00
|
|
|
Predicate::RegionOutlives(ref pred) => pred.clean(cx),
|
|
|
|
Predicate::TypeOutlives(ref pred) => pred.clean(cx),
|
2015-08-07 09:30:19 -04:00
|
|
|
Predicate::Projection(ref pred) => pred.clean(cx),
|
|
|
|
Predicate::WellFormed(_) => panic!("not user writable"),
|
|
|
|
Predicate::ObjectSafe(_) => panic!("not user writable"),
|
2016-04-06 00:20:59 -07:00
|
|
|
Predicate::ClosureKind(..) => panic!("not user writable"),
|
2017-08-07 08:08:53 +03:00
|
|
|
Predicate::ConstEvaluatable(..) => panic!("not user writable"),
|
2015-01-10 23:50:46 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Clean<WherePredicate> for ty::TraitPredicate<'a> {
|
|
|
|
fn clean(&self, cx: &DocContext) -> WherePredicate {
|
|
|
|
WherePredicate::BoundPredicate {
|
2016-08-08 23:39:49 +03:00
|
|
|
ty: self.trait_ref.self_ty().clean(cx),
|
2015-01-10 23:50:46 -08:00
|
|
|
bounds: vec![self.trait_ref.clean(cx)]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'tcx> Clean<WherePredicate> for ty::EquatePredicate<'tcx> {
|
|
|
|
fn clean(&self, cx: &DocContext) -> WherePredicate {
|
|
|
|
let ty::EquatePredicate(ref lhs, ref rhs) = *self;
|
|
|
|
WherePredicate::EqPredicate {
|
|
|
|
lhs: lhs.clean(cx),
|
|
|
|
rhs: rhs.clean(cx)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-03-09 21:47:09 -05:00
|
|
|
impl<'tcx> Clean<WherePredicate> for ty::SubtypePredicate<'tcx> {
|
2017-04-11 17:11:05 -04:00
|
|
|
fn clean(&self, _cx: &DocContext) -> WherePredicate {
|
|
|
|
panic!("subtype predicates are an internal rustc artifact \
|
|
|
|
and should not be seen by rustdoc")
|
2017-03-09 21:47:09 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-04-20 04:45:53 -04:00
|
|
|
impl<'tcx> Clean<WherePredicate> for ty::OutlivesPredicate<ty::Region<'tcx>, ty::Region<'tcx>> {
|
2015-01-10 23:50:46 -08:00
|
|
|
fn clean(&self, cx: &DocContext) -> WherePredicate {
|
|
|
|
let ty::OutlivesPredicate(ref a, ref b) = *self;
|
|
|
|
WherePredicate::RegionPredicate {
|
|
|
|
lifetime: a.clean(cx).unwrap(),
|
|
|
|
bounds: vec![b.clean(cx).unwrap()]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-14 21:44:23 -04:00
|
|
|
impl<'tcx> Clean<WherePredicate> for ty::OutlivesPredicate<Ty<'tcx>, ty::Region<'tcx>> {
|
2015-01-10 23:50:46 -08:00
|
|
|
fn clean(&self, cx: &DocContext) -> WherePredicate {
|
|
|
|
let ty::OutlivesPredicate(ref ty, ref lt) = *self;
|
|
|
|
|
|
|
|
WherePredicate::BoundPredicate {
|
|
|
|
ty: ty.clean(cx),
|
|
|
|
bounds: vec![TyParamBound::RegionBound(lt.clean(cx).unwrap())]
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'tcx> Clean<WherePredicate> 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<Type> for ty::ProjectionTy<'tcx> {
|
|
|
|
fn clean(&self, cx: &DocContext) -> Type {
|
2017-07-11 10:33:09 -04:00
|
|
|
let trait_ = match self.trait_ref(cx.tcx).clean(cx) {
|
2015-01-10 23:50:46 -08:00
|
|
|
TyParamBound::TraitBound(t, _) => t.trait_,
|
2015-04-07 00:16:35 -07:00
|
|
|
TyParamBound::RegionBound(_) => {
|
|
|
|
panic!("cleaning a trait got a region")
|
|
|
|
}
|
2015-01-10 23:50:46 -08:00
|
|
|
};
|
|
|
|
Type::QPath {
|
2017-07-11 10:33:09 -04:00
|
|
|
name: cx.tcx.associated_item(self.item_def_id).name.clean(cx),
|
|
|
|
self_type: box self.self_ty().clean(cx),
|
2015-01-10 23:50:46 -08:00
|
|
|
trait_: box trait_
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-05-02 16:25:49 -04:00
|
|
|
// maybe use a Generic enum and use Vec<Generic>?
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
|
2013-08-15 16:28:54 -04:00
|
|
|
pub struct Generics {
|
2014-03-28 10:27:24 -07:00
|
|
|
pub lifetimes: Vec<Lifetime>,
|
|
|
|
pub type_params: Vec<TyParam>,
|
2014-09-25 02:01:42 -07:00
|
|
|
pub where_predicates: Vec<WherePredicate>
|
2014-03-28 10:27:24 -07:00
|
|
|
}
|
2013-08-15 16:28:54 -04:00
|
|
|
|
2015-07-31 00:04:06 -07:00
|
|
|
impl Clean<Generics> for hir::Generics {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> Generics {
|
2013-08-15 16:28:54 -04:00
|
|
|
Generics {
|
2014-09-06 19:13:40 +03:00
|
|
|
lifetimes: self.lifetimes.clean(cx),
|
|
|
|
type_params: self.ty_params.clean(cx),
|
2014-09-25 02:01:42 -07:00
|
|
|
where_predicates: self.where_clause.predicates.clean(cx)
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-01-25 22:01:11 +02:00
|
|
|
impl<'a, 'tcx> Clean<Generics> for (&'a ty::Generics,
|
2016-08-10 20:39:09 +03:00
|
|
|
&'a ty::GenericPredicates<'tcx>) {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> Generics {
|
2015-01-10 23:50:46 -08:00
|
|
|
use self::WherePredicate as WP;
|
|
|
|
|
2016-08-10 20:39:09 +03:00
|
|
|
let (gens, preds) = *self;
|
2015-02-11 10:28:52 -05:00
|
|
|
|
2015-04-06 21:17:51 -07:00
|
|
|
// Bounds in the type_params and lifetimes fields are repeated in the
|
|
|
|
// predicates field (see rustc_typeck::collect::ty_generics), so remove
|
|
|
|
// them.
|
2016-08-10 20:39:09 +03:00
|
|
|
let stripped_typarams = gens.types.iter().filter_map(|tp| {
|
2016-08-15 01:07:09 +03:00
|
|
|
if tp.name == keywords::SelfType.name() {
|
|
|
|
assert_eq!(tp.index, 0);
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
Some(tp.clean(cx))
|
|
|
|
}
|
2015-01-10 23:50:46 -08:00
|
|
|
}).collect::<Vec<_>>();
|
|
|
|
|
2016-06-13 20:10:32 +03:00
|
|
|
let mut where_predicates = preds.predicates.to_vec().clean(cx);
|
2015-02-11 10:28:52 -05:00
|
|
|
|
2015-04-07 00:16:35 -07:00
|
|
|
// Type parameters and have a Sized bound by default unless removed with
|
2015-04-06 21:17:51 -07:00
|
|
|
// ?Sized. Scan through the predicates and mark any type parameter with
|
|
|
|
// a Sized bound, removing the bounds as we find them.
|
2015-04-07 00:16:35 -07:00
|
|
|
//
|
|
|
|
// Note that associated types also have a sized bound by default, but we
|
2015-05-06 01:49:07 +02:00
|
|
|
// don't actually know the set of associated types right here so that's
|
2015-04-07 00:16:35 -07:00
|
|
|
// handled in cleaning associated types
|
2016-11-08 14:02:55 +11:00
|
|
|
let mut sized_params = FxHashSet();
|
2015-04-07 00:16:35 -07:00
|
|
|
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
|
|
|
|
}
|
2015-01-10 23:50:46 -08:00
|
|
|
}
|
2015-04-07 00:16:35 -07:00
|
|
|
_ => true,
|
2015-01-10 23:50:46 -08:00
|
|
|
}
|
2015-04-07 00:16:35 -07:00
|
|
|
});
|
2015-02-11 10:28:52 -05:00
|
|
|
|
2015-04-07 00:16:35 -07:00
|
|
|
// Run through the type parameters again and insert a ?Sized
|
2015-04-06 21:17:51 -07:00
|
|
|
// unbound for any we didn't find to be Sized.
|
2015-01-31 12:20:46 -05:00
|
|
|
for tp in &stripped_typarams {
|
2015-01-10 23:50:46 -08:00
|
|
|
if !sized_params.contains(&tp.name) {
|
|
|
|
where_predicates.push(WP::BoundPredicate {
|
|
|
|
ty: Type::Generic(tp.name.clone()),
|
2015-04-07 00:16:35 -07:00
|
|
|
bounds: vec![TyParamBound::maybe_sized(cx)],
|
2015-01-10 23:50:46 -08:00
|
|
|
})
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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`
|
|
|
|
|
2014-05-03 02:08:58 -07:00
|
|
|
Generics {
|
2015-04-06 21:17:51 -07:00
|
|
|
type_params: simplify::ty_params(stripped_typarams),
|
2017-01-25 18:39:21 +02:00
|
|
|
lifetimes: gens.regions.clean(cx),
|
2015-04-07 12:20:24 -07:00
|
|
|
where_predicates: simplify::where_clauses(cx, where_predicates),
|
2014-05-03 02:08:58 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
2013-08-15 16:28:54 -04:00
|
|
|
pub struct Method {
|
2014-03-28 10:27:24 -07:00
|
|
|
pub generics: Generics,
|
2015-07-31 00:04:06 -07:00
|
|
|
pub unsafety: hir::Unsafety,
|
|
|
|
pub constness: hir::Constness,
|
2014-03-28 10:27:24 -07:00
|
|
|
pub decl: FnDecl,
|
2016-02-05 13:13:36 +01:00
|
|
|
pub abi: Abi,
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
|
2017-09-26 01:17:04 -04:00
|
|
|
impl<'a> Clean<Method> for (&'a hir::MethodSig, &'a hir::Generics, hir::BodyId) {
|
2015-03-10 12:28:44 +02:00
|
|
|
fn clean(&self, cx: &DocContext) -> Method {
|
|
|
|
Method {
|
2017-09-26 01:17:04 -04:00
|
|
|
generics: self.1.clean(cx),
|
2016-12-20 22:46:11 +02:00
|
|
|
unsafety: self.0.unsafety,
|
|
|
|
constness: self.0.constness,
|
2017-09-26 01:17:04 -04:00
|
|
|
decl: (&*self.0.decl, self.2).clean(cx),
|
2016-12-20 22:46:11 +02:00
|
|
|
abi: self.0.abi
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
2013-08-15 16:28:54 -04:00
|
|
|
pub struct TyMethod {
|
2015-07-31 00:04:06 -07:00
|
|
|
pub unsafety: hir::Unsafety,
|
2014-03-28 10:27:24 -07:00
|
|
|
pub decl: FnDecl,
|
|
|
|
pub generics: Generics,
|
2016-02-05 13:13:36 +01:00
|
|
|
pub abi: Abi,
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
2013-08-15 16:28:54 -04:00
|
|
|
pub struct Function {
|
2014-03-28 10:27:24 -07:00
|
|
|
pub decl: FnDecl,
|
|
|
|
pub generics: Generics,
|
2015-07-31 00:04:06 -07:00
|
|
|
pub unsafety: hir::Unsafety,
|
|
|
|
pub constness: hir::Constness,
|
2016-02-05 13:13:36 +01:00
|
|
|
pub abi: Abi,
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Clean<Item> for doctree::Function {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> Item {
|
2013-08-15 16:28:54 -04:00
|
|
|
Item {
|
2014-09-06 19:13:40 +03:00
|
|
|
name: Some(self.name.clean(cx)),
|
|
|
|
attrs: self.attrs.clean(cx),
|
|
|
|
source: self.whence.clean(cx),
|
|
|
|
visibility: self.vis.clean(cx),
|
|
|
|
stability: self.stab.clean(cx),
|
2015-12-12 23:01:27 +03:00
|
|
|
deprecation: self.depr.clean(cx),
|
2017-01-26 02:41:06 +02:00
|
|
|
def_id: cx.tcx.hir.local_def_id(self.id),
|
2013-08-15 16:28:54 -04:00
|
|
|
inner: FunctionItem(Function {
|
2016-12-20 22:46:11 +02:00
|
|
|
decl: (&self.decl, self.body).clean(cx),
|
2014-09-06 19:13:40 +03:00
|
|
|
generics: self.generics.clean(cx),
|
2014-12-09 10:36:46 -05:00
|
|
|
unsafety: self.unsafety,
|
2015-02-25 22:05:07 +02:00
|
|
|
constness: self.constness,
|
2015-04-07 14:22:55 -07:00
|
|
|
abi: self.abi,
|
2013-08-15 16:28:54 -04:00
|
|
|
}),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
|
2013-08-15 16:28:54 -04:00
|
|
|
pub struct FnDecl {
|
2014-03-28 10:27:24 -07:00
|
|
|
pub inputs: Arguments,
|
2014-11-09 16:14:15 +01:00
|
|
|
pub output: FunctionRetTy,
|
2015-08-20 18:27:53 +01:00
|
|
|
pub variadic: bool,
|
2016-11-24 01:40:52 +02:00
|
|
|
pub attrs: Attributes,
|
2014-03-28 10:27:24 -07:00
|
|
|
}
|
2013-08-15 16:28:54 -04:00
|
|
|
|
2016-05-08 21:19:29 +03:00
|
|
|
impl FnDecl {
|
|
|
|
pub fn has_self(&self) -> bool {
|
2016-10-01 16:47:43 -04:00
|
|
|
self.inputs.values.len() > 0 && self.inputs.values[0].name == "self"
|
2016-05-08 21:19:29 +03:00
|
|
|
}
|
2016-09-04 18:35:35 +02:00
|
|
|
|
|
|
|
pub fn self_type(&self) -> Option<SelfTy> {
|
|
|
|
self.inputs.values.get(0).and_then(|v| v.to_self())
|
|
|
|
}
|
2016-05-08 21:19:29 +03:00
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
|
2014-02-13 06:41:34 +11:00
|
|
|
pub struct Arguments {
|
2014-03-28 10:27:24 -07:00
|
|
|
pub values: Vec<Argument>,
|
2014-02-13 06:41:34 +11:00
|
|
|
}
|
|
|
|
|
2016-12-20 22:46:11 +02:00
|
|
|
impl<'a> Clean<Arguments> for (&'a [P<hir::Ty>], &'a [Spanned<ast::Name>]) {
|
|
|
|
fn clean(&self, cx: &DocContext) -> Arguments {
|
|
|
|
Arguments {
|
|
|
|
values: self.0.iter().enumerate().map(|(i, ty)| {
|
|
|
|
let mut name = self.1.get(i).map(|n| n.node.to_string())
|
|
|
|
.unwrap_or(String::new());
|
|
|
|
if name.is_empty() {
|
|
|
|
name = "_".to_string();
|
|
|
|
}
|
|
|
|
Argument {
|
2017-08-06 22:54:09 -07:00
|
|
|
name,
|
2016-12-20 22:46:11 +02:00
|
|
|
type_: ty.clean(cx),
|
|
|
|
}
|
|
|
|
}).collect()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Clean<Arguments> for (&'a [P<hir::Ty>], hir::BodyId) {
|
|
|
|
fn clean(&self, cx: &DocContext) -> Arguments {
|
2017-01-26 02:41:06 +02:00
|
|
|
let body = cx.tcx.hir.body(self.1);
|
2016-12-20 22:46:11 +02:00
|
|
|
|
|
|
|
Arguments {
|
|
|
|
values: self.0.iter().enumerate().map(|(i, ty)| {
|
|
|
|
Argument {
|
|
|
|
name: name_from_pat(&body.arguments[i].pat),
|
|
|
|
type_: ty.clean(cx),
|
|
|
|
}
|
|
|
|
}).collect()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a, A: Copy> Clean<FnDecl> for (&'a hir::FnDecl, A)
|
|
|
|
where (&'a [P<hir::Ty>], A): Clean<Arguments>
|
|
|
|
{
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> FnDecl {
|
2013-08-15 16:28:54 -04:00
|
|
|
FnDecl {
|
2016-12-20 22:46:11 +02:00
|
|
|
inputs: (&self.0.inputs[..], self.1).clean(cx),
|
|
|
|
output: self.0.output.clean(cx),
|
|
|
|
variadic: self.0.variadic,
|
2016-11-24 01:40:52 +02:00
|
|
|
attrs: Attributes::default()
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-02-13 10:51:06 +02:00
|
|
|
impl<'a, 'tcx> Clean<FnDecl> for (DefId, ty::PolyFnSig<'tcx>) {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> FnDecl {
|
2014-05-23 18:47:01 -07:00
|
|
|
let (did, sig) = *self;
|
2017-01-26 02:41:06 +02:00
|
|
|
let mut names = if cx.tcx.hir.as_local_node_id(did).is_some() {
|
2015-09-04 13:52:28 -04:00
|
|
|
vec![].into_iter()
|
2014-05-23 18:47:01 -07:00
|
|
|
} else {
|
2017-05-03 09:01:49 -05:00
|
|
|
cx.tcx.fn_arg_names(did).into_iter()
|
2014-05-23 18:47:01 -07:00
|
|
|
}.peekable();
|
2014-05-03 02:08:58 -07:00
|
|
|
FnDecl {
|
2016-11-28 19:35:38 -07:00
|
|
|
output: Return(sig.skip_binder().output().clean(cx)),
|
2016-11-24 01:40:52 +02:00
|
|
|
attrs: Attributes::default(),
|
2016-11-28 19:35:38 -07:00
|
|
|
variadic: sig.skip_binder().variadic,
|
2014-05-03 02:08:58 -07:00
|
|
|
inputs: Arguments {
|
2016-11-28 19:35:38 -07:00
|
|
|
values: sig.skip_binder().inputs().iter().map(|t| {
|
2014-05-03 02:08:58 -07:00
|
|
|
Argument {
|
2014-09-06 19:13:40 +03:00
|
|
|
type_: t.clean(cx),
|
2016-09-16 17:25:54 +03:00
|
|
|
name: names.next().map_or("".to_string(), |name| name.to_string()),
|
2014-05-03 02:08:58 -07:00
|
|
|
}
|
|
|
|
}).collect(),
|
|
|
|
},
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
|
2013-08-15 16:28:54 -04:00
|
|
|
pub struct Argument {
|
2014-03-28 10:27:24 -07:00
|
|
|
pub type_: Type,
|
2014-05-22 16:57:53 -07:00
|
|
|
pub name: String,
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
|
2016-05-08 21:19:29 +03:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
|
|
|
|
pub enum SelfTy {
|
|
|
|
SelfValue,
|
|
|
|
SelfBorrowed(Option<Lifetime>, Mutability),
|
|
|
|
SelfExplicit(Type),
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Argument {
|
|
|
|
pub fn to_self(&self) -> Option<SelfTy> {
|
2016-12-04 03:18:11 +02:00
|
|
|
if self.name != "self" {
|
|
|
|
return None;
|
|
|
|
}
|
|
|
|
if self.type_.is_self_type() {
|
|
|
|
return Some(SelfValue);
|
|
|
|
}
|
|
|
|
match self.type_ {
|
|
|
|
BorrowedRef{ref lifetime, mutability, ref type_} if type_.is_self_type() => {
|
|
|
|
Some(SelfBorrowed(lifetime.clone(), mutability))
|
2016-05-08 21:19:29 +03:00
|
|
|
}
|
2016-12-04 03:18:11 +02:00
|
|
|
_ => Some(SelfExplicit(self.type_.clone()))
|
2016-05-08 21:19:29 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
|
2014-11-09 16:14:15 +01:00
|
|
|
pub enum FunctionRetTy {
|
|
|
|
Return(Type),
|
2015-01-18 22:49:19 +09:00
|
|
|
DefaultReturn,
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
|
2015-07-31 00:04:06 -07:00
|
|
|
impl Clean<FunctionRetTy> for hir::FunctionRetTy {
|
2014-11-09 16:14:15 +01:00
|
|
|
fn clean(&self, cx: &DocContext) -> FunctionRetTy {
|
2013-08-15 16:28:54 -04:00
|
|
|
match *self {
|
2015-07-31 00:04:06 -07:00
|
|
|
hir::Return(ref typ) => Return(typ.clean(cx)),
|
|
|
|
hir::DefaultReturn(..) => DefaultReturn,
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-10-04 15:51:35 -05:00
|
|
|
impl GetDefId for FunctionRetTy {
|
|
|
|
fn def_id(&self) -> Option<DefId> {
|
|
|
|
match *self {
|
|
|
|
Return(ref ty) => ty.def_id(),
|
|
|
|
DefaultReturn => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
2013-08-15 16:28:54 -04:00
|
|
|
pub struct Trait {
|
2015-07-31 00:04:06 -07:00
|
|
|
pub unsafety: hir::Unsafety,
|
2015-03-10 12:28:44 +02:00
|
|
|
pub items: Vec<Item>,
|
2014-03-28 10:27:24 -07:00
|
|
|
pub generics: Generics,
|
2014-08-27 21:46:52 -04:00
|
|
|
pub bounds: Vec<TyParamBound>,
|
2017-10-04 15:51:35 -05:00
|
|
|
pub is_spotlight: bool,
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Clean<Item> for doctree::Trait {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> Item {
|
2017-10-04 15:51:35 -05:00
|
|
|
let attrs = self.attrs.clean(cx);
|
|
|
|
let is_spotlight = attrs.has_doc_flag("spotlight");
|
2013-08-15 16:28:54 -04:00
|
|
|
Item {
|
2014-09-06 19:13:40 +03:00
|
|
|
name: Some(self.name.clean(cx)),
|
2017-10-04 15:51:35 -05:00
|
|
|
attrs: attrs,
|
2014-09-06 19:13:40 +03:00
|
|
|
source: self.whence.clean(cx),
|
2017-01-26 02:41:06 +02:00
|
|
|
def_id: cx.tcx.hir.local_def_id(self.id),
|
2014-09-06 19:13:40 +03:00
|
|
|
visibility: self.vis.clean(cx),
|
|
|
|
stability: self.stab.clean(cx),
|
2015-12-12 23:01:27 +03:00
|
|
|
deprecation: self.depr.clean(cx),
|
2013-08-15 16:28:54 -04:00
|
|
|
inner: TraitItem(Trait {
|
2014-12-09 19:59:20 -05:00
|
|
|
unsafety: self.unsafety,
|
2014-09-06 19:13:40 +03:00
|
|
|
items: self.items.clean(cx),
|
|
|
|
generics: self.generics.clean(cx),
|
|
|
|
bounds: self.bounds.clean(cx),
|
2017-10-04 15:51:35 -05:00
|
|
|
is_spotlight: is_spotlight,
|
2013-08-15 16:28:54 -04:00
|
|
|
}),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-31 00:04:06 -07:00
|
|
|
impl Clean<Type> for hir::TraitRef {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> Type {
|
2014-11-20 19:44:49 -05:00
|
|
|
resolve_type(cx, self.path.clean(cx), self.ref_id)
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-31 00:04:06 -07:00
|
|
|
impl Clean<PolyTrait> for hir::PolyTraitRef {
|
2014-12-16 08:50:52 -08:00
|
|
|
fn clean(&self, cx: &DocContext) -> PolyTrait {
|
|
|
|
PolyTrait {
|
|
|
|
trait_: self.trait_ref.clean(cx),
|
|
|
|
lifetimes: self.bound_lifetimes.clean(cx)
|
|
|
|
}
|
2014-11-07 06:53:45 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-31 00:04:06 -07:00
|
|
|
impl Clean<Item> for hir::TraitItem {
|
2015-03-10 12:28:44 +02:00
|
|
|
fn clean(&self, cx: &DocContext) -> Item {
|
|
|
|
let inner = match self.node {
|
2016-12-21 12:32:59 +02:00
|
|
|
hir::TraitItemKind::Const(ref ty, default) => {
|
2015-03-14 12:05:00 -06:00
|
|
|
AssociatedConstItem(ty.clean(cx),
|
2016-12-21 12:32:59 +02:00
|
|
|
default.map(|e| print_const_expr(cx, e)))
|
2015-03-14 12:05:00 -06:00
|
|
|
}
|
2016-12-20 22:46:11 +02:00
|
|
|
hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Provided(body)) => {
|
2017-09-26 01:17:04 -04:00
|
|
|
MethodItem((sig, &self.generics, body).clean(cx))
|
2015-03-11 23:38:58 +02:00
|
|
|
}
|
2016-12-20 22:46:11 +02:00
|
|
|
hir::TraitItemKind::Method(ref sig, hir::TraitMethod::Required(ref names)) => {
|
|
|
|
TyMethodItem(TyMethod {
|
|
|
|
unsafety: sig.unsafety.clone(),
|
|
|
|
decl: (&*sig.decl, &names[..]).clean(cx),
|
2017-09-26 01:17:04 -04:00
|
|
|
generics: self.generics.clean(cx),
|
2016-12-20 22:46:11 +02:00
|
|
|
abi: sig.abi
|
|
|
|
})
|
2015-03-11 23:38:58 +02:00
|
|
|
}
|
2016-12-04 04:21:06 +02:00
|
|
|
hir::TraitItemKind::Type(ref bounds, ref default) => {
|
2015-03-10 12:28:44 +02:00
|
|
|
AssociatedTypeItem(bounds.clean(cx), default.clean(cx))
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Item {
|
2015-09-20 04:50:30 +03:00
|
|
|
name: Some(self.name.clean(cx)),
|
2015-03-10 12:28:44 +02:00
|
|
|
attrs: self.attrs.clean(cx),
|
|
|
|
source: self.span.clean(cx),
|
2017-01-26 02:41:06 +02:00
|
|
|
def_id: cx.tcx.hir.local_def_id(self.id),
|
2015-03-10 12:28:44 +02:00
|
|
|
visibility: None,
|
2017-01-26 02:41:06 +02:00
|
|
|
stability: get_stability(cx, cx.tcx.hir.local_def_id(self.id)),
|
|
|
|
deprecation: get_deprecation(cx, cx.tcx.hir.local_def_id(self.id)),
|
2017-08-06 22:54:09 -07:00
|
|
|
inner,
|
2014-08-04 13:56:56 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-31 00:04:06 -07:00
|
|
|
impl Clean<Item> for hir::ImplItem {
|
2015-03-10 12:28:44 +02:00
|
|
|
fn clean(&self, cx: &DocContext) -> Item {
|
|
|
|
let inner = match self.node {
|
2016-12-21 12:32:59 +02:00
|
|
|
hir::ImplItemKind::Const(ref ty, expr) => {
|
2016-02-12 09:34:00 +01:00
|
|
|
AssociatedConstItem(ty.clean(cx),
|
2016-12-21 12:32:59 +02:00
|
|
|
Some(print_const_expr(cx, expr)))
|
2015-03-14 12:05:00 -06:00
|
|
|
}
|
2016-12-20 22:46:11 +02:00
|
|
|
hir::ImplItemKind::Method(ref sig, body) => {
|
2017-09-26 01:17:04 -04:00
|
|
|
MethodItem((sig, &self.generics, body).clean(cx))
|
2015-03-11 23:38:58 +02:00
|
|
|
}
|
2015-11-12 15:57:51 +01:00
|
|
|
hir::ImplItemKind::Type(ref ty) => TypedefItem(Typedef {
|
2015-03-10 12:28:44 +02:00
|
|
|
type_: ty.clean(cx),
|
|
|
|
generics: Generics {
|
|
|
|
lifetimes: Vec::new(),
|
|
|
|
type_params: Vec::new(),
|
|
|
|
where_predicates: Vec::new()
|
|
|
|
},
|
2015-05-21 14:17:37 +02:00
|
|
|
}, true),
|
2015-03-10 12:28:44 +02:00
|
|
|
};
|
|
|
|
Item {
|
2015-09-20 04:50:30 +03:00
|
|
|
name: Some(self.name.clean(cx)),
|
2015-03-10 12:28:44 +02:00
|
|
|
source: self.span.clean(cx),
|
|
|
|
attrs: self.attrs.clean(cx),
|
2017-01-26 02:41:06 +02:00
|
|
|
def_id: cx.tcx.hir.local_def_id(self.id),
|
2015-03-10 12:28:44 +02:00
|
|
|
visibility: self.vis.clean(cx),
|
2017-01-26 02:41:06 +02:00
|
|
|
stability: get_stability(cx, cx.tcx.hir.local_def_id(self.id)),
|
|
|
|
deprecation: get_deprecation(cx, cx.tcx.hir.local_def_id(self.id)),
|
2017-08-06 22:54:09 -07:00
|
|
|
inner,
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-10 02:06:34 +02:00
|
|
|
impl<'tcx> Clean<Item> for ty::AssociatedItem {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> Item {
|
2016-11-10 02:06:34 +02:00
|
|
|
let inner = match self.kind {
|
|
|
|
ty::AssociatedKind::Const => {
|
2017-04-24 15:20:46 +03:00
|
|
|
let ty = cx.tcx.type_of(self.def_id);
|
2016-11-10 02:06:34 +02:00
|
|
|
AssociatedConstItem(ty.clean(cx), None)
|
2016-05-08 21:19:29 +03:00
|
|
|
}
|
2016-11-10 02:06:34 +02:00
|
|
|
ty::AssociatedKind::Method => {
|
2017-04-24 15:20:46 +03:00
|
|
|
let generics = (cx.tcx.generics_of(self.def_id),
|
|
|
|
&cx.tcx.predicates_of(self.def_id)).clean(cx);
|
2017-05-13 17:11:52 +03:00
|
|
|
let sig = cx.tcx.fn_sig(self.def_id);
|
2017-02-13 10:51:06 +02:00
|
|
|
let mut decl = (self.def_id, sig).clean(cx);
|
2016-11-10 02:06:34 +02:00
|
|
|
|
|
|
|
if self.method_has_self_argument {
|
|
|
|
let self_ty = match self.container {
|
|
|
|
ty::ImplContainer(def_id) => {
|
2017-04-24 15:20:46 +03:00
|
|
|
cx.tcx.type_of(def_id)
|
2016-11-10 02:06:34 +02:00
|
|
|
}
|
2016-11-20 03:42:54 +02:00
|
|
|
ty::TraitContainer(_) => cx.tcx.mk_self_type()
|
2016-11-10 02:06:34 +02:00
|
|
|
};
|
2017-02-13 10:51:06 +02:00
|
|
|
let self_arg_ty = *sig.input(0).skip_binder();
|
2016-11-10 02:06:34 +02:00
|
|
|
if self_arg_ty == self_ty {
|
2016-12-04 03:18:11 +02:00
|
|
|
decl.inputs.values[0].type_ = Generic(String::from("Self"));
|
2016-11-10 02:06:34 +02:00
|
|
|
} else if let ty::TyRef(_, mt) = self_arg_ty.sty {
|
|
|
|
if mt.ty == self_ty {
|
|
|
|
match decl.inputs.values[0].type_ {
|
2016-12-04 03:18:11 +02:00
|
|
|
BorrowedRef{ref mut type_, ..} => {
|
|
|
|
**type_ = Generic(String::from("Self"))
|
|
|
|
}
|
2016-11-10 02:06:34 +02:00
|
|
|
_ => unreachable!(),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-11-14 11:00:02 -05:00
|
|
|
|
2016-11-10 02:06:34 +02:00
|
|
|
let provided = match self.container {
|
|
|
|
ty::ImplContainer(_) => false,
|
2016-11-14 11:00:02 -05:00
|
|
|
ty::TraitContainer(_) => self.defaultness.has_value()
|
2016-11-10 02:06:34 +02:00
|
|
|
};
|
|
|
|
if provided {
|
|
|
|
MethodItem(Method {
|
2017-02-13 10:51:06 +02:00
|
|
|
unsafety: sig.unsafety(),
|
2017-08-06 22:54:09 -07:00
|
|
|
generics,
|
|
|
|
decl,
|
2017-02-13 10:51:06 +02:00
|
|
|
abi: sig.abi(),
|
2016-11-10 02:06:34 +02:00
|
|
|
|
2017-03-16 02:15:10 +01:00
|
|
|
// trait methods cannot (currently, at least) be const
|
2016-11-10 02:06:34 +02:00
|
|
|
constness: hir::Constness::NotConst,
|
|
|
|
})
|
|
|
|
} else {
|
|
|
|
TyMethodItem(TyMethod {
|
2017-02-13 10:51:06 +02:00
|
|
|
unsafety: sig.unsafety(),
|
2017-08-06 22:54:09 -07:00
|
|
|
generics,
|
|
|
|
decl,
|
2017-02-13 10:51:06 +02:00
|
|
|
abi: sig.abi(),
|
2016-11-10 02:06:34 +02:00
|
|
|
})
|
2016-05-08 21:19:29 +03:00
|
|
|
}
|
|
|
|
}
|
2016-11-10 02:06:34 +02:00
|
|
|
ty::AssociatedKind::Type => {
|
|
|
|
let my_name = self.name.clean(cx);
|
|
|
|
|
|
|
|
let mut bounds = 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.
|
2017-04-24 15:20:46 +03:00
|
|
|
let predicates = cx.tcx.predicates_of(did);
|
|
|
|
let generics = (cx.tcx.generics_of(did), &predicates).clean(cx);
|
2016-11-10 02:06:34 +02:00
|
|
|
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::<Vec<_>>()
|
|
|
|
} else {
|
|
|
|
vec![]
|
|
|
|
};
|
|
|
|
|
|
|
|
// 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(TyParamBound::maybe_sized(cx)),
|
|
|
|
}
|
|
|
|
|
2016-11-14 11:00:02 -05:00
|
|
|
let ty = if self.defaultness.has_value() {
|
2017-04-24 15:20:46 +03:00
|
|
|
Some(cx.tcx.type_of(self.def_id))
|
2016-11-10 02:06:34 +02:00
|
|
|
} else {
|
|
|
|
None
|
|
|
|
};
|
|
|
|
|
|
|
|
AssociatedTypeItem(bounds, ty.clean(cx))
|
2015-04-07 11:50:14 -07:00
|
|
|
}
|
|
|
|
};
|
|
|
|
|
2014-06-02 00:09:44 -07:00
|
|
|
Item {
|
2014-09-30 19:11:34 -05:00
|
|
|
name: Some(self.name.clean(cx)),
|
2016-04-11 08:15:14 +00:00
|
|
|
visibility: Some(Inherited),
|
2014-09-06 19:13:40 +03:00
|
|
|
stability: get_stability(cx, self.def_id),
|
2015-12-12 23:01:27 +03:00
|
|
|
deprecation: get_deprecation(cx, self.def_id),
|
2014-05-03 02:08:58 -07:00
|
|
|
def_id: self.def_id,
|
2016-11-20 03:42:54 +02:00
|
|
|
attrs: inline::load_attrs(cx, self.def_id),
|
2016-11-29 08:15:16 +02:00
|
|
|
source: cx.tcx.def_span(self.def_id).clean(cx),
|
2017-08-06 22:54:09 -07:00
|
|
|
inner,
|
2014-06-02 00:09:44 -07:00
|
|
|
}
|
2014-05-03 02:08:58 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-16 08:50:52 -08:00
|
|
|
/// A trait reference, which may have higher ranked lifetimes.
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
|
2014-12-16 08:50:52 -08:00
|
|
|
pub struct PolyTrait {
|
|
|
|
pub trait_: Type,
|
|
|
|
pub lifetimes: Vec<Lifetime>
|
|
|
|
}
|
|
|
|
|
2013-08-15 16:28:54 -04:00
|
|
|
/// A representation of a Type suitable for hyperlinking purposes. Ideally one can get the original
|
2016-02-29 23:36:51 +00:00
|
|
|
/// type out of the AST/TyCtxt given one of these, if more information is needed. Most importantly
|
2013-08-15 16:28:54 -04:00
|
|
|
/// it does not preserve mutability or boxes.
|
2017-05-31 18:02:35 +01:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
|
2013-08-15 16:28:54 -04:00
|
|
|
pub enum Type {
|
2015-07-31 00:04:06 -07:00
|
|
|
/// structs/enums/traits (most that'd be an hir::TyPath)
|
2013-09-27 18:23:57 -07:00
|
|
|
ResolvedPath {
|
2014-11-15 17:57:54 -08:00
|
|
|
path: Path,
|
|
|
|
typarams: Option<Vec<TyParamBound>>,
|
2015-08-16 06:32:28 -04:00
|
|
|
did: DefId,
|
2015-05-25 15:06:38 +02:00
|
|
|
/// true if is a `T::Name` path for associated types
|
|
|
|
is_generic: bool,
|
2013-09-27 18:23:57 -07:00
|
|
|
},
|
2014-12-27 19:42:27 -05:00
|
|
|
/// For parameterized types, so the consumer of the JSON don't go
|
|
|
|
/// looking for types which don't exist anywhere.
|
|
|
|
Generic(String),
|
2015-03-25 17:06:52 -07:00
|
|
|
/// Primitives are the fixed-size numeric types (plus int/usize/float), char,
|
2015-03-23 14:01:28 -07:00
|
|
|
/// arrays, slices, and tuples.
|
2014-09-11 17:07:49 +12:00
|
|
|
Primitive(PrimitiveType),
|
2013-08-15 16:28:54 -04:00
|
|
|
/// extern "ABI" fn
|
2014-05-05 18:56:44 -07:00
|
|
|
BareFunction(Box<BareFunctionDecl>),
|
2014-04-19 22:24:52 -07:00
|
|
|
Tuple(Vec<Type>),
|
2017-05-31 14:39:30 +01:00
|
|
|
Slice(Box<Type>),
|
2017-08-05 12:27:28 +03:00
|
|
|
Array(Box<Type>, String),
|
2016-08-02 15:56:20 +08:00
|
|
|
Never,
|
2014-05-05 18:56:44 -07:00
|
|
|
Unique(Box<Type>),
|
|
|
|
RawPointer(Mutability, Box<Type>),
|
2014-03-28 10:27:24 -07:00
|
|
|
BorrowedRef {
|
2014-11-15 17:57:54 -08:00
|
|
|
lifetime: Option<Lifetime>,
|
|
|
|
mutability: Mutability,
|
|
|
|
type_: Box<Type>,
|
2014-03-28 10:27:24 -07:00
|
|
|
},
|
2014-11-26 10:11:27 -05:00
|
|
|
|
|
|
|
// <Type as Trait>::Name
|
2014-11-20 21:45:05 -08:00
|
|
|
QPath {
|
|
|
|
name: String,
|
|
|
|
self_type: Box<Type>,
|
|
|
|
trait_: Box<Type>
|
|
|
|
},
|
2014-11-26 10:11:27 -05:00
|
|
|
|
|
|
|
// _
|
|
|
|
Infer,
|
|
|
|
|
2016-08-01 04:25:32 +03:00
|
|
|
// impl TraitA+TraitB
|
|
|
|
ImplTrait(Vec<TyParamBound>),
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Eq, Hash, Copy, Debug)]
|
2014-09-11 17:07:49 +12:00
|
|
|
pub enum PrimitiveType {
|
2016-08-23 03:56:52 +03:00
|
|
|
Isize, I8, I16, I32, I64, I128,
|
|
|
|
Usize, U8, U16, U32, U64, U128,
|
2014-06-24 16:34:46 -07:00
|
|
|
F32, F64,
|
2014-05-28 19:53:37 -07:00
|
|
|
Char,
|
|
|
|
Bool,
|
|
|
|
Str,
|
|
|
|
Slice,
|
2015-03-23 14:01:28 -07:00
|
|
|
Array,
|
2016-08-23 18:51:56 -04:00
|
|
|
Tuple,
|
2017-10-17 23:03:50 -07:00
|
|
|
Unit,
|
2016-08-23 18:51:56 -04:00
|
|
|
RawPointer,
|
2017-07-30 14:59:08 -05:00
|
|
|
Reference,
|
2017-07-28 12:55:30 -05:00
|
|
|
Fn,
|
2014-05-28 19:53:37 -07:00
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, Copy, Debug)]
|
2013-10-02 15:39:32 -07:00
|
|
|
pub enum TypeKind {
|
2016-10-01 00:34:00 -04:00
|
|
|
Enum,
|
|
|
|
Function,
|
|
|
|
Module,
|
|
|
|
Const,
|
|
|
|
Static,
|
|
|
|
Struct,
|
|
|
|
Union,
|
|
|
|
Trait,
|
|
|
|
Variant,
|
|
|
|
Typedef,
|
2017-09-03 19:53:58 +01:00
|
|
|
Foreign,
|
2013-10-02 15:39:32 -07:00
|
|
|
}
|
|
|
|
|
2016-03-24 06:10:52 +01:00
|
|
|
pub trait GetDefId {
|
|
|
|
fn def_id(&self) -> Option<DefId>;
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<T: GetDefId> GetDefId for Option<T> {
|
|
|
|
fn def_id(&self) -> Option<DefId> {
|
|
|
|
self.as_ref().and_then(|d| d.def_id())
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-04-07 17:35:23 -07:00
|
|
|
impl Type {
|
|
|
|
pub fn primitive_type(&self) -> Option<PrimitiveType> {
|
|
|
|
match *self {
|
|
|
|
Primitive(p) | BorrowedRef { type_: box Primitive(p), ..} => Some(p),
|
2017-05-31 14:39:30 +01:00
|
|
|
Slice(..) | BorrowedRef { type_: box Slice(..), .. } => Some(PrimitiveType::Slice),
|
|
|
|
Array(..) | BorrowedRef { type_: box Array(..), .. } => Some(PrimitiveType::Array),
|
2017-10-17 23:03:50 -07:00
|
|
|
Tuple(ref tys) => if tys.is_empty() {
|
|
|
|
Some(PrimitiveType::Unit)
|
|
|
|
} else {
|
|
|
|
Some(PrimitiveType::Tuple)
|
|
|
|
},
|
2016-08-23 18:51:56 -04:00
|
|
|
RawPointer(..) => Some(PrimitiveType::RawPointer),
|
2017-07-30 14:59:08 -05:00
|
|
|
BorrowedRef { type_: box Generic(..), .. } => Some(PrimitiveType::Reference),
|
2017-07-28 12:55:30 -05:00
|
|
|
BareFunction(..) => Some(PrimitiveType::Fn),
|
2015-04-07 17:35:23 -07:00
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
2016-03-29 01:11:08 +09:00
|
|
|
|
2016-05-09 16:48:02 +02:00
|
|
|
pub fn is_generic(&self) -> bool {
|
|
|
|
match *self {
|
|
|
|
ResolvedPath { is_generic, .. } => is_generic,
|
|
|
|
_ => false,
|
|
|
|
}
|
|
|
|
}
|
2016-12-04 03:18:11 +02:00
|
|
|
|
|
|
|
pub fn is_self_type(&self) -> bool {
|
|
|
|
match *self {
|
|
|
|
Generic(ref name) => name == "Self",
|
|
|
|
_ => false
|
|
|
|
}
|
|
|
|
}
|
2017-10-01 21:25:48 -05:00
|
|
|
|
|
|
|
pub fn generics(&self) -> Option<&[Type]> {
|
|
|
|
match *self {
|
|
|
|
ResolvedPath { ref path, .. } => {
|
|
|
|
path.segments.last().and_then(|seg| {
|
|
|
|
if let PathParameters::AngleBracketed { ref types, .. } = seg.params {
|
|
|
|
Some(&**types)
|
|
|
|
} else {
|
|
|
|
None
|
|
|
|
}
|
|
|
|
})
|
|
|
|
}
|
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
2016-03-24 06:10:52 +01:00
|
|
|
}
|
2016-03-08 11:20:16 -08:00
|
|
|
|
2016-03-24 06:10:52 +01:00
|
|
|
impl GetDefId for Type {
|
2016-03-08 11:20:16 -08:00
|
|
|
fn def_id(&self) -> Option<DefId> {
|
|
|
|
match *self {
|
|
|
|
ResolvedPath { did, .. } => Some(did),
|
2017-08-08 15:22:04 -05:00
|
|
|
Primitive(p) => ::html::render::cache().primitive_locations.get(&p).cloned(),
|
|
|
|
BorrowedRef { type_: box Generic(..), .. } =>
|
|
|
|
Primitive(PrimitiveType::Reference).def_id(),
|
|
|
|
BorrowedRef { ref type_, .. } => type_.def_id(),
|
2017-10-17 23:03:50 -07:00
|
|
|
Tuple(ref tys) => if tys.is_empty() {
|
|
|
|
Primitive(PrimitiveType::Unit).def_id()
|
|
|
|
} else {
|
|
|
|
Primitive(PrimitiveType::Tuple).def_id()
|
|
|
|
},
|
2017-08-08 15:22:04 -05:00
|
|
|
BareFunction(..) => Primitive(PrimitiveType::Fn).def_id(),
|
|
|
|
Slice(..) => Primitive(PrimitiveType::Slice).def_id(),
|
|
|
|
Array(..) => Primitive(PrimitiveType::Array).def_id(),
|
|
|
|
RawPointer(..) => Primitive(PrimitiveType::RawPointer).def_id(),
|
|
|
|
QPath { ref self_type, .. } => self_type.def_id(),
|
2016-03-08 11:20:16 -08:00
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
2015-04-07 17:35:23 -07:00
|
|
|
}
|
|
|
|
|
2014-09-11 17:07:49 +12:00
|
|
|
impl PrimitiveType {
|
|
|
|
fn from_str(s: &str) -> Option<PrimitiveType> {
|
2015-02-01 21:53:25 -05:00
|
|
|
match s {
|
2016-08-23 18:48:10 -04:00
|
|
|
"isize" => Some(PrimitiveType::Isize),
|
|
|
|
"i8" => Some(PrimitiveType::I8),
|
|
|
|
"i16" => Some(PrimitiveType::I16),
|
|
|
|
"i32" => Some(PrimitiveType::I32),
|
|
|
|
"i64" => Some(PrimitiveType::I64),
|
2016-11-21 05:40:35 +01:00
|
|
|
"i128" => Some(PrimitiveType::I128),
|
2016-08-23 18:48:10 -04:00
|
|
|
"usize" => Some(PrimitiveType::Usize),
|
|
|
|
"u8" => Some(PrimitiveType::U8),
|
|
|
|
"u16" => Some(PrimitiveType::U16),
|
|
|
|
"u32" => Some(PrimitiveType::U32),
|
|
|
|
"u64" => Some(PrimitiveType::U64),
|
2016-11-21 05:40:35 +01:00
|
|
|
"u128" => Some(PrimitiveType::U128),
|
2016-08-23 18:48:10 -04:00
|
|
|
"bool" => Some(PrimitiveType::Bool),
|
|
|
|
"char" => Some(PrimitiveType::Char),
|
|
|
|
"str" => Some(PrimitiveType::Str),
|
|
|
|
"f32" => Some(PrimitiveType::F32),
|
|
|
|
"f64" => Some(PrimitiveType::F64),
|
|
|
|
"array" => Some(PrimitiveType::Array),
|
|
|
|
"slice" => Some(PrimitiveType::Slice),
|
2016-08-23 18:51:56 -04:00
|
|
|
"tuple" => Some(PrimitiveType::Tuple),
|
2017-10-17 23:03:50 -07:00
|
|
|
"unit" => Some(PrimitiveType::Unit),
|
2016-08-23 18:51:56 -04:00
|
|
|
"pointer" => Some(PrimitiveType::RawPointer),
|
2017-07-30 14:59:08 -05:00
|
|
|
"reference" => Some(PrimitiveType::Reference),
|
2017-07-28 12:55:30 -05:00
|
|
|
"fn" => Some(PrimitiveType::Fn),
|
2014-05-28 19:53:37 -07:00
|
|
|
_ => None,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-01 11:15:42 -04:00
|
|
|
pub fn as_str(&self) -> &'static str {
|
2016-11-20 06:44:56 +01:00
|
|
|
use self::PrimitiveType::*;
|
2014-05-28 19:53:37 -07:00
|
|
|
match *self {
|
2016-08-23 03:56:52 +03:00
|
|
|
Isize => "isize",
|
|
|
|
I8 => "i8",
|
|
|
|
I16 => "i16",
|
|
|
|
I32 => "i32",
|
|
|
|
I64 => "i64",
|
|
|
|
I128 => "i128",
|
|
|
|
Usize => "usize",
|
|
|
|
U8 => "u8",
|
|
|
|
U16 => "u16",
|
|
|
|
U32 => "u32",
|
|
|
|
U64 => "u64",
|
|
|
|
U128 => "u128",
|
|
|
|
F32 => "f32",
|
|
|
|
F64 => "f64",
|
|
|
|
Str => "str",
|
|
|
|
Bool => "bool",
|
|
|
|
Char => "char",
|
|
|
|
Array => "array",
|
|
|
|
Slice => "slice",
|
|
|
|
Tuple => "tuple",
|
2017-10-17 23:03:50 -07:00
|
|
|
Unit => "unit",
|
2016-08-23 03:56:52 +03:00
|
|
|
RawPointer => "pointer",
|
2017-07-30 14:59:08 -05:00
|
|
|
Reference => "reference",
|
2017-07-28 12:55:30 -05:00
|
|
|
Fn => "fn",
|
2014-05-28 19:53:37 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn to_url_str(&self) -> &'static str {
|
2016-10-01 11:15:42 -04:00
|
|
|
self.as_str()
|
2014-05-28 19:53:37 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-23 19:12:24 -04:00
|
|
|
impl From<ast::IntTy> for PrimitiveType {
|
|
|
|
fn from(int_ty: ast::IntTy) -> PrimitiveType {
|
|
|
|
match int_ty {
|
|
|
|
ast::IntTy::Is => PrimitiveType::Isize,
|
|
|
|
ast::IntTy::I8 => PrimitiveType::I8,
|
|
|
|
ast::IntTy::I16 => PrimitiveType::I16,
|
|
|
|
ast::IntTy::I32 => PrimitiveType::I32,
|
|
|
|
ast::IntTy::I64 => PrimitiveType::I64,
|
2016-08-26 01:32:46 +03:00
|
|
|
ast::IntTy::I128 => PrimitiveType::I128,
|
2016-08-23 19:12:24 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-07-07 18:20:26 +03:00
|
|
|
|
2016-08-23 19:22:18 -04:00
|
|
|
impl From<ast::UintTy> for PrimitiveType {
|
|
|
|
fn from(uint_ty: ast::UintTy) -> PrimitiveType {
|
|
|
|
match uint_ty {
|
|
|
|
ast::UintTy::Us => PrimitiveType::Usize,
|
|
|
|
ast::UintTy::U8 => PrimitiveType::U8,
|
|
|
|
ast::UintTy::U16 => PrimitiveType::U16,
|
|
|
|
ast::UintTy::U32 => PrimitiveType::U32,
|
|
|
|
ast::UintTy::U64 => PrimitiveType::U64,
|
2016-08-26 01:32:46 +03:00
|
|
|
ast::UintTy::U128 => PrimitiveType::U128,
|
2016-08-23 19:22:18 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-23 19:41:14 -04:00
|
|
|
impl From<ast::FloatTy> for PrimitiveType {
|
|
|
|
fn from(float_ty: ast::FloatTy) -> PrimitiveType {
|
|
|
|
match float_ty {
|
|
|
|
ast::FloatTy::F32 => PrimitiveType::F32,
|
|
|
|
ast::FloatTy::F64 => PrimitiveType::F64,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-31 00:04:06 -07:00
|
|
|
impl Clean<Type> for hir::Ty {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> Type {
|
2016-03-29 08:50:44 +03:00
|
|
|
use rustc::hir::*;
|
2013-09-24 13:53:09 -07:00
|
|
|
match self.node {
|
2016-08-02 15:56:20 +08:00
|
|
|
TyNever => Never,
|
2014-09-06 19:13:40 +03:00
|
|
|
TyPtr(ref m) => RawPointer(m.mutbl.clean(cx), box m.ty.clean(cx)),
|
2017-01-09 17:46:11 +02:00
|
|
|
TyRptr(ref l, ref m) => {
|
|
|
|
let lifetime = if l.is_elided() {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
Some(l.clean(cx))
|
|
|
|
};
|
|
|
|
BorrowedRef {lifetime: lifetime, mutability: m.mutbl.clean(cx),
|
|
|
|
type_: box m.ty.clean(cx)}
|
|
|
|
}
|
2017-05-31 14:39:30 +01:00
|
|
|
TySlice(ref ty) => Slice(box ty.clean(cx)),
|
2017-08-07 08:08:53 +03:00
|
|
|
TyArray(ref ty, n) => {
|
|
|
|
let def_id = cx.tcx.hir.body_owner_def_id(n);
|
|
|
|
let param_env = ty::ParamEnv::empty(Reveal::UserFacing);
|
|
|
|
let substs = Substs::identity_for_item(cx.tcx, def_id);
|
|
|
|
let n = cx.tcx.const_eval(param_env.and((def_id, substs))).unwrap();
|
2017-08-05 16:11:24 +03:00
|
|
|
let n = if let ConstVal::Integral(ConstInt::Usize(n)) = n.val {
|
|
|
|
n.to_string()
|
2017-09-14 09:45:07 +03:00
|
|
|
} else if let ConstVal::Unevaluated(def_id, _) = n.val {
|
|
|
|
if let Some(node_id) = cx.tcx.hir.as_local_node_id(def_id) {
|
|
|
|
print_const_expr(cx, cx.tcx.hir.body_owned_by(node_id))
|
|
|
|
} else {
|
|
|
|
inline::print_inlined_const(cx, def_id)
|
|
|
|
}
|
2017-08-05 16:11:24 +03:00
|
|
|
} else {
|
|
|
|
format!("{:?}", n)
|
|
|
|
};
|
|
|
|
Array(box ty.clean(cx), n)
|
2016-07-13 10:35:58 +02:00
|
|
|
},
|
2014-09-06 19:13:40 +03:00
|
|
|
TyTup(ref tys) => Tuple(tys.clean(cx)),
|
2016-10-27 05:17:42 +03:00
|
|
|
TyPath(hir::QPath::Resolved(None, ref path)) => {
|
2016-11-25 13:21:19 +02:00
|
|
|
if let Some(new_ty) = cx.ty_substs.borrow().get(&path.def).cloned() {
|
2016-11-20 03:42:54 +02:00
|
|
|
return new_ty;
|
2016-09-01 10:21:12 +03:00
|
|
|
}
|
|
|
|
|
2016-11-20 03:42:54 +02:00
|
|
|
let mut alias = None;
|
2016-11-25 13:21:19 +02:00
|
|
|
if let Def::TyAlias(def_id) = path.def {
|
2016-11-20 03:42:54 +02:00
|
|
|
// Substitute private type aliases
|
2017-01-26 02:41:06 +02:00
|
|
|
if let Some(node_id) = cx.tcx.hir.as_local_node_id(def_id) {
|
2016-11-20 03:42:54 +02:00
|
|
|
if !cx.access_levels.borrow().is_exported(def_id) {
|
2017-01-26 02:41:06 +02:00
|
|
|
alias = Some(&cx.tcx.hir.expect_item(node_id).node);
|
2016-11-20 03:42:54 +02:00
|
|
|
}
|
2016-09-01 10:21:12 +03:00
|
|
|
}
|
2016-11-20 03:42:54 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
if let Some(&hir::ItemTy(ref ty, ref generics)) = alias {
|
2017-09-21 23:24:26 +03:00
|
|
|
let provided_params = &path.segments.last().unwrap();
|
2016-11-08 14:02:55 +11:00
|
|
|
let mut ty_substs = FxHashMap();
|
|
|
|
let mut lt_substs = FxHashMap();
|
2017-09-21 23:24:26 +03:00
|
|
|
provided_params.with_parameters(|provided_params| {
|
|
|
|
for (i, ty_param) in generics.ty_params.iter().enumerate() {
|
|
|
|
let ty_param_def = Def::TyParam(cx.tcx.hir.local_def_id(ty_param.id));
|
|
|
|
if let Some(ty) = provided_params.types.get(i).cloned() {
|
|
|
|
ty_substs.insert(ty_param_def, ty.unwrap().clean(cx));
|
|
|
|
} else if let Some(default) = ty_param.default.clone() {
|
|
|
|
ty_substs.insert(ty_param_def, default.unwrap().clean(cx));
|
|
|
|
}
|
2016-09-01 10:21:12 +03:00
|
|
|
}
|
2017-09-21 23:24:26 +03:00
|
|
|
for (i, lt_param) in generics.lifetimes.iter().enumerate() {
|
|
|
|
if let Some(lt) = provided_params.lifetimes.get(i).cloned() {
|
|
|
|
if !lt.is_elided() {
|
|
|
|
let lt_def_id = cx.tcx.hir.local_def_id(lt_param.lifetime.id);
|
|
|
|
lt_substs.insert(lt_def_id, lt.clean(cx));
|
|
|
|
}
|
2017-01-09 17:46:11 +02:00
|
|
|
}
|
2016-07-07 18:20:26 +03:00
|
|
|
}
|
2017-09-21 23:24:26 +03:00
|
|
|
});
|
2016-09-01 10:21:12 +03:00
|
|
|
return cx.enter_alias(ty_substs, lt_substs, || ty.clean(cx));
|
2016-07-07 18:20:26 +03:00
|
|
|
}
|
|
|
|
resolve_type(cx, path.clean(cx), self.id)
|
2014-11-20 19:44:49 -05:00
|
|
|
}
|
2016-10-27 05:17:42 +03:00
|
|
|
TyPath(hir::QPath::Resolved(Some(ref qself), ref p)) => {
|
2015-12-17 20:41:28 +03:00
|
|
|
let mut segments: Vec<_> = p.segments.clone().into();
|
|
|
|
segments.pop();
|
|
|
|
let trait_path = hir::Path {
|
|
|
|
span: p.span,
|
2016-11-25 13:21:19 +02:00
|
|
|
def: Def::Trait(cx.tcx.associated_item(p.def.def_id()).container.id()),
|
2015-12-17 20:41:28 +03:00
|
|
|
segments: segments.into(),
|
|
|
|
};
|
2015-01-31 05:51:21 +02:00
|
|
|
Type::QPath {
|
2016-03-06 15:54:44 +03:00
|
|
|
name: p.segments.last().unwrap().name.clean(cx),
|
2016-10-27 05:17:42 +03:00
|
|
|
self_type: box qself.clean(cx),
|
|
|
|
trait_: box resolve_type(cx, trait_path.clean(cx), self.id)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
TyPath(hir::QPath::TypeRelative(ref qself, ref segment)) => {
|
2016-10-29 13:19:59 +03:00
|
|
|
let mut def = Def::Err;
|
2017-05-03 11:53:06 -04:00
|
|
|
let ty = hir_ty_to_ty(cx.tcx, self);
|
|
|
|
if let ty::TyProjection(proj) = ty.sty {
|
2017-07-11 10:33:09 -04:00
|
|
|
def = Def::Trait(proj.trait_ref(cx.tcx).def_id);
|
2016-10-29 13:19:59 +03:00
|
|
|
}
|
2016-10-27 05:17:42 +03:00
|
|
|
let trait_path = hir::Path {
|
|
|
|
span: self.span,
|
2017-08-06 22:54:09 -07:00
|
|
|
def,
|
2016-10-27 05:17:42 +03:00
|
|
|
segments: vec![].into(),
|
|
|
|
};
|
|
|
|
Type::QPath {
|
|
|
|
name: segment.name.clean(cx),
|
|
|
|
self_type: box qself.clean(cx),
|
2015-01-31 21:20:24 +02:00
|
|
|
trait_: box resolve_type(cx, trait_path.clean(cx), self.id)
|
2015-01-31 05:51:21 +02:00
|
|
|
}
|
|
|
|
}
|
2017-01-24 17:17:06 +02:00
|
|
|
TyTraitObject(ref bounds, ref lifetime) => {
|
|
|
|
match bounds[0].clean(cx).trait_ {
|
|
|
|
ResolvedPath { path, typarams: None, did, is_generic } => {
|
|
|
|
let mut bounds: Vec<_> = bounds[1..].iter().map(|bound| {
|
|
|
|
TraitBound(bound.clean(cx), hir::TraitBoundModifier::None)
|
|
|
|
}).collect();
|
|
|
|
if !lifetime.is_elided() {
|
|
|
|
bounds.push(RegionBound(lifetime.clean(cx)));
|
|
|
|
}
|
|
|
|
ResolvedPath {
|
2017-08-06 22:54:09 -07:00
|
|
|
path,
|
2017-01-24 17:17:06 +02:00
|
|
|
typarams: Some(bounds),
|
2017-08-06 22:54:09 -07:00
|
|
|
did,
|
|
|
|
is_generic,
|
2015-05-25 15:06:38 +02:00
|
|
|
}
|
2014-11-20 19:44:49 -05:00
|
|
|
}
|
2017-01-16 23:33:45 +03:00
|
|
|
_ => Infer // shouldn't happen
|
2014-11-20 19:44:49 -05:00
|
|
|
}
|
2014-02-28 17:46:09 -08:00
|
|
|
}
|
2014-09-06 19:13:40 +03:00
|
|
|
TyBareFn(ref barefn) => BareFunction(box barefn.clean(cx)),
|
2017-10-15 13:43:06 -07:00
|
|
|
TyImplTraitExistential(ref exist_ty, ref _lts) => ImplTrait(exist_ty.bounds.clean(cx)),
|
|
|
|
TyImplTraitUniversal(_, ref bounds) => ImplTrait(bounds.clean(cx)),
|
2017-03-28 18:56:29 -07:00
|
|
|
TyInfer | TyErr => Infer,
|
2016-02-28 12:11:13 +01:00
|
|
|
TyTypeof(..) => panic!("Unimplemented type {:?}", self.node),
|
2013-09-24 13:53:09 -07:00
|
|
|
}
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2017-09-14 21:44:23 -04:00
|
|
|
impl<'tcx> Clean<Type> for Ty<'tcx> {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> Type {
|
2014-10-31 10:51:16 +02:00
|
|
|
match self.sty {
|
2016-08-02 15:56:20 +08:00
|
|
|
ty::TyNever => Never,
|
2016-08-23 18:48:10 -04:00
|
|
|
ty::TyBool => Primitive(PrimitiveType::Bool),
|
|
|
|
ty::TyChar => Primitive(PrimitiveType::Char),
|
2016-08-23 19:12:24 -04:00
|
|
|
ty::TyInt(int_ty) => Primitive(int_ty.into()),
|
2016-08-23 19:22:18 -04:00
|
|
|
ty::TyUint(uint_ty) => Primitive(uint_ty.into()),
|
2016-08-23 19:41:14 -04:00
|
|
|
ty::TyFloat(float_ty) => Primitive(float_ty.into()),
|
2016-08-23 18:48:10 -04:00
|
|
|
ty::TyStr => Primitive(PrimitiveType::Str),
|
2017-05-31 14:39:30 +01:00
|
|
|
ty::TySlice(ty) => Slice(box ty.clean(cx)),
|
2017-08-05 16:11:24 +03:00
|
|
|
ty::TyArray(ty, n) => {
|
|
|
|
let n = if let ConstVal::Integral(ConstInt::Usize(n)) = n.val {
|
|
|
|
n.to_string()
|
2017-09-14 09:45:07 +03:00
|
|
|
} else if let ConstVal::Unevaluated(def_id, _) = n.val {
|
|
|
|
if let Some(node_id) = cx.tcx.hir.as_local_node_id(def_id) {
|
|
|
|
print_const_expr(cx, cx.tcx.hir.body_owned_by(node_id))
|
|
|
|
} else {
|
|
|
|
inline::print_inlined_const(cx, def_id)
|
|
|
|
}
|
2017-08-05 16:11:24 +03:00
|
|
|
} else {
|
|
|
|
format!("{:?}", n)
|
|
|
|
};
|
|
|
|
Array(box ty.clean(cx), n)
|
|
|
|
}
|
2015-06-11 16:21:46 -07:00
|
|
|
ty::TyRawPtr(mt) => RawPointer(mt.mutbl.clean(cx), box mt.ty.clean(cx)),
|
|
|
|
ty::TyRef(r, mt) => BorrowedRef {
|
2014-09-06 19:13:40 +03:00
|
|
|
lifetime: r.clean(cx),
|
|
|
|
mutability: mt.mutbl.clean(cx),
|
|
|
|
type_: box mt.ty.clean(cx),
|
2014-05-03 02:08:58 -07:00
|
|
|
},
|
2017-05-13 17:11:52 +03:00
|
|
|
ty::TyFnDef(..) |
|
|
|
|
ty::TyFnPtr(_) => {
|
|
|
|
let ty = cx.tcx.lift(self).unwrap();
|
|
|
|
let sig = ty.fn_sig(cx.tcx);
|
|
|
|
BareFunction(box BareFunctionDecl {
|
|
|
|
unsafety: sig.unsafety(),
|
|
|
|
generics: Generics {
|
|
|
|
lifetimes: Vec::new(),
|
|
|
|
type_params: Vec::new(),
|
|
|
|
where_predicates: Vec::new()
|
|
|
|
},
|
|
|
|
decl: (cx.tcx.hir.local_def_id(ast::CRATE_NODE_ID), sig).clean(cx),
|
|
|
|
abi: sig.abi(),
|
|
|
|
})
|
|
|
|
}
|
2016-09-06 01:26:02 +03:00
|
|
|
ty::TyAdt(def, substs) => {
|
2015-07-20 22:13:36 +03:00
|
|
|
let did = def.did;
|
2016-09-06 01:26:02 +03:00
|
|
|
let kind = match def.adt_kind() {
|
2016-10-01 00:34:00 -04:00
|
|
|
AdtKind::Struct => TypeKind::Struct,
|
|
|
|
AdtKind::Union => TypeKind::Union,
|
|
|
|
AdtKind::Enum => TypeKind::Enum,
|
2014-05-03 02:08:58 -07:00
|
|
|
};
|
2015-12-05 11:58:04 +01:00
|
|
|
inline::record_extern_fqn(cx, did, kind);
|
2017-09-01 09:24:02 -07:00
|
|
|
let path = external_path(cx, &cx.tcx.item_name(did),
|
2016-08-15 01:07:09 +03:00
|
|
|
None, false, vec![], substs);
|
2014-05-03 02:08:58 -07:00
|
|
|
ResolvedPath {
|
2017-08-06 22:54:09 -07:00
|
|
|
path,
|
2014-05-03 02:08:58 -07:00
|
|
|
typarams: None,
|
2017-08-06 22:54:09 -07:00
|
|
|
did,
|
2015-05-25 15:06:38 +02:00
|
|
|
is_generic: false,
|
2014-05-03 02:08:58 -07:00
|
|
|
}
|
|
|
|
}
|
2017-09-03 19:53:58 +01:00
|
|
|
ty::TyForeign(did) => {
|
|
|
|
inline::record_extern_fqn(cx, did, TypeKind::Foreign);
|
|
|
|
let path = external_path(cx, &cx.tcx.item_name(did),
|
|
|
|
None, false, vec![], Substs::empty());
|
|
|
|
ResolvedPath {
|
|
|
|
path: path,
|
|
|
|
typarams: None,
|
|
|
|
did: did,
|
|
|
|
is_generic: false,
|
|
|
|
}
|
|
|
|
}
|
2016-11-16 09:21:49 -07:00
|
|
|
ty::TyDynamic(ref obj, ref reg) => {
|
2016-11-12 15:46:16 -07:00
|
|
|
if let Some(principal) = obj.principal() {
|
|
|
|
let did = principal.def_id();
|
|
|
|
inline::record_extern_fqn(cx, did, TypeKind::Trait);
|
|
|
|
|
|
|
|
let mut typarams = vec![];
|
2016-11-16 09:21:49 -07:00
|
|
|
reg.clean(cx).map(|b| typarams.push(RegionBound(b)));
|
2016-11-13 15:25:54 -07:00
|
|
|
for did in obj.auto_traits() {
|
2016-11-16 09:21:49 -07:00
|
|
|
let empty = cx.tcx.intern_substs(&[]);
|
2017-09-01 09:24:02 -07:00
|
|
|
let path = external_path(cx, &cx.tcx.item_name(did),
|
2016-11-13 15:25:54 -07:00
|
|
|
Some(did), false, vec![], empty);
|
|
|
|
inline::record_extern_fqn(cx, did, TypeKind::Trait);
|
|
|
|
let bound = TraitBound(PolyTrait {
|
|
|
|
trait_: ResolvedPath {
|
2017-08-06 22:54:09 -07:00
|
|
|
path,
|
2016-11-13 15:25:54 -07:00
|
|
|
typarams: None,
|
2017-08-06 22:54:09 -07:00
|
|
|
did,
|
2016-11-13 15:25:54 -07:00
|
|
|
is_generic: false,
|
|
|
|
},
|
|
|
|
lifetimes: vec![]
|
|
|
|
}, hir::TraitBoundModifier::None);
|
|
|
|
typarams.push(bound);
|
2016-11-12 15:46:16 -07:00
|
|
|
}
|
2016-08-04 15:52:57 +03:00
|
|
|
|
2016-11-12 15:46:16 -07:00
|
|
|
let mut bindings = vec![];
|
2016-11-16 09:21:49 -07:00
|
|
|
for ty::Binder(ref pb) in obj.projection_bounds() {
|
2016-11-12 15:46:16 -07:00
|
|
|
bindings.push(TypeBinding {
|
2017-07-11 10:33:09 -04:00
|
|
|
name: cx.tcx.associated_item(pb.item_def_id).name.clean(cx),
|
2016-11-12 15:46:16 -07:00
|
|
|
ty: pb.ty.clean(cx)
|
|
|
|
});
|
|
|
|
}
|
2016-08-04 15:52:57 +03:00
|
|
|
|
2017-09-01 09:24:02 -07:00
|
|
|
let path = external_path(cx, &cx.tcx.item_name(did), Some(did),
|
2016-11-13 19:42:15 -07:00
|
|
|
false, bindings, principal.0.substs);
|
2016-11-12 15:46:16 -07:00
|
|
|
ResolvedPath {
|
2017-08-06 22:54:09 -07:00
|
|
|
path,
|
2016-11-12 15:46:16 -07:00
|
|
|
typarams: Some(typarams),
|
2017-08-06 22:54:09 -07:00
|
|
|
did,
|
2016-11-12 15:46:16 -07:00
|
|
|
is_generic: false,
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
Never
|
2014-12-26 04:36:04 -05:00
|
|
|
}
|
|
|
|
}
|
2017-01-11 15:58:37 +08:00
|
|
|
ty::TyTuple(ref t, _) => Tuple(t.clean(cx)),
|
2014-05-03 02:08:58 -07:00
|
|
|
|
2015-06-11 16:21:46 -07:00
|
|
|
ty::TyProjection(ref data) => data.clean(cx),
|
2014-12-17 14:16:28 -05:00
|
|
|
|
2015-07-28 18:07:20 +02:00
|
|
|
ty::TyParam(ref p) => Generic(p.name.to_string()),
|
2014-05-03 02:08:58 -07:00
|
|
|
|
2016-07-22 18:56:22 +03:00
|
|
|
ty::TyAnon(def_id, substs) => {
|
|
|
|
// Grab the "TraitA + TraitB" from `impl TraitA + TraitB`,
|
|
|
|
// by looking up the projections associated with the def_id.
|
2017-04-24 15:20:46 +03:00
|
|
|
let predicates_of = cx.tcx.predicates_of(def_id);
|
2016-11-20 03:42:54 +02:00
|
|
|
let substs = cx.tcx.lift(&substs).unwrap();
|
2017-04-24 15:20:46 +03:00
|
|
|
let bounds = predicates_of.instantiate(cx.tcx, substs);
|
2016-06-13 20:10:32 +03:00
|
|
|
ImplTrait(bounds.predicates.into_iter().filter_map(|predicate| {
|
2016-07-22 18:56:22 +03:00
|
|
|
predicate.to_opt_poly_trait_ref().clean(cx)
|
|
|
|
}).collect())
|
|
|
|
}
|
|
|
|
|
2016-12-26 14:34:03 +01:00
|
|
|
ty::TyClosure(..) | ty::TyGenerator(..) => Tuple(vec![]), // FIXME(pcwalton)
|
2014-05-28 22:26:56 -07:00
|
|
|
|
2015-06-11 16:21:46 -07:00
|
|
|
ty::TyInfer(..) => panic!("TyInfer"),
|
|
|
|
ty::TyError => panic!("TyError"),
|
2014-05-03 02:08:58 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-31 00:04:06 -07:00
|
|
|
impl Clean<Item> for hir::StructField {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> Item {
|
2013-08-15 16:28:54 -04:00
|
|
|
Item {
|
2016-02-27 11:34:29 +03:00
|
|
|
name: Some(self.name).clean(cx),
|
|
|
|
attrs: self.attrs.clean(cx),
|
2014-09-06 19:13:40 +03:00
|
|
|
source: self.span.clean(cx),
|
2016-03-25 06:08:11 +00:00
|
|
|
visibility: self.vis.clean(cx),
|
2017-01-26 02:41:06 +02:00
|
|
|
stability: get_stability(cx, cx.tcx.hir.local_def_id(self.id)),
|
|
|
|
deprecation: get_deprecation(cx, cx.tcx.hir.local_def_id(self.id)),
|
|
|
|
def_id: cx.tcx.hir.local_def_id(self.id),
|
2016-04-02 08:17:59 +02:00
|
|
|
inner: StructFieldItem(self.ty.clean(cx)),
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-25 01:33:29 +02:00
|
|
|
impl<'tcx> Clean<Item> for ty::FieldDef {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> Item {
|
2014-05-23 00:42:33 -07:00
|
|
|
Item {
|
2016-02-27 11:34:29 +03:00
|
|
|
name: Some(self.name).clean(cx),
|
2016-11-20 03:42:54 +02:00
|
|
|
attrs: cx.tcx.get_attrs(self.did).clean(cx),
|
2016-11-29 08:15:16 +02:00
|
|
|
source: cx.tcx.def_span(self.did).clean(cx),
|
2016-03-25 06:08:11 +00:00
|
|
|
visibility: self.vis.clean(cx),
|
2015-08-02 22:52:50 +03:00
|
|
|
stability: get_stability(cx, self.did),
|
2015-12-12 23:01:27 +03:00
|
|
|
deprecation: get_deprecation(cx, self.did),
|
2015-08-02 22:52:50 +03:00
|
|
|
def_id: self.did,
|
2017-04-24 15:20:46 +03:00
|
|
|
inner: StructFieldItem(cx.tcx.type_of(self.did).clean(cx)),
|
2014-05-23 00:42:33 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-04-11 08:15:14 +00:00
|
|
|
#[derive(Clone, PartialEq, Eq, RustcDecodable, RustcEncodable, Debug)]
|
|
|
|
pub enum Visibility {
|
|
|
|
Public,
|
|
|
|
Inherited,
|
|
|
|
}
|
2013-08-15 16:28:54 -04:00
|
|
|
|
2015-07-31 00:04:06 -07:00
|
|
|
impl Clean<Option<Visibility>> for hir::Visibility {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, _: &DocContext) -> Option<Visibility> {
|
2016-04-11 08:15:14 +00:00
|
|
|
Some(if *self == hir::Visibility::Public { Public } else { Inherited })
|
2016-03-25 06:08:11 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Clean<Option<Visibility>> for ty::Visibility {
|
|
|
|
fn clean(&self, _: &DocContext) -> Option<Visibility> {
|
2016-04-11 08:15:14 +00:00
|
|
|
Some(if *self == ty::Visibility::Public { Public } else { Inherited })
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
2013-08-15 16:28:54 -04:00
|
|
|
pub struct Struct {
|
2014-03-28 10:27:24 -07:00
|
|
|
pub struct_type: doctree::StructType,
|
|
|
|
pub generics: Generics,
|
|
|
|
pub fields: Vec<Item>,
|
|
|
|
pub fields_stripped: bool,
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
|
2016-08-10 21:00:17 +03:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
|
|
|
pub struct Union {
|
|
|
|
pub struct_type: doctree::StructType,
|
|
|
|
pub generics: Generics,
|
|
|
|
pub fields: Vec<Item>,
|
|
|
|
pub fields_stripped: bool,
|
|
|
|
}
|
|
|
|
|
2013-08-15 16:28:54 -04:00
|
|
|
impl Clean<Item> for doctree::Struct {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> Item {
|
2013-08-15 16:28:54 -04:00
|
|
|
Item {
|
2014-09-06 19:13:40 +03:00
|
|
|
name: Some(self.name.clean(cx)),
|
|
|
|
attrs: self.attrs.clean(cx),
|
|
|
|
source: self.whence.clean(cx),
|
2017-01-26 02:41:06 +02:00
|
|
|
def_id: cx.tcx.hir.local_def_id(self.id),
|
2014-09-06 19:13:40 +03:00
|
|
|
visibility: self.vis.clean(cx),
|
|
|
|
stability: self.stab.clean(cx),
|
2015-12-12 23:01:27 +03:00
|
|
|
deprecation: self.depr.clean(cx),
|
2013-08-15 16:28:54 -04:00
|
|
|
inner: StructItem(Struct {
|
|
|
|
struct_type: self.struct_type,
|
2014-09-06 19:13:40 +03:00
|
|
|
generics: self.generics.clean(cx),
|
|
|
|
fields: self.fields.clean(cx),
|
2013-10-13 20:37:43 -07:00
|
|
|
fields_stripped: false,
|
2013-08-15 16:28:54 -04:00
|
|
|
}),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-08-10 21:00:17 +03:00
|
|
|
impl Clean<Item> 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),
|
2017-01-26 02:41:06 +02:00
|
|
|
def_id: cx.tcx.hir.local_def_id(self.id),
|
2016-08-10 21:00:17 +03:00
|
|
|
visibility: self.vis.clean(cx),
|
|
|
|
stability: self.stab.clean(cx),
|
|
|
|
deprecation: self.depr.clean(cx),
|
|
|
|
inner: UnionItem(Union {
|
|
|
|
struct_type: self.struct_type,
|
|
|
|
generics: self.generics.clean(cx),
|
|
|
|
fields: self.fields.clean(cx),
|
|
|
|
fields_stripped: false,
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-03-06 16:35:12 +09:00
|
|
|
/// This is a more limited form of the standard Struct, different in that
|
2013-08-15 16:28:54 -04:00
|
|
|
/// it lacks the things most items have (name, id, parameterization). Found
|
|
|
|
/// only as a variant in an enum.
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
2013-08-15 16:28:54 -04:00
|
|
|
pub struct VariantStruct {
|
2014-03-28 10:27:24 -07:00
|
|
|
pub struct_type: doctree::StructType,
|
|
|
|
pub fields: Vec<Item>,
|
|
|
|
pub fields_stripped: bool,
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
|
2016-03-29 08:50:44 +03:00
|
|
|
impl Clean<VariantStruct> for ::rustc::hir::VariantData {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> VariantStruct {
|
2013-08-15 16:28:54 -04:00
|
|
|
VariantStruct {
|
|
|
|
struct_type: doctree::struct_type_from_def(self),
|
2015-10-25 18:33:51 +03:00
|
|
|
fields: self.fields().iter().map(|x| x.clean(cx)).collect(),
|
2013-10-13 20:37:43 -07:00
|
|
|
fields_stripped: false,
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
2013-08-15 16:28:54 -04:00
|
|
|
pub struct Enum {
|
2014-03-28 10:27:24 -07:00
|
|
|
pub variants: Vec<Item>,
|
|
|
|
pub generics: Generics,
|
|
|
|
pub variants_stripped: bool,
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Clean<Item> for doctree::Enum {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> Item {
|
2013-08-15 16:28:54 -04:00
|
|
|
Item {
|
2014-09-06 19:13:40 +03:00
|
|
|
name: Some(self.name.clean(cx)),
|
|
|
|
attrs: self.attrs.clean(cx),
|
|
|
|
source: self.whence.clean(cx),
|
2017-01-26 02:41:06 +02:00
|
|
|
def_id: cx.tcx.hir.local_def_id(self.id),
|
2014-09-06 19:13:40 +03:00
|
|
|
visibility: self.vis.clean(cx),
|
|
|
|
stability: self.stab.clean(cx),
|
2015-12-12 23:01:27 +03:00
|
|
|
deprecation: self.depr.clean(cx),
|
2013-08-15 16:28:54 -04:00
|
|
|
inner: EnumItem(Enum {
|
2014-09-06 19:13:40 +03:00
|
|
|
variants: self.variants.clean(cx),
|
|
|
|
generics: self.generics.clean(cx),
|
2013-10-13 20:37:43 -07:00
|
|
|
variants_stripped: false,
|
2013-08-15 16:28:54 -04:00
|
|
|
}),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
2013-08-15 16:28:54 -04:00
|
|
|
pub struct Variant {
|
2014-03-28 10:27:24 -07:00
|
|
|
pub kind: VariantKind,
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Clean<Item> for doctree::Variant {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> Item {
|
2013-08-15 16:28:54 -04:00
|
|
|
Item {
|
2014-09-06 19:13:40 +03:00
|
|
|
name: Some(self.name.clean(cx)),
|
|
|
|
attrs: self.attrs.clean(cx),
|
|
|
|
source: self.whence.clean(cx),
|
2015-09-16 20:01:15 +03:00
|
|
|
visibility: None,
|
2014-09-06 19:13:40 +03:00
|
|
|
stability: self.stab.clean(cx),
|
2015-12-12 23:01:27 +03:00
|
|
|
deprecation: self.depr.clean(cx),
|
2017-01-26 02:41:06 +02:00
|
|
|
def_id: cx.tcx.hir.local_def_id(self.def.id()),
|
2013-08-15 16:28:54 -04:00
|
|
|
inner: VariantItem(Variant {
|
2016-10-02 19:59:48 -04:00
|
|
|
kind: self.def.clean(cx),
|
2013-08-15 16:28:54 -04:00
|
|
|
}),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-11-25 01:33:29 +02:00
|
|
|
impl<'tcx> Clean<Item> for ty::VariantDef {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> Item {
|
2016-09-15 00:51:46 +03:00
|
|
|
let kind = match self.ctor_kind {
|
|
|
|
CtorKind::Const => VariantKind::CLike,
|
|
|
|
CtorKind::Fn => {
|
2016-10-02 20:07:18 -04:00
|
|
|
VariantKind::Tuple(
|
2017-04-24 15:20:46 +03:00
|
|
|
self.fields.iter().map(|f| cx.tcx.type_of(f.did).clean(cx)).collect()
|
2015-08-02 22:52:50 +03:00
|
|
|
)
|
2014-05-23 16:14:54 -07:00
|
|
|
}
|
2016-09-15 00:51:46 +03:00
|
|
|
CtorKind::Fictive => {
|
2016-10-02 20:07:18 -04:00
|
|
|
VariantKind::Struct(VariantStruct {
|
2014-05-23 16:14:54 -07:00
|
|
|
struct_type: doctree::Plain,
|
|
|
|
fields_stripped: false,
|
2015-08-02 22:52:50 +03:00
|
|
|
fields: self.fields.iter().map(|field| {
|
2014-05-23 16:14:54 -07:00
|
|
|
Item {
|
2016-11-29 08:15:16 +02:00
|
|
|
source: cx.tcx.def_span(field.did).clean(cx),
|
2015-08-02 22:52:50 +03:00
|
|
|
name: Some(field.name.clean(cx)),
|
2016-11-20 03:42:54 +02:00
|
|
|
attrs: cx.tcx.get_attrs(field.did).clean(cx),
|
2016-03-25 06:08:11 +00:00
|
|
|
visibility: field.vis.clean(cx),
|
2016-03-25 02:18:57 +01:00
|
|
|
def_id: field.did,
|
|
|
|
stability: get_stability(cx, field.did),
|
|
|
|
deprecation: get_deprecation(cx, field.did),
|
2017-04-24 15:20:46 +03:00
|
|
|
inner: StructFieldItem(cx.tcx.type_of(field.did).clean(cx))
|
2014-05-23 16:14:54 -07:00
|
|
|
}
|
|
|
|
}).collect()
|
|
|
|
})
|
|
|
|
}
|
|
|
|
};
|
|
|
|
Item {
|
2014-09-06 19:13:40 +03:00
|
|
|
name: Some(self.name.clean(cx)),
|
2016-11-20 03:42:54 +02:00
|
|
|
attrs: inline::load_attrs(cx, self.did),
|
2016-11-29 08:15:16 +02:00
|
|
|
source: cx.tcx.def_span(self.did).clean(cx),
|
2016-04-11 08:15:14 +00:00
|
|
|
visibility: Some(Inherited),
|
2015-08-02 22:52:50 +03:00
|
|
|
def_id: self.did,
|
2014-05-23 16:14:54 -07:00
|
|
|
inner: VariantItem(Variant { kind: kind }),
|
2015-08-02 22:52:50 +03:00
|
|
|
stability: get_stability(cx, self.did),
|
2015-12-12 23:01:27 +03:00
|
|
|
deprecation: get_deprecation(cx, self.did),
|
2014-05-23 16:14:54 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
2013-08-15 16:28:54 -04:00
|
|
|
pub enum VariantKind {
|
2016-10-02 20:07:18 -04:00
|
|
|
CLike,
|
|
|
|
Tuple(Vec<Type>),
|
|
|
|
Struct(VariantStruct),
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
|
2016-10-02 19:59:48 -04:00
|
|
|
impl Clean<VariantKind> for hir::VariantData {
|
|
|
|
fn clean(&self, cx: &DocContext) -> VariantKind {
|
|
|
|
if self.is_struct() {
|
2016-10-02 20:07:18 -04:00
|
|
|
VariantKind::Struct(self.clean(cx))
|
2016-10-02 19:59:48 -04:00
|
|
|
} else if self.is_unit() {
|
2016-10-02 20:07:18 -04:00
|
|
|
VariantKind::CLike
|
2016-10-01 15:09:27 -04:00
|
|
|
} else {
|
2016-10-02 20:07:18 -04:00
|
|
|
VariantKind::Tuple(self.fields().iter().map(|x| x.ty.clean(cx)).collect())
|
2016-10-01 15:09:27 -04:00
|
|
|
}
|
2015-10-02 00:03:22 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
2013-09-27 15:12:23 -07:00
|
|
|
pub struct Span {
|
2014-05-22 16:57:53 -07:00
|
|
|
pub filename: String,
|
2015-03-25 17:06:52 -07:00
|
|
|
pub loline: usize,
|
|
|
|
pub locol: usize,
|
|
|
|
pub hiline: usize,
|
|
|
|
pub hicol: usize,
|
2013-09-27 15:12:23 -07:00
|
|
|
}
|
|
|
|
|
2014-05-23 00:42:33 -07:00
|
|
|
impl Span {
|
|
|
|
fn empty() -> Span {
|
|
|
|
Span {
|
2014-05-25 03:17:19 -07:00
|
|
|
filename: "".to_string(),
|
2014-05-23 00:42:33 -07:00
|
|
|
loline: 0, locol: 0,
|
|
|
|
hiline: 0, hicol: 0,
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-21 18:08:13 -04:00
|
|
|
impl Clean<Span> for syntax_pos::Span {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> Span {
|
2015-07-06 14:13:19 +12:00
|
|
|
if *self == DUMMY_SP {
|
|
|
|
return Span::empty();
|
|
|
|
}
|
|
|
|
|
2014-09-06 19:13:40 +03:00
|
|
|
let cm = cx.sess().codemap();
|
2013-09-27 15:12:23 -07:00
|
|
|
let filename = cm.span_to_filename(*self);
|
2017-07-31 23:04:34 +03:00
|
|
|
let lo = cm.lookup_char_pos(self.lo());
|
|
|
|
let hi = cm.lookup_char_pos(self.hi());
|
2013-09-27 15:12:23 -07:00
|
|
|
Span {
|
2014-05-25 03:17:19 -07:00
|
|
|
filename: filename.to_string(),
|
2013-09-27 15:12:23 -07:00
|
|
|
loline: lo.line,
|
2015-01-17 23:49:08 +00:00
|
|
|
locol: lo.col.to_usize(),
|
2013-09-27 15:12:23 -07:00
|
|
|
hiline: hi.line,
|
2015-01-17 23:49:08 +00:00
|
|
|
hicol: hi.col.to_usize(),
|
2013-09-27 15:12:23 -07:00
|
|
|
}
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
|
2013-08-15 16:28:54 -04:00
|
|
|
pub struct Path {
|
2014-03-28 10:27:24 -07:00
|
|
|
pub global: bool,
|
2016-11-25 13:21:19 +02:00
|
|
|
pub def: Def,
|
2014-03-28 10:27:24 -07:00
|
|
|
pub segments: Vec<PathSegment>,
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
|
2015-04-07 00:16:35 -07:00
|
|
|
impl Path {
|
|
|
|
pub fn singleton(name: String) -> Path {
|
|
|
|
Path {
|
|
|
|
global: false,
|
2016-11-25 13:21:19 +02:00
|
|
|
def: Def::Err,
|
2015-04-07 00:16:35 -07:00
|
|
|
segments: vec![PathSegment {
|
2017-08-06 22:54:09 -07:00
|
|
|
name,
|
2015-04-07 00:16:35 -07:00
|
|
|
params: PathParameters::AngleBracketed {
|
|
|
|
lifetimes: Vec::new(),
|
|
|
|
types: Vec::new(),
|
|
|
|
bindings: Vec::new()
|
|
|
|
}
|
|
|
|
}]
|
|
|
|
}
|
|
|
|
}
|
2016-03-29 01:11:08 +09:00
|
|
|
|
2016-12-21 21:27:31 -08:00
|
|
|
pub fn last_name(&self) -> &str {
|
2016-12-21 23:13:11 -08:00
|
|
|
self.segments.last().unwrap().name.as_str()
|
2016-03-29 01:11:08 +09:00
|
|
|
}
|
2015-04-07 00:16:35 -07:00
|
|
|
}
|
|
|
|
|
2015-07-31 00:04:06 -07:00
|
|
|
impl Clean<Path> for hir::Path {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> Path {
|
2013-08-15 16:28:54 -04:00
|
|
|
Path {
|
2016-12-05 03:51:11 +00:00
|
|
|
global: self.is_global(),
|
2016-11-25 13:21:19 +02:00
|
|
|
def: self.def,
|
2016-12-05 03:51:11 +00:00
|
|
|
segments: if self.is_global() { &self.segments[1..] } else { &self.segments }.clean(cx),
|
2013-09-12 15:11:06 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
|
2014-12-16 12:40:43 -08:00
|
|
|
pub enum PathParameters {
|
|
|
|
AngleBracketed {
|
|
|
|
lifetimes: Vec<Lifetime>,
|
|
|
|
types: Vec<Type>,
|
2017-03-16 22:59:55 +01:00
|
|
|
bindings: Vec<TypeBinding>,
|
2014-12-16 12:40:43 -08:00
|
|
|
},
|
|
|
|
Parenthesized {
|
|
|
|
inputs: Vec<Type>,
|
2017-03-16 22:59:55 +01:00
|
|
|
output: Option<Type>,
|
2014-12-16 12:40:43 -08:00
|
|
|
}
|
2013-09-12 15:11:06 -04:00
|
|
|
}
|
|
|
|
|
2015-07-31 00:04:06 -07:00
|
|
|
impl Clean<PathParameters> for hir::PathParameters {
|
2014-12-16 12:40:43 -08:00
|
|
|
fn clean(&self, cx: &DocContext) -> PathParameters {
|
2017-07-29 01:13:40 +03:00
|
|
|
if self.parenthesized {
|
|
|
|
let output = self.bindings[0].ty.clean(cx);
|
|
|
|
PathParameters::Parenthesized {
|
|
|
|
inputs: self.inputs().clean(cx),
|
|
|
|
output: if output != Type::Tuple(Vec::new()) { Some(output) } else { None }
|
2014-11-03 21:52:52 -05:00
|
|
|
}
|
2017-07-29 01:13:40 +03:00
|
|
|
} else {
|
|
|
|
PathParameters::AngleBracketed {
|
|
|
|
lifetimes: if self.lifetimes.iter().all(|lt| lt.is_elided()) {
|
|
|
|
vec![]
|
|
|
|
} else {
|
|
|
|
self.lifetimes.clean(cx)
|
|
|
|
},
|
|
|
|
types: self.types.clean(cx),
|
|
|
|
bindings: self.bindings.clean(cx),
|
2014-11-03 21:52:52 -05:00
|
|
|
}
|
2014-12-16 12:40:43 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-11-03 21:52:52 -05:00
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
|
2014-12-16 12:40:43 -08:00
|
|
|
pub struct PathSegment {
|
|
|
|
pub name: String,
|
2017-04-12 18:14:54 +02:00
|
|
|
pub params: PathParameters,
|
2014-12-16 12:40:43 -08:00
|
|
|
}
|
|
|
|
|
2015-07-31 00:04:06 -07:00
|
|
|
impl Clean<PathSegment> for hir::PathSegment {
|
2014-12-16 12:40:43 -08:00
|
|
|
fn clean(&self, cx: &DocContext) -> PathSegment {
|
2013-09-12 15:11:06 -04:00
|
|
|
PathSegment {
|
2016-03-06 15:54:44 +03:00
|
|
|
name: self.name.clean(cx),
|
2017-09-21 23:24:26 +03:00
|
|
|
params: self.with_parameters(|parameters| parameters.clean(cx))
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-10-27 05:17:42 +03:00
|
|
|
fn qpath_to_string(p: &hir::QPath) -> String {
|
2016-12-05 03:51:11 +00:00
|
|
|
let segments = match *p {
|
|
|
|
hir::QPath::Resolved(_, ref path) => &path.segments,
|
|
|
|
hir::QPath::TypeRelative(_, ref segment) => return segment.name.to_string(),
|
2016-10-27 05:17:42 +03:00
|
|
|
};
|
|
|
|
|
2014-05-22 16:57:53 -07:00
|
|
|
let mut s = String::new();
|
2016-12-05 03:51:11 +00:00
|
|
|
for (i, seg) in segments.iter().enumerate() {
|
|
|
|
if i > 0 {
|
2013-08-15 16:28:54 -04:00
|
|
|
s.push_str("::");
|
|
|
|
}
|
2016-12-05 03:51:11 +00:00
|
|
|
if seg.name != keywords::CrateRoot.name() {
|
|
|
|
s.push_str(&*seg.name.as_str());
|
|
|
|
}
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
2014-05-12 13:44:59 -07:00
|
|
|
s
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
|
2014-05-24 11:56:38 -07:00
|
|
|
impl Clean<String> for ast::Name {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, _: &DocContext) -> String {
|
2015-07-28 18:07:20 +02:00
|
|
|
self.to_string()
|
2014-05-23 00:42:33 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
2013-08-15 16:28:54 -04:00
|
|
|
pub struct Typedef {
|
2014-03-28 10:27:24 -07:00
|
|
|
pub type_: Type,
|
|
|
|
pub generics: Generics,
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Clean<Item> for doctree::Typedef {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> Item {
|
2013-08-15 16:28:54 -04:00
|
|
|
Item {
|
2014-09-06 19:13:40 +03:00
|
|
|
name: Some(self.name.clean(cx)),
|
|
|
|
attrs: self.attrs.clean(cx),
|
|
|
|
source: self.whence.clean(cx),
|
2017-01-26 02:41:06 +02:00
|
|
|
def_id: cx.tcx.hir.local_def_id(self.id.clone()),
|
2014-09-06 19:13:40 +03:00
|
|
|
visibility: self.vis.clean(cx),
|
|
|
|
stability: self.stab.clean(cx),
|
2015-12-12 23:01:27 +03:00
|
|
|
deprecation: self.depr.clean(cx),
|
2013-08-15 16:28:54 -04:00
|
|
|
inner: TypedefItem(Typedef {
|
2014-09-06 19:13:40 +03:00
|
|
|
type_: self.ty.clean(cx),
|
|
|
|
generics: self.gen.clean(cx),
|
2015-05-21 14:17:37 +02:00
|
|
|
}, false),
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Debug)]
|
2013-08-15 16:28:54 -04:00
|
|
|
pub struct BareFunctionDecl {
|
2015-07-31 00:04:06 -07:00
|
|
|
pub unsafety: hir::Unsafety,
|
2014-03-28 10:27:24 -07:00
|
|
|
pub generics: Generics,
|
|
|
|
pub decl: FnDecl,
|
2016-04-22 11:48:46 +01:00
|
|
|
pub abi: Abi,
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
|
2015-07-31 00:04:06 -07:00
|
|
|
impl Clean<BareFunctionDecl> for hir::BareFnTy {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> BareFunctionDecl {
|
2013-08-15 16:28:54 -04:00
|
|
|
BareFunctionDecl {
|
2014-12-09 10:36:46 -05:00
|
|
|
unsafety: self.unsafety,
|
2013-08-15 16:28:54 -04:00
|
|
|
generics: Generics {
|
2014-09-06 19:13:40 +03:00
|
|
|
lifetimes: self.lifetimes.clean(cx),
|
2014-03-05 15:28:08 -08:00
|
|
|
type_params: Vec::new(),
|
2014-09-25 02:01:42 -07:00
|
|
|
where_predicates: Vec::new()
|
2013-08-15 16:28:54 -04:00
|
|
|
},
|
2017-09-27 00:43:37 +02:00
|
|
|
decl: (&*self.decl, &self.arg_names[..]).clean(cx),
|
2016-04-22 11:48:46 +01:00
|
|
|
abi: self.abi,
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
2013-08-15 16:28:54 -04:00
|
|
|
pub struct Static {
|
2014-03-28 10:27:24 -07:00
|
|
|
pub type_: Type,
|
|
|
|
pub mutability: Mutability,
|
2013-08-15 16:28:54 -04:00
|
|
|
/// It's useful to have the value of a static documented, but I have no
|
|
|
|
/// desire to represent expressions (that'd basically be all of the AST,
|
|
|
|
/// which is huge!). So, have a string.
|
2014-05-22 16:57:53 -07:00
|
|
|
pub expr: String,
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Clean<Item> for doctree::Static {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> Item {
|
2014-12-20 00:09:35 -08:00
|
|
|
debug!("cleaning static {}: {:?}", self.name.clean(cx), self);
|
2013-08-15 16:28:54 -04:00
|
|
|
Item {
|
2014-09-06 19:13:40 +03:00
|
|
|
name: Some(self.name.clean(cx)),
|
|
|
|
attrs: self.attrs.clean(cx),
|
|
|
|
source: self.whence.clean(cx),
|
2017-01-26 02:41:06 +02:00
|
|
|
def_id: cx.tcx.hir.local_def_id(self.id),
|
2014-09-06 19:13:40 +03:00
|
|
|
visibility: self.vis.clean(cx),
|
|
|
|
stability: self.stab.clean(cx),
|
2015-12-12 23:01:27 +03:00
|
|
|
deprecation: self.depr.clean(cx),
|
2013-08-15 16:28:54 -04:00
|
|
|
inner: StaticItem(Static {
|
2014-09-06 19:13:40 +03:00
|
|
|
type_: self.type_.clean(cx),
|
|
|
|
mutability: self.mutability.clean(cx),
|
2016-12-21 12:32:59 +02:00
|
|
|
expr: print_const_expr(cx, self.expr),
|
2013-08-15 16:28:54 -04:00
|
|
|
}),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
2014-10-06 17:41:15 -07:00
|
|
|
pub struct Constant {
|
|
|
|
pub type_: Type,
|
|
|
|
pub expr: String,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Clean<Item> 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),
|
2017-01-26 02:41:06 +02:00
|
|
|
def_id: cx.tcx.hir.local_def_id(self.id),
|
2014-10-06 17:41:15 -07:00
|
|
|
visibility: self.vis.clean(cx),
|
|
|
|
stability: self.stab.clean(cx),
|
2015-12-12 23:01:27 +03:00
|
|
|
deprecation: self.depr.clean(cx),
|
2014-10-06 17:41:15 -07:00
|
|
|
inner: ConstantItem(Constant {
|
|
|
|
type_: self.type_.clean(cx),
|
2016-12-21 12:32:59 +02:00
|
|
|
expr: print_const_expr(cx, self.expr),
|
2014-10-06 17:41:15 -07:00
|
|
|
}),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Debug, Clone, RustcEncodable, RustcDecodable, PartialEq, Copy)]
|
2013-08-15 16:28:54 -04:00
|
|
|
pub enum Mutability {
|
|
|
|
Mutable,
|
|
|
|
Immutable,
|
|
|
|
}
|
|
|
|
|
2015-07-31 00:04:06 -07:00
|
|
|
impl Clean<Mutability> for hir::Mutability {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, _: &DocContext) -> Mutability {
|
2013-08-15 16:28:54 -04:00
|
|
|
match self {
|
2015-07-31 00:04:06 -07:00
|
|
|
&hir::MutMutable => Mutable,
|
|
|
|
&hir::MutImmutable => Immutable,
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, PartialEq, Copy, Debug)]
|
2015-01-21 04:35:57 +00:00
|
|
|
pub enum ImplPolarity {
|
|
|
|
Positive,
|
|
|
|
Negative,
|
|
|
|
}
|
|
|
|
|
2015-07-31 00:04:06 -07:00
|
|
|
impl Clean<ImplPolarity> for hir::ImplPolarity {
|
2015-01-21 04:35:57 +00:00
|
|
|
fn clean(&self, _: &DocContext) -> ImplPolarity {
|
|
|
|
match self {
|
2015-07-31 00:04:06 -07:00
|
|
|
&hir::ImplPolarity::Positive => ImplPolarity::Positive,
|
|
|
|
&hir::ImplPolarity::Negative => ImplPolarity::Negative,
|
2015-01-21 04:35:57 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
2013-08-15 16:28:54 -04:00
|
|
|
pub struct Impl {
|
2015-07-31 00:04:06 -07:00
|
|
|
pub unsafety: hir::Unsafety,
|
2014-03-28 10:27:24 -07:00
|
|
|
pub generics: Generics,
|
2016-11-08 14:02:55 +11:00
|
|
|
pub provided_trait_methods: FxHashSet<String>,
|
2014-03-28 10:27:24 -07:00
|
|
|
pub trait_: Option<Type>,
|
|
|
|
pub for_: Type,
|
2014-08-04 13:56:56 -07:00
|
|
|
pub items: Vec<Item>,
|
2015-01-21 04:35:57 +00:00
|
|
|
pub polarity: Option<ImplPolarity>,
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
|
2015-04-13 16:23:32 -07:00
|
|
|
impl Clean<Vec<Item>> for doctree::Impl {
|
|
|
|
fn clean(&self, cx: &DocContext) -> Vec<Item> {
|
|
|
|
let mut ret = Vec::new();
|
|
|
|
let trait_ = self.trait_.clean(cx);
|
|
|
|
let items = self.items.clean(cx);
|
|
|
|
|
|
|
|
// 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.
|
2017-08-31 09:19:33 -07:00
|
|
|
if trait_.def_id() == cx.tcx.lang_items().deref_trait() {
|
2016-03-24 06:10:52 +01:00
|
|
|
build_deref_target_impls(cx, &items, &mut ret);
|
2015-04-13 16:23:32 -07:00
|
|
|
}
|
|
|
|
|
2016-11-20 03:42:54 +02:00
|
|
|
let provided = trait_.def_id().map(|did| {
|
|
|
|
cx.tcx.provided_trait_methods(did)
|
|
|
|
.into_iter()
|
|
|
|
.map(|meth| meth.name.to_string())
|
|
|
|
.collect()
|
2016-11-08 14:02:55 +11:00
|
|
|
}).unwrap_or(FxHashSet());
|
2016-03-24 06:10:52 +01:00
|
|
|
|
2015-04-13 16:23:32 -07:00
|
|
|
ret.push(Item {
|
2013-08-15 16:28:54 -04:00
|
|
|
name: None,
|
2014-09-06 19:13:40 +03:00
|
|
|
attrs: self.attrs.clean(cx),
|
|
|
|
source: self.whence.clean(cx),
|
2017-01-26 02:41:06 +02:00
|
|
|
def_id: cx.tcx.hir.local_def_id(self.id),
|
2014-09-06 19:13:40 +03:00
|
|
|
visibility: self.vis.clean(cx),
|
|
|
|
stability: self.stab.clean(cx),
|
2015-12-12 23:01:27 +03:00
|
|
|
deprecation: self.depr.clean(cx),
|
2013-08-15 16:28:54 -04:00
|
|
|
inner: ImplItem(Impl {
|
2015-03-12 19:15:52 -07:00
|
|
|
unsafety: self.unsafety,
|
2014-09-06 19:13:40 +03:00
|
|
|
generics: self.generics.clean(cx),
|
2016-03-24 06:10:52 +01:00
|
|
|
provided_trait_methods: provided,
|
2017-08-06 22:54:09 -07:00
|
|
|
trait_,
|
2014-09-06 19:13:40 +03:00
|
|
|
for_: self.for_.clean(cx),
|
2017-08-06 22:54:09 -07:00
|
|
|
items,
|
2015-01-21 04:35:57 +00:00
|
|
|
polarity: Some(self.polarity.clean(cx)),
|
2013-08-15 16:28:54 -04:00
|
|
|
}),
|
2015-04-13 16:23:32 -07:00
|
|
|
});
|
2016-02-28 12:11:13 +01:00
|
|
|
ret
|
2015-04-13 16:23:32 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
fn build_deref_target_impls(cx: &DocContext,
|
|
|
|
items: &[Item],
|
|
|
|
ret: &mut Vec<Item>) {
|
2016-08-26 01:32:46 +03:00
|
|
|
use self::PrimitiveType::*;
|
2016-11-20 03:42:54 +02:00
|
|
|
let tcx = cx.tcx;
|
2015-04-13 16:23:32 -07:00
|
|
|
|
|
|
|
for item in items {
|
|
|
|
let target = match item.inner {
|
2015-05-21 14:17:37 +02:00
|
|
|
TypedefItem(ref t, true) => &t.type_,
|
2015-04-13 16:23:32 -07:00
|
|
|
_ => continue,
|
|
|
|
};
|
|
|
|
let primitive = match *target {
|
2015-08-16 06:32:28 -04:00
|
|
|
ResolvedPath { did, .. } if did.is_local() => continue,
|
2015-04-13 16:23:32 -07:00
|
|
|
ResolvedPath { did, .. } => {
|
2016-11-20 03:42:54 +02:00
|
|
|
ret.extend(inline::build_impls(cx, did));
|
2015-04-13 16:23:32 -07:00
|
|
|
continue
|
|
|
|
}
|
|
|
|
_ => match target.primitive_type() {
|
|
|
|
Some(prim) => prim,
|
|
|
|
None => continue,
|
|
|
|
}
|
|
|
|
};
|
|
|
|
let did = match primitive {
|
2017-08-31 09:19:33 -07:00
|
|
|
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(),
|
2016-08-23 03:56:52 +03:00
|
|
|
Bool => None,
|
2017-08-31 09:19:33 -07:00
|
|
|
Str => tcx.lang_items().str_impl(),
|
|
|
|
Slice => tcx.lang_items().slice_impl(),
|
|
|
|
Array => tcx.lang_items().slice_impl(),
|
2016-08-23 03:56:52 +03:00
|
|
|
Tuple => None,
|
2017-10-17 23:03:50 -07:00
|
|
|
Unit => None,
|
2017-08-31 09:19:33 -07:00
|
|
|
RawPointer => tcx.lang_items().const_ptr_impl(),
|
2017-07-30 14:59:08 -05:00
|
|
|
Reference => None,
|
2017-07-28 12:55:30 -05:00
|
|
|
Fn => None,
|
2015-04-13 16:23:32 -07:00
|
|
|
};
|
|
|
|
if let Some(did) = did {
|
2015-08-16 06:32:28 -04:00
|
|
|
if !did.is_local() {
|
2016-11-20 03:42:54 +02:00
|
|
|
inline::build_impl(cx, did, ret);
|
2015-04-13 16:23:32 -07:00
|
|
|
}
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-12 19:15:52 -07:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
2017-10-09 13:59:20 -03:00
|
|
|
pub struct AutoImpl {
|
2015-07-31 00:04:06 -07:00
|
|
|
pub unsafety: hir::Unsafety,
|
2015-03-12 19:15:52 -07:00
|
|
|
pub trait_: Type,
|
|
|
|
}
|
|
|
|
|
2017-10-09 13:59:20 -03:00
|
|
|
impl Clean<Item> for doctree::AutoImpl {
|
2015-03-12 19:15:52 -07:00
|
|
|
fn clean(&self, cx: &DocContext) -> Item {
|
|
|
|
Item {
|
|
|
|
name: None,
|
|
|
|
attrs: self.attrs.clean(cx),
|
|
|
|
source: self.whence.clean(cx),
|
2017-01-26 02:41:06 +02:00
|
|
|
def_id: cx.tcx.hir.local_def_id(self.id),
|
2016-04-11 08:15:14 +00:00
|
|
|
visibility: Some(Public),
|
2015-03-12 19:15:52 -07:00
|
|
|
stability: None,
|
2015-12-12 23:01:27 +03:00
|
|
|
deprecation: None,
|
2017-10-09 13:59:20 -03:00
|
|
|
inner: AutoImplItem(AutoImpl {
|
2015-03-12 19:15:52 -07:00
|
|
|
unsafety: self.unsafety,
|
|
|
|
trait_: self.trait_.clean(cx),
|
|
|
|
}),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2014-12-26 10:55:16 +02:00
|
|
|
impl Clean<Item> for doctree::ExternCrate {
|
|
|
|
fn clean(&self, cx: &DocContext) -> Item {
|
|
|
|
Item {
|
|
|
|
name: None,
|
|
|
|
attrs: self.attrs.clean(cx),
|
|
|
|
source: self.whence.clean(cx),
|
2016-04-25 08:24:50 +02:00
|
|
|
def_id: DefId { krate: self.cnum, index: CRATE_DEF_INDEX },
|
2014-12-26 10:55:16 +02:00
|
|
|
visibility: self.vis.clean(cx),
|
|
|
|
stability: None,
|
2015-12-12 23:01:27 +03:00
|
|
|
deprecation: None,
|
2014-12-26 10:55:16 +02:00
|
|
|
inner: ExternCrateItem(self.name.clean(cx), self.path.clone())
|
|
|
|
}
|
|
|
|
}
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
|
2014-12-26 10:55:16 +02:00
|
|
|
impl Clean<Vec<Item>> for doctree::Import {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> Vec<Item> {
|
2014-07-02 21:27:07 -04:00
|
|
|
// We consider inlining the documentation of `pub use` statements, but we
|
2014-05-24 11:56:38 -07:00
|
|
|
// forcefully don't inline if this is not public or if the
|
|
|
|
// #[doc(no_inline)] attribute is present.
|
2016-06-07 01:20:12 +01:00
|
|
|
// Don't inline doc(hidden) imports so they can be stripped at a later stage.
|
2015-07-31 00:04:06 -07:00
|
|
|
let denied = self.vis != hir::Public || self.attrs.iter().any(|a| {
|
2017-03-03 09:23:59 +00:00
|
|
|
a.name().unwrap() == "doc" && match a.meta_item_list() {
|
|
|
|
Some(l) => attr::list_contains_name(&l, "no_inline") ||
|
|
|
|
attr::list_contains_name(&l, "hidden"),
|
2014-05-22 22:00:18 -07:00
|
|
|
None => false,
|
|
|
|
}
|
|
|
|
});
|
2016-11-24 06:11:31 +02:00
|
|
|
let path = self.path.clean(cx);
|
|
|
|
let inner = if self.glob {
|
2016-11-25 13:21:19 +02:00
|
|
|
Import::Glob(resolve_use_source(cx, path))
|
2016-11-24 06:11:31 +02:00
|
|
|
} else {
|
|
|
|
let name = self.name;
|
|
|
|
if !denied {
|
2017-05-22 02:05:16 +01:00
|
|
|
if let Some(items) = inline::try_inline(cx, path.def, name) {
|
2016-11-24 06:11:31 +02:00
|
|
|
return items;
|
2014-12-26 10:55:16 +02:00
|
|
|
}
|
2014-02-28 17:46:09 -08:00
|
|
|
}
|
2016-11-25 13:21:19 +02:00
|
|
|
Import::Simple(name.clean(cx), resolve_use_source(cx, path))
|
2014-12-26 10:55:16 +02:00
|
|
|
};
|
2016-11-24 06:11:31 +02:00
|
|
|
vec![Item {
|
2014-12-26 10:55:16 +02:00
|
|
|
name: None,
|
|
|
|
attrs: self.attrs.clean(cx),
|
|
|
|
source: self.whence.clean(cx),
|
2017-01-26 02:41:06 +02:00
|
|
|
def_id: cx.tcx.hir.local_def_id(ast::CRATE_NODE_ID),
|
2014-12-26 10:55:16 +02:00
|
|
|
visibility: self.vis.clean(cx),
|
|
|
|
stability: None,
|
2015-12-12 23:01:27 +03:00
|
|
|
deprecation: None,
|
2014-12-26 10:55:16 +02:00
|
|
|
inner: ImportItem(inner)
|
2016-11-24 06:11:31 +02:00
|
|
|
}]
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
2014-12-26 10:55:16 +02:00
|
|
|
pub enum Import {
|
2014-11-22 19:07:54 +13:00
|
|
|
// use source as str;
|
2016-10-01 17:35:53 -04:00
|
|
|
Simple(String, ImportSource),
|
2013-09-24 13:56:52 -07:00
|
|
|
// use source::*;
|
2016-11-24 06:11:31 +02:00
|
|
|
Glob(ImportSource)
|
2013-09-24 13:56:52 -07:00
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
2013-09-24 13:56:52 -07:00
|
|
|
pub struct ImportSource {
|
2014-03-28 10:27:24 -07:00
|
|
|
pub path: Path,
|
2015-08-16 06:32:28 -04:00
|
|
|
pub did: Option<DefId>,
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
|
2015-07-31 00:04:06 -07:00
|
|
|
impl Clean<Vec<Item>> for hir::ForeignMod {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> Vec<Item> {
|
2015-04-07 14:22:55 -07:00
|
|
|
let mut items = self.items.clean(cx);
|
|
|
|
for item in &mut items {
|
2016-02-28 12:11:13 +01:00
|
|
|
if let ForeignFunctionItem(ref mut f) = item.inner {
|
|
|
|
f.abi = self.abi;
|
2015-04-07 14:22:55 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
items
|
2013-09-26 11:57:25 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-31 00:04:06 -07:00
|
|
|
impl Clean<Item> for hir::ForeignItem {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> Item {
|
2013-09-26 11:57:25 -07:00
|
|
|
let inner = match self.node {
|
2016-12-20 22:46:11 +02:00
|
|
|
hir::ForeignItemFn(ref decl, ref names, ref generics) => {
|
2013-09-26 11:57:25 -07:00
|
|
|
ForeignFunctionItem(Function {
|
2016-12-20 22:46:11 +02:00
|
|
|
decl: (&**decl, &names[..]).clean(cx),
|
2014-09-06 19:13:40 +03:00
|
|
|
generics: generics.clean(cx),
|
2015-07-31 00:04:06 -07:00
|
|
|
unsafety: hir::Unsafety::Unsafe,
|
2016-02-05 13:13:36 +01:00
|
|
|
abi: Abi::Rust,
|
2015-07-31 00:04:06 -07:00
|
|
|
constness: hir::Constness::NotConst,
|
2013-09-26 11:57:25 -07:00
|
|
|
})
|
|
|
|
}
|
2015-07-31 00:04:06 -07:00
|
|
|
hir::ForeignItemStatic(ref ty, mutbl) => {
|
2013-09-26 11:57:25 -07:00
|
|
|
ForeignStaticItem(Static {
|
2014-09-06 19:13:40 +03:00
|
|
|
type_: ty.clean(cx),
|
2013-09-26 11:57:25 -07:00
|
|
|
mutability: if mutbl {Mutable} else {Immutable},
|
2014-05-25 03:17:19 -07:00
|
|
|
expr: "".to_string(),
|
2013-09-26 11:57:25 -07:00
|
|
|
})
|
|
|
|
}
|
2017-09-03 19:53:58 +01:00
|
|
|
hir::ForeignItemType => {
|
|
|
|
ForeignTypeItem
|
|
|
|
}
|
2013-09-26 11:57:25 -07:00
|
|
|
};
|
|
|
|
Item {
|
2015-09-20 04:50:30 +03:00
|
|
|
name: Some(self.name.clean(cx)),
|
2014-09-06 19:13:40 +03:00
|
|
|
attrs: self.attrs.clean(cx),
|
|
|
|
source: self.span.clean(cx),
|
2017-01-26 02:41:06 +02:00
|
|
|
def_id: cx.tcx.hir.local_def_id(self.id),
|
2014-09-06 19:13:40 +03:00
|
|
|
visibility: self.vis.clean(cx),
|
2017-01-26 02:41:06 +02:00
|
|
|
stability: get_stability(cx, cx.tcx.hir.local_def_id(self.id)),
|
|
|
|
deprecation: get_deprecation(cx, cx.tcx.hir.local_def_id(self.id)),
|
2017-08-06 22:54:09 -07:00
|
|
|
inner,
|
2013-09-26 11:57:25 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2013-08-15 16:28:54 -04:00
|
|
|
// Utilities
|
|
|
|
|
|
|
|
trait ToSource {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn to_src(&self, cx: &DocContext) -> String;
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
|
2016-06-21 18:08:13 -04:00
|
|
|
impl ToSource for syntax_pos::Span {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn to_src(&self, cx: &DocContext) -> String {
|
2014-12-20 00:09:35 -08:00
|
|
|
debug!("converting span {:?} to snippet", self.clean(cx));
|
2014-09-06 19:13:40 +03:00
|
|
|
let sn = match cx.sess().codemap().span_to_snippet(*self) {
|
2015-02-05 16:02:22 +01:00
|
|
|
Ok(x) => x.to_string(),
|
|
|
|
Err(_) => "".to_string()
|
2013-08-15 16:28:54 -04:00
|
|
|
};
|
2013-10-21 13:08:31 -07:00
|
|
|
debug!("got snippet {}", sn);
|
2013-08-15 16:28:54 -04:00
|
|
|
sn
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-07-31 00:04:06 -07:00
|
|
|
fn name_from_pat(p: &hir::Pat) -> String {
|
2016-03-29 08:50:44 +03:00
|
|
|
use rustc::hir::*;
|
2014-12-20 00:09:35 -08:00
|
|
|
debug!("Trying to get a name from pattern: {:?}", p);
|
2013-12-29 00:13:29 -05:00
|
|
|
|
2013-08-15 16:28:54 -04:00
|
|
|
match p.node {
|
2016-02-14 15:25:12 +03:00
|
|
|
PatKind::Wild => "_".to_string(),
|
2016-11-25 13:21:19 +02:00
|
|
|
PatKind::Binding(_, _, ref p, _) => p.node.to_string(),
|
2016-10-27 05:17:42 +03:00
|
|
|
PatKind::TupleStruct(ref p, ..) | PatKind::Path(ref p) => qpath_to_string(p),
|
2016-02-14 15:25:12 +03:00
|
|
|
PatKind::Struct(ref name, ref fields, etc) => {
|
2016-10-27 05:17:42 +03:00
|
|
|
format!("{} {{ {}{} }}", qpath_to_string(name),
|
2014-10-06 13:36:53 +13:00
|
|
|
fields.iter().map(|&Spanned { node: ref fp, .. }|
|
2015-09-20 16:47:24 +03:00
|
|
|
format!("{}: {}", fp.name, name_from_pat(&*fp.pat)))
|
2015-07-10 08:19:21 -04:00
|
|
|
.collect::<Vec<String>>().join(", "),
|
2014-07-11 11:59:18 -07:00
|
|
|
if etc { ", ..." } else { "" }
|
|
|
|
)
|
2016-10-27 05:17:42 +03:00
|
|
|
}
|
2016-03-06 15:54:44 +03:00
|
|
|
PatKind::Tuple(ref elts, _) => format!("({})", elts.iter().map(|p| name_from_pat(&**p))
|
2015-07-10 08:19:21 -04:00
|
|
|
.collect::<Vec<String>>().join(", ")),
|
2016-02-14 15:25:12 +03:00
|
|
|
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, \
|
2013-12-29 00:13:29 -05:00
|
|
|
which is silly in function arguments");
|
2014-05-25 03:17:19 -07:00
|
|
|
"()".to_string()
|
2013-12-29 00:13:29 -05:00
|
|
|
},
|
2016-02-14 15:25:12 +03:00
|
|
|
PatKind::Range(..) => panic!("tried to get argument name from PatKind::Range, \
|
2013-09-05 10:14:35 -04:00
|
|
|
which is not allowed in function arguments"),
|
2016-09-20 02:14:46 +02:00
|
|
|
PatKind::Slice(ref begin, ref mid, ref end) => {
|
2015-01-04 17:52:08 +11:00
|
|
|
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));
|
2015-07-10 08:19:21 -04:00
|
|
|
format!("[{}]", begin.chain(mid).chain(end).collect::<Vec<_>>().join(", "))
|
2015-01-04 17:52:08 +11:00
|
|
|
},
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-12-21 12:32:59 +02:00
|
|
|
fn print_const_expr(cx: &DocContext, body: hir::BodyId) -> String {
|
2017-01-26 02:41:06 +02:00
|
|
|
cx.tcx.hir.node_to_pretty_string(body.node_id)
|
2016-12-21 12:32:59 +02:00
|
|
|
}
|
|
|
|
|
2016-11-25 13:21:19 +02:00
|
|
|
/// Given a type Path, resolve it to a Type using the TyCtxt
|
2014-11-20 19:44:49 -05:00
|
|
|
fn resolve_type(cx: &DocContext,
|
|
|
|
path: Path,
|
2013-09-24 13:53:09 -07:00
|
|
|
id: ast::NodeId) -> Type {
|
2015-09-08 10:08:30 -04:00
|
|
|
debug!("resolve_type({:?},{:?})", path, id);
|
|
|
|
|
2016-11-25 13:21:19 +02:00
|
|
|
let is_generic = match path.def {
|
2016-01-20 22:31:10 +03:00
|
|
|
Def::PrimTy(p) => match p {
|
2016-08-23 18:48:10 -04:00
|
|
|
hir::TyStr => return Primitive(PrimitiveType::Str),
|
|
|
|
hir::TyBool => return Primitive(PrimitiveType::Bool),
|
|
|
|
hir::TyChar => return Primitive(PrimitiveType::Char),
|
2016-08-23 19:12:24 -04:00
|
|
|
hir::TyInt(int_ty) => return Primitive(int_ty.into()),
|
2016-08-23 19:22:18 -04:00
|
|
|
hir::TyUint(uint_ty) => return Primitive(uint_ty.into()),
|
2016-08-23 19:41:14 -04:00
|
|
|
hir::TyFloat(float_ty) => return Primitive(float_ty.into()),
|
2013-08-15 16:28:54 -04:00
|
|
|
},
|
2016-01-20 22:31:10 +03:00
|
|
|
Def::SelfTy(..) if path.segments.len() == 1 => {
|
2016-04-18 22:53:50 +03:00
|
|
|
return Generic(keywords::SelfType.name().to_string());
|
2015-04-01 14:04:20 -07:00
|
|
|
}
|
2017-07-30 14:59:08 -05:00
|
|
|
Def::TyParam(..) if path.segments.len() == 1 => {
|
|
|
|
return Generic(format!("{:#}", path));
|
|
|
|
}
|
2016-06-11 18:47:47 +03:00
|
|
|
Def::SelfTy(..) | Def::TyParam(..) | Def::AssociatedTy(..) => true,
|
2015-05-25 15:06:38 +02:00
|
|
|
_ => false,
|
2014-05-09 13:52:17 -07:00
|
|
|
};
|
2016-11-25 13:21:19 +02:00
|
|
|
let did = register_def(&*cx, path.def);
|
2015-05-25 15:06:38 +02:00
|
|
|
ResolvedPath { path: path, typarams: None, did: did, is_generic: is_generic }
|
2014-05-09 13:52:17 -07:00
|
|
|
}
|
|
|
|
|
2016-01-20 22:31:10 +03:00
|
|
|
fn register_def(cx: &DocContext, def: Def) -> DefId {
|
2015-09-08 10:08:30 -04:00
|
|
|
debug!("register_def({:?})", def);
|
|
|
|
|
2014-05-09 13:52:17 -07:00
|
|
|
let (did, kind) = match def {
|
2016-10-01 00:34:00 -04:00
|
|
|
Def::Fn(i) => (i, TypeKind::Function),
|
|
|
|
Def::TyAlias(i) => (i, TypeKind::Typedef),
|
|
|
|
Def::Enum(i) => (i, TypeKind::Enum),
|
|
|
|
Def::Trait(i) => (i, TypeKind::Trait),
|
|
|
|
Def::Struct(i) => (i, TypeKind::Struct),
|
|
|
|
Def::Union(i) => (i, TypeKind::Union),
|
|
|
|
Def::Mod(i) => (i, TypeKind::Module),
|
|
|
|
Def::Static(i, _) => (i, TypeKind::Static),
|
2016-11-20 03:42:54 +02:00
|
|
|
Def::Variant(i) => (cx.tcx.parent_def_id(i).unwrap(), TypeKind::Enum),
|
2016-10-01 00:34:00 -04:00
|
|
|
Def::SelfTy(Some(def_id), _) => (def_id, TypeKind::Trait),
|
2016-08-31 14:08:22 +03:00
|
|
|
Def::SelfTy(_, Some(impl_def_id)) => {
|
|
|
|
return impl_def_id
|
2016-07-26 10:58:35 -04:00
|
|
|
}
|
2014-05-14 15:31:30 -04:00
|
|
|
_ => return def.def_id()
|
2013-08-15 16:28:54 -04:00
|
|
|
};
|
2015-08-16 06:32:28 -04:00
|
|
|
if did.is_local() { return did }
|
2014-05-24 11:56:38 -07:00
|
|
|
inline::record_extern_fqn(cx, did, kind);
|
2016-10-01 00:34:00 -04:00
|
|
|
if let TypeKind::Trait = kind {
|
2016-11-20 03:42:54 +02:00
|
|
|
let t = inline::build_external_trait(cx, did);
|
2016-04-07 05:59:02 +02:00
|
|
|
cx.external_traits.borrow_mut().insert(did, t);
|
2014-05-03 02:08:58 -07:00
|
|
|
}
|
2016-02-28 12:11:13 +01:00
|
|
|
did
|
2013-08-15 16:28:54 -04:00
|
|
|
}
|
2013-09-24 13:56:52 -07:00
|
|
|
|
2016-11-25 13:21:19 +02:00
|
|
|
fn resolve_use_source(cx: &DocContext, path: Path) -> ImportSource {
|
2013-09-24 13:56:52 -07:00
|
|
|
ImportSource {
|
2016-11-25 13:21:19 +02:00
|
|
|
did: if path.def == Def::Err {
|
|
|
|
None
|
|
|
|
} else {
|
|
|
|
Some(register_def(cx, path.def))
|
|
|
|
},
|
2017-08-06 22:54:09 -07:00
|
|
|
path,
|
2013-09-24 13:56:52 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
2014-02-16 21:40:26 -08:00
|
|
|
pub struct Macro {
|
2014-05-22 16:57:53 -07:00
|
|
|
pub source: String,
|
2015-04-13 15:25:40 -07:00
|
|
|
pub imported_from: Option<String>,
|
2014-02-16 21:40:26 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Clean<Item> for doctree::Macro {
|
2014-09-06 19:13:40 +03:00
|
|
|
fn clean(&self, cx: &DocContext) -> Item {
|
2016-08-03 12:55:01 +12:00
|
|
|
let name = self.name.clean(cx);
|
2014-02-16 21:40:26 -08:00
|
|
|
Item {
|
2015-11-26 19:14:36 +01:00
|
|
|
name: Some(name.clone()),
|
2014-09-06 19:13:40 +03:00
|
|
|
attrs: self.attrs.clean(cx),
|
|
|
|
source: self.whence.clean(cx),
|
2016-04-11 08:15:14 +00:00
|
|
|
visibility: Some(Public),
|
2014-09-06 19:13:40 +03:00
|
|
|
stability: self.stab.clean(cx),
|
2015-12-12 23:01:27 +03:00
|
|
|
deprecation: self.depr.clean(cx),
|
2016-12-19 14:24:33 -05:00
|
|
|
def_id: self.def_id,
|
2014-02-16 21:40:26 -08:00
|
|
|
inner: MacroItem(Macro {
|
2015-11-26 19:14:36 +01:00
|
|
|
source: format!("macro_rules! {} {{\n{}}}",
|
2016-08-03 12:55:01 +12:00
|
|
|
name,
|
|
|
|
self.matchers.iter().map(|span| {
|
|
|
|
format!(" {} => {{ ... }};\n", span.to_src(cx))
|
|
|
|
}).collect::<String>()),
|
2015-04-13 15:25:40 -07:00
|
|
|
imported_from: self.imported_from.clean(cx),
|
2014-02-16 21:40:26 -08:00
|
|
|
}),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2014-06-26 11:37:39 -07:00
|
|
|
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
2014-06-26 11:37:39 -07:00
|
|
|
pub struct Stability {
|
2015-10-13 06:01:31 +03:00
|
|
|
pub level: stability::StabilityLevel,
|
2015-01-12 18:40:19 -08:00
|
|
|
pub feature: String,
|
|
|
|
pub since: String,
|
2015-02-13 16:36:56 +02:00
|
|
|
pub deprecated_since: String,
|
2016-11-13 15:56:23 -05:00
|
|
|
pub deprecated_reason: String,
|
|
|
|
pub unstable_reason: String,
|
2015-08-16 15:53:18 +02:00
|
|
|
pub issue: Option<u32>
|
2014-06-26 11:37:39 -07:00
|
|
|
}
|
|
|
|
|
2015-12-12 23:01:27 +03:00
|
|
|
#[derive(Clone, RustcEncodable, RustcDecodable, Debug)]
|
|
|
|
pub struct Deprecation {
|
|
|
|
pub since: String,
|
|
|
|
pub note: String,
|
|
|
|
}
|
|
|
|
|
2014-06-26 11:37:39 -07:00
|
|
|
impl Clean<Stability> for attr::Stability {
|
2015-05-26 00:41:27 +03:00
|
|
|
fn clean(&self, _: &DocContext) -> Stability {
|
|
|
|
Stability {
|
2015-10-13 06:01:31 +03:00
|
|
|
level: stability::StabilityLevel::from_attr_level(&self.level),
|
2015-05-26 00:41:27 +03:00
|
|
|
feature: self.feature.to_string(),
|
2015-10-13 06:01:31 +03:00
|
|
|
since: match self.level {
|
|
|
|
attr::Stable {ref since} => since.to_string(),
|
|
|
|
_ => "".to_string(),
|
|
|
|
},
|
2015-12-04 19:34:28 +03:00
|
|
|
deprecated_since: match self.rustc_depr {
|
|
|
|
Some(attr::RustcDeprecation {ref since, ..}) => since.to_string(),
|
2015-10-13 06:01:31 +03:00
|
|
|
_=> "".to_string(),
|
|
|
|
},
|
2016-11-13 15:56:23 -05:00
|
|
|
deprecated_reason: match self.rustc_depr {
|
|
|
|
Some(ref depr) => depr.reason.to_string(),
|
|
|
|
_ => "".to_string(),
|
|
|
|
},
|
|
|
|
unstable_reason: match self.level {
|
|
|
|
attr::Unstable { reason: Some(ref reason), .. } => reason.to_string(),
|
|
|
|
_ => "".to_string(),
|
2015-10-13 06:01:31 +03:00
|
|
|
},
|
|
|
|
issue: match self.level {
|
|
|
|
attr::Unstable {issue, ..} => Some(issue),
|
|
|
|
_ => None,
|
|
|
|
}
|
2015-05-26 00:41:27 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl<'a> Clean<Stability> for &'a attr::Stability {
|
2015-10-13 06:01:31 +03:00
|
|
|
fn clean(&self, dc: &DocContext) -> Stability {
|
|
|
|
(**self).clean(dc)
|
2014-06-26 11:37:39 -07:00
|
|
|
}
|
|
|
|
}
|
2014-07-25 09:31:20 -07:00
|
|
|
|
2015-12-12 23:01:27 +03:00
|
|
|
impl Clean<Deprecation> for attr::Deprecation {
|
|
|
|
fn clean(&self, _: &DocContext) -> Deprecation {
|
|
|
|
Deprecation {
|
|
|
|
since: self.since.as_ref().map_or("".to_string(), |s| s.to_string()),
|
|
|
|
note: self.note.as_ref().map_or("".to_string(), |s| s.to_string()),
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-01-07 16:10:40 -08:00
|
|
|
/// An equality constraint on an associated type, e.g. `A=Bar` in `Foo<A=Bar>`
|
2015-01-28 08:34:18 -05:00
|
|
|
#[derive(Clone, PartialEq, RustcDecodable, RustcEncodable, Debug)]
|
2015-01-07 16:10:40 -08:00
|
|
|
pub struct TypeBinding {
|
|
|
|
pub name: String,
|
|
|
|
pub ty: Type
|
|
|
|
}
|
|
|
|
|
2015-07-31 00:04:06 -07:00
|
|
|
impl Clean<TypeBinding> for hir::TypeBinding {
|
2015-01-07 16:10:40 -08:00
|
|
|
fn clean(&self, cx: &DocContext) -> TypeBinding {
|
|
|
|
TypeBinding {
|
2015-09-20 16:47:24 +03:00
|
|
|
name: self.name.clean(cx),
|
2015-01-07 16:10:40 -08:00
|
|
|
ty: self.ty.clean(cx)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|