Auto merge of #127589 - notriddle:notriddle/search-sem-3, r=GuillaumeGomez

rustdoc-search: simplify rules for generics and type params

**Heads up!**: This PR is a follow-up that depends on #124544. It adds 12dc24f460, a change to the filtering behavior, and 9900ea48b5, a minor ranking tweak.

Part of https://github.com/rust-lang/rust-project-goals/issues/112

This PR overturns https://github.com/rust-lang/rust/pull/109802

## Preview

* no results: [`Box<[A]> -> Vec<B>`](http://notriddle.com/rustdoc-html-demo-12/search-sem-3/std/index.html?search=Box%3C%5BA%5D%3E%20-%3E%20Vec%3CB%3E)
* results: [`Box<[A]> -> Vec<A>`](http://notriddle.com/rustdoc-html-demo-12/search-sem-3/std/index.html?search=Box%3C%5BA%5D%3E%20-%3E%20Vec%3CA%3E)
* [`T -> U`](http://notriddle.com/rustdoc-html-demo-12/search-sem-3/std/index.html?search=T%20-%3E%20U)
* [`Cx -> TyCtxt`](http://notriddle.com/rustdoc-html-demo-12/search-sem-3-compiler/rustdoc/index.html?search=Cx%20-%3E%20TyCtxt)

![image](https://github.com/user-attachments/assets/015ae28c-7469-4f7f-be03-157d28d7ec97)

## Description

This commit is a response to feedback on the displayed type signatures results, by making generics act stricter.

- Order within generics is significant. This means `Vec<Allocator>` now matches only with a true vector of allocators, instead of matching the second type param. It also makes unboxing within generics stricter, so `Result<A, B>` only matches if `B` is in the error type and `A` is in the success type. The top level of the function search is unaffected.
- Generics are only "unboxed" if a type is explicitly opted into it. References and tuples are hardcoded to allow unboxing, and Box, Rc, Arc, Option, Result, and Future are opted in with an unstable attribute. Search result unboxing is the process that allows you to search for `i32 -> str` and get back a function with the type signature `&Future<i32> -> Box<str>`.
- Instead of ranking by set overlap, it ranks by the number of items in the type signature. This makes it easier to find single type signatures like transmute.

## Find the discussion on

* <https://rust-lang.zulipchat.com/#narrow/stream/393423-t-rustdoc.2Fmeetings/topic/meeting.202024-07-08/near/449965149>
* <https://github.com/rust-lang/rust/pull/124544#issuecomment-2204272265>
* <https://rust-lang.zulipchat.com/#narrow/channel/266220-t-rustdoc/topic/deciding.20on.20semantics.20of.20generics.20in.20rustdoc.20search>
This commit is contained in:
bors 2024-11-11 12:26:00 +00:00
commit d4822c2d84
69 changed files with 1981 additions and 852 deletions

View File

@ -204,6 +204,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> {
"meant for internal use only" { "meant for internal use only" {
keyword => rustdoc_internals keyword => rustdoc_internals
fake_variadic => rustdoc_internals fake_variadic => rustdoc_internals
search_unbox => rustdoc_internals
} }
); );
} }

View File

@ -234,6 +234,9 @@ passes_doc_masked_only_extern_crate =
passes_doc_rust_logo = passes_doc_rust_logo =
the `#[doc(rust_logo)]` attribute is used for Rust branding the `#[doc(rust_logo)]` attribute is used for Rust branding
passes_doc_search_unbox_invalid =
`#[doc(search_unbox)]` should be used on generic structs and enums
passes_doc_test_literal = `#![doc(test(...)]` does not take a literal passes_doc_test_literal = `#![doc(test(...)]` does not take a literal
passes_doc_test_takes_list = passes_doc_test_takes_list =

View File

@ -16,8 +16,8 @@ use rustc_feature::{AttributeDuplicates, AttributeType, BUILTIN_ATTRIBUTE_MAP, B
use rustc_hir::def_id::LocalModDefId; use rustc_hir::def_id::LocalModDefId;
use rustc_hir::intravisit::{self, Visitor}; use rustc_hir::intravisit::{self, Visitor};
use rustc_hir::{ use rustc_hir::{
self as hir, self, CRATE_HIR_ID, CRATE_OWNER_ID, FnSig, ForeignItem, HirId, Item, ItemKind, self as hir, self, AssocItemKind, CRATE_HIR_ID, CRATE_OWNER_ID, FnSig, ForeignItem, HirId,
MethodKind, Safety, Target, TraitItem, Item, ItemKind, MethodKind, Safety, Target, TraitItem,
}; };
use rustc_macros::LintDiagnostic; use rustc_macros::LintDiagnostic;
use rustc_middle::hir::nested_filter; use rustc_middle::hir::nested_filter;
@ -937,6 +937,23 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
} }
} }
fn check_doc_search_unbox(&self, meta: &MetaItemInner, hir_id: HirId) {
let hir::Node::Item(item) = self.tcx.hir_node(hir_id) else {
self.dcx().emit_err(errors::DocSearchUnboxInvalid { span: meta.span() });
return;
};
match item.kind {
ItemKind::Enum(_, generics) | ItemKind::Struct(_, generics)
if generics.params.len() != 0 => {}
ItemKind::Trait(_, _, generics, _, items)
if generics.params.len() != 0
|| items.iter().any(|item| matches!(item.kind, AssocItemKind::Type)) => {}
_ => {
self.dcx().emit_err(errors::DocSearchUnboxInvalid { span: meta.span() });
}
}
}
/// Checks `#[doc(inline)]`/`#[doc(no_inline)]` attributes. /// Checks `#[doc(inline)]`/`#[doc(no_inline)]` attributes.
/// ///
/// A doc inlining attribute is invalid if it is applied to a non-`use` item, or /// A doc inlining attribute is invalid if it is applied to a non-`use` item, or
@ -1149,6 +1166,12 @@ impl<'tcx> CheckAttrVisitor<'tcx> {
} }
} }
sym::search_unbox => {
if self.check_attr_not_crate_level(meta, hir_id, "fake_variadic") {
self.check_doc_search_unbox(meta, hir_id);
}
}
sym::test => { sym::test => {
if self.check_attr_crate_level(attr, meta, hir_id) { if self.check_attr_crate_level(attr, meta, hir_id) {
self.check_test_attr(meta, hir_id); self.check_test_attr(meta, hir_id);

View File

@ -244,6 +244,13 @@ pub(crate) struct DocKeywordOnlyImpl {
pub span: Span, pub span: Span,
} }
#[derive(Diagnostic)]
#[diag(passes_doc_search_unbox_invalid)]
pub(crate) struct DocSearchUnboxInvalid {
#[primary_span]
pub span: Span,
}
#[derive(Diagnostic)] #[derive(Diagnostic)]
#[diag(passes_doc_inline_conflict)] #[diag(passes_doc_inline_conflict)]
#[help] #[help]

View File

@ -1761,6 +1761,7 @@ symbols! {
saturating_add, saturating_add,
saturating_div, saturating_div,
saturating_sub, saturating_sub,
search_unbox,
select_unpredictable, select_unpredictable,
self_in_typedefs, self_in_typedefs,
self_struct_ctor, self_struct_ctor,

View File

@ -225,6 +225,7 @@ pub use thin::ThinBox;
#[fundamental] #[fundamental]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[rustc_insignificant_dtor] #[rustc_insignificant_dtor]
#[cfg_attr(not(bootstrap), doc(search_unbox))]
// The declaration of the `Box` struct must be kept in sync with the // The declaration of the `Box` struct must be kept in sync with the
// compiler or ICEs will happen. // compiler or ICEs will happen.
pub struct Box< pub struct Box<

View File

@ -307,6 +307,7 @@ fn rc_inner_layout_for_value_layout(layout: Layout) -> Layout {
/// `value.get_mut()`. This avoids conflicts with methods of the inner type `T`. /// `value.get_mut()`. This avoids conflicts with methods of the inner type `T`.
/// ///
/// [get_mut]: Rc::get_mut /// [get_mut]: Rc::get_mut
#[cfg_attr(not(bootstrap), doc(search_unbox))]
#[cfg_attr(not(test), rustc_diagnostic_item = "Rc")] #[cfg_attr(not(test), rustc_diagnostic_item = "Rc")]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[rustc_insignificant_dtor] #[rustc_insignificant_dtor]

View File

@ -235,6 +235,7 @@ macro_rules! acquire {
/// counting in general. /// counting in general.
/// ///
/// [rc_examples]: crate::rc#examples /// [rc_examples]: crate::rc#examples
#[cfg_attr(not(bootstrap), doc(search_unbox))]
#[cfg_attr(not(test), rustc_diagnostic_item = "Arc")] #[cfg_attr(not(test), rustc_diagnostic_item = "Arc")]
#[stable(feature = "rust1", since = "1.0.0")] #[stable(feature = "rust1", since = "1.0.0")]
#[rustc_insignificant_dtor] #[rustc_insignificant_dtor]

View File

@ -25,6 +25,7 @@ use crate::task::{Context, Poll};
/// [`async`]: ../../std/keyword.async.html /// [`async`]: ../../std/keyword.async.html
/// [`Waker`]: crate::task::Waker /// [`Waker`]: crate::task::Waker
#[doc(notable_trait)] #[doc(notable_trait)]
#[cfg_attr(not(bootstrap), doc(search_unbox))]
#[must_use = "futures do nothing unless you `.await` or poll them"] #[must_use = "futures do nothing unless you `.await` or poll them"]
#[stable(feature = "futures_api", since = "1.36.0")] #[stable(feature = "futures_api", since = "1.36.0")]
#[lang = "future_trait"] #[lang = "future_trait"]

View File

@ -563,6 +563,7 @@ use crate::pin::Pin;
use crate::{cmp, convert, hint, mem, slice}; use crate::{cmp, convert, hint, mem, slice};
/// The `Option` type. See [the module level documentation](self) for more. /// The `Option` type. See [the module level documentation](self) for more.
#[cfg_attr(not(bootstrap), doc(search_unbox))]
#[derive(Copy, Eq, Debug, Hash)] #[derive(Copy, Eq, Debug, Hash)]
#[rustc_diagnostic_item = "Option"] #[rustc_diagnostic_item = "Option"]
#[lang = "Option"] #[lang = "Option"]

View File

@ -520,6 +520,7 @@ use crate::{convert, fmt, hint};
/// `Result` is a type that represents either success ([`Ok`]) or failure ([`Err`]). /// `Result` is a type that represents either success ([`Ok`]) or failure ([`Err`]).
/// ///
/// See the [module documentation](self) for details. /// See the [module documentation](self) for details.
#[cfg_attr(not(bootstrap), doc(search_unbox))]
#[derive(Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)] #[derive(Copy, PartialEq, PartialOrd, Eq, Ord, Debug, Hash)]
#[must_use = "this `Result` may be an `Err` variant, which should be handled"] #[must_use = "this `Result` may be an `Err` variant, which should be handled"]
#[rustc_diagnostic_item = "Result"] #[rustc_diagnostic_item = "Result"]

View File

@ -130,29 +130,31 @@ pub trait MyTrait {
/// This function can be found using the following search queries: /// This function can be found using the following search queries:
/// ///
/// MyTrait<First=u8, Second=u32> -> bool /// MyTrait<First=u8, Second=u32> -> bool
/// MyTrait<u32, First=u8> -> bool
/// MyTrait<Second=u32> -> bool /// MyTrait<Second=u32> -> bool
/// MyTrait<u32, u8> -> bool
/// ///
/// The following queries, however, will *not* match it: /// The following queries, however, will *not* match it:
/// ///
/// MyTrait<First=u32> -> bool /// MyTrait<First=u32> -> bool
/// MyTrait<u32, u32> -> bool /// MyTrait<u32, u32> -> bool
/// MyTrait<u32, First=u8> -> bool
/// MyTrait<u32, u8> -> bool
pub fn my_fn(x: impl MyTrait<First=u8, Second=u32>) -> bool { true } pub fn my_fn(x: impl MyTrait<First=u8, Second=u32>) -> bool { true }
``` ```
Generics and function parameters are order-agnostic, but sensitive to nesting Function parameters are order-agnostic, but sensitive to nesting
and number of matches. For example, a function with the signature and number of matches. For example, a function with the signature
`fn read_all(&mut self: impl Read) -> Result<Vec<u8>, Error>` `fn read_all(&mut self: impl Read) -> Result<Vec<u8>, Error>`
will match these queries: will match these queries:
* `&mut Read -> Result<Vec<u8>, Error>` * `&mut Read -> Result<Vec<u8>, Error>`
* `Read -> Result<Vec<u8>, Error>` * `Read -> Result<Vec<u8>, Error>`
* `Read -> Result<Error, Vec>`
* `Read -> Result<Vec<u8>>` * `Read -> Result<Vec<u8>>`
* `Read -> u8` * `Read -> u8`
But it *does not* match `Result<Vec, u8>` or `Result<u8<Vec>>`. But it *does not* match `Result<Vec, u8>` or `Result<u8<Vec>>`,
because those are nested incorrectly, and it does not match
`Result<Error, Vec<u8>>` or `Result<Error>`, because those are
in the wrong order.
To search for a function that accepts a function as a parameter, To search for a function that accepts a function as a parameter,
like `Iterator::all`, wrap the nested signature in parenthesis, like `Iterator::all`, wrap the nested signature in parenthesis,

View File

@ -204,6 +204,7 @@ pub(crate) struct IndexItemFunctionType {
inputs: Vec<RenderType>, inputs: Vec<RenderType>,
output: Vec<RenderType>, output: Vec<RenderType>,
where_clause: Vec<Vec<RenderType>>, where_clause: Vec<Vec<RenderType>>,
param_names: Vec<Symbol>,
} }
impl IndexItemFunctionType { impl IndexItemFunctionType {

View File

@ -13,8 +13,8 @@ use serde::ser::{Serialize, SerializeSeq, SerializeStruct, Serializer};
use thin_vec::ThinVec; use thin_vec::ThinVec;
use tracing::instrument; use tracing::instrument;
use crate::clean;
use crate::clean::types::{Function, Generics, ItemId, Type, WherePredicate}; use crate::clean::types::{Function, Generics, ItemId, Type, WherePredicate};
use crate::clean::{self, utils};
use crate::formats::cache::{Cache, OrphanImplItem}; use crate::formats::cache::{Cache, OrphanImplItem};
use crate::formats::item_type::ItemType; use crate::formats::item_type::ItemType;
use crate::html::format::join_with_double_colon; use crate::html::format::join_with_double_colon;
@ -66,7 +66,7 @@ pub(crate) fn build_index<'tcx>(
let mut associated_types = FxHashMap::default(); let mut associated_types = FxHashMap::default();
// item type, display path, re-exported internal path // item type, display path, re-exported internal path
let mut crate_paths: Vec<(ItemType, Vec<Symbol>, Option<Vec<Symbol>>)> = vec![]; let mut crate_paths: Vec<(ItemType, Vec<Symbol>, Option<Vec<Symbol>>, bool)> = vec![];
// Attach all orphan items to the type's definition if the type // Attach all orphan items to the type's definition if the type
// has since been learned. // has since been learned.
@ -132,10 +132,11 @@ pub(crate) fn build_index<'tcx>(
map: &mut FxHashMap<F, isize>, map: &mut FxHashMap<F, isize>,
itemid: F, itemid: F,
lastpathid: &mut isize, lastpathid: &mut isize,
crate_paths: &mut Vec<(ItemType, Vec<Symbol>, Option<Vec<Symbol>>)>, crate_paths: &mut Vec<(ItemType, Vec<Symbol>, Option<Vec<Symbol>>, bool)>,
item_type: ItemType, item_type: ItemType,
path: &[Symbol], path: &[Symbol],
exact_path: Option<&[Symbol]>, exact_path: Option<&[Symbol]>,
search_unbox: bool,
) -> RenderTypeId { ) -> RenderTypeId {
match map.entry(itemid) { match map.entry(itemid) {
Entry::Occupied(entry) => RenderTypeId::Index(*entry.get()), Entry::Occupied(entry) => RenderTypeId::Index(*entry.get()),
@ -147,6 +148,7 @@ pub(crate) fn build_index<'tcx>(
item_type, item_type,
path.to_vec(), path.to_vec(),
exact_path.map(|path| path.to_vec()), exact_path.map(|path| path.to_vec()),
search_unbox,
)); ));
RenderTypeId::Index(pathid) RenderTypeId::Index(pathid)
} }
@ -160,9 +162,21 @@ pub(crate) fn build_index<'tcx>(
primitives: &mut FxHashMap<Symbol, isize>, primitives: &mut FxHashMap<Symbol, isize>,
associated_types: &mut FxHashMap<Symbol, isize>, associated_types: &mut FxHashMap<Symbol, isize>,
lastpathid: &mut isize, lastpathid: &mut isize,
crate_paths: &mut Vec<(ItemType, Vec<Symbol>, Option<Vec<Symbol>>)>, crate_paths: &mut Vec<(ItemType, Vec<Symbol>, Option<Vec<Symbol>>, bool)>,
tcx: TyCtxt<'_>,
) -> Option<RenderTypeId> { ) -> Option<RenderTypeId> {
use crate::clean::PrimitiveType;
let Cache { ref paths, ref external_paths, ref exact_paths, .. } = *cache; let Cache { ref paths, ref external_paths, ref exact_paths, .. } = *cache;
let search_unbox = match id {
RenderTypeId::Mut => false,
RenderTypeId::DefId(defid) => utils::has_doc_flag(tcx, defid, sym::search_unbox),
RenderTypeId::Primitive(PrimitiveType::Reference | PrimitiveType::Tuple) => true,
RenderTypeId::Primitive(..) => false,
RenderTypeId::AssociatedType(..) => false,
// this bool is only used by `insert_into_map`, so it doesn't matter what we set here
// because Index means we've already inserted into the map
RenderTypeId::Index(_) => false,
};
match id { match id {
RenderTypeId::Mut => Some(insert_into_map( RenderTypeId::Mut => Some(insert_into_map(
primitives, primitives,
@ -172,6 +186,7 @@ pub(crate) fn build_index<'tcx>(
ItemType::Keyword, ItemType::Keyword,
&[kw::Mut], &[kw::Mut],
None, None,
search_unbox,
)), )),
RenderTypeId::DefId(defid) => { RenderTypeId::DefId(defid) => {
if let Some(&(ref fqp, item_type)) = if let Some(&(ref fqp, item_type)) =
@ -195,6 +210,7 @@ pub(crate) fn build_index<'tcx>(
item_type, item_type,
fqp, fqp,
exact_fqp.map(|x| &x[..]).filter(|exact_fqp| exact_fqp != fqp), exact_fqp.map(|x| &x[..]).filter(|exact_fqp| exact_fqp != fqp),
search_unbox,
)) ))
} else { } else {
None None
@ -210,6 +226,7 @@ pub(crate) fn build_index<'tcx>(
ItemType::Primitive, ItemType::Primitive,
&[sym], &[sym],
None, None,
search_unbox,
)) ))
} }
RenderTypeId::Index(_) => Some(id), RenderTypeId::Index(_) => Some(id),
@ -221,6 +238,7 @@ pub(crate) fn build_index<'tcx>(
ItemType::AssocType, ItemType::AssocType,
&[sym], &[sym],
None, None,
search_unbox,
)), )),
} }
} }
@ -232,7 +250,8 @@ pub(crate) fn build_index<'tcx>(
primitives: &mut FxHashMap<Symbol, isize>, primitives: &mut FxHashMap<Symbol, isize>,
associated_types: &mut FxHashMap<Symbol, isize>, associated_types: &mut FxHashMap<Symbol, isize>,
lastpathid: &mut isize, lastpathid: &mut isize,
crate_paths: &mut Vec<(ItemType, Vec<Symbol>, Option<Vec<Symbol>>)>, crate_paths: &mut Vec<(ItemType, Vec<Symbol>, Option<Vec<Symbol>>, bool)>,
tcx: TyCtxt<'_>,
) { ) {
if let Some(generics) = &mut ty.generics { if let Some(generics) = &mut ty.generics {
for item in generics { for item in generics {
@ -244,6 +263,7 @@ pub(crate) fn build_index<'tcx>(
associated_types, associated_types,
lastpathid, lastpathid,
crate_paths, crate_paths,
tcx,
); );
} }
} }
@ -257,6 +277,7 @@ pub(crate) fn build_index<'tcx>(
associated_types, associated_types,
lastpathid, lastpathid,
crate_paths, crate_paths,
tcx,
); );
let Some(converted_associated_type) = converted_associated_type else { let Some(converted_associated_type) = converted_associated_type else {
return false; return false;
@ -271,6 +292,7 @@ pub(crate) fn build_index<'tcx>(
associated_types, associated_types,
lastpathid, lastpathid,
crate_paths, crate_paths,
tcx,
); );
} }
true true
@ -288,6 +310,7 @@ pub(crate) fn build_index<'tcx>(
associated_types, associated_types,
lastpathid, lastpathid,
crate_paths, crate_paths,
tcx,
); );
} }
if let Some(search_type) = &mut item.search_type { if let Some(search_type) = &mut item.search_type {
@ -300,6 +323,7 @@ pub(crate) fn build_index<'tcx>(
&mut associated_types, &mut associated_types,
&mut lastpathid, &mut lastpathid,
&mut crate_paths, &mut crate_paths,
tcx,
); );
} }
for item in &mut search_type.output { for item in &mut search_type.output {
@ -311,6 +335,7 @@ pub(crate) fn build_index<'tcx>(
&mut associated_types, &mut associated_types,
&mut lastpathid, &mut lastpathid,
&mut crate_paths, &mut crate_paths,
tcx,
); );
} }
for constraint in &mut search_type.where_clause { for constraint in &mut search_type.where_clause {
@ -323,6 +348,7 @@ pub(crate) fn build_index<'tcx>(
&mut associated_types, &mut associated_types,
&mut lastpathid, &mut lastpathid,
&mut crate_paths, &mut crate_paths,
tcx,
); );
} }
} }
@ -350,7 +376,12 @@ pub(crate) fn build_index<'tcx>(
.filter(|exact_fqp| { .filter(|exact_fqp| {
exact_fqp.last() == Some(&item.name) && *exact_fqp != fqp exact_fqp.last() == Some(&item.name) && *exact_fqp != fqp
}); });
crate_paths.push((short, fqp.clone(), exact_fqp.cloned())); crate_paths.push((
short,
fqp.clone(),
exact_fqp.cloned(),
utils::has_doc_flag(tcx, defid, sym::search_unbox),
));
Some(pathid) Some(pathid)
} else { } else {
None None
@ -431,7 +462,7 @@ pub(crate) fn build_index<'tcx>(
struct CrateData<'a> { struct CrateData<'a> {
items: Vec<&'a IndexItem>, items: Vec<&'a IndexItem>,
paths: Vec<(ItemType, Vec<Symbol>, Option<Vec<Symbol>>)>, paths: Vec<(ItemType, Vec<Symbol>, Option<Vec<Symbol>>, bool)>,
// The String is alias name and the vec is the list of the elements with this alias. // The String is alias name and the vec is the list of the elements with this alias.
// //
// To be noted: the `usize` elements are indexes to `items`. // To be noted: the `usize` elements are indexes to `items`.
@ -450,6 +481,7 @@ pub(crate) fn build_index<'tcx>(
name: Symbol, name: Symbol,
path: Option<usize>, path: Option<usize>,
exact_path: Option<usize>, exact_path: Option<usize>,
search_unbox: bool,
} }
impl Serialize for Paths { impl Serialize for Paths {
@ -467,6 +499,15 @@ pub(crate) fn build_index<'tcx>(
assert!(self.path.is_some()); assert!(self.path.is_some());
seq.serialize_element(path)?; seq.serialize_element(path)?;
} }
if self.search_unbox {
if self.path.is_none() {
seq.serialize_element(&None::<u8>)?;
}
if self.exact_path.is_none() {
seq.serialize_element(&None::<u8>)?;
}
seq.serialize_element(&1)?;
}
seq.end() seq.end()
} }
} }
@ -489,9 +530,15 @@ pub(crate) fn build_index<'tcx>(
mod_paths.insert(&item.path, index); mod_paths.insert(&item.path, index);
} }
let mut paths = Vec::with_capacity(self.paths.len()); let mut paths = Vec::with_capacity(self.paths.len());
for (ty, path, exact) in &self.paths { for &(ty, ref path, ref exact, search_unbox) in &self.paths {
if path.len() < 2 { if path.len() < 2 {
paths.push(Paths { ty: *ty, name: path[0], path: None, exact_path: None }); paths.push(Paths {
ty,
name: path[0],
path: None,
exact_path: None,
search_unbox,
});
continue; continue;
} }
let full_path = join_with_double_colon(&path[..path.len() - 1]); let full_path = join_with_double_colon(&path[..path.len() - 1]);
@ -517,10 +564,11 @@ pub(crate) fn build_index<'tcx>(
}); });
if let Some(index) = mod_paths.get(&full_path) { if let Some(index) = mod_paths.get(&full_path) {
paths.push(Paths { paths.push(Paths {
ty: *ty, ty,
name: *path.last().unwrap(), name: *path.last().unwrap(),
path: Some(*index), path: Some(*index),
exact_path, exact_path,
search_unbox,
}); });
continue; continue;
} }
@ -532,10 +580,11 @@ pub(crate) fn build_index<'tcx>(
match extra_paths.entry(full_path.clone()) { match extra_paths.entry(full_path.clone()) {
Entry::Occupied(entry) => { Entry::Occupied(entry) => {
paths.push(Paths { paths.push(Paths {
ty: *ty, ty,
name: *path.last().unwrap(), name: *path.last().unwrap(),
path: Some(*entry.get()), path: Some(*entry.get()),
exact_path, exact_path,
search_unbox,
}); });
} }
Entry::Vacant(entry) => { Entry::Vacant(entry) => {
@ -544,10 +593,11 @@ pub(crate) fn build_index<'tcx>(
revert_extra_paths.insert(index, full_path); revert_extra_paths.insert(index, full_path);
} }
paths.push(Paths { paths.push(Paths {
ty: *ty, ty,
name: *path.last().unwrap(), name: *path.last().unwrap(),
path: Some(index), path: Some(index),
exact_path, exact_path,
search_unbox,
}); });
} }
} }
@ -646,9 +696,25 @@ pub(crate) fn build_index<'tcx>(
full_paths.push((*index, path)); full_paths.push((*index, path));
} }
let param_names: Vec<(usize, String)> = {
let mut prev = Vec::new();
let mut result = Vec::new();
for (index, item) in self.items.iter().enumerate() {
if let Some(ty) = &item.search_type
&& let my =
ty.param_names.iter().map(|sym| sym.as_str()).collect::<Vec<_>>()
&& my != prev
{
result.push((index, my.join(",")));
prev = my;
}
}
result
};
let has_aliases = !self.aliases.is_empty(); let has_aliases = !self.aliases.is_empty();
let mut crate_data = let mut crate_data =
serializer.serialize_struct("CrateData", if has_aliases { 9 } else { 8 })?; serializer.serialize_struct("CrateData", if has_aliases { 13 } else { 12 })?;
crate_data.serialize_field("t", &types)?; crate_data.serialize_field("t", &types)?;
crate_data.serialize_field("n", &names)?; crate_data.serialize_field("n", &names)?;
crate_data.serialize_field("q", &full_paths)?; crate_data.serialize_field("q", &full_paths)?;
@ -660,6 +726,7 @@ pub(crate) fn build_index<'tcx>(
crate_data.serialize_field("b", &self.associated_item_disambiguators)?; crate_data.serialize_field("b", &self.associated_item_disambiguators)?;
crate_data.serialize_field("c", &bitmap_to_string(&deprecated))?; crate_data.serialize_field("c", &bitmap_to_string(&deprecated))?;
crate_data.serialize_field("e", &bitmap_to_string(&self.empty_desc))?; crate_data.serialize_field("e", &bitmap_to_string(&self.empty_desc))?;
crate_data.serialize_field("P", &param_names)?;
if has_aliases { if has_aliases {
crate_data.serialize_field("a", &self.aliases)?; crate_data.serialize_field("a", &self.aliases)?;
} }
@ -758,7 +825,7 @@ pub(crate) fn get_function_type_for_search<'tcx>(
None None
} }
}); });
let (mut inputs, mut output, where_clause) = match item.kind { let (mut inputs, mut output, param_names, where_clause) = match item.kind {
clean::ForeignFunctionItem(ref f, _) clean::ForeignFunctionItem(ref f, _)
| clean::FunctionItem(ref f) | clean::FunctionItem(ref f)
| clean::MethodItem(ref f, _) | clean::MethodItem(ref f, _)
@ -771,7 +838,7 @@ pub(crate) fn get_function_type_for_search<'tcx>(
inputs.retain(|a| a.id.is_some() || a.generics.is_some()); inputs.retain(|a| a.id.is_some() || a.generics.is_some());
output.retain(|a| a.id.is_some() || a.generics.is_some()); output.retain(|a| a.id.is_some() || a.generics.is_some());
Some(IndexItemFunctionType { inputs, output, where_clause }) Some(IndexItemFunctionType { inputs, output, where_clause, param_names })
} }
fn get_index_type( fn get_index_type(
@ -1285,7 +1352,7 @@ fn get_fn_inputs_and_outputs<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
impl_or_trait_generics: Option<&(clean::Type, clean::Generics)>, impl_or_trait_generics: Option<&(clean::Type, clean::Generics)>,
cache: &Cache, cache: &Cache,
) -> (Vec<RenderType>, Vec<RenderType>, Vec<Vec<RenderType>>) { ) -> (Vec<RenderType>, Vec<RenderType>, Vec<Symbol>, Vec<Vec<RenderType>>) {
let decl = &func.decl; let decl = &func.decl;
let mut rgen: FxIndexMap<SimplifiedParam, (isize, Vec<RenderType>)> = Default::default(); let mut rgen: FxIndexMap<SimplifiedParam, (isize, Vec<RenderType>)> = Default::default();
@ -1331,7 +1398,21 @@ fn get_fn_inputs_and_outputs<'tcx>(
let mut ret_types = Vec::new(); let mut ret_types = Vec::new();
simplify_fn_type(self_, generics, &decl.output, tcx, 0, &mut ret_types, &mut rgen, true, cache); simplify_fn_type(self_, generics, &decl.output, tcx, 0, &mut ret_types, &mut rgen, true, cache);
let mut simplified_params = rgen.into_values().collect::<Vec<_>>(); let mut simplified_params = rgen.into_iter().collect::<Vec<_>>();
simplified_params.sort_by_key(|(idx, _)| -idx); simplified_params.sort_by_key(|(_, (idx, _))| -idx);
(arg_types, ret_types, simplified_params.into_iter().map(|(_idx, traits)| traits).collect()) (
arg_types,
ret_types,
simplified_params
.iter()
.map(|(name, (_idx, _traits))| match name {
SimplifiedParam::Symbol(name) => *name,
SimplifiedParam::Anonymous(_) => kw::Empty,
SimplifiedParam::AssociatedType(def_id, name) => {
Symbol::intern(&format!("{}::{}", tcx.item_name(*def_id), name))
}
})
.collect(),
simplified_params.into_iter().map(|(_name, (_idx, traits))| traits).collect(),
)
} }

