mirror of https://github.com/rust-lang/rust.git
rustdoc-search: do not treat associated type names as types
Before: http://notriddle.com/rustdoc-html-demo-6/tor-before/tor_config/ After: http://notriddle.com/rustdoc-html-demo-6/tor-after/tor_config/ Profile: http://notriddle.com/rustdoc-html-demo-6/tor-profile/ 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.
This commit is contained in:
parent
ec4176167b
commit
92b84f849a
|
@ -243,7 +243,7 @@ function initSearch(rawSearchIndex) {
|
||||||
* Map from normalized type names to integers. Used to make type search
|
* Map from normalized type names to integers. Used to make type search
|
||||||
* more efficient.
|
* more efficient.
|
||||||
*
|
*
|
||||||
* @type {Map<string, integer>}
|
* @type {Map<string, {id: integer, assocOnly: boolean}>}
|
||||||
*/
|
*/
|
||||||
let typeNameIdMap;
|
let typeNameIdMap;
|
||||||
const ALIASES = new Map();
|
const ALIASES = new Map();
|
||||||
|
@ -270,19 +270,22 @@ function initSearch(rawSearchIndex) {
|
||||||
* get the same ID.
|
* get the same ID.
|
||||||
*
|
*
|
||||||
* @param {string} name
|
* @param {string} name
|
||||||
|
* @param {boolean} isAssocType - True if this is an assoc type
|
||||||
*
|
*
|
||||||
* @returns {integer}
|
* @returns {integer}
|
||||||
*/
|
*/
|
||||||
function buildTypeMapIndex(name) {
|
function buildTypeMapIndex(name, isAssocType) {
|
||||||
if (name === "" || name === null) {
|
if (name === "" || name === null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (typeNameIdMap.has(name)) {
|
if (typeNameIdMap.has(name)) {
|
||||||
return typeNameIdMap.get(name);
|
const obj = typeNameIdMap.get(name);
|
||||||
|
obj.assocOnly = isAssocType && obj.assocOnly;
|
||||||
|
return obj.id;
|
||||||
} else {
|
} else {
|
||||||
const id = typeNameIdMap.size;
|
const id = typeNameIdMap.size;
|
||||||
typeNameIdMap.set(name, id);
|
typeNameIdMap.set(name, {id, assocOnly: isAssocType});
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2129,17 +2132,20 @@ function initSearch(rawSearchIndex) {
|
||||||
* See `buildTypeMapIndex` for more information.
|
* See `buildTypeMapIndex` for more information.
|
||||||
*
|
*
|
||||||
* @param {QueryElement} elem
|
* @param {QueryElement} elem
|
||||||
|
* @param {boolean} isAssocType
|
||||||
*/
|
*/
|
||||||
function convertNameToId(elem) {
|
function convertNameToId(elem, isAssocType) {
|
||||||
if (typeNameIdMap.has(elem.pathLast)) {
|
if (typeNameIdMap.has(elem.pathLast) &&
|
||||||
elem.id = typeNameIdMap.get(elem.pathLast);
|
(isAssocType || !typeNameIdMap.get(elem.pathLast).assocOnly)) {
|
||||||
|
elem.id = typeNameIdMap.get(elem.pathLast).id;
|
||||||
} else if (!parsedQuery.literalSearch) {
|
} else if (!parsedQuery.literalSearch) {
|
||||||
let match = null;
|
let match = null;
|
||||||
let matchDist = maxEditDistance + 1;
|
let matchDist = maxEditDistance + 1;
|
||||||
let matchName = "";
|
let matchName = "";
|
||||||
for (const [name, id] of typeNameIdMap) {
|
for (const [name, {id, assocOnly}] of typeNameIdMap) {
|
||||||
const dist = editDistance(name, elem.pathLast, maxEditDistance);
|
const dist = editDistance(name, elem.pathLast, maxEditDistance);
|
||||||
if (dist <= matchDist && dist <= maxEditDistance) {
|
if (dist <= matchDist && dist <= maxEditDistance &&
|
||||||
|
(isAssocType || !assocOnly)) {
|
||||||
if (dist === matchDist && matchName > name) {
|
if (dist === matchDist && matchName > name) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -2206,12 +2212,13 @@ function initSearch(rawSearchIndex) {
|
||||||
name,
|
name,
|
||||||
" does not exist",
|
" does not exist",
|
||||||
];
|
];
|
||||||
|
return [null, []];
|
||||||
}
|
}
|
||||||
for (const elem2 of constraints) {
|
for (const elem2 of constraints) {
|
||||||
convertNameToId(elem2);
|
convertNameToId(elem2);
|
||||||
}
|
}
|
||||||
|
|
||||||
return [typeNameIdMap.get(name), constraints];
|
return [typeNameIdMap.get(name).id, constraints];
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -2720,7 +2727,7 @@ ${item.displayPath}<span class="${type}">${name}</span>\
|
||||||
*
|
*
|
||||||
* @param {RawFunctionType} type
|
* @param {RawFunctionType} type
|
||||||
*/
|
*/
|
||||||
function buildItemSearchType(type, lowercasePaths) {
|
function buildItemSearchType(type, lowercasePaths, isAssocType) {
|
||||||
const PATH_INDEX_DATA = 0;
|
const PATH_INDEX_DATA = 0;
|
||||||
const GENERICS_DATA = 1;
|
const GENERICS_DATA = 1;
|
||||||
const BINDINGS_DATA = 2;
|
const BINDINGS_DATA = 2;
|
||||||
|
@ -2749,7 +2756,7 @@ ${item.displayPath}<span class="${type}">${name}</span>\
|
||||||
//
|
//
|
||||||
// As a result, the key should never have generics on it.
|
// As a result, the key should never have generics on it.
|
||||||
return [
|
return [
|
||||||
buildItemSearchType(assocType, lowercasePaths).id,
|
buildItemSearchType(assocType, lowercasePaths, true).id,
|
||||||
buildItemSearchTypeAll(constraints, lowercasePaths),
|
buildItemSearchTypeAll(constraints, lowercasePaths),
|
||||||
];
|
];
|
||||||
}));
|
}));
|
||||||
|
@ -2780,7 +2787,7 @@ ${item.displayPath}<span class="${type}">${name}</span>\
|
||||||
}
|
}
|
||||||
const item = lowercasePaths[pathIndex - 1];
|
const item = lowercasePaths[pathIndex - 1];
|
||||||
return {
|
return {
|
||||||
id: buildTypeMapIndex(item.name),
|
id: buildTypeMapIndex(item.name, isAssocType),
|
||||||
ty: item.ty,
|
ty: item.ty,
|
||||||
path: item.path,
|
path: item.path,
|
||||||
generics,
|
generics,
|
||||||
|
|
|
@ -0,0 +1,70 @@
|
||||||
|
const EXPECTED = [
|
||||||
|
{
|
||||||
|
'query': 'T -> T',
|
||||||
|
'correction': null,
|
||||||
|
'others': [
|
||||||
|
{
|
||||||
|
'path': 'enum_variant_not_type',
|
||||||
|
'name': 'my_fn',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'path': 'enum_variant_not_type::AutoCorrectConfounder',
|
||||||
|
'name': 'assoc_type_acts_like_generic',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'query': 'InsertUnnecessarilyLongTypeNameHere -> InsertUnnecessarilyLongTypeNameHere',
|
||||||
|
'correction': null,
|
||||||
|
'others': [
|
||||||
|
{
|
||||||
|
'path': 'enum_variant_not_type',
|
||||||
|
'name': 'my_fn',
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'path': 'enum_variant_not_type::AutoCorrectConfounder',
|
||||||
|
'name': 'assoc_type_acts_like_generic',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'query': 'InsertUnnecessarilyLongTypeNameHere',
|
||||||
|
'correction': null,
|
||||||
|
'others': [
|
||||||
|
{
|
||||||
|
'path': 'enum_variant_not_type::AutoCorrectConfounder',
|
||||||
|
'name': 'InsertUnnecessarilyLongTypeNameHere',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'query': 'InsertUnnecessarilyLongTypeNameHereX',
|
||||||
|
'correction': null,
|
||||||
|
'others': [
|
||||||
|
{
|
||||||
|
'path': 'enum_variant_not_type::AutoCorrectConfounder',
|
||||||
|
'name': 'InsertUnnecessarilyLongTypeNameHere',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'query': 'T',
|
||||||
|
'correction': null,
|
||||||
|
'others': [
|
||||||
|
{
|
||||||
|
'path': 'enum_variant_not_type::MyTrait',
|
||||||
|
'name': 'T',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
{
|
||||||
|
'query': 'T',
|
||||||
|
'correction': null,
|
||||||
|
'others': [
|
||||||
|
{
|
||||||
|
'path': 'enum_variant_not_type::MyTrait',
|
||||||
|
'name': 'T',
|
||||||
|
},
|
||||||
|
],
|
||||||
|
},
|
||||||
|
];
|
|
@ -0,0 +1,14 @@
|
||||||
|
pub trait MyTrait {
|
||||||
|
// Reduced from `arti` crate.
|
||||||
|
// https://tpo.pages.torproject.net/core/doc/rust/tor_config/list_builder/trait.DirectDefaultEmptyListBuilderAccessors.html#associatedtype.T
|
||||||
|
type T;
|
||||||
|
fn not_appearing(&self) -> Option<&Self::T>;
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn my_fn<X>(t: X) -> X { t }
|
||||||
|
|
||||||
|
pub trait AutoCorrectConfounder {
|
||||||
|
type InsertUnnecessarilyLongTypeNameHere;
|
||||||
|
fn assoc_type_acts_like_generic(&self, x: &Self::InsertUnnecessarilyLongTypeNameHere)
|
||||||
|
-> Option<&Self::InsertUnnecessarilyLongTypeNameHere>;
|
||||||
|
}
|
Loading…
Reference in New Issue