mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-23 23:34:48 +00:00
Rollup merge of #118251 - notriddle:notriddle/less-recursion, r=GuillaumeGomez
rustdoc-search: avoid infinite where clause unbox Fixes #118242
This commit is contained in:
commit
0304aac0f3
@ -1755,17 +1755,26 @@ function initSearch(rawSearchIndex) {
|
||||
if (mgens && mgens.has(fnType.id) && mgens.get(fnType.id) !== 0) {
|
||||
return false;
|
||||
}
|
||||
// Where clauses can represent cyclical data.
|
||||
// `null` prevents it from trying to unbox in an infinite loop
|
||||
const mgensTmp = new Map(mgens);
|
||||
mgensTmp.set(fnType.id, null);
|
||||
// This is only a potential unbox if the search query appears in the where clause
|
||||
// for example, searching `Read -> usize` should find
|
||||
// `fn read_all<R: Read>(R) -> Result<usize>`
|
||||
// generic `R` is considered "unboxed"
|
||||
return checkIfInList(whereClause[(-fnType.id) - 1], queryElem, whereClause);
|
||||
return checkIfInList(
|
||||
whereClause[(-fnType.id) - 1],
|
||||
queryElem,
|
||||
whereClause,
|
||||
mgensTmp
|
||||
);
|
||||
} else if (fnType.generics.length > 0 || fnType.bindings.size > 0) {
|
||||
const simplifiedGenerics = [
|
||||
...fnType.generics,
|
||||
...Array.from(fnType.bindings.values()).flat(),
|
||||
];
|
||||
return checkIfInList(simplifiedGenerics, queryElem, whereClause);
|
||||
return checkIfInList(simplifiedGenerics, queryElem, whereClause, mgens);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
@ -1777,12 +1786,13 @@ function initSearch(rawSearchIndex) {
|
||||
* @param {Array<FunctionType>} list
|
||||
* @param {QueryElement} elem - The element from the parsed query.
|
||||
* @param {[FunctionType]} whereClause - Trait bounds for generic items.
|
||||
* @param {Map<number,number>|null} mgens - Map functions generics to query generics.
|
||||
*
|
||||
* @return {boolean} - Returns true if found, false otherwise.
|
||||
*/
|
||||
function checkIfInList(list, elem, whereClause) {
|
||||
function checkIfInList(list, elem, whereClause, mgens) {
|
||||
for (const entry of list) {
|
||||
if (checkType(entry, elem, whereClause)) {
|
||||
if (checkType(entry, elem, whereClause, mgens)) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -1796,23 +1806,29 @@ function initSearch(rawSearchIndex) {
|
||||
* @param {Row} row
|
||||
* @param {QueryElement} elem - The element from the parsed query.
|
||||
* @param {[FunctionType]} whereClause - Trait bounds for generic items.
|
||||
* @param {Map<number,number>|null} mgens - Map functions generics to query generics.
|
||||
*
|
||||
* @return {boolean} - Returns true if the type matches, false otherwise.
|
||||
*/
|
||||
function checkType(row, elem, whereClause) {
|
||||
function checkType(row, elem, whereClause, mgens) {
|
||||
if (row.bindings.size === 0 && elem.bindings.size === 0) {
|
||||
if (elem.id < 0) {
|
||||
return row.id < 0 || checkIfInList(row.generics, elem, whereClause);
|
||||
return row.id < 0 || checkIfInList(row.generics, elem, whereClause, mgens);
|
||||
}
|
||||
if (row.id > 0 && elem.id > 0 && elem.pathWithoutLast.length === 0 &&
|
||||
typePassesFilter(elem.typeFilter, row.ty) && elem.generics.length === 0 &&
|
||||
// special case
|
||||
elem.id !== typeNameIdOfArrayOrSlice
|
||||
) {
|
||||
return row.id === elem.id || checkIfInList(row.generics, elem, whereClause);
|
||||
return row.id === elem.id || checkIfInList(
|
||||
row.generics,
|
||||
elem,
|
||||
whereClause,
|
||||
mgens
|
||||
);
|
||||
}
|
||||
}
|
||||
return unifyFunctionTypes([row], [elem], whereClause);
|
||||
return unifyFunctionTypes([row], [elem], whereClause, mgens);
|
||||
}
|
||||
|
||||
function checkPath(contains, ty, maxEditDistance) {
|
||||
|
9
tests/rustdoc-js/assoc-type-loop.js
Normal file
9
tests/rustdoc-js/assoc-type-loop.js
Normal file
@ -0,0 +1,9 @@
|
||||
// Crash reduction of
|
||||
// https://github.com/rust-lang/rust/issues/118242
|
||||
|
||||
const EXPECTED = [
|
||||
{
|
||||
'query': 't',
|
||||
'correction': null,
|
||||
},
|
||||
];
|
35
tests/rustdoc-js/assoc-type-loop.rs
Normal file
35
tests/rustdoc-js/assoc-type-loop.rs
Normal file
@ -0,0 +1,35 @@
|
||||
#![crate_name="foo"]
|
||||
|
||||
// reduced from sqlx 0.7.3
|
||||
use std::future::Future;
|
||||
use std::pin::Pin;
|
||||
use std::ops::{Deref, DerefMut};
|
||||
pub enum Error {}
|
||||
pub trait Acquire<'c> {
|
||||
type Database: Database;
|
||||
type Connection: Deref<Target = <Self::Database as Database>::Connection> + DerefMut + Send;
|
||||
}
|
||||
pub trait Database {
|
||||
type Connection: Connection<Database = Self>;
|
||||
}
|
||||
pub trait Connection {
|
||||
type Database: Database;
|
||||
type Options: ConnectionOptions<Connection = Self>;
|
||||
fn begin(
|
||||
&mut self
|
||||
) -> Pin<Box<dyn Future<Output = Result<Transaction<'_, Self::Database>, Error>> + Send + '_>>
|
||||
where
|
||||
Self: Sized;
|
||||
}
|
||||
pub trait ConnectionOptions {
|
||||
type Connection: Connection;
|
||||
}
|
||||
pub struct Transaction<'c, DB: Database> {
|
||||
_db: &'c DB,
|
||||
}
|
||||
impl<'t, 'c, DB: Database> Acquire<'t> for &'t mut Transaction<'c, DB>
|
||||
where <DB as Database>::Connection: Send
|
||||
{
|
||||
type Database = DB;
|
||||
type Connection = &'t mut <DB as Database>::Connection;
|
||||
}
|
Loading…
Reference in New Issue
Block a user