View File

@ -264,6 +264,7 @@ a.anchor,
.mobile-topbar h2 a, .mobile-topbar h2 a,
h1 a, h1 a,
.search-results a, .search-results a,
.search-results li,
.stab, .stab,
.result-name i { .result-name i {
color: var(--main-color); color: var(--main-color);
@ -379,7 +380,7 @@ details:not(.toggle) summary {
margin-bottom: .6em; margin-bottom: .6em;
} }
code, pre, .code-header { code, pre, .code-header, .type-signature {
font-family: "Source Code Pro", monospace; font-family: "Source Code Pro", monospace;
} }
.docblock code, .docblock-short code { .docblock code, .docblock-short code {
@ -1205,22 +1206,28 @@ so that we can apply CSS-filters to change the arrow color in themes */
.search-results.active { .search-results.active {
display: block; display: block;
margin: 0;
padding: 0;
} }
.search-results > a { .search-results > a {
display: flex; display: grid;
grid-template-areas:
"search-result-name search-result-desc"
"search-result-type-signature search-result-type-signature";
grid-template-columns: .6fr .4fr;
/* A little margin ensures the browser's outlining of focused links has room to display. */ /* A little margin ensures the browser's outlining of focused links has room to display. */
margin-left: 2px; margin-left: 2px;
margin-right: 2px; margin-right: 2px;
border-bottom: 1px solid var(--search-result-border-color); border-bottom: 1px solid var(--search-result-border-color);
gap: 1em; column-gap: 1em;
} }
.search-results > a > div.desc { .search-results > a > div.desc {
white-space: nowrap; white-space: nowrap;
text-overflow: ellipsis; text-overflow: ellipsis;
overflow: hidden; overflow: hidden;
flex: 2; grid-area: search-result-desc;
} }
.search-results a:hover, .search-results a:hover,
@ -1232,7 +1239,7 @@ so that we can apply CSS-filters to change the arrow color in themes */
display: flex; display: flex;
align-items: center; align-items: center;
justify-content: start; justify-content: start;
flex: 3; grid-area: search-result-name;
} }
.search-results .result-name .alias { .search-results .result-name .alias {
color: var(--search-results-alias-color); color: var(--search-results-alias-color);
@ -1253,6 +1260,10 @@ so that we can apply CSS-filters to change the arrow color in themes */
.search-results .result-name .path > * { .search-results .result-name .path > * {
display: inline; display: inline;
} }
.search-results .type-signature {
grid-area: search-result-type-signature;
white-space: pre-wrap;
}
.popover { .popover {
position: absolute; position: absolute;

View File

@ -9,12 +9,12 @@ function initSearch(searchIndex){}
/** /**
* @typedef {{ * @typedef {{
* name: string, * name: string,
* id: integer|null, * id: number|null,
* fullPath: Array<string>, * fullPath: Array<string>,
* pathWithoutLast: Array<string>, * pathWithoutLast: Array<string>,
* pathLast: string, * pathLast: string,
* generics: Array<QueryElement>, * generics: Array<QueryElement>,
* bindings: Map<integer, Array<QueryElement>>, * bindings: Map<number, Array<QueryElement>>,
* }} * }}
*/ */
let QueryElement; let QueryElement;
@ -92,6 +92,9 @@ let Results;
* parent: (Object|undefined), * parent: (Object|undefined),
* path: string, * path: string,
* ty: number, * ty: number,
* type: FunctionSearchType?,
* displayType: Promise<Array<Array<string>>>|null,
* displayTypeMappedNames: Promise<Array<[string, Array<string>]>>|null,
* }} * }}
*/ */
let ResultObject; let ResultObject;

File diff suppressed because it is too large Load Diff

View File

@ -2,6 +2,14 @@
const fs = require("fs"); const fs = require("fs");
const path = require("path"); const path = require("path");
function arrayToCode(array) {
return array.map((value, index) => {
value = value.split("&nbsp;").join(" ");
return (index % 2 === 1) ? ("`" + value + "`") : value;
}).join("");
}
function loadContent(content) { function loadContent(content) {
const Module = module.constructor; const Module = module.constructor;
const m = new Module(); const m = new Module();
@ -84,7 +92,6 @@ function checkNeededFields(fullPath, expected, error_text, queryName, position)
if (fullPath.length === 0) { if (fullPath.length === 0) {
fieldsToCheck = [ fieldsToCheck = [
"foundElems", "foundElems",
"original",
"returned", "returned",
"userQuery", "userQuery",
"error", "error",
@ -181,15 +188,7 @@ function valueCheck(fullPath, expected, result, error_text, queryName) {
if (!result_v.forEach) { if (!result_v.forEach) {
throw result_v; throw result_v;
} }
result_v.forEach((value, index) => { result_v = arrayToCode(result_v);
value = value.split("&nbsp;").join(" ");
if (index % 2 === 1) {
result_v[index] = "`" + value + "`";
} else {
result_v[index] = value;
}
});
result_v = result_v.join("");
} }
const obj_path = fullPath + (fullPath.length > 0 ? "." : "") + key; const obj_path = fullPath + (fullPath.length > 0 ? "." : "") + key;
valueCheck(obj_path, expected[key], result_v, error_text, queryName); valueCheck(obj_path, expected[key], result_v, error_text, queryName);
@ -437,9 +436,41 @@ function loadSearchJS(doc_folder, resource_suffix) {
searchModule.initSearch(searchIndex.searchIndex); searchModule.initSearch(searchIndex.searchIndex);
const docSearch = searchModule.docSearch; const docSearch = searchModule.docSearch;
return { return {
doSearch: function(queryStr, filterCrate, currentCrate) { doSearch: async function(queryStr, filterCrate, currentCrate) {
return docSearch.execQuery(searchModule.parseQuery(queryStr), const result = await docSearch.execQuery(searchModule.parseQuery(queryStr),
filterCrate, currentCrate); filterCrate, currentCrate);
for (const tab in result) {
if (!Object.prototype.hasOwnProperty.call(result, tab)) {
continue;
}
if (!(result[tab] instanceof Array)) {
continue;
}
for (const entry of result[tab]) {
for (const key in entry) {
if (!Object.prototype.hasOwnProperty.call(entry, key)) {
continue;
}
if (key === "displayTypeSignature") {
const {type, mappedNames, whereClause} =
await entry.displayTypeSignature;
entry.displayType = arrayToCode(type);
entry.displayMappedNames = [...mappedNames.entries()]
.map(([name, qname]) => {
return `${name} = ${qname}`;
}).join(", ");
entry.displayWhereClause = [...whereClause.entries()]
.flatMap(([name, value]) => {
if (value.length === 0) {
return [];
}
return [`${name}: ${arrayToCode(value)}`];
}).join(", ");
}
}
}
}
return result;
}, },
getCorrections: function(queryStr, filterCrate, currentCrate) { getCorrections: function(queryStr, filterCrate, currentCrate) {
const parsedQuery = searchModule.parseQuery(queryStr); const parsedQuery = searchModule.parseQuery(queryStr);

View File

@ -0,0 +1,42 @@
// Check the "About this Result" popover.
// Try a complex result.
go-to: "file://" + |DOC_PATH| + "/lib2/index.html?search=scroll_traits::Iterator<T>,(T->bool)->(Extend<T>,Extend<T>)"
// These two commands are used to be sure the search will be run.
focus: ".search-input"
press-key: "Enter"
wait-for: "#search-tabs"
assert-count: ("#search-tabs button", 1)
assert-count: (".search-results > a", 1)
assert: "//div[@class='type-signature']/strong[text()='Iterator']"
assert: "//div[@class='type-signature']/strong[text()='(B']"
assert: "//div[@class='type-signature']/strong[text()='B)']"
assert: "//div[@class='type-signature']/div[@class='where']/strong[text()='FnMut']"
assert: "//div[@class='type-signature']/div[@class='where']/strong[text()='Iterator::Item']"
assert: "//div[@class='type-signature']/div[@class='where']/strong[text()='bool']"
assert: "//div[@class='type-signature']/div[@class='where']/strong[text()='Extend']"
assert-text: ("div.type-signature div.where:nth-child(4)", "where")
assert-text: ("div.type-signature div.where:nth-child(5)", " T matches Iterator::Item")
assert-text: ("div.type-signature div.where:nth-child(6)", " F: FnMut (&Iterator::Item) -> bool")
assert-text: ("div.type-signature div.where:nth-child(7)", " B: Default + Extend<Iterator::Item>")
// Try a simple result that *won't* give an info box.
go-to: "file://" + |DOC_PATH| + "/lib2/index.html?search=F->lib2::WhereWhitespace<T>"
// These two commands are used to be sure the search will be run.
focus: ".search-input"
press-key: "Enter"
wait-for: "#search-tabs"
assert-text: ("//div[@class='type-signature']", "F -> WhereWhitespace<T>")
assert-count: ("#search-tabs button", 1)
assert-count: (".search-results > a", 1)
assert-count: ("//div[@class='type-signature']/div[@class='where']", 0)
assert: "//div[@class='type-signature']/strong[text()='F']"
assert: "//div[@class='type-signature']/strong[text()='WhereWhitespace']"
assert: "//div[@class='type-signature']/strong[text()='T']"

View File

@ -24,7 +24,7 @@ assert-css: (".search-corrections", {
}) })
assert-text: ( assert-text: (
".search-corrections", ".search-corrections",
"Type \"notablestructwithlongnamr\" not found. Showing results for closest type name \"notablestructwithlongname\" instead." "Type \"NotableStructWithLongNamr\" not found. Showing results for closest type name \"notablestructwithlongname\" instead."
) )
// Corrections do get shown on the "In Return Type" tab. // Corrections do get shown on the "In Return Type" tab.
@ -35,7 +35,7 @@ assert-css: (".search-corrections", {
}) })
assert-text: ( assert-text: (
".search-corrections", ".search-corrections",
"Type \"notablestructwithlongnamr\" not found. Showing results for closest type name \"notablestructwithlongname\" instead." "Type \"NotableStructWithLongNamr\" not found. Showing results for closest type name \"notablestructwithlongname\" instead."
) )
// Now, explicit return values // Now, explicit return values
@ -52,7 +52,7 @@ assert-css: (".search-corrections", {
}) })
assert-text: ( assert-text: (
".search-corrections", ".search-corrections",
"Type \"notablestructwithlongnamr\" not found. Showing results for closest type name \"notablestructwithlongname\" instead." "Type \"NotableStructWithLongNamr\" not found. Showing results for closest type name \"notablestructwithlongname\" instead."
) )
// Now, generic correction // Now, generic correction
@ -69,7 +69,7 @@ assert-css: (".search-corrections", {
}) })
assert-text: ( assert-text: (
".search-corrections", ".search-corrections",
"Type \"notablestructwithlongnamr\" not found and used as generic parameter. Consider searching for \"notablestructwithlongname\" instead." "Type \"NotableStructWithLongNamr\" not found and used as generic parameter. Consider searching for \"notablestructwithlongname\" instead."
) )
// Now, generic correction plus error // Now, generic correction plus error
@ -86,7 +86,7 @@ assert-css: (".search-corrections", {
}) })
assert-text: ( assert-text: (
".search-corrections", ".search-corrections",
"Type \"notablestructwithlongnamr\" not found and used as generic parameter. Consider searching for \"notablestructwithlongname\" instead." "Type \"NotableStructWithLongNamr\" not found and used as generic parameter. Consider searching for \"notablestructwithlongname\" instead."
) )
go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" go-to: "file://" + |DOC_PATH| + "/test_docs/index.html"
@ -102,5 +102,5 @@ assert-css: (".error", {
}) })
assert-text: ( assert-text: (
".error", ".error",
"Query parser error: \"Generic type parameter notablestructwithlongnamr does not accept generic parameters\"." "Query parser error: \"Generic type parameter NotableStructWithLongNamr does not accept generic parameters\"."
) )

