Skip to content

Commit 8c76d2b

Browse files
Rollup merge of #154697 - lolbinarycat:rustdoc-renamed-crate, r=GuillaumeGomez
rustdoc: fix href of extern crates in search results To avoid modifying the search index, I instead overloaded an existing field that is always unused for extern crate items. fixes #148300 r? @GuillaumeGomez
2 parents 63b1743 + 8c44809 commit 8c76d2b

7 files changed

Lines changed: 67 additions & 21 deletions

File tree

src/librustdoc/html/render/search_index.rs

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use ::serde::{Deserialize, Serialize};
1313
use rustc_ast::join_path_syms;
1414
use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap};
1515
use rustc_data_structures::thin_vec::ThinVec;
16+
use rustc_hir::def_id::LOCAL_CRATE;
1617
use rustc_hir::find_attr;
1718
use rustc_middle::ty::TyCtxt;
1819
use rustc_span::def_id::DefId;
@@ -22,7 +23,7 @@ use stringdex::internals as stringdex_internals;
2223
use tracing::instrument;
2324

2425
use crate::clean::types::{Function, Generics, ItemId, Type, WherePredicate};
25-
use crate::clean::{self, utils};
26+
use crate::clean::{self, ExternalLocation, utils};
2627
use crate::config::ShouldMerge;
2728
use crate::error::Error;
2829
use crate::formats::cache::{Cache, OrphanImplItem};
@@ -616,7 +617,8 @@ impl SerializedSearchIndex {
616617
trait_parent,
617618
deprecated,
618619
unstable,
619-
associated_item_disambiguator,
620+
associated_item_disambiguator_or_extern_crate_url:
621+
associated_item_disambiguator,
620622
}| EntryData {
621623
krate: *map.get(krate).unwrap(),
622624
ty: *ty,
@@ -627,7 +629,8 @@ impl SerializedSearchIndex {
627629
trait_parent: trait_parent.and_then(|path_id| map.get(&path_id).copied()),
628630
deprecated: *deprecated,
629631
unstable: *unstable,
630-
associated_item_disambiguator: associated_item_disambiguator.clone(),
632+
associated_item_disambiguator_or_extern_crate_url:
633+
associated_item_disambiguator.clone(),
631634
},
632635
),
633636
self.descs[id].clone(),
@@ -898,7 +901,7 @@ struct EntryData {
898901
trait_parent: Option<usize>,
899902
deprecated: bool,
900903
unstable: bool,
901-
associated_item_disambiguator: Option<String>,
904+
associated_item_disambiguator_or_extern_crate_url: Option<String>,
902905
}
903906

