From 2cc263988ec6920d0f1182d6667251cac0061855 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Timoth=C3=A9e=20Delabrouille?= Date: Thu, 29 Apr 2021 19:14:29 +0200 Subject: [PATCH] only store locations in extern_locations --- src/librustdoc/clean/types.rs | 35 ++++++++++++++------------- src/librustdoc/formats/cache.rs | 10 +++----- src/librustdoc/html/format.rs | 20 ++++++++------- src/librustdoc/html/render/context.rs | 14 +++++++---- src/librustdoc/json/mod.rs | 11 +++++---- 5 files changed, 47 insertions(+), 43 deletions(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index ceacb4a4f81bc..c6c429a3510e8 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -106,38 +106,39 @@ impl ExternalCrate { crate fn location( &self, extern_url: Option<&str>, - ast_attrs: &[ast::Attribute], dst: &std::path::Path, tcx: TyCtxt<'_>, ) -> ExternalLocation { use ExternalLocation::*; + + fn to_remote(url: impl ToString) -> ExternalLocation { + let mut url = url.to_string(); + if !url.ends_with('/') { + url.push('/'); + } + Remote(url) + } + // See if there's documentation generated into the local directory + // WARNING: since rustdoc creates these directories as it generates documentation, this check is only accurate before rendering starts. + // Make sure to call `location()` by that time. let local_location = dst.join(&*self.name(tcx).as_str()); if local_location.is_dir() { return Local; } if let Some(url) = extern_url { - let mut url = url.to_string(); - if !url.ends_with('/') { - url.push('/'); - } - return Remote(url); + return to_remote(url); } // Failing that, see if there's an attribute specifying where to find this // external crate - ast_attrs + let did = DefId { krate: self.crate_num, index: CRATE_DEF_INDEX }; + tcx.get_attrs(did) .lists(sym::doc) .filter(|a| a.has_name(sym::html_root_url)) .filter_map(|a| a.value_str()) - .map(|url| { - let mut url = url.to_string(); - if !url.ends_with('/') { - url.push('/') - } - Remote(url) - }) + .map(to_remote) .next() .unwrap_or(Unknown) // Well, at least we tried. } @@ -433,7 +434,7 @@ impl Item { let relative_to = &cx.current; if let Some(ref fragment) = *fragment { let url = match cx.cache().extern_locations.get(&self.def_id.krate) { - Some(&(_, _, ExternalLocation::Local)) => { + Some(ExternalLocation::Local) => { if relative_to[0] == "std" { let depth = relative_to.len() - 1; "../".repeat(depth) @@ -442,10 +443,10 @@ impl Item { format!("{}std/", "../".repeat(depth)) } } - Some(&(_, _, ExternalLocation::Remote(ref s))) => { + Some(ExternalLocation::Remote(ref s)) => { format!("{}/std/", s.trim_end_matches('/')) } - Some(&(_, _, ExternalLocation::Unknown)) | None => format!( + Some(ExternalLocation::Unknown) | None => format!( "https://doc.rust-lang.org/{}/std/", crate::doc_rust_lang_org_channel(), ), diff --git a/src/librustdoc/formats/cache.rs b/src/librustdoc/formats/cache.rs index 64deee96a3564..8723e47586ee4 100644 --- a/src/librustdoc/formats/cache.rs +++ b/src/librustdoc/formats/cache.rs @@ -1,13 +1,12 @@ use std::collections::BTreeMap; use std::mem; -use std::path::{Path, PathBuf}; +use std::path::Path; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_hir::def_id::{CrateNum, DefId, CRATE_DEF_INDEX}; use rustc_middle::middle::privacy::AccessLevels; use rustc_middle::ty::TyCtxt; use rustc_span::symbol::sym; -use rustc_span::Symbol; use crate::clean::{self, GetDefId}; use crate::fold::DocFolder; @@ -71,7 +70,7 @@ crate struct Cache { crate implementors: FxHashMap>, /// Cache of where external crate documentation can be found. - crate extern_locations: FxHashMap, + crate extern_locations: FxHashMap, /// Cache of where documentation for primitives can be found. crate primitive_locations: FxHashMap, @@ -157,10 +156,7 @@ impl Cache { let name = e.name(tcx); let extern_url = extern_html_root_urls.get(&*name.as_str()).map(|u| &**u); let did = DefId { krate: n, index: CRATE_DEF_INDEX }; - self.extern_locations.insert( - n, - (name, e.src_root(tcx), e.location(extern_url, tcx.get_attrs(did), &dst, tcx)), - ); + self.extern_locations.insert(n, e.location(extern_url, &dst, tcx)); self.external_paths.insert(did, (vec![name.to_string()], ItemType::Module)); } diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index e39652c6dd5de..6f372952095c5 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -16,7 +16,7 @@ use rustc_middle::ty::TyCtxt; 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::clean::{self, utils::find_nearest_parent_module, ExternalCrate, PrimitiveType}; use crate::formats::item_type::ItemType; use crate::html::escape::Escape; use crate::html::render::cache::ExternalLocation; @@ -461,14 +461,14 @@ crate fn href(did: DefId, cx: &Context<'_>) -> Option<(String, ItemType, Vec { + ExternalLocation::Remote(ref s) => { let s = s.trim_end_matches('/'); let mut s = vec![&s[..]]; s.extend(module_fqp[..].iter().map(String::as_str)); s } - (.., ExternalLocation::Local) => href_relative_parts(module_fqp, relative_to), - (.., ExternalLocation::Unknown) => return None, + ExternalLocation::Local => href_relative_parts(module_fqp, relative_to), + ExternalLocation::Unknown => return None, }, ) } @@ -574,12 +574,14 @@ fn primitive_link( Some(&def_id) => { let cname_str; let loc = match m.extern_locations[&def_id.krate] { - (ref cname, _, ExternalLocation::Remote(ref s)) => { - cname_str = cname.as_str(); + ExternalLocation::Remote(ref s) => { + cname_str = + ExternalCrate { crate_num: def_id.krate }.name(cx.tcx()).as_str(); Some(vec![s.trim_end_matches('/'), &cname_str[..]]) } - (ref cname, _, ExternalLocation::Local) => { - cname_str = cname.as_str(); + ExternalLocation::Local => { + cname_str = + ExternalCrate { crate_num: def_id.krate }.name(cx.tcx()).as_str(); Some(if cx.current.first().map(|x| &x[..]) == Some(&cname_str[..]) { iter::repeat("..").take(cx.current.len() - 1).collect() } else { @@ -587,7 +589,7 @@ fn primitive_link( iter::repeat("..").take(cx.current.len()).chain(cname).collect() }) } - (.., ExternalLocation::Unknown) => None, + ExternalLocation::Unknown => None, }; if let Some(loc) = loc { write!( diff --git a/src/librustdoc/html/render/context.rs b/src/librustdoc/html/render/context.rs index 4c8ba0e7b496e..293c0a40fa799 100644 --- a/src/librustdoc/html/render/context.rs +++ b/src/librustdoc/html/render/context.rs @@ -18,7 +18,7 @@ use super::print_item::{full_path, item_path, print_item}; use super::write_shared::write_shared; use super::{print_sidebar, settings, AllTypes, NameDoc, StylePath, BASIC_KEYWORDS}; -use crate::clean; +use crate::clean::{self, ExternalCrate}; use crate::config::RenderOptions; use crate::docfs::{DocFS, PathError}; use crate::error::Error; @@ -304,12 +304,16 @@ impl<'tcx> Context<'tcx> { } } else { let (krate, src_root) = match *self.cache.extern_locations.get(&cnum)? { - (name, ref src, ExternalLocation::Local) => (name, src), - (name, ref src, ExternalLocation::Remote(ref s)) => { + ExternalLocation::Local => { + let e = ExternalCrate { crate_num: cnum }; + (e.name(self.tcx()), e.src_root(self.tcx())) + } + ExternalLocation::Remote(ref s) => { root = s.to_string(); - (name, src) + let e = ExternalCrate { crate_num: cnum }; + (e.name(self.tcx()), e.src_root(self.tcx())) } - (_, _, ExternalLocation::Unknown) => return None, + ExternalLocation::Unknown => return None, }; sources::clean_path(&src_root, file, false, |component| { diff --git a/src/librustdoc/json/mod.rs b/src/librustdoc/json/mod.rs index 96ea4b6c3b8c1..ae4d1be3ec2b8 100644 --- a/src/librustdoc/json/mod.rs +++ b/src/librustdoc/json/mod.rs @@ -17,7 +17,7 @@ use rustc_session::Session; use rustdoc_json_types as types; -use crate::clean; +use crate::clean::{self, ExternalCrate}; use crate::config::RenderOptions; use crate::error::Error; use crate::formats::cache::Cache; @@ -218,12 +218,13 @@ impl<'tcx> FormatRenderer<'tcx> for JsonRenderer<'tcx> { .cache .extern_locations .iter() - .map(|(k, v)| { + .map(|(crate_num, external_location)| { + let e = ExternalCrate { crate_num: *crate_num }; ( - k.as_u32(), + crate_num.as_u32(), types::ExternalCrate { - name: v.0.to_string(), - html_root_url: match &v.2 { + name: e.name(self.tcx).to_string(), + html_root_url: match external_location { ExternalLocation::Remote(s) => Some(s.clone()), _ => None, },