View File

@ -2,12 +2,15 @@
const EXPECTED = [ const EXPECTED = [
{ {
'query': 'bufread -> result<u8>', 'query': 'bufread -> result<[u8]>',
'others': [
{ 'path': 'std::boxed::Box', 'name': 'fill_buf' },
],
},
{
'query': 'split<bufread> -> option<result<vec<u8>>>',
'others': [ 'others': [
{ 'path': 'std::io::Split', 'name': 'next' }, { 'path': 'std::io::Split', 'name': 'next' },
{ 'path': 'std::boxed::Box', 'name': 'fill_buf' },
{ 'path': 'std::io::Chain', 'name': 'fill_buf' },
{ 'path': 'std::io::Take', 'name': 'fill_buf' },
], ],
}, },
]; ];

View File

@ -6,79 +6,198 @@ const EXPECTED = [
{ {
'query': 'option, fnonce -> option', 'query': 'option, fnonce -> option',
'others': [ 'others': [
{ 'path': 'std::option::Option', 'name': 'map' }, {
'path': 'std::option::Option',
'name': 'map',
'displayType': '`Option`<T>, F -> `Option`<U>',
'displayWhereClause': "F: `FnOnce` (T) -> U",
},
],
},
{
'query': 'option<t>, fnonce -> option',
'others': [
{
'path': 'std::option::Option',
'name': 'map',
'displayType': '`Option`<`T`>, F -> `Option`<U>',
'displayWhereClause': "F: `FnOnce` (T) -> U",
},
], ],
}, },
{ {
'query': 'option -> default', 'query': 'option -> default',
'others': [ 'others': [
{ 'path': 'std::option::Option', 'name': 'unwrap_or_default' }, {
{ 'path': 'std::option::Option', 'name': 'get_or_insert_default' }, 'path': 'std::option::Option',
'name': 'unwrap_or_default',
'displayType': '`Option`<T> -> `T`',
'displayWhereClause': "T: `Default`",
},
{
'path': 'std::option::Option',
'name': 'get_or_insert_default',
'displayType': '&mut `Option`<T> -> &mut `T`',
'displayWhereClause': "T: `Default`",
},
], ],
}, },
{ {
'query': 'option -> []', 'query': 'option -> []',
'others': [ 'others': [
{ 'path': 'std::option::Option', 'name': 'as_slice' }, {
{ 'path': 'std::option::Option', 'name': 'as_mut_slice' }, 'path': 'std::option::Option',
'name': 'as_slice',
'displayType': '&`Option`<T> -> &`[`T`]`',
},
{
'path': 'std::option::Option',
'name': 'as_mut_slice',
'displayType': '&mut `Option`<T> -> &mut `[`T`]`',
},
], ],
}, },
{ {
'query': 'option<t>, option<t> -> option<t>', 'query': 'option<t>, option<t> -> option<t>',
'others': [ 'others': [
{ 'path': 'std::option::Option', 'name': 'or' }, {
{ 'path': 'std::option::Option', 'name': 'xor' }, 'path': 'std::option::Option',
'name': 'or',
'displayType': '`Option`<`T`>, `Option`<`T`> -> `Option`<`T`>',
},
{
'path': 'std::option::Option',
'name': 'xor',
'displayType': '`Option`<`T`>, `Option`<`T`> -> `Option`<`T`>',
},
], ],
}, },
{ {
'query': 'option<t>, option<u> -> option<u>', 'query': 'option<t>, option<u> -> option<u>',
'others': [ 'others': [
{ 'path': 'std::option::Option', 'name': 'and' }, {
{ 'path': 'std::option::Option', 'name': 'zip' }, 'path': 'std::option::Option',
'name': 'and',
'displayType': '`Option`<`T`>, `Option`<`U`> -> `Option`<`U`>',
},
], ],
}, },
{ {
'query': 'option<t>, option<u> -> option<t>', 'query': 'option<t>, option<u> -> option<t>',
'others': [ 'others': [
{ 'path': 'std::option::Option', 'name': 'and' }, {
{ 'path': 'std::option::Option', 'name': 'zip' }, 'path': 'std::option::Option',
'name': 'and',
'displayType': '`Option`<`T`>, `Option`<`U`> -> `Option`<`U`>',
},
{
'path': 'std::option::Option',
'name': 'zip',
'displayType': '`Option`<`T`>, `Option`<`U`> -> `Option`<(`T`, U)>',
},
], ],
}, },
{ {
'query': 'option<t>, option<u> -> option<t, u>', 'query': 'option<t>, option<u> -> option<(t, u)>',
'others': [ 'others': [
{ 'path': 'std::option::Option', 'name': 'zip' }, {
'path': 'std::option::Option',
'name': 'zip',
'displayType': '`Option`<`T`>, `Option`<`U`> -> `Option`<`(T`, `U)`>',
},
], ],
}, },
{ {
'query': 'option<t>, e -> result<t, e>', 'query': 'option<t>, e -> result<t, e>',
'others': [ 'others': [
{ 'path': 'std::option::Option', 'name': 'ok_or' }, {
{ 'path': 'std::result::Result', 'name': 'transpose' }, 'path': 'std::option::Option',
'name': 'ok_or',
'displayType': '`Option`<`T`>, `E` -> `Result`<`T`, `E`>',
},
{
'path': 'std::result::Result',
'name': 'transpose',
'displayType': 'Result<`Option`<`T`>, `E`> -> Option<`Result`<`T`, `E`>>',
},
], ],
}, },
{ {
'query': 'result<option<t>, e> -> option<result<t, e>>', 'query': 'result<option<t>, e> -> option<result<t, e>>',
'others': [ 'others': [
{ 'path': 'std::result::Result', 'name': 'transpose' }, {
'path': 'std::result::Result',
'name': 'transpose',
'displayType': '`Result`<`Option`<`T`>, `E`> -> `Option`<`Result`<`T`, `E`>>',
},
], ],
}, },
{ {
'query': 'option<t>, option<t> -> bool', 'query': 'option<t>, option<t> -> bool',
'others': [ 'others': [
{ 'path': 'std::option::Option', 'name': 'eq' }, {
'path': 'std::option::Option',
'name': 'eq',
'displayType': '&`Option`<`T`>, &`Option`<`T`> -> `bool`',
},
], ],
}, },
{ {
'query': 'option<option<t>> -> option<t>', 'query': 'option<option<t>> -> option<t>',
'others': [ 'others': [
{ 'path': 'std::option::Option', 'name': 'flatten' }, {
'path': 'std::option::Option',
'name': 'flatten',
'displayType': '`Option`<`Option`<`T`>> -> `Option`<`T`>',
},
], ],
}, },
{ {
'query': 'option<t>', 'query': 'option<t>',
'returned': [ 'returned': [
{ 'path': 'std::result::Result', 'name': 'ok' }, {
'path': 'std::result::Result',
'name': 'ok',
'displayType': 'Result<T, E> -> `Option`<`T`>',
},
],
},
{
'query': 'option<t>, (fnonce () -> u) -> option',
'others': [
{
'path': 'std::option::Option',
'name': 'map',
'displayType': '`Option`<`T`>, F -> `Option`<U>',
'displayMappedNames': `t = T, u = U`,
'displayWhereClause': "F: `FnOnce` (T) -> `U`",
},
{
'path': 'std::option::Option',
'name': 'and_then',
'displayType': '`Option`<`T`>, F -> `Option`<U>',
'displayMappedNames': `t = T, u = U`,
'displayWhereClause': "F: `FnOnce` (T) -> Option<`U`>",
},
{
'path': 'std::option::Option',
'name': 'zip_with',
'displayType': 'Option<T>, `Option`<`U`>, F -> `Option`<R>',
'displayMappedNames': `t = U, u = R`,
'displayWhereClause': "F: `FnOnce` (T, U) -> `R`",
},
],
},
{
'query': 'option<t>, (fnonce () -> option<u>) -> option',
'others': [
{
'path': 'std::option::Option',
'name': 'and_then',
'displayType': '`Option`<`T`>, F -> `Option`<U>',
'displayMappedNames': `t = T, u = U`,
'displayWhereClause': "F: `FnOnce` (T) -> `Option`<`U`>",
},
], ],
}, },
]; ];

View File