904907
impl Serialize for EntryData {
@@ -915,7 +918,7 @@ impl Serialize for EntryData {
915918
seq.serialize_element(&self.trait_parent.map(|id| id + 1).unwrap_or(0))?;
916919
seq.serialize_element(&if self.deprecated { 1 } else { 0 })?;
917920
seq.serialize_element(&if self.unstable { 1 } else { 0 })?;
918-
if let Some(disambig) = &self.associated_item_disambiguator {
921+
if let Some(disambig) = &self.associated_item_disambiguator_or_extern_crate_url {
919922
seq.serialize_element(&disambig)?;
920923
}
921924
seq.end()
@@ -961,7 +964,8 @@ impl<'de> Deserialize<'de> for EntryData {
961964
trait_parent: Option::<i32>::from(trait_parent).map(|path| path as usize),
962965
deprecated: deprecated != 0,
963966
unstable: unstable != 0,
964-
associated_item_disambiguator,
967+
associated_item_disambiguator_or_extern_crate_url:
968+
associated_item_disambiguator,
965969
})
966970
}
967971
}
@@ -1389,7 +1393,7 @@ pub(crate) fn build_index(
13891393
trait_parent: None,
13901394
deprecated: false,
13911395
unstable: false,
1392-
associated_item_disambiguator: None,
1396+
associated_item_disambiguator_or_extern_crate_url: None,
13931397
}),
13941398
crate_doc,
13951399
None,
@@ -1528,7 +1532,8 @@ pub(crate) fn build_index(
15281532
exact_module_path,
15291533
deprecated: item.is_deprecated,
15301534
unstable: item.is_unstable,
1531-
associated_item_disambiguator: if let Some(impl_id) = item.impl_id
1535+
associated_item_disambiguator_or_extern_crate_url: if let Some(impl_id) =
1536+
item.impl_id
15321537
&& let Some(parent_idx) = item.parent_idx
15331538
&& associated_item_duplicates
15341539
.get(&(parent_idx, item.ty, item.name))
@@ -1537,6 +1542,14 @@ pub(crate) fn build_index(
15371542
> 1
15381543
{
15391544
Some(render::get_id_for_impl(tcx, ItemId::DefId(impl_id)))
1545+
} else if item.ty == ItemType::ExternCrate
1546+
&& let Some(local_def_id) = item.defid.and_then(|def_id| def_id.as_local())
1547+
&& let cnum = tcx.extern_mod_stmt_cnum(local_def_id).unwrap_or(LOCAL_CRATE)
1548+
&& let Some(ExternalLocation::Remote { url, is_absolute }) =
1549+
cache.extern_locations.get(&cnum)
1550+
&& *is_absolute
1551+
{
1552+
Some(format!("{}{}", url, tcx.crate_name(cnum).as_str()))
15401553
} else {
15411554
None
15421555
},

src/librustdoc/html/static/js/rustdoc.d.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ declare namespace rustdoc {
244244
traitParent: number?,
245245
deprecated: boolean,
246246
unstable: boolean,
247-
associatedItemDisambiguator: string?,
247+
associatedItemDisambiguatorOrExternCrateUrl: string?,
248248
}
249249

250250
/**

src/librustdoc/html/static/js/search.js

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1657,7 +1657,7 @@ class DocSearch {
16571657
traitParent: raw[5] === 0 ? null : raw[5] - 1,
16581658
deprecated: raw[6] === 1 ? true : false,
16591659
unstable: raw[7] === 1 ? true : false,
1660-
associatedItemDisambiguator: raw.length === 8 ? null : raw[8],
1660+
associatedItemDisambiguatorOrExternCrateUrl: raw.length === 8 ? null : raw[8],
16611661
};
16621662
}
16631663

@@ -2176,7 +2176,12 @@ class DocSearch {
21762176
"/" + type + "." + name + ".html";
21772177
} else if (type === "externcrate") {
21782178
displayPath = "";
2179-
href = this.rootPath + name + "/index.html";
2179+
let base = this.rootPath + name;
2180+
if (item.entry && item.entry.associatedItemDisambiguatorOrExternCrateUrl) {
2181+
base = item.entry.associatedItemDisambiguatorOrExternCrateUrl;
2182+
}
2183+
2184+
href = base + "/index.html";
21802185
} else if (item.parent) {
21812186
const myparent = item.parent;
21822187
let anchor = type + "." + name;
@@ -2201,8 +2206,8 @@ class DocSearch {
22012206
} else {
22022207
displayPath = path + "::" + myparent.name + "::";
22032208
}
2204-
if (item.entry && item.entry.associatedItemDisambiguator !== null) {
2205-
anchor = item.entry.associatedItemDisambiguator + "/" + anchor;
2209+
if (item.entry && item.entry.associatedItemDisambiguatorOrExternCrateUrl !== null) {
2210+
anchor = item.entry.associatedItemDisambiguatorOrExternCrateUrl + "/" + anchor;
22062211
}
22072212
href = this.rootPath + path.replace(/::/g, "/") +
22082213
"/" + pageType +

src/tools/rustdoc-js/tester.js

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ const fs = require("fs");
44
const path = require("path");
55
const { isGeneratorObject } = require("util/types");
66

7+
const CHANNEL_REGEX = new RegExp("/nightly/|/beta/|/stable/|/1\\.[0-9]+\\.[0-9]+/");
8+
79
function arrayToCode(array) {
810
return array.map((value, index) => {
911
value = value.split("&nbsp;").join(" ");
@@ -56,6 +58,8 @@ function valueMapper(key, testOutput) {
5658
value = testOutput["parent"]["name"];
5759
}
5860
}
61+
} else if (key === "href") {
62+
value = value.replace(CHANNEL_REGEX, "/$CHANNEL/");
5963
}
6064
return value;
6165
}
@@ -69,13 +73,14 @@ function betterLookingDiff(expected, testOutput) {
6973
if (!Object.prototype.hasOwnProperty.call(expected, key)) {
7074
continue;
7175
}
76+
const expectedValue = expected[key];
7277
if (!testOutput || !Object.prototype.hasOwnProperty.call(testOutput, key)) {
73-
output += "-" + spaces + contentToDiffLine(key, expected[key]) + "\n";
78+
output += "-" + spaces + contentToDiffLine(key, expectedValue) + "\n";
7479
continue;
7580
}
7681
const value = valueMapper(key, testOutput);
77-
if (value !== expected[key]) {
78-
output += "-" + spaces + contentToDiffLine(key, expected[key]) + "\n";
82+
if (value !== expectedValue) {
83+
output += "-" + spaces + contentToDiffLine(key, expectedValue) + "\n";
7984
output += "+" + spaces + contentToDiffLine(key, value) + "\n";
8085
} else {
8186
output += spaces + " " + contentToDiffLine(key, value) + "\n";
@@ -92,7 +97,11 @@ function lookForEntry(expected, testOutput) {
9297
continue;
9398
}
9499
const value = valueMapper(key, testOutputEntry);
95-
if (value !== expected[key]) {
100+
let expectedValue = expected[key];
101+
if (key === "href") {
102+
expectedValue = expectedValue.replace(CHANNEL_REGEX, "/$CHANNEL/");
103+
}
104+
if (value !== expectedValue) {
96105
allGood = false;
97106
break;
98107
}

tests/rustdoc-js/import-filter.js

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,21 @@ const EXPECTED = [
66
'query': 'import:st',
77
'others': [
88
{ 'path': 'foo', 'name': 'st', 'href': '../foo/index.html#reexport.st' },
9-
// FIXME: `href` is wrong: <https://github.com/rust-lang/rust/issues/148300>
10-
{ 'path': 'foo', 'name': 'st2', 'href': '../st2/index.html' },
9+
{
10+
'path': 'foo',
11+
'name': 'st2',
12+
'href': 'https://doc.rust-lang.org/$CHANNEL/std/index.html'
13+
},
1114
],
1215
},
1316
{
1417
'query': 'externcrate:st',
1518
'others': [
16-
// FIXME: `href` is wrong: <https://github.com/rust-lang/rust/issues/148300>
17-
{ 'path': 'foo', 'name': 'st2', 'href': '../st2/index.html' },
19+
{
20+
'path': 'foo',
21+
'name': 'st2',
22+
'href': 'https://doc.rust-lang.org/$CHANNEL/std/index.html'
23+
},
1824
],
1925
},
2026
];
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
// Regression test for <https://github.com/rust-lang/rust/issues/148300>
2+
//
3+
// This ensures that extern crates in search results link to the correct url.
4+
5+
const EXPECTED = [
6+
{
7+
query: 'st2',
8+
others: [
9+
{ name: 'st2', href: 'https://doc.rust-lang.org/$CHANNEL/std/index.html' }
10+
],
11+
},
12+
];
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
pub extern crate std as st2;

0 commit comments

Comments
 (0)