Skip to content

Commit c89672e

Browse files
Rollup merge of #118812 - notriddle:notriddle/assoc-name-intern, r=GuillaumeGomez
rustdoc-search: do not treat associated type names as types [Before](http://notriddle.com/rustdoc-html-demo-6/tor-before/tor_config/list_builder/trait.DirectDefaultEmptyListBuilderAccessors.html?search=DirectDefaultEmptyListBuilderAccessors%3CT%3DT%3E%20-%3E%20Vec%3CT%3E#associatedtype.T) [After](http://notriddle.com/rustdoc-html-demo-6/tor-after/tor_config/list_builder/trait.DirectDefaultEmptyListBuilderAccessors.html?search=DirectDefaultEmptyListBuilderAccessors%3CT%3DT%3E%20-%3E%20Vec%3CT%3E#associatedtype.T) [Profile](http://notriddle.com/rustdoc-html-demo-6/tor-profile/index.html) As a bit of background information: in type-based queries, a type name that does not exist gets treated as a generic type variable. This causes a counterintuitive behavior in the `tor_config` crate, which has a trait with an associated type variable called `T`. This isn't a searchable concrete type, but its name still gets stored in the typeNameIdMap, as a convenient way to intern its name. (The second commit is a mostly unrelated bugfix.)
2 parents f712d73 + 7162cb9 commit c89672e

File tree

4 files changed

+116
-14
lines changed

4 files changed

+116
-14
lines changed

Diff for: src/librustdoc/html/static/js/search.js

+21-14
Original file line numberDiff line numberDiff line change
@@ -243,7 +243,7 @@ function initSearch(rawSearchIndex) {
243243
* Map from normalized type names to integers. Used to make type search
244244
* more efficient.
245245
*
246-
* @type {Map<string, integer>}
246+
* @type {Map<string, {id: integer, assocOnly: boolean}>}
247247
*/
248248
let typeNameIdMap;
249249
const ALIASES = new Map();
@@ -270,19 +270,22 @@ function initSearch(rawSearchIndex) {
270270
* get the same ID.
271271
*
272272
* @param {string} name
273+
* @param {boolean} isAssocType - True if this is an assoc type
273274
*
274275
* @returns {integer}
275276
*/
276-
function buildTypeMapIndex(name) {
277+
function buildTypeMapIndex(name, isAssocType) {
277278
if (name === "" || name === null) {
278279
return null;
279280
}
280281

281282
if (typeNameIdMap.has(name)) {
282-
return typeNameIdMap.get(name);
283+
const obj = typeNameIdMap.get(name);
284+
obj.assocOnly = isAssocType && obj.assocOnly;
285+
return obj.id;
283286
} else {
284287
const id = typeNameIdMap.size;
285-
typeNameIdMap.set(name, id);
288+
typeNameIdMap.set(name, {id, assocOnly: isAssocType});
286289
return id;
287290
}
288291
}
@@ -1430,7 +1433,7 @@ function initSearch(rawSearchIndex) {
14301433
return true;
14311434
}
14321435
} else if (unifyFunctionTypes(
1433-
fnType.generics,
1436+
[...fnType.generics, ...Array.from(fnType.bindings.values()).flat() ],
14341437
queryElems,
14351438
whereClause,
14361439
mgens ? new Map(mgens) : null,
@@ -2129,17 +2132,20 @@ function initSearch(rawSearchIndex) {
21292132
* See `buildTypeMapIndex` for more information.
21302133
*
21312134
* @param {QueryElement} elem
2135+
* @param {boolean} isAssocType
21322136
*/
2133-
function convertNameToId(elem) {
2134-
if (typeNameIdMap.has(elem.pathLast)) {
2135-
elem.id = typeNameIdMap.get(elem.pathLast);
2137+
function convertNameToId(elem, isAssocType) {
2138+
if (typeNameIdMap.has(elem.pathLast) &&
2139+
(isAssocType || !typeNameIdMap.get(elem.pathLast).assocOnly)) {
2140+
elem.id = typeNameIdMap.get(elem.pathLast).id;
21362141
} else if (!parsedQuery.literalSearch) {
21372142
let match = null;
21382143
let matchDist = maxEditDistance + 1;
21392144
let matchName = "";
2140-
for (const [name, id] of typeNameIdMap) {
2145+
for (const [name, {id, assocOnly}] of typeNameIdMap) {
21412146
const dist = editDistance(name, elem.pathLast, maxEditDistance);
2142-
if (dist <= matchDist && dist <= maxEditDistance) {
2147+
if (dist <= matchDist && dist <= maxEditDistance &&
2148+
(isAssocType || !assocOnly)) {
21432149
if (dist === matchDist && matchName > name) {
21442150
continue;
21452151
}
@@ -2206,12 +2212,13 @@ function initSearch(rawSearchIndex) {
22062212
name,
22072213
" does not exist",
22082214
];
2215+
return [null, []];
22092216
}
22102217
for (const elem2 of constraints) {
22112218
convertNameToId(elem2);
22122219
}
22132220

2214-
return [typeNameIdMap.get(name), constraints];
2221+
return [typeNameIdMap.get(name).id, constraints];
22152222
})
22162223
);
22172224
}
@@ -2720,7 +2727,7 @@ ${item.displayPath}<span class="${type}">${name}</span>\
27202727
*
27212728
* @param {RawFunctionType} type
27222729
*/
2723-
function buildItemSearchType(type, lowercasePaths) {
2730+
function buildItemSearchType(type, lowercasePaths, isAssocType) {
27242731
const PATH_INDEX_DATA = 0;
27252732
const GENERICS_DATA = 1;
27262733
const BINDINGS_DATA = 2;
@@ -2749,7 +2756,7 @@ ${item.displayPath}<span class="${type}">${name}</span>\
27492756
//
27502757
// As a result, the key should never have generics on it.
27512758
return [
2752-
buildItemSearchType(assocType, lowercasePaths).id,
2759+
buildItemSearchType(assocType, lowercasePaths, true).id,
27532760
buildItemSearchTypeAll(constraints, lowercasePaths),
27542761
];
27552762
}));
@@ -2780,7 +2787,7 @@ ${item.displayPath}<span class="${type}">${name}</span>\
27802787
}
27812788
const item = lowercasePaths[pathIndex - 1];
27822789
return {
2783-
id: buildTypeMapIndex(item.name),
2790+
id: buildTypeMapIndex(item.name, isAssocType),
27842791
ty: item.ty,
27852792
path: item.path,
27862793
generics,

Diff for: tests/rustdoc-js/assoc-type.js

+11
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,17 @@ const EXPECTED = [
1919
{ 'path': 'assoc_type::my', 'name': 'other_fn' },
2020
],
2121
},
22+
{
23+
'query': 'something',
24+
'correction': null,
25+
'others': [
26+
{ 'path': 'assoc_type', 'name': 'Something' },
27+
],
28+
'in_args': [
29+
{ 'path': 'assoc_type', 'name': 'my_fn' },
30+
{ 'path': 'assoc_type::my', 'name': 'other_fn' },
31+
],
32+
},
2233
// if I write an explicit binding, only it shows up
2334
{
2435
'query': 'iterator<item=something> -> u32',

Diff for: tests/rustdoc-js/enum-variant-not-type.js

+70
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
const EXPECTED = [
2+
{
3+
'query': 'T -> T',
4+
'correction': null,
5+
'others': [
6+
{
7+
'path': 'enum_variant_not_type',
8+
'name': 'my_fn',
9+
},
10+
{
11+
'path': 'enum_variant_not_type::AutoCorrectConfounder',
12+
'name': 'assoc_type_acts_like_generic',
13+
},
14+
],
15+
},
16+
{
17+
'query': 'InsertUnnecessarilyLongTypeNameHere -> InsertUnnecessarilyLongTypeNameHere',
18+
'correction': null,
19+
'others': [
20+
{
21+
'path': 'enum_variant_not_type',
22+
'name': 'my_fn',
23+
},
24+
{
25+
'path': 'enum_variant_not_type::AutoCorrectConfounder',
26+
'name': 'assoc_type_acts_like_generic',
27+
},
28+
],
29+
},
30+
{
31+
'query': 'InsertUnnecessarilyLongTypeNameHere',
32+
'correction': null,
33+
'others': [
34+
{
35+
'path': 'enum_variant_not_type::AutoCorrectConfounder',
36+
'name': 'InsertUnnecessarilyLongTypeNameHere',
37+
},
38+
],
39+
},
40+
{
41+
'query': 'InsertUnnecessarilyLongTypeNameHereX',
42+
'correction': null,
43+
'others': [
44+
{
45+
'path': 'enum_variant_not_type::AutoCorrectConfounder',
46+
'name': 'InsertUnnecessarilyLongTypeNameHere',
47+
},
48+
],
49+
},
50+
{
51+
'query': 'T',
52+
'correction': null,
53+
'others': [
54+
{
55+
'path': 'enum_variant_not_type::MyTrait',
56+
'name': 'T',
57+
},
58+
],
59+
},
60+
{
61+
'query': 'T',
62+
'correction': null,
63+
'others': [
64+
{
65+
'path': 'enum_variant_not_type::MyTrait',
66+
'name': 'T',
67+
},
68+
],
69+
},
70+
];

Diff for: tests/rustdoc-js/enum-variant-not-type.rs

+14
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
pub trait MyTrait {
2+
// Reduced from `arti` crate.
3+
// https://tpo.pages.torproject.net/core/doc/rust/tor_config/list_builder/trait.DirectDefaultEmptyListBuilderAccessors.html#associatedtype.T
4+
type T;
5+
fn not_appearing(&self) -> Option<&Self::T>;
6+
}
7+
8+
pub fn my_fn<X>(t: X) -> X { t }
9+
10+
pub trait AutoCorrectConfounder {
11+
type InsertUnnecessarilyLongTypeNameHere;
12+
fn assoc_type_acts_like_generic(&self, x: &Self::InsertUnnecessarilyLongTypeNameHere)
13+
-> Option<&Self::InsertUnnecessarilyLongTypeNameHere>;
14+
}

0 commit comments

Comments
 (0)