@ -3,20 +3,22 @@ const PARSED = [
query: 'A<B=C>', query: 'A<B=C>',
elems: [ elems: [
{ {
name: "a", name: "A",
fullPath: ["a"], fullPath: ["a"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "a", pathLast: "a",
normalizedPathLast: "a",
generics: [], generics: [],
bindings: [ bindings: [
[ [
'b', 'b',
[ [
{ {
name: "c", name: "C",
fullPath: ["c"], fullPath: ["c"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "c", pathLast: "c",
normalizedPathLast: "c",
generics: [], generics: [],
typeFilter: -1, typeFilter: -1,
}, },
@ -27,16 +29,15 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: 'A<B=C>', userQuery: 'A<B=C>',
returned: [], returned: [],
userQuery: 'a<b=c>',
error: null, error: null,
}, },
{ {
query: 'A<B = C>', query: 'A<B = C>',
elems: [ elems: [
{ {
name: "a", name: "A",
fullPath: ["a"], fullPath: ["a"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "a", pathLast: "a",
@ -45,7 +46,7 @@ const PARSED = [
[ [
'b', 'b',
[{ [{
name: "c", name: "C",
fullPath: ["c"], fullPath: ["c"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "c", pathLast: "c",
@ -58,16 +59,15 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: 'A<B = C>', userQuery: 'A<B = C>',
returned: [], returned: [],
userQuery: 'a<b = c>',
error: null, error: null,
}, },
{ {
query: 'A<B=!>', query: 'A<B=!>',
elems: [ elems: [
{ {
name: "a", name: "A",
fullPath: ["a"], fullPath: ["a"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "a", pathLast: "a",
@ -89,16 +89,15 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: 'A<B=!>', userQuery: 'A<B=!>',
returned: [], returned: [],
userQuery: 'a<b=!>',
error: null, error: null,
}, },
{ {
query: 'A<B=[]>', query: 'A<B=[]>',
elems: [ elems: [
{ {
name: "a", name: "A",
fullPath: ["a"], fullPath: ["a"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "a", pathLast: "a",
@ -120,16 +119,15 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: 'A<B=[]>', userQuery: 'A<B=[]>',
returned: [], returned: [],
userQuery: 'a<b=[]>',
error: null, error: null,
}, },
{ {
query: 'A<B=[!]>', query: 'A<B=[!]>',
elems: [ elems: [
{ {
name: "a", name: "A",
fullPath: ["a"], fullPath: ["a"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "a", pathLast: "a",
@ -160,52 +158,47 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: 'A<B=[!]>', userQuery: 'A<B=[!]>',
returned: [], returned: [],
userQuery: 'a<b=[!]>',
error: null, error: null,
}, },
{ {
query: 'A<B=C=>', query: 'A<B=C=>',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: 'A<B=C=>', userQuery: 'A<B=C=>',
returned: [], returned: [],
userQuery: 'a<b=c=>',
error: "Cannot write `=` twice in a binding", error: "Cannot write `=` twice in a binding",
}, },
{ {
query: 'A<B=>', query: 'A<B=>',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: 'A<B=>', userQuery: 'A<B=>',
returned: [], returned: [],
userQuery: 'a<b=>',
error: "Unexpected `>` after `=`", error: "Unexpected `>` after `=`",
}, },
{ {
query: 'B=C', query: 'B=C',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: 'B=C', userQuery: 'B=C',
returned: [], returned: [],
userQuery: 'b=c',
error: "Type parameter `=` must be within generics list", error: "Type parameter `=` must be within generics list",
}, },
{ {
query: '[B=C]', query: '[B=C]',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: '[B=C]', userQuery: '[B=C]',
returned: [], returned: [],
userQuery: '[b=c]',
error: "Type parameter `=` cannot be within slice `[]`", error: "Type parameter `=` cannot be within slice `[]`",
}, },
{ {
query: 'A<B<X>=C>', query: 'A<B<X>=C>',
elems: [ elems: [
{ {
name: "a", name: "A",
fullPath: ["a"], fullPath: ["a"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "a", pathLast: "a",
@ -215,7 +208,7 @@ const PARSED = [
'b', 'b',
[ [
{ {
name: "c", name: "C",
fullPath: ["c"], fullPath: ["c"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "c", pathLast: "c",
@ -223,7 +216,7 @@ const PARSED = [
typeFilter: -1, typeFilter: -1,
}, },
{ {
name: "x", name: "X",
fullPath: ["x"], fullPath: ["x"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "x", pathLast: "x",
@ -237,9 +230,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: 'A<B<X>=C>', userQuery: 'A<B<X>=C>',
returned: [], returned: [],
userQuery: 'a<b<x>=c>',
error: null, error: null,
}, },
]; ];

View File

@ -3,450 +3,400 @@ const PARSED = [
query: '<P>', query: '<P>',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "<P>", userQuery: "<P>",
returned: [], returned: [],
userQuery: "<p>",
error: "Found generics without a path", error: "Found generics without a path",
}, },
{ {
query: '-> <P>', query: '-> <P>',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "-> <P>", userQuery: "-> <P>",
returned: [], returned: [],
userQuery: "-> <p>",
error: "Found generics without a path", error: "Found generics without a path",
}, },
{ {
query: '-> *', query: '-> *',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "-> *",
returned: [],
userQuery: "-> *", userQuery: "-> *",
returned: [],
error: "Unexpected `*` after ` ` (not a valid identifier)", error: "Unexpected `*` after ` ` (not a valid identifier)",
}, },
{ {
query: 'a<"P">', query: 'a<"P">',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "a<\"P\">", userQuery: "a<\"P\">",
returned: [], returned: [],
userQuery: "a<\"p\">",
error: "Unexpected `\"` in generics", error: "Unexpected `\"` in generics",
}, },
{ {
query: '"P" "P"', query: '"P" "P"',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "\"P\" \"P\"", userQuery: "\"P\" \"P\"",
returned: [], returned: [],
userQuery: "\"p\" \"p\"",
error: "Cannot have more than one element if you use quotes", error: "Cannot have more than one element if you use quotes",
}, },
{ {
query: '"P","P"', query: '"P","P"',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "\"P\",\"P\"", userQuery: "\"P\",\"P\"",
returned: [], returned: [],
userQuery: "\"p\",\"p\"",
error: "Cannot have more than one literal search element", error: "Cannot have more than one literal search element",
}, },
{ {
query: "P,\"P\"", query: "P,\"P\"",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "P,\"P\"", userQuery: "P,\"P\"",
returned: [], returned: [],
userQuery: "p,\"p\"",
error: "Cannot use literal search when there is more than one element", error: "Cannot use literal search when there is more than one element",
}, },
{ {
query: '"p" p', query: '"p" p',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "\"p\" p",
returned: [],
userQuery: "\"p\" p", userQuery: "\"p\" p",
returned: [],
error: "Cannot have more than one element if you use quotes", error: "Cannot have more than one element if you use quotes",
}, },
{ {
query: '"p",p', query: '"p",p',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "\"p\",p",
returned: [],
userQuery: "\"p\",p", userQuery: "\"p\",p",
returned: [],
error: "Cannot have more than one element if you use quotes", error: "Cannot have more than one element if you use quotes",
}, },
{ {
query: '"const": p', query: '"const": p',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "\"const\": p",
returned: [],
userQuery: "\"const\": p", userQuery: "\"const\": p",
returned: [],
error: "Cannot use quotes on type filter", error: "Cannot use quotes on type filter",
}, },
{ {
query: "a<:a>", query: "a<:a>",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "a<:a>",
returned: [],
userQuery: "a<:a>", userQuery: "a<:a>",
returned: [],
error: "Expected type filter before `:`", error: "Expected type filter before `:`",
}, },
{ {
query: "a<::a>", query: "a<::a>",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "a<::a>",
returned: [],
userQuery: "a<::a>", userQuery: "a<::a>",
returned: [],
error: "Unexpected `::`: paths cannot start with `::`", error: "Unexpected `::`: paths cannot start with `::`",
}, },
{ {
query: "(p -> p", query: "(p -> p",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "(p -> p",
returned: [],
userQuery: "(p -> p", userQuery: "(p -> p",
returned: [],
error: "Unclosed `(`", error: "Unclosed `(`",
}, },
{ {
query: "::a::b", query: "::a::b",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "::a::b",
returned: [],
userQuery: "::a::b", userQuery: "::a::b",
returned: [],
error: "Paths cannot start with `::`", error: "Paths cannot start with `::`",
}, },
{ {
query: " ::a::b", query: " ::a::b",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "::a::b",
returned: [],
userQuery: "::a::b", userQuery: "::a::b",
returned: [],
error: "Paths cannot start with `::`", error: "Paths cannot start with `::`",
}, },
{ {
query: "a::::b", query: "a::::b",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "a::::b",
returned: [],
userQuery: "a::::b", userQuery: "a::::b",
returned: [],
error: "Unexpected `::::`", error: "Unexpected `::::`",
}, },
{ {
query: "a:: ::b", query: "a:: ::b",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "a:: ::b",
returned: [],
userQuery: "a:: ::b", userQuery: "a:: ::b",
returned: [],
error: "Unexpected `:: ::`", error: "Unexpected `:: ::`",
}, },
{ {
query: "a::\t::b", query: "a::\t::b",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "a:: ::b",
returned: [],
userQuery: "a:: ::b", userQuery: "a:: ::b",
returned: [],
error: "Unexpected `:: ::`", error: "Unexpected `:: ::`",
}, },
{ {
query: "a::b::", query: "a::b::",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "a::b::",
returned: [],
userQuery: "a::b::", userQuery: "a::b::",
returned: [],
error: "Paths cannot end with `::`", error: "Paths cannot end with `::`",
}, },
{ {
query: ":a", query: ":a",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: ":a",
returned: [],
userQuery: ":a", userQuery: ":a",
returned: [],
error: "Expected type filter before `:`", error: "Expected type filter before `:`",
}, },
{ {
query: "a,b:", query: "a,b:",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "a,b:",
returned: [],
userQuery: "a,b:", userQuery: "a,b:",
returned: [],
error: "Unexpected `:` (expected path after type filter `b:`)", error: "Unexpected `:` (expected path after type filter `b:`)",
}, },
{ {
query: "a (b:", query: "a (b:",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "a (b:",
returned: [],
userQuery: "a (b:", userQuery: "a (b:",
returned: [],
error: "Unclosed `(`", error: "Unclosed `(`",
}, },
{ {
query: "_:", query: "_:",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "_:",
returned: [],
userQuery: "_:", userQuery: "_:",
returned: [],
error: "Unexpected `_` (not a valid identifier)", error: "Unexpected `_` (not a valid identifier)",
}, },
{ {
query: "ab:", query: "ab:",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "ab:",
returned: [],
userQuery: "ab:", userQuery: "ab:",
returned: [],
error: "Unexpected `:` (expected path after type filter `ab:`)", error: "Unexpected `:` (expected path after type filter `ab:`)",
}, },
{ {
query: "a:b", query: "a:b",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "a:b",
returned: [],
userQuery: "a:b", userQuery: "a:b",
returned: [],
error: "Unknown type filter `a`", error: "Unknown type filter `a`",
}, },
{ {
query: "a-bb", query: "a-bb",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "a-bb",
returned: [],
userQuery: "a-bb", userQuery: "a-bb",
returned: [],
error: "Unexpected `-` (did you mean `->`?)", error: "Unexpected `-` (did you mean `->`?)",
}, },
{ {
query: "a>bb", query: "a>bb",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "a>bb",
returned: [],
userQuery: "a>bb", userQuery: "a>bb",
returned: [],
error: "Unexpected `>` (did you mean `->`?)", error: "Unexpected `>` (did you mean `->`?)",
}, },
{ {
query: "ab'", query: "ab'",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "ab'",
returned: [],
userQuery: "ab'", userQuery: "ab'",
returned: [],
error: "Unexpected `'` after `b` (not a valid identifier)", error: "Unexpected `'` after `b` (not a valid identifier)",
}, },
{ {
query: '"p" <a>', query: '"p" <a>',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: '"p" <a>',
returned: [],
userQuery: '"p" <a>', userQuery: '"p" <a>',
returned: [],
error: "Cannot have more than one element if you use quotes", error: "Cannot have more than one element if you use quotes",
}, },
{ {
query: '"p",<a>', query: '"p",<a>',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: '"p",<a>',
returned: [],
userQuery: '"p",<a>', userQuery: '"p",<a>',
returned: [],
error: "Found generics without a path", error: "Found generics without a path",
}, },
{ {
query: '"p" a<a>', query: '"p" a<a>',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: '"p" a<a>',
returned: [],
userQuery: '"p" a<a>', userQuery: '"p" a<a>',
returned: [],
error: "Cannot have more than one element if you use quotes", error: "Cannot have more than one element if you use quotes",
}, },
{ {
query: '"p",a<a>', query: '"p",a<a>',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: '"p",a<a>',
returned: [],
userQuery: '"p",a<a>', userQuery: '"p",a<a>',
returned: [],
error: "Cannot have more than one element if you use quotes", error: "Cannot have more than one element if you use quotes",
}, },
{ {
query: "a,<", query: "a,<",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: 'a,<',
returned: [],
userQuery: 'a,<', userQuery: 'a,<',
returned: [],
error: 'Found generics without a path', error: 'Found generics without a path',
}, },
{ {
query: "aaaaa<>b", query: "aaaaa<>b",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: 'aaaaa<>b',
returned: [],
userQuery: 'aaaaa<>b', userQuery: 'aaaaa<>b',
returned: [],
error: 'Expected `,`, `:` or `->` after `>`, found `b`', error: 'Expected `,`, `:` or `->` after `>`, found `b`',
}, },
{ {
query: "fn:aaaaa<>b", query: "fn:aaaaa<>b",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: 'fn:aaaaa<>b',
returned: [],
userQuery: 'fn:aaaaa<>b', userQuery: 'fn:aaaaa<>b',
returned: [],
error: 'Expected `,`, `:` or `->` after `>`, found `b`', error: 'Expected `,`, `:` or `->` after `>`, found `b`',
}, },
{ {
query: "->a<>b", query: "->a<>b",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: '->a<>b',
returned: [],
userQuery: '->a<>b', userQuery: '->a<>b',
returned: [],
error: 'Expected `,` or `=` after `>`, found `b`', error: 'Expected `,` or `=` after `>`, found `b`',
}, },
{ {
query: "a<->", query: "a<->",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: 'a<->',
returned: [],
userQuery: 'a<->', userQuery: 'a<->',
returned: [],
error: 'Unclosed `<`', error: 'Unclosed `<`',
}, },
{ {
query: "a<a>:", query: "a<a>:",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "a<a>:",
returned: [],
userQuery: "a<a>:", userQuery: "a<a>:",
returned: [],
error: 'Unexpected `<` in type filter (before `:`)', error: 'Unexpected `<` in type filter (before `:`)',
}, },
{ {
query: "a<>:", query: "a<>:",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "a<>:",
returned: [],
userQuery: "a<>:", userQuery: "a<>:",
returned: [],
error: 'Unexpected `<` in type filter (before `:`)', error: 'Unexpected `<` in type filter (before `:`)',
}, },
{ {
query: "a,:", query: "a,:",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "a,:",
returned: [],
userQuery: "a,:", userQuery: "a,:",
returned: [],
error: 'Expected type filter before `:`', error: 'Expected type filter before `:`',
}, },
{ {
query: "a!:", query: "a!:",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "a!:",
returned: [],
userQuery: "a!:", userQuery: "a!:",
returned: [],
error: 'Unexpected `!` in type filter (before `:`)', error: 'Unexpected `!` in type filter (before `:`)',
}, },
{ {
query: " a<> :", query: " a<> :",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "a<> :",
returned: [],
userQuery: "a<> :", userQuery: "a<> :",
returned: [],
error: 'Expected `,`, `:` or `->` after `>`, found `:`', error: 'Expected `,`, `:` or `->` after `>`, found `:`',
}, },
{ {
query: "mod : :", query: "mod : :",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "mod : :",
returned: [],
userQuery: "mod : :", userQuery: "mod : :",
returned: [],
error: 'Unexpected `:` (expected path after type filter `mod:`)', error: 'Unexpected `:` (expected path after type filter `mod:`)',
}, },
{ {
query: "mod: :", query: "mod: :",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "mod: :",
returned: [],
userQuery: "mod: :", userQuery: "mod: :",
returned: [],
error: 'Unexpected `:` (expected path after type filter `mod:`)', error: 'Unexpected `:` (expected path after type filter `mod:`)',
}, },
{ {
query: "a!a", query: "a!a",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "a!a",
returned: [],
userQuery: "a!a", userQuery: "a!a",
returned: [],
error: 'Unexpected `!`: it can only be at the end of an ident', error: 'Unexpected `!`: it can only be at the end of an ident',
}, },
{ {
query: "a!!", query: "a!!",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "a!!",
returned: [],
userQuery: "a!!", userQuery: "a!!",
returned: [],
error: 'Cannot have more than one `!` in an ident', error: 'Cannot have more than one `!` in an ident',
}, },
{ {
query: "mod:a!", query: "mod:a!",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "mod:a!",
returned: [],
userQuery: "mod:a!", userQuery: "mod:a!",
returned: [],
error: 'Invalid search type: macro `!` and `mod` both specified', error: 'Invalid search type: macro `!` and `mod` both specified',
}, },
{ {
query: "mod:!", query: "mod:!",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "mod:!",
returned: [],
userQuery: "mod:!", userQuery: "mod:!",
returned: [],
error: 'Invalid search type: primitive never type `!` and `mod` both specified', error: 'Invalid search type: primitive never type `!` and `mod` both specified',
}, },
{ {
query: "a!::a", query: "a!::a",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "a!::a",
returned: [],
userQuery: "a!::a", userQuery: "a!::a",
returned: [],
error: 'Cannot have associated items in macros', error: 'Cannot have associated items in macros',
}, },
{ {
query: "a<", query: "a<",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "a<",
returned: [],
userQuery: "a<", userQuery: "a<",
returned: [],
error: "Unclosed `<`", error: "Unclosed `<`",
}, },
{ {
@ -479,9 +429,8 @@ const PARSED = [
}, },
], ],
foundElems: 2, foundElems: 2,
original: "p<x> , y",
returned: [],
userQuery: "p<x> , y", userQuery: "p<x> , y",
returned: [],
error: null, error: null,
}, },
{ {
@ -514,9 +463,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: "p<x , y>",
returned: [],
userQuery: "p<x , y>", userQuery: "p<x , y>",
returned: [],
error: null, error: null,
}, },
{ {
@ -548,9 +496,8 @@ const PARSED = [
}, },
], ],
foundElems: 3, foundElems: 3,
original: "p ,x , y",
returned: [],
userQuery: "p ,x , y", userQuery: "p ,x , y",
returned: [],
error: null, error: null,
}, },
]; ];

View File

@ -10,9 +10,8 @@ const PARSED = [
typeFilter: 7, typeFilter: 7,
}], }],
foundElems: 1, foundElems: 1,
original: "fn:foo",
returned: [],
userQuery: "fn:foo", userQuery: "fn:foo",
returned: [],
error: null, error: null,
}, },
{ {
@ -26,18 +25,16 @@ const PARSED = [
typeFilter: 6, typeFilter: 6,
}], }],
foundElems: 1, foundElems: 1,
original: "enum : foo",
returned: [],
userQuery: "enum : foo", userQuery: "enum : foo",
returned: [],
error: null, error: null,
}, },
{ {
query: 'macro<f>:foo', query: 'macro<f>:foo',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "macro<f>:foo",
returned: [],
userQuery: "macro<f>:foo", userQuery: "macro<f>:foo",
returned: [],
error: "Unexpected `<` in type filter (before `:`)", error: "Unexpected `<` in type filter (before `:`)",
}, },
{ {
@ -51,9 +48,8 @@ const PARSED = [
typeFilter: 16, typeFilter: 16,
}], }],
foundElems: 1, foundElems: 1,
original: "macro!",
returned: [],
userQuery: "macro!", userQuery: "macro!",
returned: [],
error: null, error: null,
}, },
{ {
@ -67,9 +63,8 @@ const PARSED = [
typeFilter: 16, typeFilter: 16,
}], }],
foundElems: 1, foundElems: 1,
original: "macro:mac!",
returned: [],
userQuery: "macro:mac!", userQuery: "macro:mac!",
returned: [],
error: null, error: null,
}, },
{ {
@ -83,16 +78,15 @@ const PARSED = [
typeFilter: 16, typeFilter: 16,
}], }],
foundElems: 1, foundElems: 1,
original: "a::mac!",
returned: [],
userQuery: "a::mac!", userQuery: "a::mac!",
returned: [],
error: null, error: null,
}, },
{ {
query: '-> fn:foo', query: '-> fn:foo',
elems: [], elems: [],
foundElems: 1, foundElems: 1,
original: "-> fn:foo", userQuery: "-> fn:foo",
returned: [{ returned: [{
name: "foo", name: "foo",
fullPath: ["foo"], fullPath: ["foo"],
@ -101,14 +95,13 @@ const PARSED = [
generics: [], generics: [],
typeFilter: 7, typeFilter: 7,
}], }],
userQuery: "-> fn:foo",
error: null, error: null,
}, },
{ {
query: '-> fn:foo<fn:bar>', query: '-> fn:foo<fn:bar>',
elems: [], elems: [],
foundElems: 1, foundElems: 1,
original: "-> fn:foo<fn:bar>", userQuery: "-> fn:foo<fn:bar>",
returned: [{ returned: [{
name: "foo", name: "foo",
fullPath: ["foo"], fullPath: ["foo"],
@ -126,14 +119,13 @@ const PARSED = [
], ],
typeFilter: 7, typeFilter: 7,
}], }],
userQuery: "-> fn:foo<fn:bar>",
error: null, error: null,
}, },
{ {
query: '-> fn:foo<fn:bar, enum : baz::fuzz>', query: '-> fn:foo<fn:bar, enum : baz::fuzz>',
elems: [], elems: [],
foundElems: 1, foundElems: 1,
original: "-> fn:foo<fn:bar, enum : baz::fuzz>", userQuery: "-> fn:foo<fn:bar, enum : baz::fuzz>",
returned: [{ returned: [{
name: "foo", name: "foo",
fullPath: ["foo"], fullPath: ["foo"],
@ -159,7 +151,6 @@ const PARSED = [
], ],
typeFilter: 7, typeFilter: 7,
}], }],
userQuery: "-> fn:foo<fn:bar, enum : baz::fuzz>",
error: null, error: null,
}, },
]; ];

View File

@ -3,9 +3,8 @@ const PARSED = [
query: 'A<B<C<D>, E>', query: 'A<B<C<D>, E>',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: 'A<B<C<D>, E>', userQuery: 'A<B<C<D>, E>',
returned: [], returned: [],
userQuery: 'a<b<c<d>, e>',
error: 'Unclosed `<`', error: 'Unclosed `<`',
}, },
{ {
@ -29,9 +28,8 @@ const PARSED = [
}, },
], ],
foundElems: 2, foundElems: 2,
original: "p<>,u8",
returned: [],
userQuery: "p<>,u8", userQuery: "p<>,u8",
returned: [],
error: null, error: null,
}, },
{ {
@ -55,9 +53,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: '"p"<a>',
returned: [],
userQuery: '"p"<a>', userQuery: '"p"<a>',
returned: [],
error: null, error: null,
}, },
{ {
@ -89,9 +86,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: 'p<u<x>>',
returned: [],
userQuery: 'p<u<x>>', userQuery: 'p<u<x>>',
returned: [],
error: null, error: null,
}, },
{ {
@ -130,9 +126,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: 'p<u<x>, r>',
returned: [],
userQuery: 'p<u<x>, r>', userQuery: 'p<u<x>, r>',
returned: [],
error: null, error: null,
}, },
{ {
@ -171,9 +166,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: 'p<u<x, r>>',
returned: [],
userQuery: 'p<u<x, r>>', userQuery: 'p<u<x, r>>',
returned: [],
error: null, error: null,
}, },
]; ];

View File

@ -12,13 +12,13 @@ const PARSED = [
[ [
"output", "output",
[{ [{
name: "f", name: "F",
fullPath: ["f"], fullPath: ["f"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "f", pathLast: "f",
generics: [ generics: [
{ {
name: "p", name: "P",
fullPath: ["p"], fullPath: ["p"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "p", pathLast: "p",
@ -32,9 +32,8 @@ const PARSED = [
typeFilter: -1, typeFilter: -1,
}], }],
foundElems: 1, foundElems: 1,
original: "(-> F<P>)", userQuery: "(-> F<P>)",
returned: [], returned: [],
userQuery: "(-> f<p>)",
error: null, error: null,
}, },
{ {
@ -49,7 +48,7 @@ const PARSED = [
[ [
"output", "output",
[{ [{
name: "p", name: "P",
fullPath: ["p"], fullPath: ["p"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "p", pathLast: "p",
@ -61,9 +60,8 @@ const PARSED = [
typeFilter: -1, typeFilter: -1,
}], }],
foundElems: 1, foundElems: 1,
original: "(-> P)", userQuery: "(-> P)",
returned: [], returned: [],
userQuery: "(-> p)",
error: null, error: null,
}, },
{ {
@ -90,9 +88,8 @@ const PARSED = [
typeFilter: -1, typeFilter: -1,
}], }],
foundElems: 1, foundElems: 1,
original: "(->,a)",
returned: [],
userQuery: "(->,a)", userQuery: "(->,a)",
returned: [],
error: null, error: null,
}, },
{ {
@ -103,13 +100,13 @@ const PARSED = [
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "->", pathLast: "->",
generics: [{ generics: [{
name: "f", name: "F",
fullPath: ["f"], fullPath: ["f"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "f", pathLast: "f",
generics: [ generics: [
{ {
name: "p", name: "P",
fullPath: ["p"], fullPath: ["p"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "p", pathLast: "p",
@ -127,9 +124,8 @@ const PARSED = [
typeFilter: -1, typeFilter: -1,
}], }],
foundElems: 1, foundElems: 1,
original: "(F<P> ->)", userQuery: "(F<P> ->)",
returned: [], returned: [],
userQuery: "(f<p> ->)",
error: null, error: null,
}, },
{ {
@ -140,7 +136,7 @@ const PARSED = [
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "->", pathLast: "->",
generics: [{ generics: [{
name: "p", name: "P",
fullPath: ["p"], fullPath: ["p"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "p", pathLast: "p",
@ -156,9 +152,8 @@ const PARSED = [
typeFilter: -1, typeFilter: -1,
}], }],
foundElems: 1, foundElems: 1,
original: "(P ->)", userQuery: "(P ->)",
returned: [], returned: [],
userQuery: "(p ->)",
error: null, error: null,
}, },
{ {
@ -185,9 +180,8 @@ const PARSED = [
typeFilter: -1, typeFilter: -1,
}], }],
foundElems: 1, foundElems: 1,
original: "(,a->)",
returned: [],
userQuery: "(,a->)", userQuery: "(,a->)",
returned: [],
error: null, error: null,
}, },
{ {
@ -221,9 +215,8 @@ const PARSED = [
typeFilter: -1, typeFilter: -1,
}], }],
foundElems: 1, foundElems: 1,
original: "(aaaaa->a)",
returned: [],
userQuery: "(aaaaa->a)", userQuery: "(aaaaa->a)",
returned: [],
error: null, error: null,
}, },
{ {
@ -267,9 +260,8 @@ const PARSED = [
typeFilter: -1, typeFilter: -1,
}], }],
foundElems: 1, foundElems: 1,
original: "(aaaaa, b -> a)",
returned: [],
userQuery: "(aaaaa, b -> a)", userQuery: "(aaaaa, b -> a)",
returned: [],
error: null, error: null,
}, },
{ {
@ -313,9 +305,8 @@ const PARSED = [
typeFilter: 1, typeFilter: 1,
}], }],
foundElems: 1, foundElems: 1,
original: "primitive:(aaaaa, b -> a)",
returned: [],
userQuery: "primitive:(aaaaa, b -> a)", userQuery: "primitive:(aaaaa, b -> a)",
returned: [],
error: null, error: null,
}, },
{ {
@ -369,16 +360,15 @@ const PARSED = [
} }
], ],
foundElems: 2, foundElems: 2,
original: "x, trait:(aaaaa, b -> a)",
returned: [],
userQuery: "x, trait:(aaaaa, b -> a)", userQuery: "x, trait:(aaaaa, b -> a)",
returned: [],
error: null, error: null,
}, },
// Rust-style HOF // Rust-style HOF
{ {
query: "Fn () -> F<P>", query: "Fn () -> F<P>",
elems: [{ elems: [{
name: "fn", name: "Fn",
fullPath: ["fn"], fullPath: ["fn"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "fn", pathLast: "fn",
@ -387,13 +377,13 @@ const PARSED = [
[ [
"output", "output",
[{ [{
name: "f", name: "F",
fullPath: ["f"], fullPath: ["f"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "f", pathLast: "f",
generics: [ generics: [
{ {
name: "p", name: "P",
fullPath: ["p"], fullPath: ["p"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "p", pathLast: "p",
@ -407,15 +397,14 @@ const PARSED = [
typeFilter: -1, typeFilter: -1,
}], }],
foundElems: 1, foundElems: 1,
original: "Fn () -> F<P>", userQuery: "Fn () -> F<P>",
returned: [], returned: [],
userQuery: "fn () -> f<p>",
error: null, error: null,
}, },
{ {
query: "FnMut() -> P", query: "FnMut() -> P",
elems: [{ elems: [{
name: "fnmut", name: "FnMut",
fullPath: ["fnmut"], fullPath: ["fnmut"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "fnmut", pathLast: "fnmut",
@ -424,7 +413,7 @@ const PARSED = [
[ [
"output", "output",
[{ [{
name: "p", name: "P",
fullPath: ["p"], fullPath: ["p"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "p", pathLast: "p",
@ -436,15 +425,14 @@ const PARSED = [
typeFilter: -1, typeFilter: -1,
}], }],
foundElems: 1, foundElems: 1,
original: "FnMut() -> P", userQuery: "FnMut() -> P",
returned: [], returned: [],
userQuery: "fnmut() -> p",
error: null, error: null,
}, },
{ {
query: "(FnMut() -> P)", query: "(FnMut() -> P)",
elems: [{ elems: [{
name: "fnmut", name: "FnMut",
fullPath: ["fnmut"], fullPath: ["fnmut"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "fnmut", pathLast: "fnmut",
@ -453,7 +441,7 @@ const PARSED = [
[ [
"output", "output",
[{ [{
name: "p", name: "P",
fullPath: ["p"], fullPath: ["p"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "p", pathLast: "p",
@ -465,26 +453,25 @@ const PARSED = [
typeFilter: -1, typeFilter: -1,
}], }],
foundElems: 1, foundElems: 1,
original: "(FnMut() -> P)", userQuery: "(FnMut() -> P)",
returned: [], returned: [],
userQuery: "(fnmut() -> p)",
error: null, error: null,
}, },
{ {
query: "Fn(F<P>)", query: "Fn(F<P>)",
elems: [{ elems: [{
name: "fn", name: "Fn",
fullPath: ["fn"], fullPath: ["fn"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "fn", pathLast: "fn",
generics: [{ generics: [{
name: "f", name: "F",
fullPath: ["f"], fullPath: ["f"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "f", pathLast: "f",
generics: [ generics: [
{ {
name: "p", name: "P",
fullPath: ["p"], fullPath: ["p"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "p", pathLast: "p",
@ -502,9 +489,8 @@ const PARSED = [
typeFilter: -1, typeFilter: -1,
}], }],
foundElems: 1, foundElems: 1,
original: "Fn(F<P>)", userQuery: "Fn(F<P>)",
returned: [], returned: [],
userQuery: "fn(f<p>)",
error: null, error: null,
}, },
{ {
@ -548,9 +534,8 @@ const PARSED = [
typeFilter: 1, typeFilter: 1,
}], }],
foundElems: 1, foundElems: 1,
original: "primitive:fnonce(aaaaa, b) -> a",
returned: [],
userQuery: "primitive:fnonce(aaaaa, b) -> a", userQuery: "primitive:fnonce(aaaaa, b) -> a",
returned: [],
error: null, error: null,
}, },
{ {
@ -594,9 +579,8 @@ const PARSED = [
typeFilter: 1, typeFilter: 1,
}], }],
foundElems: 1, foundElems: 1,
original: "primitive:fnonce(aaaaa, keyword:b) -> trait:a",
returned: [],
userQuery: "primitive:fnonce(aaaaa, keyword:b) -> trait:a", userQuery: "primitive:fnonce(aaaaa, keyword:b) -> trait:a",
returned: [],
error: null, error: null,
}, },
{ {
@ -665,9 +649,8 @@ const PARSED = [
} }
], ],
foundElems: 2, foundElems: 2,
original: "x, trait:fn(aaaaa, b -> a)",
returned: [],
userQuery: "x, trait:fn(aaaaa, b -> a)", userQuery: "x, trait:fn(aaaaa, b -> a)",
returned: [],
error: null, error: null,
}, },
{ {
@ -704,9 +687,8 @@ const PARSED = [
} }
], ],
foundElems: 2, foundElems: 2,
original: "a,b(c)",
returned: [],
userQuery: "a,b(c)", userQuery: "a,b(c)",
returned: [],
error: null, error: null,
}, },
]; ];

View File

@ -2,7 +2,7 @@ const PARSED = [
{ {
query: "R<!>", query: "R<!>",
elems: [{ elems: [{
name: "r", name: "R",
fullPath: ["r"], fullPath: ["r"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "r", pathLast: "r",
@ -19,9 +19,8 @@ const PARSED = [
typeFilter: -1, typeFilter: -1,
}], }],
foundElems: 1, foundElems: 1,
original: "R<!>", userQuery: "R<!>",
returned: [], returned: [],
userQuery: "r<!>",
error: null, error: null,
}, },
{ {
@ -35,9 +34,8 @@ const PARSED = [
typeFilter: 1, typeFilter: 1,
}], }],
foundElems: 1, foundElems: 1,
original: "!",
returned: [],
userQuery: "!", userQuery: "!",
returned: [],
error: null, error: null,
}, },
{ {
@ -51,27 +49,24 @@ const PARSED = [
typeFilter: 16, typeFilter: 16,
}], }],
foundElems: 1, foundElems: 1,
original: "a!",
returned: [],
userQuery: "a!", userQuery: "a!",
returned: [],
error: null, error: null,
}, },
{ {
query: "a!::b", query: "a!::b",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "a!::b",
returned: [],
userQuery: "a!::b", userQuery: "a!::b",
returned: [],
error: "Cannot have associated items in macros", error: "Cannot have associated items in macros",
}, },
{ {
query: "!<T>", query: "!<T>",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "!<T>", userQuery: "!<T>",
returned: [], returned: [],
userQuery: "!<t>",
error: "Never type `!` does not accept generic parameters", error: "Never type `!` does not accept generic parameters",
}, },
{ {
@ -85,36 +80,32 @@ const PARSED = [
typeFilter: -1, typeFilter: -1,
}], }],
foundElems: 1, foundElems: 1,
original: "!::b",
returned: [],
userQuery: "!::b", userQuery: "!::b",
returned: [],
error: null, error: null,
}, },
{ {
query: "b::!", query: "b::!",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "b::!",
returned: [],
userQuery: "b::!", userQuery: "b::!",
returned: [],
error: "Never type `!` is not associated item", error: "Never type `!` is not associated item",
}, },
{ {
query: "!::!", query: "!::!",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "!::!",
returned: [],
userQuery: "!::!", userQuery: "!::!",
returned: [],
error: "Never type `!` is not associated item", error: "Never type `!` is not associated item",
}, },
{ {
query: "b::!::c", query: "b::!::c",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "b::!::c",
returned: [],
userQuery: "b::!::c", userQuery: "b::!::c",
returned: [],
error: "Never type `!` is not associated item", error: "Never type `!` is not associated item",
}, },
{ {
@ -126,7 +117,7 @@ const PARSED = [
pathLast: "b", pathLast: "b",
generics: [ generics: [
{ {
name: "t", name: "T",
fullPath: ["t"], fullPath: ["t"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "t", pathLast: "t",
@ -137,18 +128,16 @@ const PARSED = [
typeFilter: -1, typeFilter: -1,
}], }],
foundElems: 1, foundElems: 1,
original: "!::b<T>", userQuery: "!::b<T>",
returned: [], returned: [],
userQuery: "!::b<t>",
error: null, error: null,
}, },
{ {
query: "a!::b!", query: "a!::b!",
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "a!::b!",
returned: [],
userQuery: "a!::b!", userQuery: "a!::b!",
returned: [],
error: "Cannot have associated items in macros", error: "Cannot have associated items in macros",
}, },
]; ];

View File

@ -2,13 +2,13 @@ const PARSED = [
{ {
query: 'R<P>', query: 'R<P>',
elems: [{ elems: [{
name: "r", name: "R",
fullPath: ["r"], fullPath: ["r"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "r", pathLast: "r",
generics: [ generics: [
{ {
name: "p", name: "P",
fullPath: ["p"], fullPath: ["p"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "p", pathLast: "p",
@ -18,9 +18,8 @@ const PARSED = [
typeFilter: -1, typeFilter: -1,
}], }],
foundElems: 1, foundElems: 1,
original: "R<P>", userQuery: "R<P>",
returned: [], returned: [],
userQuery: "r<p>",
error: null, error: null,
} }
]; ];

View File

@ -2,7 +2,7 @@ const PARSED = [
{ {
query: 'A::B', query: 'A::B',
elems: [{ elems: [{
name: "a::b", name: "A::B",
fullPath: ["a", "b"], fullPath: ["a", "b"],
pathWithoutLast: ["a"], pathWithoutLast: ["a"],
pathLast: "b", pathLast: "b",
@ -10,9 +10,8 @@ const PARSED = [
typeFilter: -1, typeFilter: -1,
}], }],
foundElems: 1, foundElems: 1,
original: "A::B", userQuery: "A::B",
returned: [], returned: [],
userQuery: "a::b",
error: null, error: null,
}, },
{ {
@ -26,9 +25,8 @@ const PARSED = [
typeFilter: -1, typeFilter: -1,
}], }],
foundElems: 1, foundElems: 1,
original: 'a:: a',
returned: [],
userQuery: 'a:: a', userQuery: 'a:: a',
returned: [],
error: null, error: null,
}, },
{ {
@ -42,9 +40,8 @@ const PARSED = [
typeFilter: -1, typeFilter: -1,
}], }],
foundElems: 1, foundElems: 1,
original: 'a ::a',
returned: [],
userQuery: 'a ::a', userQuery: 'a ::a',
returned: [],
error: null, error: null,
}, },
{ {
@ -58,16 +55,15 @@ const PARSED = [
typeFilter: -1, typeFilter: -1,
}], }],
foundElems: 1, foundElems: 1,
original: 'a :: a',
returned: [],
userQuery: 'a :: a', userQuery: 'a :: a',
returned: [],
error: null, error: null,
}, },
{ {
query: 'A::B,C', query: 'A::B,C',
elems: [ elems: [
{ {
name: "a::b", name: "A::B",
fullPath: ["a", "b"], fullPath: ["a", "b"],
pathWithoutLast: ["a"], pathWithoutLast: ["a"],
pathLast: "b", pathLast: "b",
@ -75,7 +71,7 @@ const PARSED = [
typeFilter: -1, typeFilter: -1,
}, },
{ {
name: "c", name: "C",
fullPath: ["c"], fullPath: ["c"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "c", pathLast: "c",
@ -84,16 +80,15 @@ const PARSED = [
}, },
], ],
foundElems: 2, foundElems: 2,
original: 'A::B,C', userQuery: 'A::B,C',
returned: [], returned: [],
userQuery: 'a::b,c',
error: null, error: null,
}, },
{ {
query: 'A::B<f>,C', query: 'A::B<f>,C',
elems: [ elems: [
{ {
name: "a::b", name: "A::B",
fullPath: ["a", "b"], fullPath: ["a", "b"],
pathWithoutLast: ["a"], pathWithoutLast: ["a"],
pathLast: "b", pathLast: "b",
@ -109,7 +104,7 @@ const PARSED = [
typeFilter: -1, typeFilter: -1,
}, },
{ {
name: "c", name: "C",
fullPath: ["c"], fullPath: ["c"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "c", pathLast: "c",
@ -118,9 +113,8 @@ const PARSED = [
}, },
], ],
foundElems: 2, foundElems: 2,
original: 'A::B<f>,C', userQuery: 'A::B<f>,C',
returned: [], returned: [],
userQuery: 'a::b<f>,c',
error: null, error: null,
}, },
{ {
@ -134,9 +128,8 @@ const PARSED = [
typeFilter: -1, typeFilter: -1,
}], }],
foundElems: 1, foundElems: 1,
original: "mod::a",
returned: [],
userQuery: "mod::a", userQuery: "mod::a",
returned: [],
error: null, error: null,
}, },
]; ];

View File

@ -3,7 +3,7 @@ const PARSED = [
query: '-> "p"', query: '-> "p"',
elems: [], elems: [],
foundElems: 1, foundElems: 1,
original: '-> "p"', userQuery: '-> "p"',
returned: [{ returned: [{
name: "p", name: "p",
fullPath: ["p"], fullPath: ["p"],
@ -12,7 +12,6 @@ const PARSED = [
generics: [], generics: [],
typeFilter: -1, typeFilter: -1,
}], }],
userQuery: '-> "p"',
error: null, error: null,
}, },
{ {
@ -26,54 +25,48 @@ const PARSED = [
typeFilter: -1, typeFilter: -1,
}], }],
foundElems: 1, foundElems: 1,
original: '"p",',
returned: [],
userQuery: '"p",', userQuery: '"p",',
returned: [],
error: null, error: null,
}, },
{ {
query: '"p" -> a', query: '"p" -> a',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: '"p" -> a',
returned: [],
userQuery: '"p" -> a', userQuery: '"p" -> a',
returned: [],
error: "Cannot have more than one element if you use quotes", error: "Cannot have more than one element if you use quotes",
}, },
{ {
query: '"a" -> "p"', query: '"a" -> "p"',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: '"a" -> "p"',
returned: [],
userQuery: '"a" -> "p"', userQuery: '"a" -> "p"',
returned: [],
error: "Cannot have more than one literal search element", error: "Cannot have more than one literal search element",
}, },
{ {
query: '->"-"', query: '->"-"',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: '->"-"',
returned: [],
userQuery: '->"-"', userQuery: '->"-"',
returned: [],
error: 'Unexpected `-` in a string element', error: 'Unexpected `-` in a string element',
}, },
{ {
query: '"a', query: '"a',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: '"a',
returned: [],
userQuery: '"a', userQuery: '"a',
returned: [],
error: 'Unclosed `"`', error: 'Unclosed `"`',
}, },
{ {
query: '""', query: '""',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: '""',
returned: [],
userQuery: '""', userQuery: '""',
returned: [],
error: 'Cannot have empty string element', error: 'Cannot have empty string element',
}, },
]; ];

View File

@ -3,18 +3,16 @@ const PARSED = [
query: '&[', query: '&[',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: '&[',
returned: [],
userQuery: '&[', userQuery: '&[',
returned: [],
error: 'Unclosed `[`', error: 'Unclosed `[`',
}, },
{ {
query: '[&', query: '[&',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: '[&',
returned: [],
userQuery: '[&', userQuery: '[&',
returned: [],
error: 'Unclosed `[`', error: 'Unclosed `[`',
}, },
{ {
@ -39,7 +37,7 @@ const PARSED = [
pathLast: "reference", pathLast: "reference",
generics: [ generics: [
{ {
name: "d", name: "D",
fullPath: ["d"], fullPath: ["d"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "d", pathLast: "d",
@ -65,9 +63,8 @@ const PARSED = [
}, },
], ],
foundElems: 2, foundElems: 2,
original: '&&&D, []', userQuery: '&&&D, []',
returned: [], returned: [],
userQuery: '&&&d, []',
error: null, error: null,
}, },
{ {
@ -98,7 +95,7 @@ const PARSED = [
pathLast: "[]", pathLast: "[]",
generics: [ generics: [
{ {
name: "d", name: "D",
fullPath: ["d"], fullPath: ["d"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "d", pathLast: "d",
@ -119,9 +116,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: '&&&[D]', userQuery: '&&&[D]',
returned: [], returned: [],
userQuery: '&&&[d]',
error: null, error: null,
}, },
{ {
@ -137,9 +133,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: '&',
returned: [],
userQuery: '&', userQuery: '&',
returned: [],
error: null, error: null,
}, },
{ {
@ -164,9 +159,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: '&mut',
returned: [],
userQuery: '&mut', userQuery: '&mut',
returned: [],
error: null, error: null,
}, },
{ {
@ -190,9 +184,8 @@ const PARSED = [
}, },
], ],
foundElems: 2, foundElems: 2,
original: "&,u8",
returned: [],
userQuery: "&,u8", userQuery: "&,u8",
returned: [],
error: null, error: null,
}, },
{ {
@ -225,9 +218,8 @@ const PARSED = [
}, },
], ],
foundElems: 2, foundElems: 2,
original: "&mut,u8",
returned: [],
userQuery: "&mut,u8", userQuery: "&mut,u8",
returned: [],
error: null, error: null,
}, },
{ {
@ -252,9 +244,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: "&u8",
returned: [],
userQuery: "&u8", userQuery: "&u8",
returned: [],
error: null, error: null,
}, },
{ {
@ -288,9 +279,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: "&u8<u8>",
returned: [],
userQuery: "&u8<u8>", userQuery: "&u8<u8>",
returned: [],
error: null, error: null,
}, },
{ {
@ -324,9 +314,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: "u8<&u8>",
returned: [],
userQuery: "u8<&u8>", userQuery: "u8<&u8>",
returned: [],
error: null, error: null,
}, },
{ {
@ -368,9 +357,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: "u8<&u8, u8>",
returned: [],
userQuery: "u8<&u8, u8>", userQuery: "u8<&u8, u8>",
returned: [],
error: null, error: null,
}, },
{ {
@ -404,9 +392,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: "u8<&u8>",
returned: [],
userQuery: "u8<&u8>", userQuery: "u8<&u8>",
returned: [],
error: null, error: null,
}, },
{ {
@ -456,9 +443,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: "u8<&mut u8, u8>",
returned: [],
userQuery: "u8<&mut u8, u8>", userQuery: "u8<&mut u8, u8>",
returned: [],
error: null, error: null,
}, },
{ {
@ -483,18 +469,16 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: "primitive:&u8",
returned: [],
userQuery: "primitive:&u8", userQuery: "primitive:&u8",
returned: [],
error: null, error: null,
}, },
{ {
query: 'macro:&u8', query: 'macro:&u8',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "macro:&u8",
returned: [],
userQuery: "macro:&u8", userQuery: "macro:&u8",
returned: [],
error: "Invalid search type: primitive `&` and `macro` both specified", error: "Invalid search type: primitive `&` and `macro` both specified",
}, },
{ {
@ -519,9 +503,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: "&macro:u8",
returned: [],
userQuery: "&macro:u8", userQuery: "&macro:u8",
returned: [],
error: null, error: null,
}, },
]; ];

View File

@ -3,15 +3,15 @@ const PARSED = [
query: "-> F<P>", query: "-> F<P>",
elems: [], elems: [],
foundElems: 1, foundElems: 1,
original: "-> F<P>", userQuery: "-> F<P>",
returned: [{ returned: [{
name: "f", name: "F",
fullPath: ["f"], fullPath: ["f"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "f", pathLast: "f",
generics: [ generics: [
{ {
name: "p", name: "P",
fullPath: ["p"], fullPath: ["p"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "p", pathLast: "p",
@ -20,30 +20,28 @@ const PARSED = [
], ],
typeFilter: -1, typeFilter: -1,
}], }],
userQuery: "-> f<p>",
error: null, error: null,
}, },
{ {
query: "-> P", query: "-> P",
elems: [], elems: [],
foundElems: 1, foundElems: 1,
original: "-> P", userQuery: "-> P",
returned: [{ returned: [{
name: "p", name: "P",
fullPath: ["p"], fullPath: ["p"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "p", pathLast: "p",
generics: [], generics: [],
typeFilter: -1, typeFilter: -1,
}], }],
userQuery: "-> p",
error: null, error: null,
}, },
{ {
query: "->,a", query: "->,a",
elems: [], elems: [],
foundElems: 1, foundElems: 1,
original: "->,a", userQuery: "->,a",
returned: [{ returned: [{
name: "a", name: "a",
fullPath: ["a"], fullPath: ["a"],
@ -52,7 +50,6 @@ const PARSED = [
generics: [], generics: [],
typeFilter: -1, typeFilter: -1,
}], }],
userQuery: "->,a",
error: null, error: null,
}, },
{ {
@ -66,7 +63,7 @@ const PARSED = [
typeFilter: -1, typeFilter: -1,
}], }],
foundElems: 2, foundElems: 2,
original: "aaaaa->a", userQuery: "aaaaa->a",
returned: [{ returned: [{
name: "a", name: "a",
fullPath: ["a"], fullPath: ["a"],
@ -75,14 +72,13 @@ const PARSED = [
generics: [], generics: [],
typeFilter: -1, typeFilter: -1,
}], }],
userQuery: "aaaaa->a",
error: null, error: null,
}, },
{ {
query: "-> !", query: "-> !",
elems: [], elems: [],
foundElems: 1, foundElems: 1,
original: "-> !", userQuery: "-> !",
returned: [{ returned: [{
name: "never", name: "never",
fullPath: ["never"], fullPath: ["never"],
@ -91,7 +87,6 @@ const PARSED = [
generics: [], generics: [],
typeFilter: 1, typeFilter: 1,
}], }],
userQuery: "-> !",
error: null, error: null,
}, },
{ {
@ -105,9 +100,8 @@ const PARSED = [
typeFilter: -1, typeFilter: -1,
}], }],
foundElems: 1, foundElems: 1,
original: "a->",
returned: [],
userQuery: "a->", userQuery: "a->",
returned: [],
hasReturnArrow: true, hasReturnArrow: true,
error: null, error: null,
}, },
@ -122,9 +116,8 @@ const PARSED = [
typeFilter: 1, typeFilter: 1,
}], }],
foundElems: 1, foundElems: 1,
original: "!->",
returned: [],
userQuery: "!->", userQuery: "!->",
returned: [],
hasReturnArrow: true, hasReturnArrow: true,
error: null, error: null,
}, },
@ -139,9 +132,8 @@ const PARSED = [
typeFilter: 1, typeFilter: 1,
}], }],
foundElems: 1, foundElems: 1,
original: "! ->",
returned: [],
userQuery: "! ->", userQuery: "! ->",
returned: [],
hasReturnArrow: true, hasReturnArrow: true,
error: null, error: null,
}, },
@ -156,9 +148,8 @@ const PARSED = [
typeFilter: 1, typeFilter: 1,
}], }],
foundElems: 1, foundElems: 1,
original: "primitive:!->",
returned: [],
userQuery: "primitive:!->", userQuery: "primitive:!->",
returned: [],
hasReturnArrow: true, hasReturnArrow: true,
error: null, error: null,
}, },

View File

@ -14,9 +14,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: "aaaaaa b",
returned: [],
userQuery: "aaaaaa b", userQuery: "aaaaaa b",
returned: [],
error: null, error: null,
}, },
{ {
@ -40,9 +39,8 @@ const PARSED = [
}, },
], ],
foundElems: 2, foundElems: 2,
original: "aaaaaa, b",
returned: [],
userQuery: "aaaaaa, b", userQuery: "aaaaaa, b",
returned: [],
error: null, error: null,
}, },
{ {
@ -58,9 +56,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: "a b",
returned: [],
userQuery: "a b", userQuery: "a b",
returned: [],
error: null, error: null,
}, },
{ {
@ -84,9 +81,8 @@ const PARSED = [
}, },
], ],
foundElems: 2, foundElems: 2,
original: "a,b",
returned: [],
userQuery: "a,b", userQuery: "a,b",
returned: [],
error: null, error: null,
}, },
{ {
@ -102,9 +98,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: "a b",
returned: [],
userQuery: "a b", userQuery: "a b",
returned: [],
error: null, error: null,
}, },
{ {
@ -128,9 +123,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: "a<b c>",
returned: [],
userQuery: "a<b c>", userQuery: "a<b c>",
returned: [],
error: null, error: null,
}, },
{ {
@ -161,9 +155,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: "a<b,c>",
returned: [],
userQuery: "a<b,c>", userQuery: "a<b,c>",
returned: [],
error: null, error: null,
}, },
{ {
@ -187,9 +180,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: "a<b c>",
returned: [],
userQuery: "a<b c>", userQuery: "a<b c>",
returned: [],
error: null, error: null,
}, },
]; ];

View File

@ -3,9 +3,8 @@ const PARSED = [
query: '[[[D, []]]', query: '[[[D, []]]',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: '[[[D, []]]', userQuery: '[[[D, []]]',
returned: [], returned: [],
userQuery: '[[[d, []]]',
error: 'Unclosed `[`', error: 'Unclosed `[`',
}, },
{ {
@ -30,7 +29,7 @@ const PARSED = [
pathLast: "[]", pathLast: "[]",
generics: [ generics: [
{ {
name: "d", name: "D",
fullPath: ["d"], fullPath: ["d"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "d", pathLast: "d",
@ -56,9 +55,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: '[[[D, []]]]', userQuery: '[[[D, []]]]',
returned: [], returned: [],
userQuery: '[[[d, []]]]',
error: null, error: null,
}, },
{ {
@ -82,9 +80,8 @@ const PARSED = [
}, },
], ],
foundElems: 2, foundElems: 2,
original: "[],u8",
returned: [],
userQuery: "[],u8", userQuery: "[],u8",
returned: [],
error: null, error: null,
}, },
{ {
@ -109,9 +106,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: "[u8]",
returned: [],
userQuery: "[u8]", userQuery: "[u8]",
returned: [],
error: null, error: null,
}, },
{ {
@ -144,9 +140,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: "[u8,u8]",
returned: [],
userQuery: "[u8,u8]", userQuery: "[u8,u8]",
returned: [],
error: null, error: null,
}, },
{ {
@ -180,9 +175,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: "[u8<u8>]",
returned: [],
userQuery: "[u8<u8>]", userQuery: "[u8<u8>]",
returned: [],
error: null, error: null,
}, },
{ {
@ -198,90 +192,80 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: "[]",
returned: [],
userQuery: "[]", userQuery: "[]",
returned: [],
error: null, error: null,
}, },
{ {
query: '[>', query: '[>',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "[>",
returned: [],
userQuery: "[>", userQuery: "[>",
returned: [],
error: "Unexpected `>` after `[`", error: "Unexpected `>` after `[`",
}, },
{ {
query: '[<', query: '[<',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "[<",
returned: [],
userQuery: "[<", userQuery: "[<",
returned: [],
error: "Found generics without a path", error: "Found generics without a path",
}, },
{ {
query: '[a>', query: '[a>',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "[a>",
returned: [],
userQuery: "[a>", userQuery: "[a>",
returned: [],
error: "Unexpected `>` after `[`", error: "Unexpected `>` after `[`",
}, },
{ {
query: '[a<', query: '[a<',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "[a<",
returned: [],
userQuery: "[a<", userQuery: "[a<",
returned: [],
error: "Unclosed `<`", error: "Unclosed `<`",
}, },
{ {
query: '[a', query: '[a',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "[a",
returned: [],
userQuery: "[a", userQuery: "[a",
returned: [],
error: "Unclosed `[`", error: "Unclosed `[`",
}, },
{ {
query: '[', query: '[',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "[",
returned: [],
userQuery: "[", userQuery: "[",
returned: [],
error: "Unclosed `[`", error: "Unclosed `[`",
}, },
{ {
query: ']', query: ']',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "]",
returned: [],
userQuery: "]", userQuery: "]",
returned: [],
error: "Unexpected `]`", error: "Unexpected `]`",
}, },
{ {
query: '[a<b>', query: '[a<b>',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "[a<b>",
returned: [],
userQuery: "[a<b>", userQuery: "[a<b>",
returned: [],
error: "Unclosed `[`", error: "Unclosed `[`",
}, },
{ {
query: 'a<b>]', query: 'a<b>]',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "a<b>]",
returned: [],
userQuery: "a<b>]", userQuery: "a<b>]",
returned: [],
error: "Unexpected `]` after `>`", error: "Unexpected `]` after `>`",
}, },
{ {
@ -306,18 +290,16 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: "primitive:[u8]",
returned: [],
userQuery: "primitive:[u8]", userQuery: "primitive:[u8]",
returned: [],
error: null, error: null,
}, },
{ {
query: 'macro:[u8]', query: 'macro:[u8]',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "macro:[u8]",
returned: [],
userQuery: "macro:[u8]", userQuery: "macro:[u8]",
returned: [],
error: "Invalid search type: primitive `[]` and `macro` both specified", error: "Invalid search type: primitive `[]` and `macro` both specified",
}, },
]; ];

View File

@ -3,9 +3,8 @@ const PARSED = [
query: '(((D, ()))', query: '(((D, ()))',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: '(((D, ()))', userQuery: '(((D, ()))',
returned: [], returned: [],
userQuery: '(((d, ()))',
error: 'Unclosed `(`', error: 'Unclosed `(`',
}, },
{ {
@ -18,7 +17,7 @@ const PARSED = [
pathLast: "()", pathLast: "()",
generics: [ generics: [
{ {
name: "d", name: "D",
fullPath: ["d"], fullPath: ["d"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "d", pathLast: "d",
@ -38,9 +37,8 @@ const PARSED = [
} }
], ],
foundElems: 1, foundElems: 1,
original: '(((D, ())))', userQuery: '(((D, ())))',
returned: [], returned: [],
userQuery: '(((d, ())))',
error: null, error: null,
}, },
{ {
@ -64,9 +62,8 @@ const PARSED = [
}, },
], ],
foundElems: 2, foundElems: 2,
original: "(),u8",
returned: [],
userQuery: "(),u8", userQuery: "(),u8",
returned: [],
error: null, error: null,
}, },
// Parens act as grouping operators when: // Parens act as grouping operators when:
@ -88,9 +85,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: "(u8)",
returned: [],
userQuery: "(u8)", userQuery: "(u8)",
returned: [],
error: null, error: null,
}, },
{ {
@ -115,9 +111,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: "(u8,)",
returned: [],
userQuery: "(u8,)", userQuery: "(u8,)",
returned: [],
error: null, error: null,
}, },
{ {
@ -142,9 +137,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: "(,u8)",
returned: [],
userQuery: "(,u8)", userQuery: "(,u8)",
returned: [],
error: null, error: null,
}, },
{ {
@ -169,9 +163,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: "primitive:(u8)",
returned: [],
userQuery: "primitive:(u8)", userQuery: "primitive:(u8)",
returned: [],
error: null, error: null,
}, },
{ {
@ -187,9 +180,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: "(primitive:u8)",
returned: [],
userQuery: "(primitive:u8)", userQuery: "(primitive:u8)",
returned: [],
error: null, error: null,
}, },
{ {
@ -222,9 +214,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: "(u8,u8)",
returned: [],
userQuery: "(u8,u8)", userQuery: "(u8,u8)",
returned: [],
error: null, error: null,
}, },
{ {
@ -249,9 +240,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: "(u8<u8>)",
returned: [],
userQuery: "(u8<u8>)", userQuery: "(u8<u8>)",
returned: [],
error: null, error: null,
}, },
{ {
@ -267,99 +257,88 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: "()",
returned: [],
userQuery: "()", userQuery: "()",
returned: [],
error: null, error: null,
}, },
{ {
query: '(>', query: '(>',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "(>",
returned: [],
userQuery: "(>", userQuery: "(>",
returned: [],
error: "Unexpected `>` after `(`", error: "Unexpected `>` after `(`",
}, },
{ {
query: '(<', query: '(<',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "(<",
returned: [],
userQuery: "(<", userQuery: "(<",
returned: [],
error: "Found generics without a path", error: "Found generics without a path",
}, },
{ {
query: '(a>', query: '(a>',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "(a>",
returned: [],
userQuery: "(a>", userQuery: "(a>",
returned: [],
error: "Unexpected `>` after `(`", error: "Unexpected `>` after `(`",
}, },
{ {
query: '(a<', query: '(a<',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "(a<",
returned: [],
userQuery: "(a<", userQuery: "(a<",
returned: [],
error: "Unclosed `<`", error: "Unclosed `<`",
}, },
{ {
query: '(a', query: '(a',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "(a",
returned: [],
userQuery: "(a", userQuery: "(a",
returned: [],
error: "Unclosed `(`", error: "Unclosed `(`",
}, },
{ {
query: '(', query: '(',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "(",
returned: [],
userQuery: "(", userQuery: "(",
returned: [],
error: "Unclosed `(`", error: "Unclosed `(`",
}, },
{ {
query: ')', query: ')',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: ")",
returned: [],
userQuery: ")", userQuery: ")",
returned: [],
error: "Unexpected `)`", error: "Unexpected `)`",
}, },
{ {
query: '(a<b>', query: '(a<b>',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "(a<b>",
returned: [],
userQuery: "(a<b>", userQuery: "(a<b>",
returned: [],
error: "Unclosed `(`", error: "Unclosed `(`",
}, },
{ {
query: 'a<b>)', query: 'a<b>)',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "a<b>)",
returned: [],
userQuery: "a<b>)", userQuery: "a<b>)",
returned: [],
error: "Unexpected `)` after `>`", error: "Unexpected `)` after `>`",
}, },
{ {
query: 'macro:(u8)', query: 'macro:(u8)',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "macro:(u8)",
returned: [],
userQuery: "macro:(u8)", userQuery: "macro:(u8)",
returned: [],
error: "Invalid search type: primitive `()` and `macro` both specified", error: "Invalid search type: primitive `()` and `macro` both specified",
}, },
]; ];

View File

@ -15,9 +15,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: "a b",
returned: [],
userQuery: "a b", userQuery: "a b",
returned: [],
error: null, error: null,
}, },
{ {
@ -32,9 +31,8 @@ const PARSED = [
}, },
], ],
foundElems: 1, foundElems: 1,
original: "a b",
returned: [],
userQuery: "a b", userQuery: "a b",
returned: [],
error: null, error: null,
}, },
{ {
@ -56,36 +54,32 @@ const PARSED = [
}, },
], ],
foundElems: 2, foundElems: 2,
original: "aaa,a",
returned: [],
userQuery: "aaa,a", userQuery: "aaa,a",
returned: [],
error: null, error: null,
}, },
{ {
query: ',,,,', query: ',,,,',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: ",,,,",
returned: [],
userQuery: ",,,,", userQuery: ",,,,",
returned: [],
error: null, error: null,
}, },
{ {
query: 'mod :', query: 'mod :',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: 'mod :',
returned: [],
userQuery: 'mod :', userQuery: 'mod :',
returned: [],
error: "Unexpected `:` (expected path after type filter `mod:`)", error: "Unexpected `:` (expected path after type filter `mod:`)",
}, },
{ {
query: 'mod\t:', query: 'mod\t:',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: 'mod :',
returned: [],
userQuery: 'mod :', userQuery: 'mod :',
returned: [],
error: "Unexpected `:` (expected path after type filter `mod:`)", error: "Unexpected `:` (expected path after type filter `mod:`)",
}, },
]; ];

View File

@ -20,11 +20,6 @@ const EXPECTED = [
'name': 'simd_min', 'name': 'simd_min',
'href': '../std/simd/prelude/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci16,+N%3E/method.simd_min' 'href': '../std/simd/prelude/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci16,+N%3E/method.simd_min'
}, },
{
'path': 'std::simd::prelude::Simd',
'name': 'simd_clamp',
'href': '../std/simd/prelude/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci16,+N%3E/method.simd_clamp'
},
{ {
'path': 'std::simd::prelude::Simd', 'path': 'std::simd::prelude::Simd',
'name': 'saturating_add', 'name': 'saturating_add',
@ -35,6 +30,11 @@ const EXPECTED = [
'name': 'saturating_sub', 'name': 'saturating_sub',
'href': '../std/simd/prelude/struct.Simd.html#impl-SimdInt-for-Simd%3Ci16,+N%3E/method.saturating_sub' 'href': '../std/simd/prelude/struct.Simd.html#impl-SimdInt-for-Simd%3Ci16,+N%3E/method.saturating_sub'
}, },
{
'path': 'std::simd::prelude::Simd',
'name': 'simd_clamp',
'href': '../std/simd/prelude/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci16,+N%3E/method.simd_clamp'
},
], ],
}, },
{ {
@ -50,11 +50,6 @@ const EXPECTED = [
'name': 'simd_min', 'name': 'simd_min',
'href': '../std/simd/prelude/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci8,+N%3E/method.simd_min' 'href': '../std/simd/prelude/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci8,+N%3E/method.simd_min'
}, },
{
'path': 'std::simd::prelude::Simd',
'name': 'simd_clamp',
'href': '../std/simd/prelude/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci8,+N%3E/method.simd_clamp'
},
{ {
'path': 'std::simd::prelude::Simd', 'path': 'std::simd::prelude::Simd',
'name': 'saturating_add', 'name': 'saturating_add',
@ -65,6 +60,11 @@ const EXPECTED = [
'name': 'saturating_sub', 'name': 'saturating_sub',
'href': '../std/simd/prelude/struct.Simd.html#impl-SimdInt-for-Simd%3Ci8,+N%3E/method.saturating_sub' 'href': '../std/simd/prelude/struct.Simd.html#impl-SimdInt-for-Simd%3Ci8,+N%3E/method.saturating_sub'
}, },
{
'path': 'std::simd::prelude::Simd',
'name': 'simd_clamp',
'href': '../std/simd/prelude/struct.Simd.html#impl-SimdOrd-for-Simd%3Ci8,+N%3E/method.simd_clamp'
},
], ],
}, },
]; ];

