Auto merge of #80987 - GuillaumeGomez:remove-cache-key, r=jyn514
Remove CACHE_KEY global We realized in https://github.com/rust-lang/rust/pull/80914 that the cache handling (through a global) needed to be updated to make it much easier to handle. r? `@jyn514`
This commit is contained in:
commit
613ef740f3
14 changed files with 792 additions and 623 deletions
|
@ -2329,14 +2329,14 @@ impl Clean<Item> for (&hir::MacroDef<'_>, Option<Symbol>) {
|
|||
if matchers.len() <= 1 {
|
||||
format!(
|
||||
"{}macro {}{} {{\n ...\n}}",
|
||||
vis.print_with_space(cx.tcx, def_id),
|
||||
vis.print_with_space(cx.tcx, def_id, &cx.cache),
|
||||
name,
|
||||
matchers.iter().map(|span| span.to_src(cx)).collect::<String>(),
|
||||
)
|
||||
} else {
|
||||
format!(
|
||||
"{}macro {} {{\n{}}}",
|
||||
vis.print_with_space(cx.tcx, def_id),
|
||||
vis.print_with_space(cx.tcx, def_id, &cx.cache),
|
||||
name,
|
||||
matchers
|
||||
.iter()
|
||||
|
|
|
@ -37,7 +37,7 @@ use crate::clean::inline;
|
|||
use crate::clean::types::Type::{QPath, ResolvedPath};
|
||||
use crate::clean::Clean;
|
||||
use crate::core::DocContext;
|
||||
use crate::formats::cache::cache;
|
||||
use crate::formats::cache::Cache;
|
||||
use crate::formats::item_type::ItemType;
|
||||
use crate::html::render::cache::ExternalLocation;
|
||||
|
||||
|
@ -169,8 +169,8 @@ impl Item {
|
|||
self.attrs.collapsed_doc_value()
|
||||
}
|
||||
|
||||
crate fn links(&self) -> Vec<RenderedLink> {
|
||||
self.attrs.links(&self.def_id.krate)
|
||||
crate fn links(&self, cache: &Cache) -> Vec<RenderedLink> {
|
||||
self.attrs.links(&self.def_id.krate, cache)
|
||||
}
|
||||
|
||||
crate fn is_crate(&self) -> bool {
|
||||
|
@ -826,7 +826,7 @@ impl Attributes {
|
|||
/// Gets links as a vector
|
||||
///
|
||||
/// Cache must be populated before call
|
||||
crate fn links(&self, krate: &CrateNum) -> Vec<RenderedLink> {
|
||||
crate fn links(&self, krate: &CrateNum, cache: &Cache) -> Vec<RenderedLink> {
|
||||
use crate::html::format::href;
|
||||
use crate::html::render::CURRENT_DEPTH;
|
||||
|
||||
|
@ -835,7 +835,7 @@ impl Attributes {
|
|||
.filter_map(|ItemLink { link: s, link_text, did, fragment }| {
|
||||
match *did {
|
||||
Some(did) => {
|
||||
if let Some((mut href, ..)) = href(did) {
|
||||
if let Some((mut href, ..)) = href(did, cache) {
|
||||
if let Some(ref fragment) = *fragment {
|
||||
href.push('#');
|
||||
href.push_str(fragment);
|
||||
|
@ -851,7 +851,6 @@ impl Attributes {
|
|||
}
|
||||
None => {
|
||||
if let Some(ref fragment) = *fragment {
|
||||
let cache = cache();
|
||||
let url = match cache.extern_locations.get(krate) {
|
||||
Some(&(_, _, ExternalLocation::Local)) => {
|
||||
let depth = CURRENT_DEPTH.with(|l| l.get());
|
||||
|
@ -1177,6 +1176,13 @@ impl GetDefId for FnRetTy {
|
|||
DefaultReturn => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn def_id_full(&self, cache: &Cache) -> Option<DefId> {
|
||||
match *self {
|
||||
Return(ref ty) => ty.def_id_full(cache),
|
||||
DefaultReturn => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
@ -1299,13 +1305,31 @@ crate enum TypeKind {
|
|||
}
|
||||
|
||||
crate trait GetDefId {
|
||||
/// Use this method to get the [`DefId`] of a [`clean`] AST node.
|
||||
/// This will return [`None`] when called on a primitive [`clean::Type`].
|
||||
/// Use [`Self::def_id_full`] if you want to include primitives.
|
||||
///
|
||||
/// [`clean`]: crate::clean
|
||||
/// [`clean::Type`]: crate::clean::Type
|
||||
// FIXME: get rid of this function and always use `def_id_full`
|
||||
fn def_id(&self) -> Option<DefId>;
|
||||
|
||||
/// Use this method to get the [DefId] of a [clean] AST node, including [PrimitiveType]s.
|
||||
///
|
||||
/// See [`Self::def_id`] for more.
|
||||
///
|
||||
/// [clean]: crate::clean
|
||||
fn def_id_full(&self, cache: &Cache) -> Option<DefId>;
|
||||
}
|
||||
|
||||
impl<T: GetDefId> GetDefId for Option<T> {
|
||||
fn def_id(&self) -> Option<DefId> {
|
||||
self.as_ref().and_then(|d| d.def_id())
|
||||
}
|
||||
|
||||
fn def_id_full(&self, cache: &Cache) -> Option<DefId> {
|
||||
self.as_ref().and_then(|d| d.def_id_full(cache))
|
||||
}
|
||||
}
|
||||
|
||||
impl Type {
|
||||
|
@ -1393,31 +1417,41 @@ impl Type {
|
|||
}
|
||||
}
|
||||
|
||||
impl GetDefId for Type {
|
||||
fn def_id(&self) -> Option<DefId> {
|
||||
match *self {
|
||||
ResolvedPath { did, .. } => Some(did),
|
||||
Primitive(p) => cache().primitive_locations.get(&p).cloned(),
|
||||
BorrowedRef { type_: box Generic(..), .. } => {
|
||||
Primitive(PrimitiveType::Reference).def_id()
|
||||
}
|
||||
BorrowedRef { ref type_, .. } => type_.def_id(),
|
||||
impl Type {
|
||||
fn inner_def_id(&self, cache: Option<&Cache>) -> Option<DefId> {
|
||||
let t: PrimitiveType = match *self {
|
||||
ResolvedPath { did, .. } => return Some(did),
|
||||
Primitive(p) => return cache.and_then(|c| c.primitive_locations.get(&p).cloned()),
|
||||
BorrowedRef { type_: box Generic(..), .. } => PrimitiveType::Reference,
|
||||
BorrowedRef { ref type_, .. } => return type_.inner_def_id(cache),
|
||||
Tuple(ref tys) => {
|
||||
if tys.is_empty() {
|
||||
Primitive(PrimitiveType::Unit).def_id()
|
||||
PrimitiveType::Unit
|
||||
} else {
|
||||
Primitive(PrimitiveType::Tuple).def_id()
|
||||
PrimitiveType::Tuple
|
||||
}
|
||||
}
|
||||
BareFunction(..) => Primitive(PrimitiveType::Fn).def_id(),
|
||||
Never => Primitive(PrimitiveType::Never).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(),
|
||||
_ => None,
|
||||
BareFunction(..) => PrimitiveType::Fn,
|
||||
Never => PrimitiveType::Never,
|
||||
Slice(..) => PrimitiveType::Slice,
|
||||
Array(..) => PrimitiveType::Array,
|
||||
RawPointer(..) => PrimitiveType::RawPointer,
|
||||
QPath { ref self_type, .. } => return self_type.inner_def_id(cache),
|
||||
// FIXME: remove this wildcard
|
||||
_ => return None,
|
||||
};
|
||||
cache.and_then(|c| Primitive(t).def_id_full(c))
|
||||
}
|
||||
}
|
||||
|
||||
impl GetDefId for Type {
|
||||
fn def_id(&self) -> Option<DefId> {
|
||||
self.inner_def_id(None)
|
||||
}
|
||||
|
||||
fn def_id_full(&self, cache: &Cache) -> Option<DefId> {
|
||||
self.inner_def_id(Some(cache))
|
||||
}
|
||||
}
|
||||
|
||||
impl PrimitiveType {
|
||||
|
@ -1817,6 +1851,10 @@ impl GetDefId for Typedef {
|
|||
fn def_id(&self) -> Option<DefId> {
|
||||
self.type_.def_id()
|
||||
}
|
||||
|
||||
fn def_id_full(&self, cache: &Cache) -> Option<DefId> {
|
||||
self.type_.def_id_full(cache)
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
|
|
|
@ -177,7 +177,7 @@ crate fn get_real_types(
|
|||
return res;
|
||||
}
|
||||
if arg.is_full_generic() {
|
||||
let arg_s = Symbol::intern(&arg.print().to_string());
|
||||
let arg_s = Symbol::intern(&arg.print(&cx.cache).to_string());
|
||||
if let Some(where_pred) = generics.where_predicates.iter().find(|g| match g {
|
||||
WherePredicate::BoundPredicate { ty, .. } => ty.def_id() == arg.def_id(),
|
||||
_ => false,
|
||||
|
@ -473,7 +473,7 @@ crate fn resolve_type(cx: &DocContext<'_>, path: Path, id: hir::HirId) -> Type {
|
|||
return Generic(kw::SelfUpper);
|
||||
}
|
||||
Res::Def(DefKind::TyParam, _) if path.segments.len() == 1 => {
|
||||
return Generic(Symbol::intern(&format!("{:#}", path.print())));
|
||||
return Generic(Symbol::intern(&format!("{:#}", path.print(&cx.cache))));
|
||||
}
|
||||
Res::SelfTy(..) | Res::Def(DefKind::TyParam | DefKind::AssocTy, _) => true,
|
||||
_ => false,
|
||||
|
|
|
@ -261,7 +261,7 @@ crate struct RenderOptions {
|
|||
}
|
||||
|
||||
/// Temporary storage for data obtained during `RustdocVisitor::clean()`.
|
||||
/// Later on moved into `CACHE_KEY`.
|
||||
/// Later on moved into `cache`.
|
||||
#[derive(Default, Clone)]
|
||||
crate struct RenderInfo {
|
||||
crate inlined: FxHashSet<DefId>,
|
||||
|
|
|
@ -32,6 +32,7 @@ use crate::clean;
|
|||
use crate::clean::{AttributesExt, MAX_DEF_ID};
|
||||
use crate::config::{Options as RustdocOptions, RenderOptions};
|
||||
use crate::config::{OutputFormat, RenderInfo};
|
||||
use crate::formats::cache::Cache;
|
||||
use crate::passes::{self, Condition::*, ConditionalPass};
|
||||
|
||||
crate use rustc_session::config::{DebuggingOptions, Input, Options};
|
||||
|
@ -45,9 +46,9 @@ crate struct DocContext<'tcx> {
|
|||
///
|
||||
/// Most of this logic is copied from rustc_lint::late.
|
||||
crate param_env: Cell<ParamEnv<'tcx>>,
|
||||
/// Later on moved into `CACHE_KEY`
|
||||
/// Later on moved into `cache`
|
||||
crate renderinfo: RefCell<RenderInfo>,
|
||||
/// Later on moved through `clean::Crate` into `CACHE_KEY`
|
||||
/// Later on moved through `clean::Crate` into `cache`
|
||||
crate external_traits: Rc<RefCell<FxHashMap<DefId, clean::Trait>>>,
|
||||
/// Used while populating `external_traits` to ensure we don't process the same trait twice at
|
||||
/// the same time.
|
||||
|
@ -75,6 +76,8 @@ crate struct DocContext<'tcx> {
|
|||
/// See `collect_intra_doc_links::traits_implemented_by` for more details.
|
||||
/// `map<module, set<trait>>`
|
||||
crate module_trait_cache: RefCell<FxHashMap<DefId, FxHashSet<DefId>>>,
|
||||
/// Fake empty cache used when cache is required as parameter.
|
||||
crate cache: Cache,
|
||||
}
|
||||
|
||||
impl<'tcx> DocContext<'tcx> {
|
||||
|
@ -524,6 +527,7 @@ crate fn run_global_ctxt(
|
|||
.collect(),
|
||||
render_options,
|
||||
module_trait_cache: RefCell::new(FxHashMap::default()),
|
||||
cache: Cache::default(),
|
||||
};
|
||||
debug!("crate: {:?}", tcx.hir().krate());
|
||||
|
||||
|
|
|
@ -1,8 +1,6 @@
|
|||
use std::cell::RefCell;
|
||||
use std::collections::BTreeMap;
|
||||
use std::mem;
|
||||
use std::path::{Path, PathBuf};
|
||||
use std::sync::Arc;
|
||||
|
||||
use rustc_data_structures::fx::{FxHashMap, FxHashSet};
|
||||
use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX};
|
||||
|
@ -19,8 +17,6 @@ use crate::html::markdown::short_markdown_summary;
|
|||
use crate::html::render::cache::{extern_location, get_index_search_type, ExternalLocation};
|
||||
use crate::html::render::IndexItem;
|
||||
|
||||
thread_local!(crate static CACHE_KEY: RefCell<Arc<Cache>> = Default::default());
|
||||
|
||||
/// This cache is used to store information about the [`clean::Crate`] being
|
||||
/// rendered in order to provide more useful documentation. This contains
|
||||
/// information like all implementors of a trait, all traits a type implements,
|
||||
|
@ -197,6 +193,7 @@ impl Cache {
|
|||
}
|
||||
|
||||
cache.stack.push(krate.name.to_string());
|
||||
|
||||
krate = cache.fold_crate(krate);
|
||||
|
||||
for (trait_did, dids, impl_) in cache.orphan_trait_impls.drain(..) {
|
||||
|
@ -319,7 +316,7 @@ impl DocFolder for Cache {
|
|||
.map_or_else(String::new, |x| short_markdown_summary(&x.as_str())),
|
||||
parent,
|
||||
parent_idx: None,
|
||||
search_type: get_index_search_type(&item),
|
||||
search_type: get_index_search_type(&item, None),
|
||||
});
|
||||
|
||||
for alias in item.attrs.get_doc_aliases() {
|
||||
|
@ -477,7 +474,3 @@ impl DocFolder for Cache {
|
|||
ret
|
||||
}
|
||||
}
|
||||
|
||||
crate fn cache() -> Arc<Cache> {
|
||||
CACHE_KEY.with(|c| c.borrow().clone())
|
||||
}
|
||||
|
|
|
@ -8,6 +8,7 @@ use rustc_span::def_id::DefId;
|
|||
|
||||
use crate::clean;
|
||||
use crate::clean::types::GetDefId;
|
||||
use crate::formats::cache::Cache;
|
||||
|
||||
/// Specifies whether rendering directly implemented trait items or ones from a certain Deref
|
||||
/// impl.
|
||||
|
@ -41,4 +42,8 @@ impl Impl {
|
|||
crate fn trait_did(&self) -> Option<DefId> {
|
||||
self.inner_impl().trait_.def_id()
|
||||
}
|
||||
|
||||
crate fn trait_did_full(&self, cache: &Cache) -> Option<DefId> {
|
||||
self.inner_impl().trait_.def_id_full(cache)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,12 +1,10 @@
|
|||
use std::sync::Arc;
|
||||
|
||||
use rustc_middle::ty::TyCtxt;
|
||||
use rustc_span::edition::Edition;
|
||||
|
||||
use crate::clean;
|
||||
use crate::config::{RenderInfo, RenderOptions};
|
||||
use crate::error::Error;
|
||||
use crate::formats::cache::{Cache, CACHE_KEY};
|
||||
use crate::formats::cache::Cache;
|
||||
|
||||
/// Allows for different backends to rustdoc to be used with the `run_format()` function. Each
|
||||
/// backend renderer has hooks for initialization, documenting an item, entering and exiting a
|
||||
|
@ -22,20 +20,15 @@ crate trait FormatRenderer<'tcx>: Clone {
|
|||
options: RenderOptions,
|
||||
render_info: RenderInfo,
|
||||
edition: Edition,
|
||||
cache: &mut Cache,
|
||||
cache: Cache,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
) -> Result<(Self, clean::Crate), Error>;
|
||||
|
||||
/// Renders a single non-module item. This means no recursive sub-item rendering is required.
|
||||
fn item(&mut self, item: clean::Item, cache: &Cache) -> Result<(), Error>;
|
||||
fn item(&mut self, item: clean::Item) -> Result<(), Error>;
|
||||
|
||||
/// Renders a module (should not handle recursing into children).
|
||||
fn mod_item_in(
|
||||
&mut self,
|
||||
item: &clean::Item,
|
||||
item_name: &str,
|
||||
cache: &Cache,
|
||||
) -> Result<(), Error>;
|
||||
fn mod_item_in(&mut self, item: &clean::Item, item_name: &str) -> Result<(), Error>;
|
||||
|
||||
/// Runs after recursively rendering all sub-items of a module.
|
||||
fn mod_item_out(&mut self, item_name: &str) -> Result<(), Error>;
|
||||
|
@ -46,9 +39,10 @@ crate trait FormatRenderer<'tcx>: Clone {
|
|||
fn after_krate(
|
||||
&mut self,
|
||||
krate: &clean::Crate,
|
||||
cache: &Cache,
|
||||
diag: &rustc_errors::Handler,
|
||||
) -> Result<(), Error>;
|
||||
|
||||
fn cache(&self) -> &Cache;
|
||||
}
|
||||
|
||||
/// Main method for rendering a crate.
|
||||
|
@ -60,7 +54,7 @@ crate fn run_format<'tcx, T: FormatRenderer<'tcx>>(
|
|||
edition: Edition,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
) -> Result<(), Error> {
|
||||
let (krate, mut cache) = tcx.sess.time("create_format_cache", || {
|
||||
let (krate, cache) = tcx.sess.time("create_format_cache", || {
|
||||
Cache::from_krate(
|
||||
render_info.clone(),
|
||||
options.document_private,
|
||||
|
@ -73,12 +67,7 @@ crate fn run_format<'tcx, T: FormatRenderer<'tcx>>(
|
|||
|
||||
let (mut format_renderer, mut krate) = prof
|
||||
.extra_verbose_generic_activity("create_renderer", T::descr())
|
||||
.run(|| T::init(krate, options, render_info, edition, &mut cache, tcx))?;
|
||||
|
||||
let cache = Arc::new(cache);
|
||||
// Freeze the cache now that the index has been built. Put an Arc into TLS for future
|
||||
// parallelization opportunities
|
||||
CACHE_KEY.with(|v| *v.borrow_mut() = cache.clone());
|
||||
.run(|| T::init(krate, options, render_info, edition, cache, tcx))?;
|
||||
|
||||
let mut item = match krate.module.take() {
|
||||
Some(i) => i,
|
||||
|
@ -101,7 +90,7 @@ crate fn run_format<'tcx, T: FormatRenderer<'tcx>>(
|
|||
}
|
||||
let _timer = prof.generic_activity_with_arg("render_mod_item", name.as_str());
|
||||
|
||||
cx.mod_item_in(&item, &name, &cache)?;
|
||||
cx.mod_item_in(&item, &name)?;
|
||||
let module = match *item.kind {
|
||||
clean::StrippedItem(box clean::ModuleItem(m)) | clean::ModuleItem(m) => m,
|
||||
_ => unreachable!(),
|
||||
|
@ -114,9 +103,9 @@ crate fn run_format<'tcx, T: FormatRenderer<'tcx>>(
|
|||
cx.mod_item_out(&name)?;
|
||||
} else if item.name.is_some() {
|
||||
prof.generic_activity_with_arg("render_item", &*item.name.unwrap_or(unknown).as_str())
|
||||
.run(|| cx.item(item, &cache))?;
|
||||
.run(|| cx.item(item))?;
|
||||
}
|
||||
}
|
||||
prof.extra_verbose_generic_activity("renderer_after_krate", T::descr())
|
||||
.run(|| format_renderer.after_krate(&krate, &cache, diag))
|
||||
.run(|| format_renderer.after_krate(&krate, diag))
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ use rustc_span::def_id::{DefId, CRATE_DEF_INDEX};
|
|||
use rustc_target::spec::abi::Abi;
|
||||
|
||||
use crate::clean::{self, utils::find_nearest_parent_module, PrimitiveType};
|
||||
use crate::formats::cache::cache;
|
||||
use crate::formats::cache::Cache;
|
||||
use crate::formats::item_type::ItemType;
|
||||
use crate::html::escape::Escape;
|
||||
use crate::html::render::cache::ExternalLocation;
|
||||
|
@ -152,24 +152,27 @@ fn comma_sep<T: fmt::Display>(items: impl Iterator<Item = T>) -> impl fmt::Displ
|
|||
})
|
||||
}
|
||||
|
||||
crate fn print_generic_bounds(bounds: &[clean::GenericBound]) -> impl fmt::Display + '_ {
|
||||
crate fn print_generic_bounds<'a>(
|
||||
bounds: &'a [clean::GenericBound],
|
||||
cache: &'a Cache,
|
||||
) -> impl fmt::Display + 'a {
|
||||
display_fn(move |f| {
|
||||
let mut bounds_dup = FxHashSet::default();
|
||||
|
||||
for (i, bound) in
|
||||
bounds.iter().filter(|b| bounds_dup.insert(b.print().to_string())).enumerate()
|
||||
bounds.iter().filter(|b| bounds_dup.insert(b.print(cache).to_string())).enumerate()
|
||||
{
|
||||
if i > 0 {
|
||||
f.write_str(" + ")?;
|
||||
}
|
||||
fmt::Display::fmt(&bound.print(), f)?;
|
||||
fmt::Display::fmt(&bound.print(cache), f)?;
|
||||
}
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
|
||||
impl clean::GenericParamDef {
|
||||
crate fn print(&self) -> impl fmt::Display + '_ {
|
||||
crate fn print<'a>(&'a self, cache: &'a Cache) -> impl fmt::Display + 'a {
|
||||
display_fn(move |f| match self.kind {
|
||||
clean::GenericParamDefKind::Lifetime => write!(f, "{}", self.name),
|
||||
clean::GenericParamDefKind::Type { ref bounds, ref default, .. } => {
|
||||
|
@ -177,17 +180,17 @@ impl clean::GenericParamDef {
|
|||
|
||||
if !bounds.is_empty() {
|
||||
if f.alternate() {
|
||||
write!(f, ": {:#}", print_generic_bounds(bounds))?;
|
||||
write!(f, ": {:#}", print_generic_bounds(bounds, cache))?;
|
||||
} else {
|
||||
write!(f, ": {}", print_generic_bounds(bounds))?;
|
||||
write!(f, ": {}", print_generic_bounds(bounds, cache))?;
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(ref ty) = default {
|
||||
if f.alternate() {
|
||||
write!(f, " = {:#}", ty.print())?;
|
||||
write!(f, " = {:#}", ty.print(cache))?;
|
||||
} else {
|
||||
write!(f, " = {}", ty.print())?;
|
||||
write!(f, " = {}", ty.print(cache))?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -195,9 +198,9 @@ impl clean::GenericParamDef {
|
|||
}
|
||||
clean::GenericParamDefKind::Const { ref ty, .. } => {
|
||||
if f.alternate() {
|
||||
write!(f, "const {}: {:#}", self.name, ty.print())
|
||||
write!(f, "const {}: {:#}", self.name, ty.print(cache))
|
||||
} else {
|
||||
write!(f, "const {}: {}", self.name, ty.print())
|
||||
write!(f, "const {}: {}", self.name, ty.print(cache))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -205,7 +208,7 @@ impl clean::GenericParamDef {
|
|||
}
|
||||
|
||||
impl clean::Generics {
|
||||
crate fn print(&self) -> impl fmt::Display + '_ {
|
||||
crate fn print<'a>(&'a self, cache: &'a Cache) -> impl fmt::Display + 'a {
|
||||
display_fn(move |f| {
|
||||
let real_params =
|
||||
self.params.iter().filter(|p| !p.is_synthetic_type_param()).collect::<Vec<_>>();
|
||||
|
@ -213,16 +216,17 @@ impl clean::Generics {
|
|||
return Ok(());
|
||||
}
|
||||
if f.alternate() {
|
||||
write!(f, "<{:#}>", comma_sep(real_params.iter().map(|g| g.print())))
|
||||
write!(f, "<{:#}>", comma_sep(real_params.iter().map(|g| g.print(cache))))
|
||||
} else {
|
||||
write!(f, "<{}>", comma_sep(real_params.iter().map(|g| g.print())))
|
||||
write!(f, "<{}>", comma_sep(real_params.iter().map(|g| g.print(cache))))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a> fmt::Display for WhereClause<'a> {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
impl<'a> WhereClause<'a> {
|
||||
crate fn print<'b>(&'b self, cache: &'b Cache) -> impl fmt::Display + 'b {
|
||||
display_fn(move |f| {
|
||||
let &WhereClause { gens, indent, end_newline } = self;
|
||||
if gens.where_predicates.is_empty() {
|
||||
return Ok(());
|
||||
|
@ -250,14 +254,14 @@ impl<'a> fmt::Display for WhereClause<'a> {
|
|||
if f.alternate() {
|
||||
clause.push_str(&format!(
|
||||
"{:#}: {:#}",
|
||||
ty.print(),
|
||||
print_generic_bounds(bounds)
|
||||
ty.print(cache),
|
||||
print_generic_bounds(bounds, cache)
|
||||
));
|
||||
} else {
|
||||
clause.push_str(&format!(
|
||||
"{}: {}",
|
||||
ty.print(),
|
||||
print_generic_bounds(bounds)
|
||||
ty.print(cache),
|
||||
print_generic_bounds(bounds, cache)
|
||||
));
|
||||
}
|
||||
}
|
||||
|
@ -267,16 +271,24 @@ impl<'a> fmt::Display for WhereClause<'a> {
|
|||
lifetime.print(),
|
||||
bounds
|
||||
.iter()
|
||||
.map(|b| b.print().to_string())
|
||||
.map(|b| b.print(cache).to_string())
|
||||
.collect::<Vec<_>>()
|
||||
.join(" + ")
|
||||
));
|
||||
}
|
||||
clean::WherePredicate::EqPredicate { lhs, rhs } => {
|
||||
if f.alternate() {
|
||||
clause.push_str(&format!("{:#} == {:#}", lhs.print(), rhs.print()));
|
||||
clause.push_str(&format!(
|
||||
"{:#} == {:#}",
|
||||
lhs.print(cache),
|
||||
rhs.print(cache)
|
||||
));
|
||||
} else {
|
||||
clause.push_str(&format!("{} == {}", lhs.print(), rhs.print()));
|
||||
clause.push_str(&format!(
|
||||
"{} == {}",
|
||||
lhs.print(cache),
|
||||
rhs.print(cache)
|
||||
));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -305,6 +317,7 @@ impl<'a> fmt::Display for WhereClause<'a> {
|
|||
}
|
||||
}
|
||||
write!(f, "{}", clause)
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -327,34 +340,34 @@ impl clean::Constant {
|
|||
}
|
||||
|
||||
impl clean::PolyTrait {
|
||||
fn print(&self) -> impl fmt::Display + '_ {
|
||||
fn print<'a>(&'a self, cache: &'a Cache) -> impl fmt::Display + 'a {
|
||||
display_fn(move |f| {
|
||||
if !self.generic_params.is_empty() {
|
||||
if f.alternate() {
|
||||
write!(
|
||||
f,
|
||||
"for<{:#}> ",
|
||||
comma_sep(self.generic_params.iter().map(|g| g.print()))
|
||||
comma_sep(self.generic_params.iter().map(|g| g.print(cache)))
|
||||
)?;
|
||||
} else {
|
||||
write!(
|
||||
f,
|
||||
"for<{}> ",
|
||||
comma_sep(self.generic_params.iter().map(|g| g.print()))
|
||||
comma_sep(self.generic_params.iter().map(|g| g.print(cache)))
|
||||
)?;
|
||||
}
|
||||
}
|
||||
if f.alternate() {
|
||||
write!(f, "{:#}", self.trait_.print())
|
||||
write!(f, "{:#}", self.trait_.print(cache))
|
||||
} else {
|
||||
write!(f, "{}", self.trait_.print())
|
||||
write!(f, "{}", self.trait_.print(cache))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl clean::GenericBound {
|
||||
crate fn print(&self) -> impl fmt::Display + '_ {
|
||||
crate fn print<'a>(&'a self, cache: &'a Cache) -> impl fmt::Display + 'a {
|
||||
display_fn(move |f| match self {
|
||||
clean::GenericBound::Outlives(lt) => write!(f, "{}", lt.print()),
|
||||
clean::GenericBound::TraitBound(ty, modifier) => {
|
||||
|
@ -364,9 +377,9 @@ impl clean::GenericBound {
|
|||
hir::TraitBoundModifier::MaybeConst => "?const",
|
||||
};
|
||||
if f.alternate() {
|
||||
write!(f, "{}{:#}", modifier_str, ty.print())
|
||||
write!(f, "{}{:#}", modifier_str, ty.print(cache))
|
||||
} else {
|
||||
write!(f, "{}{}", modifier_str, ty.print())
|
||||
write!(f, "{}{}", modifier_str, ty.print(cache))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -374,7 +387,7 @@ impl clean::GenericBound {
|
|||
}
|
||||
|
||||
impl clean::GenericArgs {
|
||||
fn print(&self) -> impl fmt::Display + '_ {
|
||||
fn print<'a>(&'a self, cache: &'a Cache) -> impl fmt::Display + 'a {
|
||||
display_fn(move |f| {
|
||||
match self {
|
||||
clean::GenericArgs::AngleBracketed { args, bindings } => {
|
||||
|
@ -391,9 +404,9 @@ impl clean::GenericArgs {
|
|||
}
|
||||
comma = true;
|
||||
if f.alternate() {
|
||||
write!(f, "{:#}", arg.print())?;
|
||||
write!(f, "{:#}", arg.print(cache))?;
|
||||
} else {
|
||||
write!(f, "{}", arg.print())?;
|
||||
write!(f, "{}", arg.print(cache))?;
|
||||
}
|
||||
}
|
||||
for binding in bindings {
|
||||
|
@ -402,9 +415,9 @@ impl clean::GenericArgs {
|
|||
}
|
||||
comma = true;
|
||||
if f.alternate() {
|
||||
write!(f, "{:#}", binding.print())?;
|
||||
write!(f, "{:#}", binding.print(cache))?;
|
||||
} else {
|
||||
write!(f, "{}", binding.print())?;
|
||||
write!(f, "{}", binding.print(cache))?;
|
||||
}
|
||||
}
|
||||
if f.alternate() {
|
||||
|
@ -423,17 +436,17 @@ impl clean::GenericArgs {
|
|||
}
|
||||
comma = true;
|
||||
if f.alternate() {
|
||||
write!(f, "{:#}", ty.print())?;
|
||||
write!(f, "{:#}", ty.print(cache))?;
|
||||
} else {
|
||||
write!(f, "{}", ty.print())?;
|
||||
write!(f, "{}", ty.print(cache))?;
|
||||
}
|
||||
}
|
||||
f.write_str(")")?;
|
||||
if let Some(ref ty) = *output {
|
||||
if f.alternate() {
|
||||
write!(f, " -> {:#}", ty.print())?;
|
||||
write!(f, " -> {:#}", ty.print(cache))?;
|
||||
} else {
|
||||
write!(f, " -> {}", ty.print())?;
|
||||
write!(f, " -> {}", ty.print(cache))?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -444,19 +457,19 @@ impl clean::GenericArgs {
|
|||
}
|
||||
|
||||
impl clean::PathSegment {
|
||||
crate fn print(&self) -> impl fmt::Display + '_ {
|
||||
crate fn print<'a>(&'a self, cache: &'a Cache) -> impl fmt::Display + 'a {
|
||||
display_fn(move |f| {
|
||||
if f.alternate() {
|
||||
write!(f, "{}{:#}", self.name, self.args.print())
|
||||
write!(f, "{}{:#}", self.name, self.args.print(cache))
|
||||
} else {
|
||||
write!(f, "{}{}", self.name, self.args.print())
|
||||
write!(f, "{}{}", self.name, self.args.print(cache))
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl clean::Path {
|
||||
crate fn print(&self) -> impl fmt::Display + '_ {
|
||||
crate fn print<'a>(&'a self, cache: &'a Cache) -> impl fmt::Display + 'a {
|
||||
display_fn(move |f| {
|
||||
if self.global {
|
||||
f.write_str("::")?
|
||||
|
@ -467,9 +480,9 @@ impl clean::Path {
|
|||
f.write_str("::")?
|
||||
}
|
||||
if f.alternate() {
|
||||
write!(f, "{:#}", seg.print())?;
|
||||
write!(f, "{:#}", seg.print(cache))?;
|
||||
} else {
|
||||
write!(f, "{}", seg.print())?;
|
||||
write!(f, "{}", seg.print(cache))?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
@ -477,8 +490,7 @@ impl clean::Path {
|
|||
}
|
||||
}
|
||||
|
||||
crate fn href(did: DefId) -> Option<(String, ItemType, Vec<String>)> {
|
||||
let cache = cache();
|
||||
crate fn href(did: DefId, cache: &Cache) -> Option<(String, ItemType, Vec<String>)> {
|
||||
if !did.is_local() && !cache.access_levels.is_public(did) && !cache.document_private {
|
||||
return None;
|
||||
}
|
||||
|
@ -526,6 +538,7 @@ fn resolved_path(
|
|||
path: &clean::Path,
|
||||
print_all: bool,
|
||||
use_absolute: bool,
|
||||
cache: &Cache,
|
||||
) -> fmt::Result {
|
||||
let last = path.segments.last().unwrap();
|
||||
|
||||
|
@ -535,18 +548,22 @@ fn resolved_path(
|
|||
}
|
||||
}
|
||||
if w.alternate() {
|
||||
write!(w, "{}{:#}", &last.name, last.args.print())?;
|
||||
write!(w, "{}{:#}", &last.name, last.args.print(cache))?;
|
||||
} else {
|
||||
let path = if use_absolute {
|
||||
if let Some((_, _, fqp)) = href(did) {
|
||||
format!("{}::{}", fqp[..fqp.len() - 1].join("::"), anchor(did, fqp.last().unwrap()))
|
||||
if let Some((_, _, fqp)) = href(did, cache) {
|
||||
format!(
|
||||
"{}::{}",
|
||||
fqp[..fqp.len() - 1].join("::"),
|
||||
anchor(did, fqp.last().unwrap(), cache)
|
||||
)
|
||||
} else {
|
||||
last.name.to_string()
|
||||
}
|
||||
} else {
|
||||
anchor(did, &*last.name.as_str()).to_string()
|
||||
anchor(did, &*last.name.as_str(), cache).to_string()
|
||||
};
|
||||
write!(w, "{}{}", path, last.args.print())?;
|
||||
write!(w, "{}{}", path, last.args.print(cache))?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -555,8 +572,8 @@ fn primitive_link(
|
|||
f: &mut fmt::Formatter<'_>,
|
||||
prim: clean::PrimitiveType,
|
||||
name: &str,
|
||||
m: &Cache,
|
||||
) -> fmt::Result {
|
||||
let m = cache();
|
||||
let mut needs_termination = false;
|
||||
if !f.alternate() {
|
||||
match m.primitive_locations.get(&prim) {
|
||||
|
@ -602,12 +619,15 @@ fn primitive_link(
|
|||
}
|
||||
|
||||
/// Helper to render type parameters
|
||||
fn tybounds(param_names: &Option<Vec<clean::GenericBound>>) -> impl fmt::Display + '_ {
|
||||
fn tybounds<'a>(
|
||||
param_names: &'a Option<Vec<clean::GenericBound>>,
|
||||
cache: &'a Cache,
|
||||
) -> impl fmt::Display + 'a {
|
||||
display_fn(move |f| match *param_names {
|
||||
Some(ref params) => {
|
||||
for param in params {
|
||||
write!(f, " + ")?;
|
||||
fmt::Display::fmt(¶m.print(), f)?;
|
||||
fmt::Display::fmt(¶m.print(cache), f)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
@ -615,9 +635,9 @@ fn tybounds(param_names: &Option<Vec<clean::GenericBound>>) -> impl fmt::Display
|
|||
})
|
||||
}
|
||||
|
||||
crate fn anchor(did: DefId, text: &str) -> impl fmt::Display + '_ {
|
||||
crate fn anchor<'a>(did: DefId, text: &'a str, cache: &'a Cache) -> impl fmt::Display + 'a {
|
||||
display_fn(move |f| {
|
||||
if let Some((url, short_ty, fqp)) = href(did) {
|
||||
if let Some((url, short_ty, fqp)) = href(did, cache) {
|
||||
write!(
|
||||
f,
|
||||
r#"<a class="{}" href="{}" title="{} {}">{}</a>"#,
|
||||
|
@ -633,7 +653,12 @@ crate fn anchor(did: DefId, text: &str) -> impl fmt::Display + '_ {
|
|||
})
|
||||
}
|
||||
|
||||
fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) -> fmt::Result {
|
||||
fn fmt_type(
|
||||
t: &clean::Type,
|
||||
f: &mut fmt::Formatter<'_>,
|
||||
use_absolute: bool,
|
||||
cache: &Cache,
|
||||
) -> fmt::Result {
|
||||
match *t {
|
||||
clean::Generic(name) => write!(f, "{}", name),
|
||||
clean::ResolvedPath { did, ref param_names, ref path, is_generic } => {
|
||||
|
@ -641,11 +666,11 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
|
|||
f.write_str("dyn ")?;
|
||||
}
|
||||
// Paths like `T::Output` and `Self::Output` should be rendered with all segments.
|
||||
resolved_path(f, did, path, is_generic, use_absolute)?;
|
||||
fmt::Display::fmt(&tybounds(param_names), f)
|
||||
resolved_path(f, did, path, is_generic, use_absolute, cache)?;
|
||||
fmt::Display::fmt(&tybounds(param_names, cache), f)
|
||||
}
|
||||
clean::Infer => write!(f, "_"),
|
||||
clean::Primitive(prim) => primitive_link(f, prim, prim.as_str()),
|
||||
clean::Primitive(prim) => primitive_link(f, prim, prim.as_str(), cache),
|
||||
clean::BareFunction(ref decl) => {
|
||||
if f.alternate() {
|
||||
write!(
|
||||
|
@ -653,8 +678,8 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
|
|||
"{}{:#}fn{:#}{:#}",
|
||||
decl.unsafety.print_with_space(),
|
||||
print_abi_with_space(decl.abi),
|
||||
decl.print_generic_params(),
|
||||
decl.decl.print()
|
||||
decl.print_generic_params(cache),
|
||||
decl.decl.print(cache)
|
||||
)
|
||||
} else {
|
||||
write!(
|
||||
|
@ -663,46 +688,46 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
|
|||
decl.unsafety.print_with_space(),
|
||||
print_abi_with_space(decl.abi)
|
||||
)?;
|
||||
primitive_link(f, PrimitiveType::Fn, "fn")?;
|
||||
write!(f, "{}{}", decl.print_generic_params(), decl.decl.print())
|
||||
primitive_link(f, PrimitiveType::Fn, "fn", cache)?;
|
||||
write!(f, "{}{}", decl.print_generic_params(cache), decl.decl.print(cache))
|
||||
}
|
||||
}
|
||||
clean::Tuple(ref typs) => {
|
||||
match &typs[..] {
|
||||
&[] => primitive_link(f, PrimitiveType::Unit, "()"),
|
||||
&[] => primitive_link(f, PrimitiveType::Unit, "()", cache),
|
||||
&[ref one] => {
|
||||
primitive_link(f, PrimitiveType::Tuple, "(")?;
|
||||
primitive_link(f, PrimitiveType::Tuple, "(", cache)?;
|
||||
// Carry `f.alternate()` into this display w/o branching manually.
|
||||
fmt::Display::fmt(&one.print(), f)?;
|
||||
primitive_link(f, PrimitiveType::Tuple, ",)")
|
||||
fmt::Display::fmt(&one.print(cache), f)?;
|
||||
primitive_link(f, PrimitiveType::Tuple, ",)", cache)
|
||||
}
|
||||
many => {
|
||||
primitive_link(f, PrimitiveType::Tuple, "(")?;
|
||||
primitive_link(f, PrimitiveType::Tuple, "(", cache)?;
|
||||
for (i, item) in many.iter().enumerate() {
|
||||
if i != 0 {
|
||||
write!(f, ", ")?;
|
||||
}
|
||||
fmt::Display::fmt(&item.print(), f)?;
|
||||
fmt::Display::fmt(&item.print(cache), f)?;
|
||||
}
|
||||
primitive_link(f, PrimitiveType::Tuple, ")")
|
||||
primitive_link(f, PrimitiveType::Tuple, ")", cache)
|
||||
}
|
||||
}
|
||||
}
|
||||
clean::Slice(ref t) => {
|
||||
primitive_link(f, PrimitiveType::Slice, "[")?;
|
||||
fmt::Display::fmt(&t.print(), f)?;
|
||||
primitive_link(f, PrimitiveType::Slice, "]")
|
||||
primitive_link(f, PrimitiveType::Slice, "[", cache)?;
|
||||
fmt::Display::fmt(&t.print(cache), f)?;
|
||||
primitive_link(f, PrimitiveType::Slice, "]", cache)
|
||||
}
|
||||
clean::Array(ref t, ref n) => {
|
||||
primitive_link(f, PrimitiveType::Array, "[")?;
|
||||
fmt::Display::fmt(&t.print(), f)?;
|
||||
primitive_link(f, PrimitiveType::Array, "[", cache)?;
|
||||
fmt::Display::fmt(&t.print(cache), f)?;
|
||||
if f.alternate() {
|
||||
primitive_link(f, PrimitiveType::Array, &format!("; {}]", n))
|
||||
primitive_link(f, PrimitiveType::Array, &format!("; {}]", n), cache)
|
||||
} else {
|
||||
primitive_link(f, PrimitiveType::Array, &format!("; {}]", Escape(n)))
|
||||
primitive_link(f, PrimitiveType::Array, &format!("; {}]", Escape(n)), cache)
|
||||
}
|
||||
}
|
||||
clean::Never => primitive_link(f, PrimitiveType::Never, "!"),
|
||||
clean::Never => primitive_link(f, PrimitiveType::Never, "!", cache),
|
||||
clean::RawPointer(m, ref t) => {
|
||||
let m = match m {
|
||||
hir::Mutability::Mut => "mut",
|
||||
|
@ -714,19 +739,26 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
|
|||
primitive_link(
|
||||
f,
|
||||
clean::PrimitiveType::RawPointer,
|
||||
&format!("*{} {:#}", m, t.print()),
|
||||
&format!("*{} {:#}", m, t.print(cache)),
|
||||
cache,
|
||||
)
|
||||
} else {
|
||||
primitive_link(
|
||||
f,
|
||||
clean::PrimitiveType::RawPointer,
|
||||
&format!("*{} {}", m, t.print()),
|
||||
&format!("*{} {}", m, t.print(cache)),
|
||||
cache,
|
||||
)
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
primitive_link(f, clean::PrimitiveType::RawPointer, &format!("*{} ", m))?;
|
||||
fmt::Display::fmt(&t.print(), f)
|
||||
primitive_link(
|
||||
f,
|
||||
clean::PrimitiveType::RawPointer,
|
||||
&format!("*{} ", m),
|
||||
cache,
|
||||
)?;
|
||||
fmt::Display::fmt(&t.print(cache), f)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -746,13 +778,15 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
|
|||
primitive_link(
|
||||
f,
|
||||
PrimitiveType::Slice,
|
||||
&format!("{}{}{}[{:#}]", amp, lt, m, bt.print()),
|
||||
&format!("{}{}{}[{:#}]", amp, lt, m, bt.print(cache)),
|
||||
cache,
|
||||
)
|
||||
} else {
|
||||
primitive_link(
|
||||
f,
|
||||
PrimitiveType::Slice,
|
||||
&format!("{}{}{}[{}]", amp, lt, m, bt.print()),
|
||||
&format!("{}{}{}[{}]", amp, lt, m, bt.print(cache)),
|
||||
cache,
|
||||
)
|
||||
}
|
||||
}
|
||||
|
@ -761,36 +795,42 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
|
|||
f,
|
||||
PrimitiveType::Slice,
|
||||
&format!("{}{}{}[", amp, lt, m),
|
||||
cache,
|
||||
)?;
|
||||
if f.alternate() {
|
||||
write!(f, "{:#}", bt.print())?;
|
||||
write!(f, "{:#}", bt.print(cache))?;
|
||||
} else {
|
||||
write!(f, "{}", bt.print())?;
|
||||
write!(f, "{}", bt.print(cache))?;
|
||||
}
|
||||
primitive_link(f, PrimitiveType::Slice, "]")
|
||||
primitive_link(f, PrimitiveType::Slice, "]", cache)
|
||||
}
|
||||
}
|
||||
}
|
||||
clean::ResolvedPath { param_names: Some(ref v), .. } if !v.is_empty() => {
|
||||
write!(f, "{}{}{}(", amp, lt, m)?;
|
||||
fmt_type(&ty, f, use_absolute)?;
|
||||
fmt_type(&ty, f, use_absolute, cache)?;
|
||||
write!(f, ")")
|
||||
}
|
||||
clean::Generic(..) => {
|
||||
primitive_link(f, PrimitiveType::Reference, &format!("{}{}{}", amp, lt, m))?;
|
||||
fmt_type(&ty, f, use_absolute)
|
||||
primitive_link(
|
||||
f,
|
||||
PrimitiveType::Reference,
|
||||
&format!("{}{}{}", amp, lt, m),
|
||||
cache,
|
||||
)?;
|
||||
fmt_type(&ty, f, use_absolute, cache)
|
||||
}
|
||||
_ => {
|
||||
write!(f, "{}{}{}", amp, lt, m)?;
|
||||
fmt_type(&ty, f, use_absolute)
|
||||
fmt_type(&ty, f, use_absolute, cache)
|
||||
}
|
||||
}
|
||||
}
|
||||
clean::ImplTrait(ref bounds) => {
|
||||
if f.alternate() {
|
||||
write!(f, "impl {:#}", print_generic_bounds(bounds))
|
||||
write!(f, "impl {:#}", print_generic_bounds(bounds, cache))
|
||||
} else {
|
||||
write!(f, "impl {}", print_generic_bounds(bounds))
|
||||
write!(f, "impl {}", print_generic_bounds(bounds, cache))
|
||||
}
|
||||
}
|
||||
clean::QPath { ref name, ref self_type, ref trait_ } => {
|
||||
|
@ -802,15 +842,15 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
|
|||
};
|
||||
if f.alternate() {
|
||||
if should_show_cast {
|
||||
write!(f, "<{:#} as {:#}>::", self_type.print(), trait_.print())?
|
||||
write!(f, "<{:#} as {:#}>::", self_type.print(cache), trait_.print(cache))?
|
||||
} else {
|
||||
write!(f, "{:#}::", self_type.print())?
|
||||
write!(f, "{:#}::", self_type.print(cache))?
|
||||
}
|
||||
} else {
|
||||
if should_show_cast {
|
||||
write!(f, "<{} as {}>::", self_type.print(), trait_.print())?
|
||||
write!(f, "<{} as {}>::", self_type.print(cache), trait_.print(cache))?
|
||||
} else {
|
||||
write!(f, "{}::", self_type.print())?
|
||||
write!(f, "{}::", self_type.print(cache))?
|
||||
}
|
||||
};
|
||||
match *trait_ {
|
||||
|
@ -825,7 +865,7 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
|
|||
// everything comes in as a fully resolved QPath (hard to
|
||||
// look at).
|
||||
box clean::ResolvedPath { did, ref param_names, .. } => {
|
||||
match href(did) {
|
||||
match href(did, cache) {
|
||||
Some((ref url, _, ref path)) if !f.alternate() => {
|
||||
write!(
|
||||
f,
|
||||
|
@ -851,22 +891,27 @@ fn fmt_type(t: &clean::Type, f: &mut fmt::Formatter<'_>, use_absolute: bool) ->
|
|||
}
|
||||
|
||||
impl clean::Type {
|
||||
crate fn print(&self) -> impl fmt::Display + '_ {
|
||||
display_fn(move |f| fmt_type(self, f, false))
|
||||
crate fn print<'b, 'a: 'b>(&'a self, cache: &'b Cache) -> impl fmt::Display + 'b {
|
||||
display_fn(move |f| fmt_type(self, f, false, cache))
|
||||
}
|
||||
}
|
||||
|
||||
impl clean::Impl {
|
||||
crate fn print(&self) -> impl fmt::Display + '_ {
|
||||
self.print_inner(true, false)
|
||||
crate fn print<'a>(&'a self, cache: &'a Cache) -> impl fmt::Display + 'a {
|
||||
self.print_inner(true, false, cache)
|
||||
}
|
||||
|
||||
fn print_inner(&self, link_trait: bool, use_absolute: bool) -> impl fmt::Display + '_ {
|
||||
fn print_inner<'a>(
|
||||
&'a self,
|
||||
link_trait: bool,
|
||||
use_absolute: bool,
|
||||
cache: &'a Cache,
|
||||
) -> impl fmt::Display + 'a {
|
||||
display_fn(move |f| {
|
||||
if f.alternate() {
|
||||
write!(f, "impl{:#} ", self.generics.print())?;
|
||||
write!(f, "impl{:#} ", self.generics.print(cache))?;
|
||||
} else {
|
||||
write!(f, "impl{} ", self.generics.print())?;
|
||||
write!(f, "impl{} ", self.generics.print(cache))?;
|
||||
}
|
||||
|
||||
if let Some(ref ty) = self.trait_ {
|
||||
|
@ -875,7 +920,7 @@ impl clean::Impl {
|
|||
}
|
||||
|
||||
if link_trait {
|
||||
fmt::Display::fmt(&ty.print(), f)?;
|
||||
fmt::Display::fmt(&ty.print(cache), f)?;
|
||||
} else {
|
||||
match ty {
|
||||
clean::ResolvedPath {
|
||||
|
@ -883,7 +928,7 @@ impl clean::Impl {
|
|||
} => {
|
||||
let last = path.segments.last().unwrap();
|
||||
fmt::Display::fmt(&last.name, f)?;
|
||||
fmt::Display::fmt(&last.args.print(), f)?;
|
||||
fmt::Display::fmt(&last.args.print(cache), f)?;
|
||||
}
|
||||
_ => unreachable!(),
|
||||
}
|
||||
|
@ -892,36 +937,39 @@ impl clean::Impl {
|
|||
}
|
||||
|
||||
if let Some(ref ty) = self.blanket_impl {
|
||||
fmt_type(ty, f, use_absolute)?;
|
||||
fmt_type(ty, f, use_absolute, cache)?;
|
||||
} else {
|
||||
fmt_type(&self.for_, f, use_absolute)?;
|
||||
fmt_type(&self.for_, f, use_absolute, cache)?;
|
||||
}
|
||||
|
||||
fmt::Display::fmt(
|
||||
&WhereClause { gens: &self.generics, indent: 0, end_newline: true },
|
||||
f,
|
||||
)?;
|
||||
let where_clause = WhereClause { gens: &self.generics, indent: 0, end_newline: true };
|
||||
fmt::Display::fmt(&where_clause.print(cache), f)?;
|
||||
Ok(())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
// The difference from above is that trait is not hyperlinked.
|
||||
crate fn fmt_impl_for_trait_page(i: &clean::Impl, f: &mut Buffer, use_absolute: bool) {
|
||||
f.from_display(i.print_inner(false, use_absolute))
|
||||
crate fn fmt_impl_for_trait_page(
|
||||
i: &clean::Impl,
|
||||
f: &mut Buffer,
|
||||
use_absolute: bool,
|
||||
cache: &Cache,
|
||||
) {
|
||||
f.from_display(i.print_inner(false, use_absolute, cache))
|
||||
}
|
||||
|
||||
impl clean::Arguments {
|
||||
crate fn print(&self) -> impl fmt::Display + '_ {
|
||||
crate fn print<'a>(&'a self, cache: &'a Cache) -> impl fmt::Display + 'a {
|
||||
display_fn(move |f| {
|
||||
for (i, input) in self.values.iter().enumerate() {
|
||||
if !input.name.is_empty() {
|
||||
write!(f, "{}: ", input.name)?;
|
||||
}
|
||||
if f.alternate() {
|
||||
write!(f, "{:#}", input.type_.print())?;
|
||||
write!(f, "{:#}", input.type_.print(cache))?;
|
||||
} else {
|
||||
write!(f, "{}", input.type_.print())?;
|
||||
write!(f, "{}", input.type_.print(cache))?;
|
||||
}
|
||||
if i + 1 < self.values.len() {
|
||||
write!(f, ", ")?;
|
||||
|
@ -933,41 +981,41 @@ impl clean::Arguments {
|
|||
}
|
||||
|
||||
impl clean::FnRetTy {
|
||||
crate fn print(&self) -> impl fmt::Display + '_ {
|
||||
crate fn print<'a>(&'a self, cache: &'a Cache) -> impl fmt::Display + 'a {
|
||||
display_fn(move |f| match self {
|
||||
clean::Return(clean::Tuple(tys)) if tys.is_empty() => Ok(()),
|
||||
clean::Return(ty) if f.alternate() => write!(f, " -> {:#}", ty.print()),
|
||||
clean::Return(ty) => write!(f, " -> {}", ty.print()),
|
||||
clean::Return(ty) if f.alternate() => write!(f, " -> {:#}", ty.print(cache)),
|
||||
clean::Return(ty) => write!(f, " -> {}", ty.print(cache)),
|
||||
clean::DefaultReturn => Ok(()),
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
impl clean::BareFunctionDecl {
|
||||
fn print_generic_params(&self) -> impl fmt::Display + '_ {
|
||||
comma_sep(self.generic_params.iter().map(|g| g.print()))
|
||||
fn print_generic_params<'a>(&'a self, cache: &'a Cache) -> impl fmt::Display + 'a {
|
||||
comma_sep(self.generic_params.iter().map(move |g| g.print(cache)))
|
||||
}
|
||||
}
|
||||
|
||||
impl clean::FnDecl {
|
||||
crate fn print(&self) -> impl fmt::Display + '_ {
|
||||
crate fn print<'a>(&'a self, cache: &'a Cache) -> impl fmt::Display + 'a {
|
||||
display_fn(move |f| {
|
||||
let ellipsis = if self.c_variadic { ", ..." } else { "" };
|
||||
if f.alternate() {
|
||||
write!(
|
||||
f,
|
||||
"({args:#}{ellipsis}){arrow:#}",
|
||||
args = self.inputs.print(),
|
||||
args = self.inputs.print(cache),
|
||||
ellipsis = ellipsis,
|
||||
arrow = self.output.print()
|
||||
arrow = self.output.print(cache)
|
||||
)
|
||||
} else {
|
||||
write!(
|
||||
f,
|
||||
"({args}{ellipsis}){arrow}",
|
||||
args = self.inputs.print(),
|
||||
args = self.inputs.print(cache),
|
||||
ellipsis = ellipsis,
|
||||
arrow = self.output.print()
|
||||
arrow = self.output.print(cache)
|
||||
)
|
||||
}
|
||||
})
|
||||
|
@ -975,7 +1023,7 @@ impl clean::FnDecl {
|
|||
}
|
||||
|
||||
impl Function<'_> {
|
||||
crate fn print(&self) -> impl fmt::Display + '_ {
|
||||
crate fn print<'b, 'a: 'b>(&'a self, cache: &'b Cache) -> impl fmt::Display + 'b {
|
||||
display_fn(move |f| {
|
||||
let &Function { decl, header_len, indent, asyncness } = self;
|
||||
let amp = if f.alternate() { "&" } else { "&" };
|
||||
|
@ -1011,11 +1059,11 @@ impl Function<'_> {
|
|||
}
|
||||
clean::SelfExplicit(ref typ) => {
|
||||
if f.alternate() {
|
||||
args.push_str(&format!("self: {:#}", typ.print()));
|
||||
args.push_str(&format!("self: {:#}", typ.print(cache)));
|
||||
} else {
|
||||
args.push_str(&format!("self: {}", typ.print()));
|
||||
args.push_str(&format!("self: {}", typ.print(cache)));
|
||||
}
|
||||
args_plain.push_str(&format!("self: {:#}", typ.print()));
|
||||
args_plain.push_str(&format!("self: {:#}", typ.print(cache)));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
@ -1029,11 +1077,11 @@ impl Function<'_> {
|
|||
}
|
||||
|
||||
if f.alternate() {
|
||||
args.push_str(&format!("{:#}", input.type_.print()));
|
||||
args.push_str(&format!("{:#}", input.type_.print(cache)));
|
||||
} else {
|
||||
args.push_str(&input.type_.print().to_string());
|
||||
args.push_str(&input.type_.print(cache).to_string());
|
||||
}
|
||||
args_plain.push_str(&format!("{:#}", input.type_.print()));
|
||||
args_plain.push_str(&format!("{:#}", input.type_.print(cache)));
|
||||
}
|
||||
if i + 1 < decl.inputs.values.len() {
|
||||
args.push(',');
|
||||
|
@ -1054,11 +1102,11 @@ impl Function<'_> {
|
|||
Cow::Borrowed(&decl.output)
|
||||
};
|
||||
|
||||
let arrow_plain = format!("{:#}", &output.print());
|
||||
let arrow_plain = format!("{:#}", &output.print(cache));
|
||||
let arrow = if f.alternate() {
|
||||
format!("{:#}", &output.print())
|
||||
format!("{:#}", &output.print(cache))
|
||||
} else {
|
||||
output.print().to_string()
|
||||
output.print(cache).to_string()
|
||||
};
|
||||
|
||||
let declaration_len = header_len + args_plain.len() + arrow_plain.len();
|
||||
|
@ -1089,13 +1137,13 @@ impl clean::Visibility {
|
|||
self,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
item_did: DefId,
|
||||
cache: &Cache,
|
||||
) -> impl fmt::Display + 'tcx {
|
||||
use rustc_span::symbol::kw;
|
||||
|
||||
display_fn(move |f| match self {
|
||||
clean::Public => f.write_str("pub "),
|
||||
clean::Inherited => Ok(()),
|
||||
|
||||
let to_print = match self {
|
||||
clean::Public => "pub ".to_owned(),
|
||||
clean::Inherited => String::new(),
|
||||
clean::Visibility::Restricted(vis_did) => {
|
||||
// FIXME(camelid): This may not work correctly if `item_did` is a module.
|
||||
// However, rustdoc currently never displays a module's
|
||||
|
@ -1103,38 +1151,41 @@ impl clean::Visibility {
|
|||
let parent_module = find_nearest_parent_module(tcx, item_did);
|
||||
|
||||
if vis_did.index == CRATE_DEF_INDEX {
|
||||
write!(f, "pub(crate) ")
|
||||
"pub(crate) ".to_owned()
|
||||
} else if parent_module == Some(vis_did) {
|
||||
// `pub(in foo)` where `foo` is the parent module
|
||||
// is the same as no visibility modifier
|
||||
Ok(())
|
||||
String::new()
|
||||
} else if parent_module
|
||||
.map(|parent| find_nearest_parent_module(tcx, parent))
|
||||
.flatten()
|
||||
== Some(vis_did)
|
||||
{
|
||||
write!(f, "pub(super) ")
|
||||
"pub(super) ".to_owned()
|
||||
} else {
|
||||
f.write_str("pub(")?;
|
||||
let path = tcx.def_path(vis_did);
|
||||
debug!("path={:?}", path);
|
||||
let first_name =
|
||||
path.data[0].data.get_opt_name().expect("modules are always named");
|
||||
// modified from `resolved_path()` to work with `DefPathData`
|
||||
let last_name = path.data.last().unwrap().data.get_opt_name().unwrap();
|
||||
let anchor = anchor(vis_did, &last_name.as_str(), cache).to_string();
|
||||
|
||||
let mut s = "pub(".to_owned();
|
||||
if path.data.len() != 1
|
||||
|| (first_name != kw::SelfLower && first_name != kw::Super)
|
||||
{
|
||||
f.write_str("in ")?;
|
||||
s.push_str("in ");
|
||||
}
|
||||
// modified from `resolved_path()` to work with `DefPathData`
|
||||
let last_name = path.data.last().unwrap().data.get_opt_name().unwrap();
|
||||
for seg in &path.data[..path.data.len() - 1] {
|
||||
write!(f, "{}::", seg.data.get_opt_name().unwrap())?;
|
||||
s.push_str(&format!("{}::", seg.data.get_opt_name().unwrap()));
|
||||
}
|
||||
let path = anchor(vis_did, &last_name.as_str()).to_string();
|
||||
write!(f, "{}) ", path)
|
||||
s.push_str(&format!("{}) ", anchor));
|
||||
s
|
||||
}
|
||||
}
|
||||
})
|
||||
};
|
||||
display_fn(move |f| f.write_str(&to_print))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1179,20 +1230,20 @@ impl PrintWithSpace for hir::Mutability {
|
|||
}
|
||||
|
||||
impl clean::Import {
|
||||
crate fn print(&self) -> impl fmt::Display + '_ {
|
||||
crate fn print<'b, 'a: 'b>(&'a self, cache: &'b Cache) -> impl fmt::Display + 'b {
|
||||
display_fn(move |f| match self.kind {
|
||||
clean::ImportKind::Simple(name) => {
|
||||
if name == self.source.path.last() {
|
||||
write!(f, "use {};", self.source.print())
|
||||
write!(f, "use {};", self.source.print(cache))
|
||||
} else {
|
||||
write!(f, "use {} as {};", self.source.print(), name)
|
||||
write!(f, "use {} as {};", self.source.print(cache), name)
|
||||
}
|
||||
}
|
||||
clean::ImportKind::Glob => {
|
||||
if self.source.path.segments.is_empty() {
|
||||
write!(f, "use *;")
|
||||
} else {
|
||||
write!(f, "use {}::*;", self.source.print())
|
||||
write!(f, "use {}::*;", self.source.print(cache))
|
||||
}
|
||||
}
|
||||
})
|
||||
|
@ -1200,16 +1251,16 @@ impl clean::Import {
|
|||
}
|
||||
|
||||
impl clean::ImportSource {
|
||||
crate fn print(&self) -> impl fmt::Display + '_ {
|
||||
crate fn print<'b, 'a: 'b>(&'a self, cache: &'b Cache) -> impl fmt::Display + 'b {
|
||||
display_fn(move |f| match self.did {
|
||||
Some(did) => resolved_path(f, did, &self.path, true, false),
|
||||
Some(did) => resolved_path(f, did, &self.path, true, false, cache),
|
||||
_ => {
|
||||
for seg in &self.path.segments[..self.path.segments.len() - 1] {
|
||||
write!(f, "{}::", seg.name)?;
|
||||
}
|
||||
let name = self.path.last_name();
|
||||
if let hir::def::Res::PrimTy(p) = self.path.res {
|
||||
primitive_link(f, PrimitiveType::from(p), &*name)?;
|
||||
primitive_link(f, PrimitiveType::from(p), &*name, cache)?;
|
||||
} else {
|
||||
write!(f, "{}", name)?;
|
||||
}
|
||||
|
@ -1220,23 +1271,23 @@ impl clean::ImportSource {
|
|||
}
|
||||
|
||||
impl clean::TypeBinding {
|
||||
crate fn print(&self) -> impl fmt::Display + '_ {
|
||||
crate fn print<'b, 'a: 'b>(&'a self, cache: &'b Cache) -> impl fmt::Display + 'b {
|
||||
display_fn(move |f| {
|
||||
f.write_str(&*self.name.as_str())?;
|
||||
match self.kind {
|
||||
clean::TypeBindingKind::Equality { ref ty } => {
|
||||
if f.alternate() {
|
||||
write!(f, " = {:#}", ty.print())?;
|
||||
write!(f, " = {:#}", ty.print(cache))?;
|
||||
} else {
|
||||
write!(f, " = {}", ty.print())?;
|
||||
write!(f, " = {}", ty.print(cache))?;
|
||||
}
|
||||
}
|
||||
clean::TypeBindingKind::Constraint { ref bounds } => {
|
||||
if !bounds.is_empty() {
|
||||
if f.alternate() {
|
||||
write!(f, ": {:#}", print_generic_bounds(bounds))?;
|
||||
write!(f, ": {:#}", print_generic_bounds(bounds, cache))?;
|
||||
} else {
|
||||
write!(f, ": {}", print_generic_bounds(bounds))?;
|
||||
write!(f, ": {}", print_generic_bounds(bounds, cache))?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1261,10 +1312,10 @@ crate fn print_default_space<'a>(v: bool) -> &'a str {
|
|||
}
|
||||
|
||||
impl clean::GenericArg {
|
||||
crate fn print(&self) -> impl fmt::Display + '_ {
|
||||
crate fn print<'b, 'a: 'b>(&'a self, cache: &'b Cache) -> impl fmt::Display + 'b {
|
||||
display_fn(move |f| match self {
|
||||
clean::GenericArg::Lifetime(lt) => fmt::Display::fmt(<.print(), f),
|
||||
clean::GenericArg::Type(ty) => fmt::Display::fmt(&ty.print(), f),
|
||||
clean::GenericArg::Type(ty) => fmt::Display::fmt(&ty.print(cache), f),
|
||||
clean::GenericArg::Const(ct) => fmt::Display::fmt(&ct.print(), f),
|
||||
})
|
||||
}
|
||||
|
|
|
@ -67,31 +67,31 @@ crate fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
|
|||
let mut crate_items = Vec::with_capacity(cache.search_index.len());
|
||||
let mut crate_paths = vec![];
|
||||
|
||||
let Cache { ref mut search_index, ref orphan_impl_items, ref paths, ref mut aliases, .. } =
|
||||
*cache;
|
||||
|
||||
// Attach all orphan items to the type's definition if the type
|
||||
// has since been learned.
|
||||
for &(did, ref item) in orphan_impl_items {
|
||||
if let Some(&(ref fqp, _)) = paths.get(&did) {
|
||||
search_index.push(IndexItem {
|
||||
for &(did, ref item) in &cache.orphan_impl_items {
|
||||
if let Some(&(ref fqp, _)) = cache.paths.get(&did) {
|
||||
cache.search_index.push(IndexItem {
|
||||
ty: item.type_(),
|
||||
name: item.name.unwrap().to_string(),
|
||||
path: fqp[..fqp.len() - 1].join("::"),
|
||||
desc: item.doc_value().map_or_else(String::new, |s| short_markdown_summary(&s)),
|
||||
parent: Some(did),
|
||||
parent_idx: None,
|
||||
search_type: get_index_search_type(&item),
|
||||
search_type: get_index_search_type(&item, None),
|
||||
});
|
||||
for alias in item.attrs.get_doc_aliases() {
|
||||
aliases
|
||||
cache
|
||||
.aliases
|
||||
.entry(alias.to_lowercase())
|
||||
.or_insert(Vec::new())
|
||||
.push(search_index.len() - 1);
|
||||
.push(cache.search_index.len() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
let Cache { ref mut search_index, ref paths, ref mut aliases, .. } = *cache;
|
||||
|
||||
// Reduce `DefId` in paths into smaller sequential numbers,
|
||||
// and prune the paths that do not appear in the index.
|
||||
let mut lastpath = String::new();
|
||||
|
@ -164,7 +164,10 @@ crate fn build_index(krate: &clean::Crate, cache: &mut Cache) -> String {
|
|||
)
|
||||
}
|
||||
|
||||
crate fn get_index_search_type(item: &clean::Item) -> Option<IndexItemFunctionType> {
|
||||
crate fn get_index_search_type(
|
||||
item: &clean::Item,
|
||||
cache: Option<&Cache>,
|
||||
) -> Option<IndexItemFunctionType> {
|
||||
let (all_types, ret_types) = match *item.kind {
|
||||
clean::FunctionItem(ref f) => (&f.all_types, &f.ret_types),
|
||||
clean::MethodItem(ref m, _) => (&m.all_types, &m.ret_types),
|
||||
|
@ -174,12 +177,12 @@ crate fn get_index_search_type(item: &clean::Item) -> Option<IndexItemFunctionTy
|
|||
|
||||
let inputs = all_types
|
||||
.iter()
|
||||
.map(|(ty, kind)| TypeWithKind::from((get_index_type(&ty), *kind)))
|
||||
.map(|(ty, kind)| TypeWithKind::from((get_index_type(&ty, &cache), *kind)))
|
||||
.filter(|a| a.ty.name.is_some())
|
||||
.collect();
|
||||
let output = ret_types
|
||||
.iter()
|
||||
.map(|(ty, kind)| TypeWithKind::from((get_index_type(&ty), *kind)))
|
||||
.map(|(ty, kind)| TypeWithKind::from((get_index_type(&ty, &cache), *kind)))
|
||||
.filter(|a| a.ty.name.is_some())
|
||||
.collect::<Vec<_>>();
|
||||
let output = if output.is_empty() { None } else { Some(output) };
|
||||
|
@ -187,12 +190,12 @@ crate fn get_index_search_type(item: &clean::Item) -> Option<IndexItemFunctionTy
|
|||
Some(IndexItemFunctionType { inputs, output })
|
||||
}
|
||||
|
||||
fn get_index_type(clean_type: &clean::Type) -> RenderType {
|
||||
fn get_index_type(clean_type: &clean::Type, cache: &Option<&Cache>) -> RenderType {
|
||||
RenderType {
|
||||
ty: clean_type.def_id(),
|
||||
ty: cache.map_or_else(|| clean_type.def_id(), |cache| clean_type.def_id_full(cache)),
|
||||
idx: None,
|
||||
name: get_index_type_name(clean_type, true).map(|s| s.as_str().to_ascii_lowercase()),
|
||||
generics: get_generics(clean_type),
|
||||
generics: get_generics(clean_type, cache),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -216,14 +219,14 @@ fn get_index_type_name(clean_type: &clean::Type, accept_generic: bool) -> Option
|
|||
}
|
||||
}
|
||||
|
||||
fn get_generics(clean_type: &clean::Type) -> Option<Vec<Generic>> {
|
||||
fn get_generics(clean_type: &clean::Type, cache: &Option<&Cache>) -> Option<Vec<Generic>> {
|
||||
clean_type.generics().and_then(|types| {
|
||||
let r = types
|
||||
.iter()
|
||||
.filter_map(|t| {
|
||||
get_index_type_name(t, false).map(|name| Generic {
|
||||
name: name.as_str().to_ascii_lowercase(),
|
||||
defid: t.def_id(),
|
||||
defid: cache.map_or_else(|| t.def_id(), |cache| t.def_id_full(cache)),
|
||||
idx: None,
|
||||
})
|
||||
})
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -32,6 +32,7 @@ crate struct JsonRenderer<'tcx> {
|
|||
index: Rc<RefCell<FxHashMap<types::Id, types::Item>>>,
|
||||
/// The directory where the blob will be written to.
|
||||
out_path: PathBuf,
|
||||
cache: Rc<Cache>,
|
||||
}
|
||||
|
||||
impl JsonRenderer<'_> {
|
||||
|
@ -39,12 +40,8 @@ impl JsonRenderer<'_> {
|
|||
self.tcx.sess
|
||||
}
|
||||
|
||||
fn get_trait_implementors(
|
||||
&mut self,
|
||||
id: rustc_span::def_id::DefId,
|
||||
cache: &Cache,
|
||||
) -> Vec<types::Id> {
|
||||
cache
|
||||
fn get_trait_implementors(&mut self, id: rustc_span::def_id::DefId) -> Vec<types::Id> {
|
||||
Rc::clone(&self.cache)
|
||||
.implementors
|
||||
.get(&id)
|
||||
.map(|implementors| {
|
||||
|
@ -52,7 +49,7 @@ impl JsonRenderer<'_> {
|
|||
.iter()
|
||||
.map(|i| {
|
||||
let item = &i.impl_item;
|
||||
self.item(item.clone(), cache).unwrap();
|
||||
self.item(item.clone()).unwrap();
|
||||
item.def_id.into()
|
||||
})
|
||||
.collect()
|
||||
|
@ -60,8 +57,8 @@ impl JsonRenderer<'_> {
|
|||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
fn get_impls(&mut self, id: rustc_span::def_id::DefId, cache: &Cache) -> Vec<types::Id> {
|
||||
cache
|
||||
fn get_impls(&mut self, id: rustc_span::def_id::DefId) -> Vec<types::Id> {
|
||||
Rc::clone(&self.cache)
|
||||
.impls
|
||||
.get(&id)
|
||||
.map(|impls| {
|
||||
|
@ -70,7 +67,7 @@ impl JsonRenderer<'_> {
|
|||
.filter_map(|i| {
|
||||
let item = &i.impl_item;
|
||||
if item.def_id.is_local() {
|
||||
self.item(item.clone(), cache).unwrap();
|
||||
self.item(item.clone()).unwrap();
|
||||
Some(item.def_id.into())
|
||||
} else {
|
||||
None
|
||||
|
@ -81,24 +78,25 @@ impl JsonRenderer<'_> {
|
|||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
fn get_trait_items(&mut self, cache: &Cache) -> Vec<(types::Id, types::Item)> {
|
||||
cache
|
||||
fn get_trait_items(&mut self) -> Vec<(types::Id, types::Item)> {
|
||||
Rc::clone(&self.cache)
|
||||
.traits
|
||||
.iter()
|
||||
.filter_map(|(&id, trait_item)| {
|
||||
// only need to synthesize items for external traits
|
||||
if !id.is_local() {
|
||||
trait_item.items.clone().into_iter().for_each(|i| self.item(i, cache).unwrap());
|
||||
trait_item.items.clone().into_iter().for_each(|i| self.item(i).unwrap());
|
||||
Some((
|
||||
id.into(),
|
||||
types::Item {
|
||||
id: id.into(),
|
||||
crate_id: id.krate.as_u32(),
|
||||
name: cache
|
||||
name: self
|
||||
.cache
|
||||
.paths
|
||||
.get(&id)
|
||||
.unwrap_or_else(|| {
|
||||
cache
|
||||
self.cache
|
||||
.external_paths
|
||||
.get(&id)
|
||||
.expect("Trait should either be in local or external paths")
|
||||
|
@ -134,7 +132,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
|
|||
options: RenderOptions,
|
||||
_render_info: RenderInfo,
|
||||
_edition: Edition,
|
||||
_cache: &mut Cache,
|
||||
cache: Cache,
|
||||
tcx: TyCtxt<'tcx>,
|
||||
) -> Result<(Self, clean::Crate), Error> {
|
||||
debug!("Initializing json renderer");
|
||||
|
@ -143,6 +141,7 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
|
|||
tcx,
|
||||
index: Rc::new(RefCell::new(FxHashMap::default())),
|
||||
out_path: options.output,
|
||||
cache: Rc::new(cache),
|
||||
},
|
||||
krate,
|
||||
))
|
||||
|
@ -151,18 +150,18 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
|
|||
/// Inserts an item into the index. This should be used rather than directly calling insert on
|
||||
/// the hashmap because certain items (traits and types) need to have their mappings for trait
|
||||
/// implementations filled out before they're inserted.
|
||||
fn item(&mut self, item: clean::Item, cache: &Cache) -> Result<(), Error> {
|
||||
fn item(&mut self, item: clean::Item) -> Result<(), Error> {
|
||||
// Flatten items that recursively store other items
|
||||
item.kind.inner_items().for_each(|i| self.item(i.clone(), cache).unwrap());
|
||||
item.kind.inner_items().for_each(|i| self.item(i.clone()).unwrap());
|
||||
|
||||
let id = item.def_id;
|
||||
if let Some(mut new_item) = self.convert_item(item) {
|
||||
if let types::ItemEnum::TraitItem(ref mut t) = new_item.inner {
|
||||
t.implementors = self.get_trait_implementors(id, cache)
|
||||
t.implementors = self.get_trait_implementors(id)
|
||||
} else if let types::ItemEnum::StructItem(ref mut s) = new_item.inner {
|
||||
s.impls = self.get_impls(id, cache)
|
||||
s.impls = self.get_impls(id)
|
||||
} else if let types::ItemEnum::EnumItem(ref mut e) = new_item.inner {
|
||||
e.impls = self.get_impls(id, cache)
|
||||
e.impls = self.get_impls(id)
|
||||
}
|
||||
let removed = self.index.borrow_mut().insert(id.into(), new_item.clone());
|
||||
// FIXME(adotinthevoid): Currently, the index is duplicated. This is a sanity check
|
||||
|
@ -175,27 +174,20 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn mod_item_in(
|
||||
&mut self,
|
||||
item: &clean::Item,
|
||||
_module_name: &str,
|
||||
cache: &Cache,
|
||||
) -> Result<(), Error> {
|
||||
fn mod_item_in(&mut self, item: &clean::Item, _module_name: &str) -> Result<(), Error> {
|
||||
use clean::types::ItemKind::*;
|
||||
if let ModuleItem(m) = &*item.kind {
|
||||
for item in &m.items {
|
||||
match &*item.kind {
|
||||
// These don't have names so they don't get added to the output by default
|
||||
ImportItem(_) => self.item(item.clone(), cache).unwrap(),
|
||||
ExternCrateItem(_, _) => self.item(item.clone(), cache).unwrap(),
|
||||
ImplItem(i) => {
|
||||
i.items.iter().for_each(|i| self.item(i.clone(), cache).unwrap())
|
||||
}
|
||||
ImportItem(_) => self.item(item.clone()).unwrap(),
|
||||
ExternCrateItem(_, _) => self.item(item.clone()).unwrap(),
|
||||
ImplItem(i) => i.items.iter().for_each(|i| self.item(i.clone()).unwrap()),
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
self.item(item.clone(), cache).unwrap();
|
||||
self.item(item.clone()).unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
@ -206,22 +198,22 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
|
|||
fn after_krate(
|
||||
&mut self,
|
||||
krate: &clean::Crate,
|
||||
cache: &Cache,
|
||||
_diag: &rustc_errors::Handler,
|
||||
) -> Result<(), Error> {
|
||||
debug!("Done with crate");
|
||||
let mut index = (*self.index).clone().into_inner();
|
||||
index.extend(self.get_trait_items(cache));
|
||||
index.extend(self.get_trait_items());
|
||||
let output = types::Crate {
|
||||
root: types::Id(String::from("0:0")),
|
||||
crate_version: krate.version.clone(),
|
||||
includes_private: cache.document_private,
|
||||
includes_private: self.cache.document_private,
|
||||
index,
|
||||
paths: cache
|
||||
paths: self
|
||||
.cache
|
||||
.paths
|
||||
.clone()
|
||||
.into_iter()
|
||||
.chain(cache.external_paths.clone().into_iter())
|
||||
.chain(self.cache.external_paths.clone().into_iter())
|
||||
.map(|(k, (path, kind))| {
|
||||
(
|
||||
k.into(),
|
||||
|
@ -229,7 +221,8 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
|
|||
)
|
||||
})
|
||||
.collect(),
|
||||
external_crates: cache
|
||||
external_crates: self
|
||||
.cache
|
||||
.extern_locations
|
||||
.iter()
|
||||
.map(|(k, v)| {
|
||||
|
@ -254,4 +247,8 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> {
|
|||
serde_json::ser::to_writer(&file, &output).unwrap();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn cache(&self) -> &Cache {
|
||||
&self.cache
|
||||
}
|
||||
}
|
||||
|
|
|
@ -218,7 +218,12 @@ impl<'a, 'b> fold::DocFolder for CoverageCalculator<'a, 'b> {
|
|||
clean::ImplItem(ref impl_) => {
|
||||
let filename = i.source.filename(self.ctx.sess());
|
||||
if let Some(ref tr) = impl_.trait_ {
|
||||
debug!("impl {:#} for {:#} in {}", tr.print(), impl_.for_.print(), filename,);
|
||||
debug!(
|
||||
"impl {:#} for {:#} in {}",
|
||||
tr.print(&self.ctx.cache),
|
||||
impl_.for_.print(&self.ctx.cache),
|
||||
filename,
|
||||
);
|
||||
|
||||
// don't count trait impls, the missing-docs lint doesn't so we shouldn't
|
||||
// either
|
||||
|
@ -227,7 +232,7 @@ impl<'a, 'b> fold::DocFolder for CoverageCalculator<'a, 'b> {
|
|||
// inherent impls *can* be documented, and those docs show up, but in most
|
||||
// cases it doesn't make sense, as all methods on a type are in one single
|
||||
// impl block
|
||||
debug!("impl {:#} in {}", impl_.for_.print(), filename);
|
||||
debug!("impl {:#} in {}", impl_.for_.print(&self.ctx.cache), filename);
|
||||
}
|
||||
}
|
||||
_ => {
|
||||
|
|
75
src/test/rustdoc-js-std/primitive.js
Normal file
75
src/test/rustdoc-js-std/primitive.js
Normal file
|
@ -0,0 +1,75 @@
|
|||
const QUERY = [
|
||||
'i8',
|
||||
'u32',
|
||||
'str',
|
||||
'char',
|
||||
'unit',
|
||||
'tuple',
|
||||
'fn',
|
||||
];
|
||||
|
||||
const EXPECTED = [
|
||||
{
|
||||
'others': [
|
||||
{
|
||||
'path': 'std',
|
||||
'name': 'i8',
|
||||
'href': '../std/primitive.i8.html',
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
'others': [
|
||||
{
|
||||
'path': 'std',
|
||||
'name': 'u32',
|
||||
'href': '../std/primitive.u32.html',
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
'others': [
|
||||
{
|
||||
'path': 'std',
|
||||
'name': 'str',
|
||||
'href': '../std/primitive.str.html',
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
'others': [
|
||||
{
|
||||
'path': 'std',
|
||||
'name': 'char',
|
||||
'href': '../std/primitive.char.html',
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
'others': [
|
||||
{
|
||||
'path': 'std',
|
||||
'name': 'unit',
|
||||
'href': '../std/primitive.unit.html',
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
'others': [
|
||||
{
|
||||
'path': 'std',
|
||||
'name': 'tuple',
|
||||
'href': '../std/primitive.tuple.html',
|
||||
},
|
||||
]
|
||||
},
|
||||
{
|
||||
'others': [
|
||||
{
|
||||
'path': 'std',
|
||||
'name': 'fn',
|
||||
'href': '../std/primitive.fn.html',
|
||||
},
|
||||
]
|
||||
},
|
||||
];
|
Loading…
Add table
Add a link
Reference in a new issue