View File

@ -0,0 +1,13 @@
// should-fail
const EXPECTED = [
{
// Keep this test case identical to `transmute`, except the
// should-fail tag and the search query below:
'query': 'generic:T -> generic:T',
'others': [
{ 'path': 'std::intrinsics::simd', 'name': 'simd_as' },
{ 'path': 'std::intrinsics::simd', 'name': 'simd_cast' },
{ 'path': 'std::intrinsics', 'name': 'transmute' },
],
},
];

View File

@ -0,0 +1,12 @@
const EXPECTED = [
{
// Keep this test case identical to `transmute-fail`, except the
// should-fail tag and the search query below:
'query': 'generic:T -> generic:U',
'others': [
{ 'path': 'std::intrinsics::simd', 'name': 'simd_as' },
{ 'path': 'std::intrinsics::simd', 'name': 'simd_cast' },
{ 'path': 'std::intrinsics', 'name': 'transmute' },
],
},
];

View File

@ -19,4 +19,16 @@ const EXPECTED = [
{ 'path': 'std::vec::IntoIter', 'name': 'next_chunk' }, { 'path': 'std::vec::IntoIter', 'name': 'next_chunk' },
], ],
}, },
{
'query': 'vec<T, Allocator> -> Box<[T]>',
'others': [
{
'path': 'std::boxed::Box',
'name': 'from',
'displayType': '`Vec`<`T`, `A`> -> `Box`<`[T]`, A>',
'displayMappedNames': `T = T`,
'displayWhereClause': 'A: `Allocator`',
},
],
},
]; ];

View File

@ -6,7 +6,6 @@ const EXPECTED = [
'correction': null, 'correction': null,
'others': [ 'others': [
{ 'path': 'assoc_type_backtrack::MyTrait', 'name': 'fold' }, { 'path': 'assoc_type_backtrack::MyTrait', 'name': 'fold' },
{ 'path': 'assoc_type_backtrack::Cloned', 'name': 'fold' },
], ],
}, },
{ {
@ -14,6 +13,19 @@ const EXPECTED = [
'correction': null, 'correction': null,
'others': [ 'others': [
{ 'path': 'assoc_type_backtrack::MyTrait', 'name': 'fold' }, { 'path': 'assoc_type_backtrack::MyTrait', 'name': 'fold' },
],
},
{
'query': 'cloned<mytrait>, mytrait2 -> T',
'correction': null,
'others': [
{ 'path': 'assoc_type_backtrack::Cloned', 'name': 'fold' },
],
},
{
'query': 'cloned<mytrait<U>>, mytrait2 -> T',
'correction': null,
'others': [
{ 'path': 'assoc_type_backtrack::Cloned', 'name': 'fold' }, { 'path': 'assoc_type_backtrack::Cloned', 'name': 'fold' },
], ],
}, },
@ -22,7 +34,6 @@ const EXPECTED = [
'correction': null, 'correction': null,
'others': [ 'others': [
{ 'path': 'assoc_type_backtrack::MyTrait', 'name': 'fold' }, { 'path': 'assoc_type_backtrack::MyTrait', 'name': 'fold' },
{ 'path': 'assoc_type_backtrack::Cloned', 'name': 'fold' },
], ],
}, },
{ {
@ -50,14 +61,14 @@ const EXPECTED = [
], ],
}, },
{ {
'query': 'mytrait<U> -> Option<T>', 'query': 'cloned<mytrait<U>> -> Option<T>',
'correction': null, 'correction': null,
'others': [ 'others': [
{ 'path': 'assoc_type_backtrack::Cloned', 'name': 'next' }, { 'path': 'assoc_type_backtrack::Cloned', 'name': 'next' },
], ],
}, },
{ {
'query': 'mytrait<Item=U> -> Option<T>', 'query': 'cloned<mytrait<Item=U>> -> Option<T>',
'correction': null, 'correction': null,
'others': [ 'others': [
{ 'path': 'assoc_type_backtrack::Cloned', 'name': 'next' }, { 'path': 'assoc_type_backtrack::Cloned', 'name': 'next' },
@ -89,19 +100,21 @@ const EXPECTED = [
], ],
}, },
{ {
'query': 'myintofuture<myfuture<t>> -> myfuture<t>', 'query': 'myintofuture<t, myfuture<t>> -> myfuture<t>',
'correction': null, 'correction': null,
'others': [ 'others': [
{ 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future' }, { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future' },
{ 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' }, { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' },
], ],
}, },
// Invalid unboxing of the one-argument case. // Unboxings of the one-argument case.
// If you unbox one of the myfutures, you need to unbox both of them.
{ {
'query': 'myintofuture<fut=t> -> myfuture<t>', 'query': 'myintofuture<fut=t> -> myfuture<t>',
'correction': null, 'correction': null,
'others': [], 'others': [
{ 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future' },
{ 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' },
],
}, },
// Unboxings of the two-argument case. // Unboxings of the two-argument case.
{ {
@ -119,7 +132,7 @@ const EXPECTED = [
], ],
}, },
{ {
'query': 'myintofuture<myfuture>, myintofuture<myfuture> -> myfuture', 'query': 'myintofuture<t, myfuture>, myintofuture<t, myfuture> -> myfuture',
'correction': null, 'correction': null,
'others': [ 'others': [
{ 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' }, { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' },
@ -132,24 +145,29 @@ const EXPECTED = [
{ 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' }, { 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' },
], ],
}, },
// Invalid unboxings of the two-argument case. // If you unbox one of the myfutures, you don't need to unbox all of them.
// If you unbox one of the myfutures, you need to unbox all of them.
{ {
'query': 'myintofuture<fut=t>, myintofuture<fut=myfuture<t>> -> myfuture<t>', 'query': 'myintofuture<fut=t>, myintofuture<fut=myfuture<t>> -> myfuture<t>',
'correction': null, 'correction': null,
'others': [], 'others': [
{ 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' },
],
}, },
{ {
'query': 'myintofuture<fut=myfuture<t>>, myintofuture<fut=t> -> myfuture<t>', 'query': 'myintofuture<fut=myfuture<t>>, myintofuture<fut=t> -> myfuture<t>',
'correction': null, 'correction': null,
'others': [], 'others': [
{ 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' },
],
}, },
{ {
'query': 'myintofuture<fut=myfuture<t>>, myintofuture<fut=myfuture<t>> -> t', 'query': 'myintofuture<fut=myfuture<t>>, myintofuture<fut=myfuture<t>> -> t',
'correction': null, 'correction': null,
'others': [], 'others': [
{ 'path': 'assoc_type_backtrack::MyIntoFuture', 'name': 'into_future_2' },
],
}, },
// different generics don't match up either // different generics must match up
{ {
'query': 'myintofuture<fut=myfuture<u>>, myintofuture<fut=myfuture<t>> -> myfuture<t>', 'query': 'myintofuture<fut=myfuture<u>>, myintofuture<fut=myfuture<t>> -> myfuture<t>',
'correction': null, 'correction': null,

View File

@ -1,3 +1,5 @@
#![feature(rustdoc_internals)]
pub trait MyTrait2<X> { pub trait MyTrait2<X> {
type Output; type Output;
} }
@ -31,10 +33,12 @@ where
} }
} }
#[doc(search_unbox)]
pub trait MyFuture { pub trait MyFuture {
type Output; type Output;
} }
#[doc(search_unbox)]
pub trait MyIntoFuture { pub trait MyIntoFuture {
type Output; type Output;
type Fut: MyFuture<Output = Self::Output>; type Fut: MyFuture<Output = Self::Output>;

View File

@ -0,0 +1,39 @@
// exact-check
const EXPECTED = [
// Trait-associated types (that is, associated types with no constraints)
// are treated like type parameters, so that you can "pattern match"
// them. We should avoid redundant output (no `Item=MyIter::Item` stuff)
// and should give reasonable results
{
'query': 'MyIter<T> -> Option<T>',
'correction': null,
'others': [
{
'path': 'assoc_type_unbound::MyIter',
'name': 'next',
'displayType': '&mut `MyIter` -> `Option`<`MyIter::Item`>',
'displayMappedNames': 'T = MyIter::Item',
'displayWhereClause': '',
},
],
},
{
'query': 'MyIter<Item=T> -> Option<T>',
'correction': null,
'others': [
{
'path': 'assoc_type_unbound::MyIter',
'name': 'next',
'displayType': '&mut `MyIter` -> `Option`<`MyIter::Item`>',
'displayMappedNames': 'T = MyIter::Item',
'displayWhereClause': '',
},
],
},
{
'query': 'MyIter<T> -> Option<Item=T>',
'correction': null,
'others': [],
},
];

View File

@ -0,0 +1,4 @@
pub trait MyIter {
type Item;
fn next(&mut self) -> Option<Self::Item>;
}

View File

@ -7,16 +7,40 @@ const EXPECTED = [
'query': 'iterator<something> -> u32', 'query': 'iterator<something> -> u32',
'correction': null, 'correction': null,
'others': [ 'others': [
{ 'path': 'assoc_type::my', 'name': 'other_fn' }, {
{ 'path': 'assoc_type', 'name': 'my_fn' }, 'path': 'assoc_type::my',
'name': 'other_fn',
'displayType': 'X -> `u32`',
'displayMappedNames': '',
'displayWhereClause': 'X: `Iterator`<`Something`>',
},
{
'path': 'assoc_type',
'name': 'my_fn',
'displayType': 'X -> `u32`',
'displayMappedNames': '',
'displayWhereClause': 'X: `Iterator`<Item=`Something`>',
},
], ],
}, },
{ {
'query': 'iterator<something>', 'query': 'iterator<something>',
'correction': null, 'correction': null,
'in_args': [ 'in_args': [
{ 'path': 'assoc_type::my', 'name': 'other_fn' }, {
{ 'path': 'assoc_type', 'name': 'my_fn' }, 'path': 'assoc_type::my',
'name': 'other_fn',
'displayType': 'X -> u32',
'displayMappedNames': '',
'displayWhereClause': 'X: `Iterator`<`Something`>',
},
{
'path': 'assoc_type',
'name': 'my_fn',
'displayType': 'X -> u32',
'displayMappedNames': '',
'displayWhereClause': 'X: `Iterator`<Item=`Something`>',
},
], ],
}, },
{ {
@ -26,8 +50,20 @@ const EXPECTED = [
{ 'path': 'assoc_type', 'name': 'Something' }, { 'path': 'assoc_type', 'name': 'Something' },
], ],
'in_args': [ 'in_args': [
{ 'path': 'assoc_type::my', 'name': 'other_fn' }, {
{ 'path': 'assoc_type', 'name': 'my_fn' }, 'path': 'assoc_type::my',
'name': 'other_fn',
'displayType': '`X` -> u32',
'displayMappedNames': '',
'displayWhereClause': 'X: Iterator<`Something`>',
},
{
'path': 'assoc_type',
'name': 'my_fn',
'displayType': '`X` -> u32',
'displayMappedNames': '',
'displayWhereClause': 'X: Iterator<Item=`Something`>',
},
], ],
}, },
// if I write an explicit binding, only it shows up // if I write an explicit binding, only it shows up

View File

@ -1,12 +1,22 @@
pub fn my_fn<X: Iterator<Item = Something>>(_x: X) -> u32 { #![feature(rustdoc_internals)]
pub fn my_fn<X: other::Iterator<Item = Something>>(_x: X) -> u32 {
3 3
} }
pub struct Something; pub struct Something;
pub mod my { pub mod my {
#[doc(search_unbox)]
pub trait Iterator<T> {} pub trait Iterator<T> {}
pub fn other_fn<X: Iterator<crate::Something>>(_: X) -> u32 { pub fn other_fn<X: Iterator<crate::Something>>(_: X) -> u32 {
3 3
} }
} }
pub mod other {
#[doc(search_unbox)]
pub trait Iterator {
type Item;
}
}

View File

@ -14,7 +14,7 @@ const EXPECTED = [
], ],
}, },
{ {
'query': 'Aaaaaaa -> usize', 'query': 'Aaaaaaa -> Result<usize>',
'others': [ 'others': [
{ 'path': 'generics_impl::Aaaaaaa', 'name': 'read' }, { 'path': 'generics_impl::Aaaaaaa', 'name': 'read' },
], ],
@ -23,6 +23,11 @@ const EXPECTED = [
'query': 'Read -> u64', 'query': 'Read -> u64',
'others': [ 'others': [
{ 'path': 'generics_impl::Ddddddd', 'name': 'eeeeeee' }, { 'path': 'generics_impl::Ddddddd', 'name': 'eeeeeee' },
],
},
{
'query': 'Ddddddd<Read> -> u64',
'others': [
{ 'path': 'generics_impl::Ddddddd', 'name': 'ggggggg' }, { 'path': 'generics_impl::Ddddddd', 'name': 'ggggggg' },
], ],
}, },
@ -30,7 +35,6 @@ const EXPECTED = [
'query': 'trait:Read -> u64', 'query': 'trait:Read -> u64',
'others': [ 'others': [
{ 'path': 'generics_impl::Ddddddd', 'name': 'eeeeeee' }, { 'path': 'generics_impl::Ddddddd', 'name': 'eeeeeee' },
{ 'path': 'generics_impl::Ddddddd', 'name': 'ggggggg' },
], ],
}, },
{ {

View File

@ -1,4 +1,4 @@
use std::io::{Read, Result as IoResult}; use std::io::{self, Read};
pub struct Aaaaaaa; pub struct Aaaaaaa;
@ -12,7 +12,7 @@ impl Aaaaaaa {
} }
impl Read for Aaaaaaa { impl Read for Aaaaaaa {
fn read(&mut self, out: &mut [u8]) -> IoResult<usize> { fn read(&mut self, out: &mut [u8]) -> io::Result<usize> {
Ok(out.len()) Ok(out.len())
} }
} }

View File

@ -0,0 +1,68 @@
// ignore-order
// exact-check
// Make sure that results are order-agnostic, even when there's search items that only differ
// by generics.
const EXPECTED = [
{
'query': 'Wrap',
'in_args': [
{ 'path': 'generics_match_ambiguity', 'name': 'bar' },
{ 'path': 'generics_match_ambiguity', 'name': 'foo' },
],
},
{
'query': 'Wrap<i32>',
'in_args': [
{ 'path': 'generics_match_ambiguity', 'name': 'bar' },
{ 'path': 'generics_match_ambiguity', 'name': 'foo' },
],
},
{
'query': 'Wrap<i32>, Wrap<i32, u32>',
'others': [
{ 'path': 'generics_match_ambiguity', 'name': 'bar' },
{ 'path': 'generics_match_ambiguity', 'name': 'foo' },
],
},
{
'query': 'Wrap<i32, u32>, Wrap<i32>',
'others': [
{ 'path': 'generics_match_ambiguity', 'name': 'bar' },
{ 'path': 'generics_match_ambiguity', 'name': 'foo' },
],
},
{
'query': 'W3<i32>, W3<i32, u32>',
'others': [
{ 'path': 'generics_match_ambiguity', 'name': 'baaa' },
{ 'path': 'generics_match_ambiguity', 'name': 'baab' },
],
},
{
'query': 'W3<i32, u32>, W3<i32>',
'others': [
{ 'path': 'generics_match_ambiguity', 'name': 'baaa' },
{ 'path': 'generics_match_ambiguity', 'name': 'baab' },
],
},
{
// strict generics matching; W2<i32, u32> doesn't match W2<W3<i32, u32>>,
// even though W2<i32> works just fine (ignoring the W3)
'query': 'W2<i32>, W2<i32, u32>',
'others': [],
},
{
'query': 'W2<i32, u32>, W2<i32>',
'others': [],
},
{
'query': 'W2<i32>, W3<i32, u32>',
'others': [],
},
{
'query': 'W2<i32>, W2<i32>',
'others': [],
},
];

View File

@ -0,0 +1,18 @@
#![crate_name = "generics_match_ambiguity"]
pub struct Wrap<T, U = ()>(pub T, pub U);
pub fn foo(a: Wrap<i32>, b: Wrap<i32, u32>) {}
pub fn bar(a: Wrap<i32, u32>, b: Wrap<i32>) {}
pub struct W2<T>(pub T);
pub struct W3<T, U = ()>(pub T, pub U);
pub fn baaa(a: W3<i32>, b: W3<i32, u32>) {}
pub fn baab(a: W3<i32, u32>, b: W3<i32>) {}
pub fn baac(a: W2<W3<i32>>, b: W3<i32, u32>) {}
pub fn baad(a: W2<W3<i32, u32>>, b: W3<i32>) {}
pub fn baae(a: W3<i32>, b: W2<W3<i32, u32>>) {}
pub fn baaf(a: W3<i32, u32>, b: W2<W3<i32>>) {}
pub fn baag(a: W2<W3<i32>>, b: W2<W3<i32, u32>>) {}
pub fn baah(a: W2<W3<i32, u32>>, b: W2<W3<i32>>) {}

View File

@ -60,18 +60,14 @@ const EXPECTED = [
], ],
}, },
{ {
// strict generics matching; W2<i32, u32> doesn't match W2<W3<i32, u32>>,
// even though W2<i32> works just fine (ignoring the W3)
'query': 'W2<i32>, W2<i32, u32>', 'query': 'W2<i32>, W2<i32, u32>',
'others': [ 'others': [],
{ 'path': 'generics_match_ambiguity', 'name': 'baag' },
{ 'path': 'generics_match_ambiguity', 'name': 'baah' },
],
}, },
{ {
'query': 'W2<i32, u32>, W2<i32>', 'query': 'W2<i32, u32>, W2<i32>',
'others': [ 'others': [],
{ 'path': 'generics_match_ambiguity', 'name': 'baag' },
{ 'path': 'generics_match_ambiguity', 'name': 'baah' },
],
}, },
{ {
'query': 'W2<i32>, W3<i32, u32>', 'query': 'W2<i32>, W3<i32, u32>',

View File

@ -1,9 +1,14 @@
#![feature(rustdoc_internals)]
#[doc(search_unbox)]
pub struct Wrap<T, U = ()>(pub T, pub U); pub struct Wrap<T, U = ()>(pub T, pub U);
pub fn foo(a: Wrap<i32>, b: Wrap<i32, u32>) {} pub fn foo(a: Wrap<i32>, b: Wrap<i32, u32>) {}
pub fn bar(a: Wrap<i32, u32>, b: Wrap<i32>) {} pub fn bar(a: Wrap<i32, u32>, b: Wrap<i32>) {}
#[doc(search_unbox)]
pub struct W2<T>(pub T); pub struct W2<T>(pub T);
#[doc(search_unbox)]
pub struct W3<T, U = ()>(pub T, pub U); pub struct W3<T, U = ()>(pub T, pub U);
pub fn baaa(a: W3<i32>, b: W3<i32, u32>) {} pub fn baaa(a: W3<i32>, b: W3<i32, u32>) {}
@ -14,4 +19,3 @@ pub fn baae(a: W3<i32>, b: W2<W3<i32, u32>>) {}
pub fn baaf(a: W3<i32, u32>, b: W2<W3<i32>>) {} pub fn baaf(a: W3<i32, u32>, b: W2<W3<i32>>) {}
pub fn baag(a: W2<W3<i32>>, b: W2<W3<i32, u32>>) {} pub fn baag(a: W2<W3<i32>>, b: W2<W3<i32, u32>>) {}
pub fn baah(a: W2<W3<i32, u32>>, b: W2<W3<i32>>) {} pub fn baah(a: W2<W3<i32, u32>>, b: W2<W3<i32>>) {}
//

View File

@ -18,9 +18,8 @@ const EXPECTED = [
], ],
}, },
{ {
// can't put generics out of order
'query': '-> Out<Second, First>', 'query': '-> Out<Second, First>',
'others': [ 'others': [],
{ 'path': 'generics_nested', 'name': 'bet' },
],
}, },
]; ];

View File

@ -5,10 +5,22 @@ const EXPECTED = [
'query': 'Result<SomeTrait>', 'query': 'Result<SomeTrait>',
'correction': null, 'correction': null,
'in_args': [ 'in_args': [
{ 'path': 'generics_trait', 'name': 'beta' }, {
'path': 'generics_trait',
'name': 'beta',
'displayType': '`Result`<`T`, ()> -> ()',
'displayMappedNames': '',
'displayWhereClause': 'T: `SomeTrait`',
},
], ],
'returned': [ 'returned': [
{ 'path': 'generics_trait', 'name': 'bet' }, {
'path': 'generics_trait',
'name': 'bet',
'displayType': ' -> `Result`<`T`, ()>',
'displayMappedNames': '',
'displayWhereClause': 'T: `SomeTrait`',
},
], ],
}, },
{ {
@ -25,20 +37,44 @@ const EXPECTED = [
'query': 'OtherThingxxxxxxxx', 'query': 'OtherThingxxxxxxxx',
'correction': null, 'correction': null,
'in_args': [ 'in_args': [
{ 'path': 'generics_trait', 'name': 'alpha' }, {
'path': 'generics_trait',
'name': 'alpha',
'displayType': 'Result<`T`, ()> -> ()',
'displayMappedNames': '',
'displayWhereClause': 'T: `OtherThingxxxxxxxx`',
},
], ],
'returned': [ 'returned': [
{ 'path': 'generics_trait', 'name': 'alef' }, {
'path': 'generics_trait',
'name': 'alef',
'displayType': ' -> Result<`T`, ()>',
'displayMappedNames': '',
'displayWhereClause': 'T: `OtherThingxxxxxxxx`',
},
], ],
}, },
{ {
'query': 'OtherThingxxxxxxxy', 'query': 'OtherThingxxxxxxxy',
'correction': 'OtherThingxxxxxxxx', 'correction': 'OtherThingxxxxxxxx',
'in_args': [ 'in_args': [
{ 'path': 'generics_trait', 'name': 'alpha' }, {
'path': 'generics_trait',
'name': 'alpha',
'displayType': 'Result<`T`, ()> -> ()',
'displayMappedNames': '',
'displayWhereClause': 'T: `OtherThingxxxxxxxx`',
},
], ],
'returned': [ 'returned': [
{ 'path': 'generics_trait', 'name': 'alef' }, {
'path': 'generics_trait',
'name': 'alef',
'displayType': ' -> Result<`T`, ()>',
'displayMappedNames': '',
'displayWhereClause': 'T: `OtherThingxxxxxxxx`',
},
], ],
}, },
]; ];

View File

@ -11,20 +11,17 @@ const EXPECTED = [
'query': 'Inside<T> -> Out3<T>', 'query': 'Inside<T> -> Out3<T>',
'others': [ 'others': [
{ 'path': 'generics_unbox', 'name': 'beta' }, { 'path': 'generics_unbox', 'name': 'beta' },
{ 'path': 'generics_unbox', 'name': 'gamma' },
], ],
}, },
{ {
'query': 'Inside<T> -> Out4<T>', 'query': 'Inside<T> -> Out4<T>',
'others': [ 'others': [
{ 'path': 'generics_unbox', 'name': 'beta' },
{ 'path': 'generics_unbox', 'name': 'gamma' }, { 'path': 'generics_unbox', 'name': 'gamma' },
], ],
}, },
{ {
'query': 'Inside<T> -> Out3<U, T>', 'query': 'Inside<T> -> Out3<U, T>',
'others': [ 'others': [
{ 'path': 'generics_unbox', 'name': 'beta' },
{ 'path': 'generics_unbox', 'name': 'gamma' }, { 'path': 'generics_unbox', 'name': 'gamma' },
], ],
}, },
@ -32,7 +29,6 @@ const EXPECTED = [
'query': 'Inside<T> -> Out4<U, T>', 'query': 'Inside<T> -> Out4<U, T>',
'others': [ 'others': [
{ 'path': 'generics_unbox', 'name': 'beta' }, { 'path': 'generics_unbox', 'name': 'beta' },
{ 'path': 'generics_unbox', 'name': 'gamma' },
], ],
}, },
]; ];

View File

@ -1,26 +1,34 @@
#![feature(rustdoc_internals)]
#[doc(search_unbox)]
pub struct Out<A, B = ()> { pub struct Out<A, B = ()> {
a: A, a: A,
b: B, b: B,
} }
#[doc(search_unbox)]
pub struct Out1<A, const N: usize> { pub struct Out1<A, const N: usize> {
a: [A; N], a: [A; N],
} }
#[doc(search_unbox)]
pub struct Out2<A, const N: usize> { pub struct Out2<A, const N: usize> {
a: [A; N], a: [A; N],
} }
#[doc(search_unbox)]
pub struct Out3<A, B> { pub struct Out3<A, B> {
a: A, a: A,
b: B, b: B,
} }
#[doc(search_unbox)]
pub struct Out4<A, B> { pub struct Out4<A, B> {
a: A, a: A,
b: B, b: B,
} }
#[doc(search_unbox)]
pub struct Inside<T>(T); pub struct Inside<T>(T);
pub fn alpha<const N: usize, T>(_: Inside<T>) -> Out<Out1<T, N>, Out2<T, N>> { pub fn alpha<const N: usize, T>(_: Inside<T>) -> Out<Out1<T, N>, Out2<T, N>> {

View File

@ -30,21 +30,13 @@ const EXPECTED = [
'others': [ 'others': [
{ 'path': 'generics', 'name': 'P' }, { 'path': 'generics', 'name': 'P' },
], ],
'returned': [ 'returned': [],
{ 'path': 'generics', 'name': 'alef' }, 'in_args': [],
],
'in_args': [
{ 'path': 'generics', 'name': 'alpha' },
],
}, },
{ {
'query': 'P', 'query': 'P',
'returned': [ 'returned': [],
{ 'path': 'generics', 'name': 'alef' }, 'in_args': [],
],
'in_args': [
{ 'path': 'generics', 'name': 'alpha' },
],
}, },
{ {
'query': '"ExtraCreditStructMulti"<ExtraCreditInnerMulti, ExtraCreditInnerMulti>', 'query': '"ExtraCreditStructMulti"<ExtraCreditInnerMulti, ExtraCreditInnerMulti>',

View File

@ -9,19 +9,19 @@ const EXPECTED = [
// ML-style higher-order function notation // ML-style higher-order function notation
{ {
'query': 'bool, (u32 -> !) -> ()', 'query': 'bool, (first<u32> -> !) -> ()',
'others': [ 'others': [
{"path": "hof", "name": "fn_ptr"}, {"path": "hof", "name": "fn_ptr"},
], ],
}, },
{ {
'query': 'u8, (u32 -> !) -> ()', 'query': 'u8, (second<u32> -> !) -> ()',
'others': [ 'others': [
{"path": "hof", "name": "fn_once"}, {"path": "hof", "name": "fn_once"},
], ],
}, },
{ {
'query': 'i8, (u32 -> !) -> ()', 'query': 'i8, (third<u32> -> !) -> ()',
'others': [ 'others': [
{"path": "hof", "name": "fn_mut"}, {"path": "hof", "name": "fn_mut"},
], ],
@ -54,9 +54,6 @@ const EXPECTED = [
'query': '(u32 -> !) -> ()', 'query': '(u32 -> !) -> ()',
'others': [ 'others': [
{"path": "hof", "name": "fn_"}, {"path": "hof", "name": "fn_"},
{"path": "hof", "name": "fn_ptr"},
{"path": "hof", "name": "fn_mut"},
{"path": "hof", "name": "fn_once"},
], ],
}, },
{ {
@ -95,30 +92,30 @@ const EXPECTED = [
// Rust-style higher-order function notation // Rust-style higher-order function notation
{ {
'query': 'bool, fn(u32) -> ! -> ()', 'query': 'bool, fn(first<u32>) -> ! -> ()',
'others': [ 'others': [
{"path": "hof", "name": "fn_ptr"}, {"path": "hof", "name": "fn_ptr"},
], ],
}, },
{ {
'query': 'u8, fnonce(u32) -> ! -> ()', 'query': 'u8, fnonce(second<u32>) -> ! -> ()',
'others': [ 'others': [
{"path": "hof", "name": "fn_once"}, {"path": "hof", "name": "fn_once"},
], ],
}, },
{ {
'query': 'u8, fn(u32) -> ! -> ()', 'query': 'u8, fn(second<u32>) -> ! -> ()',
// fnonce != fn // fnonce != fn
'others': [], 'others': [],
}, },
{ {
'query': 'i8, fnmut(u32) -> ! -> ()', 'query': 'i8, fnmut(third<u32>) -> ! -> ()',
'others': [ 'others': [
{"path": "hof", "name": "fn_mut"}, {"path": "hof", "name": "fn_mut"},
], ],
}, },
{ {
'query': 'i8, fn(u32) -> ! -> ()', 'query': 'i8, fn(third<u32>) -> ! -> ()',
// fnmut != fn // fnmut != fn
'others': [], 'others': [],
}, },
@ -152,7 +149,7 @@ const EXPECTED = [
], ],
}, },
{ {
'query': 'fn(u32) -> ! -> ()', 'query': 'fn() -> ! -> ()',
'others': [ 'others': [
// fn matches primitive:fn and trait:Fn // fn matches primitive:fn and trait:Fn
{"path": "hof", "name": "fn_"}, {"path": "hof", "name": "fn_"},
@ -160,14 +157,14 @@ const EXPECTED = [
], ],
}, },
{ {
'query': 'trait:fn(u32) -> ! -> ()', 'query': 'trait:fn() -> ! -> ()',
'others': [ 'others': [
// fn matches primitive:fn and trait:Fn // fn matches primitive:fn and trait:Fn
{"path": "hof", "name": "fn_"}, {"path": "hof", "name": "fn_"},
], ],
}, },
{ {
'query': 'primitive:fn(u32) -> ! -> ()', 'query': 'primitive:fn() -> ! -> ()',
'others': [ 'others': [
// fn matches primitive:fn and trait:Fn // fn matches primitive:fn and trait:Fn
{"path": "hof", "name": "fn_ptr"}, {"path": "hof", "name": "fn_ptr"},

View File

@ -23,8 +23,8 @@ const EXPECTED = [
'others': [ 'others': [
{ 'path': 'impl_trait', 'name': 'bbbbbbb' }, { 'path': 'impl_trait', 'name': 'bbbbbbb' },
{ 'path': 'impl_trait::Ccccccc', 'name': 'ddddddd' }, { 'path': 'impl_trait::Ccccccc', 'name': 'ddddddd' },
{ 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' },
{ 'path': 'impl_trait::Ccccccc', 'name': 'ggggggg' }, { 'path': 'impl_trait::Ccccccc', 'name': 'ggggggg' },
{ 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' },
], ],
}, },
{ {
@ -39,14 +39,14 @@ const EXPECTED = [
{ 'path': 'impl_trait', 'name': 'Aaaaaaa' }, { 'path': 'impl_trait', 'name': 'Aaaaaaa' },
], ],
'in_args': [ 'in_args': [
{ 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' },
{ 'path': 'impl_trait::Ccccccc', 'name': 'eeeeeee' }, { 'path': 'impl_trait::Ccccccc', 'name': 'eeeeeee' },
{ 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' },
], ],
'returned': [ 'returned': [
{ 'path': 'impl_trait', 'name': 'bbbbbbb' }, { 'path': 'impl_trait', 'name': 'bbbbbbb' },
{ 'path': 'impl_trait::Ccccccc', 'name': 'ddddddd' }, { 'path': 'impl_trait::Ccccccc', 'name': 'ddddddd' },
{ 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' },
{ 'path': 'impl_trait::Ccccccc', 'name': 'ggggggg' }, { 'path': 'impl_trait::Ccccccc', 'name': 'ggggggg' },
{ 'path': 'impl_trait::Ccccccc', 'name': 'fffffff' },
], ],
}, },
]; ];

View File

@ -1,9 +1,15 @@
// https://github.com/rust-lang/rust/pull/122247 // https://github.com/rust-lang/rust/pull/122247
// exact-check // exact-check
const EXPECTED = { const EXPECTED = [
{
'query': 'canonicalvarinfo, intoiterator -> intoiterator', 'query': 'canonicalvarinfo, intoiterator -> intoiterator',
'others': [],
},
{
'query': '[canonicalvarinfo], interner<tys=intoiterator> -> intoiterator',
'others': [ 'others': [
{ 'path': 'looks_like_rustc_interner::Interner', 'name': 'mk_canonical_var_infos' }, { 'path': 'looks_like_rustc_interner::Interner', 'name': 'mk_canonical_var_infos' },
], ],
}; },
];

View File

@ -33,9 +33,8 @@ const EXPECTED = [
}, },
{ {
'query': '-> Result<i32, u32, bool>', 'query': '-> Result<i32, u32, bool>',
'others': [ // can't put nested generics out of order
{ 'path': 'nested_unboxed', 'name': 'something' }, 'others': [],
],
}, },
{ {
'query': '-> Result<Object<i32>, bool>', 'query': '-> Result<Object<i32>, bool>',
@ -45,9 +44,7 @@ const EXPECTED = [
}, },
{ {
'query': '-> Result<Object<u32>, bool>', 'query': '-> Result<Object<u32>, bool>',
'others': [ 'others': [],
{ 'path': 'nested_unboxed', 'name': 'something' },
],
}, },
{ {
'query': '-> Result<Object<i32>, u32, bool>', 'query': '-> Result<Object<i32>, u32, bool>',

View File

@ -1,3 +1,6 @@
#![feature(rustdoc_internals)]
#[doc(search_unbox)]
pub struct Object<T, U>(T, U); pub struct Object<T, U>(T, U);
pub fn something() -> Result<Object<i32, u32>, bool> { pub fn something() -> Result<Object<i32, u32>, bool> {

View File

@ -11,30 +11,29 @@ const PARSED = [
}], }],
returned: [], returned: [],
foundElems: 1, foundElems: 1,
original: "中文",
userQuery: "中文", userQuery: "中文",
error: null, error: null,
}, },
{ {
query: '_0Mixed中英文', query: '_0Mixed中英文',
elems: [{ elems: [{
name: "_0mixed中英文", name: "_0Mixed中英文",
fullPath: ["_0mixed中英文"], fullPath: ["_0mixed中英文"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "_0mixed中英文", pathLast: "_0mixed中英文",
normalizedPathLast: "0mixed中英文",
generics: [], generics: [],
typeFilter: -1, typeFilter: -1,
}], }],
foundElems: 1, foundElems: 1,
original: "_0Mixed中英文", userQuery: "_0Mixed中英文",
returned: [], returned: [],
userQuery: "_0mixed中英文",
error: null, error: null,
}, },
{ {
query: 'my_crate::中文API', query: 'my_crate::中文API',
elems: [{ elems: [{
name: "my_crate::中文api", name: "my_crate::中文API",
fullPath: ["my_crate", "中文api"], fullPath: ["my_crate", "中文api"],
pathWithoutLast: ["my_crate"], pathWithoutLast: ["my_crate"],
pathLast: "中文api", pathLast: "中文api",
@ -42,26 +41,25 @@ const PARSED = [
typeFilter: -1, typeFilter: -1,
}], }],
foundElems: 1, foundElems: 1,
original: "my_crate::中文API", userQuery: "my_crate::中文API",
returned: [], returned: [],
userQuery: "my_crate::中文api",
error: null, error: null,
}, },
{ {
query: '类型A,类型B<约束C>->返回类型<关联类型=路径::约束D>', query: '类型A,类型B<约束C>->返回类型<关联类型=路径::约束D>',
elems: [{ elems: [{
name: "类型a", name: "类型A",
fullPath: ["类型a"], fullPath: ["类型a"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "类型a", pathLast: "类型a",
generics: [], generics: [],
}, { }, {
name: "类型b", name: "类型B",
fullPath: ["类型b"], fullPath: ["类型b"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "类型b", pathLast: "类型b",
generics: [{ generics: [{
name: "约束c", name: "约束C",
fullPath: ["约束c"], fullPath: ["约束c"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "约束c", pathLast: "约束c",
@ -71,15 +69,21 @@ const PARSED = [
foundElems: 3, foundElems: 3,
totalElems: 5, totalElems: 5,
literalSearch: true, literalSearch: true,
original: "类型A,类型B<约束C>->返回类型<关联类型=路径::约束D>", userQuery: "类型A,类型B<约束C>->返回类型<关联类型=路径::约束D>",
returned: [{ returned: [{
name: "返回类型", name: "返回类型",
fullPath: ["返回类型"], fullPath: ["返回类型"],
pathWithoutLast: [], pathWithoutLast: [],
pathLast: "返回类型", pathLast: "返回类型",
generics: [], generics: [],
bindings: [["关联类型", [{
name: "路径::约束D",
fullPath: ["路径", "约束d"],
pathWithoutLast: ["路径"],
pathLast: "约束d",
generics: [],
}]]],
}], }],
userQuery: "类型a,类型b<约束c>->返回类型<关联类型=路径::约束d>",
error: null, error: null,
}, },
{ {
@ -93,18 +97,16 @@ const PARSED = [
typeFilter: 16, typeFilter: 16,
}], }],
foundElems: 1, foundElems: 1,
original: "my_crate 中文宏!",
returned: [],
userQuery: "my_crate 中文宏!", userQuery: "my_crate 中文宏!",
returned: [],
error: null, error: null,
}, },
{ {
query: '非法符号——', query: '非法符号——',
elems: [], elems: [],
foundElems: 0, foundElems: 0,
original: "非法符号——",
returned: [],
userQuery: "非法符号——", userQuery: "非法符号——",
returned: [],
error: "Unexpected `—` after `号` (not a valid identifier)", error: "Unexpected `—` after `号` (not a valid identifier)",
} }
] ]

View File

@ -79,9 +79,8 @@ const EXPECTED = [
}, },
{ {
'query': 'reference<ring>, reference<ring> -> ()', 'query': 'reference<ring>, reference<ring> -> ()',
'others': [ // can't leave out the `mut`, because can't reorder like that
{ 'path': 'reference::Ring', 'name': 'wear' }, 'others': [],
],
}, },
{ {
'query': 'reference<mut, ring>, reference<ring> -> ()', 'query': 'reference<mut, ring>, reference<ring> -> ()',
@ -102,9 +101,8 @@ const EXPECTED = [
}, },
{ {
'query': 'reference<middle>, reference<middle> -> ()', 'query': 'reference<middle>, reference<middle> -> ()',
'others': [ // can't leave out the mut
{ 'path': 'reference', 'name': 'show' }, 'others': [],
],
}, },
{ {
'query': 'reference<mut, middle>, reference<mut, middle> -> ()', 'query': 'reference<mut, middle>, reference<mut, middle> -> ()',
@ -203,9 +201,8 @@ const EXPECTED = [
// middle with shorthand // middle with shorthand
{ {
'query': '&middle, &middle -> ()', 'query': '&middle, &middle -> ()',
'others': [ // can't leave out the mut
{ 'path': 'reference', 'name': 'show' }, 'others': [],
],
}, },
{ {
'query': '&mut middle, &mut middle -> ()', 'query': '&mut middle, &mut middle -> ()',

View File

@ -57,7 +57,7 @@ const EXPECTED = [
'in_args': [], 'in_args': [],
}, },
{ {
'query': '(Q, ())', 'query': '(Q, R<()>)',
'returned': [ 'returned': [
{ 'path': 'tuple_unit', 'name': 'nest' }, { 'path': 'tuple_unit', 'name': 'nest' },
], ],
@ -71,7 +71,7 @@ const EXPECTED = [
'in_args': [], 'in_args': [],
}, },
{ {
'query': '(u32)', 'query': 'R<(u32)>',
'returned': [ 'returned': [
{ 'path': 'tuple_unit', 'name': 'nest' }, { 'path': 'tuple_unit', 'name': 'nest' },
], ],

View File

@ -11,9 +11,9 @@ const EXPECTED = [
{ {
query: '-> generic:T', query: '-> generic:T',
others: [ others: [
{ path: 'foo', name: 'beta' },
{ path: 'foo', name: 'bet' }, { path: 'foo', name: 'bet' },
{ path: 'foo', name: 'alef' }, { path: 'foo', name: 'alef' },
{ path: 'foo', name: 'beta' },
], ],
}, },
{ {
@ -50,8 +50,8 @@ const EXPECTED = [
{ {
query: 'generic:T', query: 'generic:T',
in_args: [ in_args: [
{ path: 'foo', name: 'beta' },
{ path: 'foo', name: 'bet' }, { path: 'foo', name: 'bet' },
{ path: 'foo', name: 'beta' },
{ path: 'foo', name: 'alternate' }, { path: 'foo', name: 'alternate' },
{ path: 'foo', name: 'other' }, { path: 'foo', name: 'other' },
], ],
@ -59,8 +59,8 @@ const EXPECTED = [
{ {
query: 'generic:Other', query: 'generic:Other',
in_args: [ in_args: [
{ path: 'foo', name: 'beta' },
{ path: 'foo', name: 'bet' }, { path: 'foo', name: 'bet' },
{ path: 'foo', name: 'beta' },
{ path: 'foo', name: 'alternate' }, { path: 'foo', name: 'alternate' },
{ path: 'foo', name: 'other' }, { path: 'foo', name: 'other' },
], ],

View File

@ -7,4 +7,7 @@ trait Mine {}
#[doc(fake_variadic)] //~ ERROR: `#[doc(fake_variadic)]` is meant for internal use only #[doc(fake_variadic)] //~ ERROR: `#[doc(fake_variadic)]` is meant for internal use only
impl<T> Mine for (T,) {} impl<T> Mine for (T,) {}
#[doc(search_unbox)] //~ ERROR: `#[doc(search_unbox)]` is meant for internal use only
struct Wrap<T> (T);
fn main() {} fn main() {}

View File

@ -18,6 +18,16 @@ LL | #[doc(fake_variadic)]
= help: add `#![feature(rustdoc_internals)]` to the crate attributes to enable = help: add `#![feature(rustdoc_internals)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 2 previous errors error[E0658]: `#[doc(search_unbox)]` is meant for internal use only
--> $DIR/feature-gate-rustdoc_internals.rs:10:1
|
LL | #[doc(search_unbox)]
| ^^^^^^^^^^^^^^^^^^^^
|
= note: see issue #90418 <https://github.com/rust-lang/rust/issues/90418> for more information
= help: add `#![feature(rustdoc_internals)]` to the crate attributes to enable
= note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date
error: aborting due to 3 previous errors
For more information about this error, try `rustc --explain E0658`. For more information about this error, try `rustc --explain E0658`.