1
Fork 0

Auto merge of #96263 - Dylan-DPC:rollup-0eofl13, r=Dylan-DPC

Rollup of 5 pull requests

Successful merges:

 - #90630 (Create real parser for search queries)
 - #96193 ([fuchsia] Add implementation for `current_exe`)
 - #96196 (Remove assertion that all paths in `ShouldRun` exist)
 - #96228 (Fix locations for intrinsics impls and change to links)
 - #96236 (Add an explicit `Span` field to `OutlivesConstraint`)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
This commit is contained in:
bors 2022-04-21 02:16:32 +00:00
commit 7be1da0319
40 changed files with 2390 additions and 532 deletions

View file

@ -156,6 +156,7 @@ impl<'s, 'tcx, D: ConstraintGraphDirecton> Iterator for Edges<'s, 'tcx, D> {
sup: self.static_region, sup: self.static_region,
sub: next_static_idx.into(), sub: next_static_idx.into(),
locations: Locations::All(DUMMY_SP), locations: Locations::All(DUMMY_SP),
span: DUMMY_SP,
category: ConstraintCategory::Internal, category: ConstraintCategory::Internal,
variance_info: VarianceDiagInfo::default(), variance_info: VarianceDiagInfo::default(),
}) })

View file

@ -2,6 +2,7 @@ use rustc_data_structures::graph::scc::Sccs;
use rustc_index::vec::IndexVec; use rustc_index::vec::IndexVec;
use rustc_middle::mir::ConstraintCategory; use rustc_middle::mir::ConstraintCategory;
use rustc_middle::ty::{RegionVid, VarianceDiagInfo}; use rustc_middle::ty::{RegionVid, VarianceDiagInfo};
use rustc_span::Span;
use std::fmt; use std::fmt;
use std::ops::Index; use std::ops::Index;
@ -87,6 +88,12 @@ pub struct OutlivesConstraint<'tcx> {
/// Where did this constraint arise? /// Where did this constraint arise?
pub locations: Locations, pub locations: Locations,
/// The `Span` associated with the creation of this constraint.
/// This should be used in preference to obtaining the span from
/// `locations`, since the `locations` may give a poor span
/// in some cases (e.g. converting a constraint from a promoted).
pub span: Span,
/// What caused this constraint? /// What caused this constraint?
pub category: ConstraintCategory, pub category: ConstraintCategory,

View file

@ -74,14 +74,18 @@ impl<'tcx> RegionInferenceContext<'tcx> {
let mut constraints: Vec<_> = self.constraints.outlives().iter().collect(); let mut constraints: Vec<_> = self.constraints.outlives().iter().collect();
constraints.sort_by_key(|c| (c.sup, c.sub)); constraints.sort_by_key(|c| (c.sup, c.sub));
for constraint in &constraints { for constraint in &constraints {
let OutlivesConstraint { sup, sub, locations, category, variance_info: _ } = constraint; let OutlivesConstraint { sup, sub, locations, category, span, variance_info: _ } =
constraint;
let (name, arg) = match locations { let (name, arg) = match locations {
Locations::All(span) => { Locations::All(span) => {
("All", tcx.sess.source_map().span_to_embeddable_string(*span)) ("All", tcx.sess.source_map().span_to_embeddable_string(*span))
} }
Locations::Single(loc) => ("Single", format!("{:?}", loc)), Locations::Single(loc) => ("Single", format!("{:?}", loc)),
}; };
with_msg(&format!("{:?}: {:?} due to {:?} at {}({})", sup, sub, category, name, arg))?; with_msg(&format!(
"{:?}: {:?} due to {:?} at {}({}) ({:?}",
sup, sub, category, name, arg, span
))?;
} }
Ok(()) Ok(())

View file

@ -1733,7 +1733,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
crate fn retrieve_closure_constraint_info( crate fn retrieve_closure_constraint_info(
&self, &self,
body: &Body<'tcx>, _body: &Body<'tcx>,
constraint: &OutlivesConstraint<'tcx>, constraint: &OutlivesConstraint<'tcx>,
) -> BlameConstraint<'tcx> { ) -> BlameConstraint<'tcx> {
let loc = match constraint.locations { let loc = match constraint.locations {
@ -1760,7 +1760,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
.unwrap_or(BlameConstraint { .unwrap_or(BlameConstraint {
category: constraint.category, category: constraint.category,
from_closure: false, from_closure: false,
cause: ObligationCause::dummy_with_span(body.source_info(loc).span), cause: ObligationCause::dummy_with_span(constraint.span),
variance_info: constraint.variance_info, variance_info: constraint.variance_info,
}) })
} }
@ -1869,6 +1869,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
sup: r, sup: r,
sub: constraint.min_choice, sub: constraint.min_choice,
locations: Locations::All(p_c.definition_span), locations: Locations::All(p_c.definition_span),
span: p_c.definition_span,
category: ConstraintCategory::OpaqueType, category: ConstraintCategory::OpaqueType,
variance_info: ty::VarianceDiagInfo::default(), variance_info: ty::VarianceDiagInfo::default(),
}; };
@ -2017,7 +2018,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
category: constraint.category, category: constraint.category,
from_closure: false, from_closure: false,
cause: ObligationCause::new( cause: ObligationCause::new(
constraint.locations.span(body), constraint.span,
CRATE_HIR_ID, CRATE_HIR_ID,
cause_code.clone(), cause_code.clone(),
), ),

View file

@ -8,7 +8,7 @@ use rustc_middle::mir::ConstraintCategory;
use rustc_middle::ty::subst::GenericArgKind; use rustc_middle::ty::subst::GenericArgKind;
use rustc_middle::ty::TypeFoldable; use rustc_middle::ty::TypeFoldable;
use rustc_middle::ty::{self, TyCtxt}; use rustc_middle::ty::{self, TyCtxt};
use rustc_span::DUMMY_SP; use rustc_span::{Span, DUMMY_SP};
use crate::{ use crate::{
constraints::OutlivesConstraint, constraints::OutlivesConstraint,
@ -26,6 +26,7 @@ crate struct ConstraintConversion<'a, 'tcx> {
implicit_region_bound: Option<ty::Region<'tcx>>, implicit_region_bound: Option<ty::Region<'tcx>>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
locations: Locations, locations: Locations,
span: Span,
category: ConstraintCategory, category: ConstraintCategory,
constraints: &'a mut MirTypeckRegionConstraints<'tcx>, constraints: &'a mut MirTypeckRegionConstraints<'tcx>,
} }
@ -38,6 +39,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
implicit_region_bound: Option<ty::Region<'tcx>>, implicit_region_bound: Option<ty::Region<'tcx>>,
param_env: ty::ParamEnv<'tcx>, param_env: ty::ParamEnv<'tcx>,
locations: Locations, locations: Locations,
span: Span,
category: ConstraintCategory, category: ConstraintCategory,
constraints: &'a mut MirTypeckRegionConstraints<'tcx>, constraints: &'a mut MirTypeckRegionConstraints<'tcx>,
) -> Self { ) -> Self {
@ -49,6 +51,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
implicit_region_bound, implicit_region_bound,
param_env, param_env,
locations, locations,
span,
category, category,
constraints, constraints,
} }
@ -153,6 +156,7 @@ impl<'a, 'tcx> ConstraintConversion<'a, 'tcx> {
self.constraints.outlives_constraints.push(OutlivesConstraint { self.constraints.outlives_constraints.push(OutlivesConstraint {
locations: self.locations, locations: self.locations,
category: self.category, category: self.category,
span: self.span,
sub, sub,
sup, sup,
variance_info: ty::VarianceDiagInfo::default(), variance_info: ty::VarianceDiagInfo::default(),

View file

@ -316,6 +316,7 @@ impl<'tcx> UniversalRegionRelationsBuilder<'_, 'tcx> {
self.implicit_region_bound, self.implicit_region_bound,
self.param_env, self.param_env,
Locations::All(DUMMY_SP), Locations::All(DUMMY_SP),
DUMMY_SP,
ConstraintCategory::Internal, ConstraintCategory::Internal,
&mut self.constraints, &mut self.constraints,
) )

View file

@ -235,6 +235,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
Some(self.implicit_region_bound), Some(self.implicit_region_bound),
self.param_env, self.param_env,
Locations::All(DUMMY_SP), Locations::All(DUMMY_SP),
DUMMY_SP,
ConstraintCategory::Internal, ConstraintCategory::Internal,
&mut self.borrowck_context.constraints, &mut self.borrowck_context.constraints,
) )

View file

@ -1141,6 +1141,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
Some(self.implicit_region_bound), Some(self.implicit_region_bound),
self.param_env, self.param_env,
locations, locations,
locations.span(self.body),
category, category,
&mut self.borrowck_context.constraints, &mut self.borrowck_context.constraints,
) )
@ -2401,6 +2402,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
sup: ref_region.to_region_vid(), sup: ref_region.to_region_vid(),
sub: borrow_region.to_region_vid(), sub: borrow_region.to_region_vid(),
locations: location.to_locations(), locations: location.to_locations(),
span: location.to_locations().span(body),
category, category,
variance_info: ty::VarianceDiagInfo::default(), variance_info: ty::VarianceDiagInfo::default(),
}); });

View file

@ -116,6 +116,7 @@ impl<'tcx> TypeRelatingDelegate<'tcx> for NllTypeRelatingDelegate<'_, '_, 'tcx>
sup, sup,
sub, sub,
locations: self.locations, locations: self.locations,
span: self.locations.span(self.type_checker.body),
category: self.category, category: self.category,
variance_info: info, variance_info: info,
}, },

View file

@ -1,7 +1,7 @@
//! Compiler intrinsics. //! Compiler intrinsics.
//! //!
//! The corresponding definitions are in `compiler/rustc_codegen_llvm/src/intrinsic.rs`. //! The corresponding definitions are in <https://github.com/rust-lang/rust/blob/master/compiler/rustc_codegen_llvm/src/intrinsic.rs>.
//! The corresponding const implementations are in `compiler/rustc_mir/src/interpret/intrinsics.rs` //! The corresponding const implementations are in <https://github.com/rust-lang/rust/blob/master/compiler/rustc_const_eval/src/interpret/intrinsics.rs>.
//! //!
//! # Const intrinsics //! # Const intrinsics
//! //!
@ -10,8 +10,8 @@
//! //!
//! In order to make an intrinsic usable at compile-time, one needs to copy the implementation //! In order to make an intrinsic usable at compile-time, one needs to copy the implementation
//! from <https://github.com/rust-lang/miri/blob/master/src/shims/intrinsics.rs> to //! from <https://github.com/rust-lang/miri/blob/master/src/shims/intrinsics.rs> to
//! `compiler/rustc_mir/src/interpret/intrinsics.rs` and add a //! <https://github.com/rust-lang/rust/blob/master/compiler/rustc_const_eval/src/interpret/intrinsics.rs> and add a
//! `#[rustc_const_unstable(feature = "foo", issue = "01234")]` to the intrinsic. //! `#[rustc_const_unstable(feature = "const_such_and_such", issue = "01234")]` to the intrinsic declaration.
//! //!
//! If an intrinsic is supposed to be used from a `const fn` with a `rustc_const_stable` attribute, //! If an intrinsic is supposed to be used from a `const fn` with a `rustc_const_stable` attribute,
//! the intrinsic's attribute must be `rustc_const_stable`, too. Such a change should not be done //! the intrinsic's attribute must be `rustc_const_stable`, too. Such a change should not be done

View file

@ -427,7 +427,7 @@ pub fn current_exe() -> io::Result<PathBuf> {
crate::fs::read_to_string("sys:exe").map(PathBuf::from) crate::fs::read_to_string("sys:exe").map(PathBuf::from)
} }
#[cfg(any(target_os = "fuchsia", target_os = "l4re"))] #[cfg(target_os = "l4re")]
pub fn current_exe() -> io::Result<PathBuf> { pub fn current_exe() -> io::Result<PathBuf> {
use crate::io::ErrorKind; use crate::io::ErrorKind;
Err(io::const_io_error!(ErrorKind::Unsupported, "Not yet implemented!")) Err(io::const_io_error!(ErrorKind::Unsupported, "Not yet implemented!"))
@ -451,6 +451,26 @@ pub fn current_exe() -> io::Result<PathBuf> {
super::unsupported::unsupported() super::unsupported::unsupported()
} }
#[cfg(target_os = "fuchsia")]
pub fn current_exe() -> io::Result<PathBuf> {
use crate::io::ErrorKind;
#[cfg(test)]
use realstd::env;
#[cfg(not(test))]
use crate::env;
let exe_path = env::args().next().ok_or(io::const_io_error!(
ErrorKind::Uncategorized,
"an executable path was not found because no arguments were provided through argv"
))?;
let path = PathBuf::from(exe_path);
// Prepend the current working directory to the path if it's not absolute.
if !path.is_absolute() { getcwd().map(|cwd| cwd.join(path)) } else { Ok(path) }
}
pub struct Env { pub struct Env {
iter: vec::IntoIter<(OsString, OsString)>, iter: vec::IntoIter<(OsString, OsString)>,
} }

View file

@ -388,11 +388,13 @@ impl<'a> ShouldRun<'a> {
paths paths
.iter() .iter()
.map(|p| { .map(|p| {
assert!( // FIXME(#96188): make sure this is actually a path.
self.builder.src.join(p).exists(), // This currently breaks for paths within submodules.
"`should_run.paths` should correspond to real on-disk paths - use `alias` if there is no relevant path: {}", //assert!(
p // self.builder.src.join(p).exists(),
); // "`should_run.paths` should correspond to real on-disk paths - use `alias` if there is no relevant path: {}",
// p
//);
TaskPath { path: p.into(), kind: Some(self.kind) } TaskPath { path: p.into(), kind: Some(self.kind) }
}) })
.collect(), .collect(),

View file

@ -8,10 +8,34 @@ function initSearch(searchIndex){}
/** /**
* @typedef {{ * @typedef {{
* raw: string, * name: string,
* query: string, * fullPath: Array<string>,
* type: string, * pathWithoutLast: Array<string>,
* id: string, * pathLast: string,
* generics: Array<QueryElement>,
* }}
*/
var QueryElement;
/**
* @typedef {{
* pos: number,
* totalElems: number,
* typeFilter: (null|string),
* userQuery: string,
* }}
*/
var ParserState;
/**
* @typedef {{
* original: string,
* userQuery: string,
* typeFilter: number,
* elems: Array<QueryElement>,
* args: Array<QueryElement>,
* returned: Array<QueryElement>,
* foundElems: number,
* }} * }}
*/ */
var ParsedQuery; var ParsedQuery;
@ -30,3 +54,30 @@ var ParsedQuery;
* }} * }}
*/ */
var Row; var Row;
/**
* @typedef {{
* in_args: Array<Object>,
* returned: Array<Object>,
* others: Array<Object>,
* query: ParsedQuery,
* }}
*/
var ResultsTable;
/**
* @typedef {{
* desc: string,
* displayPath: string,
* fullPath: string,
* href: string,
* id: number,
* lev: number,
* name: string,
* normalizedName: string,
* parent: (Object|undefined),
* path: string,
* ty: number,
* }}
*/
var Results;

File diff suppressed because it is too large Load diff

View file

@ -25,14 +25,14 @@
| '_#2r live at {bb0[0..=1]} | '_#2r live at {bb0[0..=1]}
| '_#3r live at {bb0[0..=1]} | '_#3r live at {bb0[0..=1]}
| '_#4r live at {bb0[0..=1]} | '_#4r live at {bb0[0..=1]}
| '_#1r: '_#6r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:26: 12:27) | '_#1r: '_#6r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:26: 12:27) ($DIR/named-lifetimes-basic.rs:12:26: 12:27 (#0)
| '_#1r: '_#8r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:54: 12:55) | '_#1r: '_#8r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:54: 12:55) ($DIR/named-lifetimes-basic.rs:12:54: 12:55 (#0)
| '_#2r: '_#7r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:42: 12:43) | '_#2r: '_#7r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:42: 12:43) ($DIR/named-lifetimes-basic.rs:12:42: 12:43 (#0)
| '_#3r: '_#9r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:66: 12:67) | '_#3r: '_#9r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:66: 12:67) ($DIR/named-lifetimes-basic.rs:12:66: 12:67 (#0)
| '_#6r: '_#1r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:26: 12:27) | '_#6r: '_#1r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:26: 12:27) ($DIR/named-lifetimes-basic.rs:12:26: 12:27 (#0)
| '_#7r: '_#2r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:42: 12:43) | '_#7r: '_#2r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:42: 12:43) ($DIR/named-lifetimes-basic.rs:12:42: 12:43 (#0)
| '_#8r: '_#1r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:54: 12:55) | '_#8r: '_#1r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:54: 12:55) ($DIR/named-lifetimes-basic.rs:12:54: 12:55 (#0)
| '_#9r: '_#3r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:66: 12:67) | '_#9r: '_#3r due to BoringNoLocation at All($DIR/named-lifetimes-basic.rs:12:66: 12:67) ($DIR/named-lifetimes-basic.rs:12:66: 12:67 (#0)
| |
fn use_x(_1: &'_#6r mut i32, _2: &'_#7r u32, _3: &'_#8r u32, _4: &'_#9r u32) -> bool { fn use_x(_1: &'_#6r mut i32, _2: &'_#7r u32, _3: &'_#8r u32, _4: &'_#9r u32) -> bool {
debug w => _1; // in scope 0 at $DIR/named-lifetimes-basic.rs:12:26: 12:27 debug w => _1; // in scope 0 at $DIR/named-lifetimes-basic.rs:12:26: 12:27

View file

@ -18,8 +18,8 @@
| '_#3r live at {bb1[0]} | '_#3r live at {bb1[0]}
| '_#4r live at {bb1[1..=3]} | '_#4r live at {bb1[1..=3]}
| '_#5r live at {bb1[4..=7], bb2[0..=2]} | '_#5r live at {bb1[4..=7], bb2[0..=2]}
| '_#3r: '_#4r due to Assignment at Single(bb1[0]) | '_#3r: '_#4r due to Assignment at Single(bb1[0]) ($DIR/region-subtyping-basic.rs:18:13: 18:18 (#0)
| '_#4r: '_#5r due to Assignment at Single(bb1[3]) | '_#4r: '_#5r due to Assignment at Single(bb1[3]) ($DIR/region-subtyping-basic.rs:19:13: 19:14 (#0)
| |
fn main() -> () { fn main() -> () {
let mut _0: (); // return place in scope 0 at $DIR/region-subtyping-basic.rs:16:11: 16:11 let mut _0: (); // return place in scope 0 at $DIR/region-subtyping-basic.rs:16:11: 16:11

View file

@ -18,8 +18,8 @@
| '_#3r live at {bb1[0]} | '_#3r live at {bb1[0]}
| '_#4r live at {bb1[1..=3]} | '_#4r live at {bb1[1..=3]}
| '_#5r live at {bb1[4..=7], bb2[0..=2]} | '_#5r live at {bb1[4..=7], bb2[0..=2]}
| '_#3r: '_#4r due to Assignment at Single(bb1[0]) | '_#3r: '_#4r due to Assignment at Single(bb1[0]) ($DIR/region-subtyping-basic.rs:18:13: 18:18 (#0)
| '_#4r: '_#5r due to Assignment at Single(bb1[3]) | '_#4r: '_#5r due to Assignment at Single(bb1[3]) ($DIR/region-subtyping-basic.rs:19:13: 19:14 (#0)
| |
fn main() -> () { fn main() -> () {
let mut _0: (); // return place in scope 0 at $DIR/region-subtyping-basic.rs:16:11: 16:11 let mut _0: (); // return place in scope 0 at $DIR/region-subtyping-basic.rs:16:11: 16:11

View file

@ -16,7 +16,7 @@
| '_#1r live at {bb0[0..=22]} | '_#1r live at {bb0[0..=22]}
| '_#3r live at {bb0[10]} | '_#3r live at {bb0[10]}
| '_#4r live at {bb0[11]} | '_#4r live at {bb0[11]}
| '_#3r: '_#4r due to Assignment at Single(bb0[10]) | '_#3r: '_#4r due to Assignment at Single(bb0[10]) ($DIR/storage_ranges.rs:6:17: 6:25 (#0)
| |
fn main() -> () { fn main() -> () {
let mut _0: (); // return place in scope 0 at $DIR/storage_ranges.rs:3:11: 3:11 let mut _0: (); // return place in scope 0 at $DIR/storage_ranges.rs:3:11: 3:11

View file

@ -1,6 +1,6 @@
// exact-check // exact-check
const QUERY = 'hashmap'; const QUERY = '"hashmap"';
const FILTER_CRATE = 'core'; const FILTER_CRATE = 'core';
const EXPECTED = { const EXPECTED = {

View file

@ -0,0 +1,365 @@
const QUERY = [
'<P>',
'-> <P>',
'a<"P">',
'"P" "P"',
'P "P"',
'"p" p',
'"const": p',
"a<:a>",
"a<::a>",
"((a))",
"(p -> p",
"::a::b",
"a::::b",
"a::b::",
":a",
"a b:",
"a (b:",
"_:",
"a-bb",
"a>bb",
"ab'",
"a->",
'"p" <a>',
'"p" a<a>',
"a,<",
"aaaaa<>b",
"fn:aaaaa<>b",
"->a<>b",
"a<->",
"a:: a",
"a ::a",
"a<a>:",
"a<>:",
"a,:",
" a<> :",
"mod : :",
];
const PARSED = [
{
elems: [],
foundElems: 0,
original: "<P>",
returned: [],
typeFilter: -1,
userQuery: "<p>",
error: "Found generics without a path",
},
{
elems: [],
foundElems: 0,
original: "-> <P>",
returned: [],
typeFilter: -1,
userQuery: "-> <p>",
error: "Found generics without a path",
},
{
elems: [],
foundElems: 0,
original: "a<\"P\">",
returned: [],
typeFilter: -1,
userQuery: "a<\"p\">",
error: "`\"` cannot be used in generics",
},
{
elems: [],
foundElems: 0,
original: "\"P\" \"P\"",
returned: [],
typeFilter: -1,
userQuery: "\"p\" \"p\"",
error: "Cannot have more than one literal search element",
},
{
elems: [],
foundElems: 0,
original: "P \"P\"",
returned: [],
typeFilter: -1,
userQuery: "p \"p\"",
error: "Cannot use literal search when there is more than one element",
},
{
elems: [],
foundElems: 0,
original: "\"p\" p",
returned: [],
typeFilter: -1,
userQuery: "\"p\" p",
error: "You cannot have more than one element if you use quotes",
},
{
elems: [],
foundElems: 0,
original: "\"const\": p",
returned: [],
typeFilter: -1,
userQuery: "\"const\": p",
error: "You cannot use quotes on type filter",
},
{
elems: [],
foundElems: 0,
original: "a<:a>",
returned: [],
typeFilter: -1,
userQuery: "a<:a>",
error: "Unexpected `:` after `<`",
},
{
elems: [],
foundElems: 0,
original: "a<::a>",
returned: [],
typeFilter: -1,
userQuery: "a<::a>",
error: "Unexpected `::`: paths cannot start with `::`",
},
{
elems: [],
foundElems: 0,
original: "((a))",
returned: [],
typeFilter: -1,
userQuery: "((a))",
error: "Unexpected `(`",
},
{
elems: [],
foundElems: 0,
original: "(p -> p",
returned: [],
typeFilter: -1,
userQuery: "(p -> p",
error: "Unexpected `(`",
},
{
elems: [],
foundElems: 0,
original: "::a::b",
returned: [],
typeFilter: -1,
userQuery: "::a::b",
error: "Paths cannot start with `::`",
},
{
elems: [],
foundElems: 0,
original: "a::::b",
returned: [],
typeFilter: -1,
userQuery: "a::::b",
error: "Unexpected `::::`",
},
{
elems: [],
foundElems: 0,
original: "a::b::",
returned: [],
typeFilter: -1,
userQuery: "a::b::",
error: "Paths cannot end with `::`",
},
{
elems: [],
foundElems: 0,
original: ":a",
returned: [],
typeFilter: -1,
userQuery: ":a",
error: "Expected type filter before `:`",
},
{
elems: [],
foundElems: 0,
original: "a b:",
returned: [],
typeFilter: -1,
userQuery: "a b:",
error: "Unexpected `:`",
},
{
elems: [],
foundElems: 0,
original: "a (b:",
returned: [],
typeFilter: -1,
userQuery: "a (b:",
error: "Unexpected `(`",
},
{
elems: [],
foundElems: 0,
original: "_:",
returned: [],
typeFilter: -1,
userQuery: "_:",
error: "Unknown type filter `_`",
},
{
elems: [],
foundElems: 0,
original: "a-bb",
returned: [],
typeFilter: -1,
userQuery: "a-bb",
error: "Unexpected `-` (did you mean `->`?)",
},
{
elems: [],
foundElems: 0,
original: "a>bb",
returned: [],
typeFilter: -1,
userQuery: "a>bb",
error: "Unexpected `>` (did you mean `->`?)",
},
{
elems: [],
foundElems: 0,
original: "ab'",
returned: [],
typeFilter: -1,
userQuery: "ab'",
error: "Unexpected `'`",
},
{
elems: [],
foundElems: 0,
original: "a->",
returned: [],
typeFilter: -1,
userQuery: "a->",
error: "Expected at least one item after `->`",
},
{
elems: [],
foundElems: 0,
original: '"p" <a>',
returned: [],
typeFilter: -1,
userQuery: '"p" <a>',
error: "Found generics without a path",
},
{
elems: [],
foundElems: 0,
original: '"p" a<a>',
returned: [],
typeFilter: -1,
userQuery: '"p" a<a>',
error: "You cannot have more than one element if you use quotes",
},
{
elems: [],
foundElems: 0,
original: 'a,<',
returned: [],
typeFilter: -1,
userQuery: 'a,<',
error: 'Found generics without a path',
},
{
elems: [],
foundElems: 0,
original: 'aaaaa<>b',
returned: [],
typeFilter: -1,
userQuery: 'aaaaa<>b',
error: 'Expected `,`, ` `, `:` or `->`, found `b`',
},
{
elems: [],
foundElems: 0,
original: 'fn:aaaaa<>b',
returned: [],
typeFilter: -1,
userQuery: 'fn:aaaaa<>b',
error: 'Expected `,`, ` ` or `->`, found `b`',
},
{
elems: [],
foundElems: 0,
original: '->a<>b',
returned: [],
typeFilter: -1,
userQuery: '->a<>b',
error: 'Expected `,` or ` `, found `b`',
},
{
elems: [],
foundElems: 0,
original: 'a<->',
returned: [],
typeFilter: -1,
userQuery: 'a<->',
error: 'Unexpected `-` after `<`',
},
{
elems: [],
foundElems: 0,
original: 'a:: a',
returned: [],
typeFilter: -1,
userQuery: 'a:: a',
error: 'Paths cannot end with `::`',
},
{
elems: [],
foundElems: 0,
original: 'a ::a',
returned: [],
typeFilter: -1,
userQuery: 'a ::a',
error: 'Paths cannot start with `::`',
},
{
elems: [],
foundElems: 0,
original: "a<a>:",
returned: [],
typeFilter: -1,
userQuery: "a<a>:",
error: 'Unexpected `:`',
},
{
elems: [],
foundElems: 0,
original: "a<>:",
returned: [],
typeFilter: -1,
userQuery: "a<>:",
error: 'Unexpected `<` in type filter',
},
{
elems: [],
foundElems: 0,
original: "a,:",
returned: [],
typeFilter: -1,
userQuery: "a,:",
error: 'Unexpected `,` in type filter',
},
{
elems: [],
foundElems: 0,
original: "a<> :",
returned: [],
typeFilter: -1,
userQuery: "a<> :",
error: 'Unexpected `<` in type filter',
},
{
elems: [],
foundElems: 0,
original: "mod : :",
returned: [],
typeFilter: -1,
userQuery: "mod : :",
error: 'Unexpected `:`',
},
];

View file

@ -0,0 +1,43 @@
const QUERY = ['fn:foo', 'enum : foo', 'macro<f>:foo'];
const PARSED = [
{
elems: [{
name: "foo",
fullPath: ["foo"],
pathWithoutLast: [],
pathLast: "foo",
generics: [],
}],
foundElems: 1,
original: "fn:foo",
returned: [],
typeFilter: 5,
userQuery: "fn:foo",
error: null,
},
{
elems: [{
name: "foo",
fullPath: ["foo"],
pathWithoutLast: [],
pathLast: "foo",
generics: [],
}],
foundElems: 1,
original: "enum : foo",
returned: [],
typeFilter: 4,
userQuery: "enum : foo",
error: null,
},
{
elems: [],
foundElems: 0,
original: "macro<f>:foo",
returned: [],
typeFilter: -1,
userQuery: "macro<f>:foo",
error: "Unexpected `:`",
},
];

View file

@ -0,0 +1,62 @@
const QUERY = ['A<B<C<D>, E>', 'p<> u8', '"p"<a>'];
const PARSED = [
{
elems: [],
foundElems: 0,
original: 'A<B<C<D>, E>',
returned: [],
typeFilter: -1,
userQuery: 'a<b<c<d>, e>',
error: 'Unexpected `<` after `<`',
},
{
elems: [
{
name: "p",
fullPath: ["p"],
pathWithoutLast: [],
pathLast: "p",
generics: [],
},
{
name: "u8",
fullPath: ["u8"],
pathWithoutLast: [],
pathLast: "u8",
generics: [],
},
],
foundElems: 2,
original: "p<> u8",
returned: [],
typeFilter: -1,
userQuery: "p<> u8",
error: null,
},
{
elems: [
{
name: "p",
fullPath: ["p"],
pathWithoutLast: [],
pathLast: "p",
generics: [
{
name: "a",
fullPath: ["a"],
pathWithoutLast: [],
pathLast: "a",
generics: [],
},
],
},
],
foundElems: 1,
original: '"p"<a>',
returned: [],
typeFilter: -1,
userQuery: '"p"<a>',
error: null,
},
];

View file

@ -0,0 +1,27 @@
const QUERY = ['R<P>'];
const PARSED = [
{
elems: [{
name: "r",
fullPath: ["r"],
pathWithoutLast: [],
pathLast: "r",
generics: [
{
name: "p",
fullPath: ["p"],
pathWithoutLast: [],
pathLast: "p",
generics: [],
},
],
}],
foundElems: 1,
original: "R<P>",
returned: [],
typeFilter: -1,
userQuery: "r<p>",
error: null,
}
];

View file

@ -0,0 +1,90 @@
const QUERY = ['A::B', 'A::B,C', 'A::B<f>,C', 'mod::a'];
const PARSED = [
{
elems: [{
name: "a::b",
fullPath: ["a", "b"],
pathWithoutLast: ["a"],
pathLast: "b",
generics: [],
}],
foundElems: 1,
original: "A::B",
returned: [],
typeFilter: -1,
userQuery: "a::b",
error: null,
},
{
elems: [
{
name: "a::b",
fullPath: ["a", "b"],
pathWithoutLast: ["a"],
pathLast: "b",
generics: [],
},
{
name: "c",
fullPath: ["c"],
pathWithoutLast: [],
pathLast: "c",
generics: [],
},
],
foundElems: 2,
original: 'A::B,C',
returned: [],
typeFilter: -1,
userQuery: 'a::b,c',
error: null,
},
{
elems: [
{
name: "a::b",
fullPath: ["a", "b"],
pathWithoutLast: ["a"],
pathLast: "b",
generics: [
{
name: "f",
fullPath: ["f"],
pathWithoutLast: [],
pathLast: "f",
generics: [],
},
],
},
{
name: "c",
fullPath: ["c"],
pathWithoutLast: [],
pathLast: "c",
generics: [],
},
],
foundElems: 2,
original: 'A::B<f>,C',
returned: [],
typeFilter: -1,
userQuery: 'a::b<f>,c',
error: null,
},
{
elems: [{
name: "mod::a",
fullPath: ["mod", "a"],
pathWithoutLast: ["mod"],
pathLast: "a",
generics: [],
}],
foundElems: 1,
original: "mod::a",
returned: [],
typeFilter: -1,
userQuery: "mod::a",
error: null,
},
];

View file

@ -0,0 +1,87 @@
const QUERY = [
'-> "p"',
'"p",',
'"p" -> a',
'"a" -> "p"',
'->"-"',
'"a',
'""',
];
const PARSED = [
{
elems: [],
foundElems: 1,
original: '-> "p"',
returned: [{
name: "p",
fullPath: ["p"],
pathWithoutLast: [],
pathLast: "p",
generics: [],
}],
typeFilter: -1,
userQuery: '-> "p"',
error: null,
},
{
elems: [{
name: "p",
fullPath: ["p"],
pathWithoutLast: [],
pathLast: "p",
generics: [],
}],
foundElems: 1,
original: '"p",',
returned: [],
typeFilter: -1,
userQuery: '"p",',
error: null,
},
{
elems: [],
foundElems: 0,
original: '"p" -> a',
returned: [],
typeFilter: -1,
userQuery: '"p" -> a',
error: "You cannot have more than one element if you use quotes",
},
{
elems: [],
foundElems: 0,
original: '"a" -> "p"',
returned: [],
typeFilter: -1,
userQuery: '"a" -> "p"',
error: "Cannot have more than one literal search element",
},
{
elems: [],
foundElems: 0,
original: '->"-"',
returned: [],
typeFilter: -1,
userQuery: '->"-"',
error: 'Unexpected `-` in a string element',
},
{
elems: [],
foundElems: 0,
original: '"a',
returned: [],
typeFilter: -1,
userQuery: '"a',
error: 'Unclosed `"`',
},
{
elems: [],
foundElems: 0,
original: '""',
returned: [],
typeFilter: -1,
userQuery: '""',
error: 'Cannot have empty string element',
},
];

View file

@ -0,0 +1,78 @@
const QUERY = ['-> F<P>', '-> P', '->,a', 'aaaaa->a'];
const PARSED = [
{
elems: [],
foundElems: 1,
original: "-> F<P>",
returned: [{
name: "f",
fullPath: ["f"],
pathWithoutLast: [],
pathLast: "f",
generics: [
{
name: "p",
fullPath: ["p"],
pathWithoutLast: [],
pathLast: "p",
generics: [],
},
],
}],
typeFilter: -1,
userQuery: "-> f<p>",
error: null,
},
{
elems: [],
foundElems: 1,
original: "-> P",
returned: [{
name: "p",
fullPath: ["p"],
pathWithoutLast: [],
pathLast: "p",
generics: [],
}],
typeFilter: -1,
userQuery: "-> p",
error: null,
},
{
elems: [],
foundElems: 1,
original: "->,a",
returned: [{
name: "a",
fullPath: ["a"],
pathWithoutLast: [],
pathLast: "a",
generics: [],
}],
typeFilter: -1,
userQuery: "->,a",
error: null,
},
{
elems: [{
name: "aaaaa",
fullPath: ["aaaaa"],
pathWithoutLast: [],
pathLast: "aaaaa",
generics: [],
}],
foundElems: 2,
original: "aaaaa->a",
returned: [{
name: "a",
fullPath: ["a"],
pathWithoutLast: [],
pathLast: "a",
generics: [],
}],
typeFilter: -1,
userQuery: "aaaaa->a",
error: null,
},
];

View file

@ -0,0 +1,206 @@
// ignore-tidy-tab
const QUERY = [
'aaaaaa b',
'a b',
'a,b',
'a\tb',
'a<b c>',
'a<b,c>',
'a<b\tc>',
];
const PARSED = [
{
elems: [
{
name: 'aaaaaa',
fullPath: ['aaaaaa'],
pathWithoutLast: [],
pathLast: 'aaaaaa',
generics: [],
},
{
name: 'b',
fullPath: ['b'],
pathWithoutLast: [],
pathLast: 'b',
generics: [],
},
],
foundElems: 2,
original: "aaaaaa b",
returned: [],
typeFilter: -1,
userQuery: "aaaaaa b",
error: null,
},
{
elems: [
{
name: 'a',
fullPath: ['a'],
pathWithoutLast: [],
pathLast: 'a',
generics: [],
},
{
name: 'b',
fullPath: ['b'],
pathWithoutLast: [],
pathLast: 'b',
generics: [],
},
],
foundElems: 2,
original: "a b",
returned: [],
typeFilter: -1,
userQuery: "a b",
error: null,
},
{
elems: [
{
name: 'a',
fullPath: ['a'],
pathWithoutLast: [],
pathLast: 'a',
generics: [],
},
{
name: 'b',
fullPath: ['b'],
pathWithoutLast: [],
pathLast: 'b',
generics: [],
},
],
foundElems: 2,
original: "a,b",
returned: [],
typeFilter: -1,
userQuery: "a,b",
error: null,
},
{
elems: [
{
name: 'a',
fullPath: ['a'],
pathWithoutLast: [],
pathLast: 'a',
generics: [],
},
{
name: 'b',
fullPath: ['b'],
pathWithoutLast: [],
pathLast: 'b',
generics: [],
},
],
foundElems: 2,
original: "a\tb",
returned: [],
typeFilter: -1,
userQuery: "a\tb",
error: null,
},
{
elems: [
{
name: 'a',
fullPath: ['a'],
pathWithoutLast: [],
pathLast: 'a',
generics: [
{
name: 'b',
fullPath: ['b'],
pathWithoutLast: [],
pathLast: 'b',
generics: [],
},
{
name: 'c',
fullPath: ['c'],
pathWithoutLast: [],
pathLast: 'c',
generics: [],
},
],
},
],
foundElems: 1,
original: "a<b c>",
returned: [],
typeFilter: -1,
userQuery: "a<b c>",
error: null,
},
{
elems: [
{
name: 'a',
fullPath: ['a'],
pathWithoutLast: [],
pathLast: 'a',
generics: [
{
name: 'b',
fullPath: ['b'],
pathWithoutLast: [],
pathLast: 'b',
generics: [],
},
{
name: 'c',
fullPath: ['c'],
pathWithoutLast: [],
pathLast: 'c',
generics: [],
},
],
},
],
foundElems: 1,
original: "a<b,c>",
returned: [],
typeFilter: -1,
userQuery: "a<b,c>",
error: null,
},
{
elems: [
{
name: 'a',
fullPath: ['a'],
pathWithoutLast: [],
pathLast: 'a',
generics: [
{
name: 'b',
fullPath: ['b'],
pathWithoutLast: [],
pathLast: 'b',
generics: [],
},
{
name: 'c',
fullPath: ['c'],
pathWithoutLast: [],
pathLast: 'c',
generics: [],
},
],
},
],
foundElems: 1,
original: "a<b\tc>",
returned: [],
typeFilter: -1,
userQuery: "a<b\tc>",
error: null,
},
];

View file

@ -0,0 +1,123 @@
// This test is mostly to check that the parser still kinda outputs something
// (and doesn't enter an infinite loop!) even though the query is completely
// invalid.
const QUERY = [
'a b',
'a b',
'a,b(c)',
'aaa,a',
',,,,',
'mod :',
'mod\t:',
];
const PARSED = [
{
elems: [
{
name: "a",
fullPath: ["a"],
pathWithoutLast: [],
pathLast: "a",
generics: [],
},
{
name: "b",
fullPath: ["b"],
pathWithoutLast: [],
pathLast: "b",
generics: [],
},
],
foundElems: 2,
original: "a b",
returned: [],
typeFilter: -1,
userQuery: "a b",
error: null,
},
{
elems: [
{
name: "a",
fullPath: ["a"],
pathWithoutLast: [],
pathLast: "a",
generics: [],
},
{
name: "b",
fullPath: ["b"],
pathWithoutLast: [],
pathLast: "b",
generics: [],
},
],
foundElems: 2,
original: "a b",
returned: [],
typeFilter: -1,
userQuery: "a b",
error: null,
},
{
elems: [],
foundElems: 0,
original: "a,b(c)",
returned: [],
typeFilter: -1,
userQuery: "a,b(c)",
error: "Unexpected `(`",
},
{
elems: [
{
name: "aaa",
fullPath: ["aaa"],
pathWithoutLast: [],
pathLast: "aaa",
generics: [],
},
{
name: "a",
fullPath: ["a"],
pathWithoutLast: [],
pathLast: "a",
generics: [],
},
],
foundElems: 2,
original: "aaa,a",
returned: [],
typeFilter: -1,
userQuery: "aaa,a",
error: null,
},
{
elems: [],
foundElems: 0,
original: ",,,,",
returned: [],
typeFilter: -1,
userQuery: ",,,,",
error: null,
},
{
elems: [],
foundElems: 0,
original: 'mod :',
returned: [],
typeFilter: 0,
userQuery: 'mod :',
error: null,
},
{
elems: [],
foundElems: 0,
original: 'mod\t:',
returned: [],
typeFilter: 0,
userQuery: 'mod\t:',
error: null,
},
];

View file

@ -1,4 +1,7 @@
// ignore-order
const QUERY = '"error"'; const QUERY = '"error"';
const FILTER_CRATE = 'std';
const EXPECTED = { const EXPECTED = {
'others': [ 'others': [
@ -6,7 +9,12 @@ const EXPECTED = {
{ 'path': 'std::fmt', 'name': 'Error' }, { 'path': 'std::fmt', 'name': 'Error' },
{ 'path': 'std::io', 'name': 'Error' }, { 'path': 'std::io', 'name': 'Error' },
], ],
'in_args': [], 'in_args': [
{ 'path': 'std::fmt::Error', 'name': 'eq' },
{ 'path': 'std::fmt::Error', 'name': 'cmp' },
{ 'path': 'std::fmt::Error', 'name': 'partial_cmp' },
],
'returned': [ 'returned': [
{ 'path': 'std::fmt::LowerExp', 'name': 'fmt' }, { 'path': 'std::fmt::LowerExp', 'name': 'fmt' },
], ],

View file

@ -1,8 +1,8 @@
const QUERY = 'struct:Vec'; const QUERY = 'struct:VecD';
const EXPECTED = { const EXPECTED = {
'others': [ 'others': [
{ 'path': 'std::vec', 'name': 'Vec' },
{ 'path': 'std::collections', 'name': 'VecDeque' }, { 'path': 'std::collections', 'name': 'VecDeque' },
{ 'path': 'std::vec', 'name': 'Vec' },
], ],
}; };

View file

@ -1,6 +1,7 @@
// exact-check // exact-check
const QUERY = 'macro:print'; const QUERY = 'macro:print';
const FILTER_CRATE = 'std';
const EXPECTED = { const EXPECTED = {
'others': [ 'others': [
@ -9,6 +10,8 @@ const EXPECTED = {
{ 'path': 'std', 'name': 'println' }, { 'path': 'std', 'name': 'println' },
{ 'path': 'std', 'name': 'eprintln' }, { 'path': 'std', 'name': 'eprintln' },
{ 'path': 'std::pin', 'name': 'pin' }, { 'path': 'std::pin', 'name': 'pin' },
{ 'path': 'core::pin', 'name': 'pin' }, { 'path': 'std::future', 'name': 'join' },
{ 'path': 'std', 'name': 'line' },
{ 'path': 'std', 'name': 'write' },
], ],
}; };

View file

@ -4,6 +4,6 @@ const EXPECTED = {
'others': [ 'others': [
{ 'path': 'std::vec::Vec', 'name': 'new' }, { 'path': 'std::vec::Vec', 'name': 'new' },
{ 'path': 'std::vec::Vec', 'name': 'ne' }, { 'path': 'std::vec::Vec', 'name': 'ne' },
{ 'path': 'std::rc::Rc', 'name': 'ne' }, { 'path': 'alloc::vec::Vec', 'name': 'ne' },
], ],
}; };

View file

@ -1,6 +1,6 @@
// exact-check // exact-check
const QUERY = 'true'; const QUERY = '"true"';
const FILTER_CRATE = 'doc_alias_filter'; const FILTER_CRATE = 'doc_alias_filter';

View file

@ -27,6 +27,7 @@ const QUERY = [
const EXPECTED = [ const EXPECTED = [
{ {
// StructItem
'others': [ 'others': [
{ {
'path': 'doc_alias', 'path': 'doc_alias',
@ -38,6 +39,7 @@ const EXPECTED = [
], ],
}, },
{ {
// StructFieldItem
'others': [ 'others': [
{ {
'path': 'doc_alias::Struct', 'path': 'doc_alias::Struct',
@ -49,6 +51,7 @@ const EXPECTED = [
], ],
}, },
{ {
// StructMethodItem
'others': [ 'others': [
{ {
'path': 'doc_alias::Struct', 'path': 'doc_alias::Struct',
@ -76,6 +79,7 @@ const EXPECTED = [
], ],
}, },
{ {
// ImplTraitFunction
'others': [ 'others': [
{ {
'path': 'doc_alias::Struct', 'path': 'doc_alias::Struct',
@ -87,6 +91,7 @@ const EXPECTED = [
], ],
}, },
{ {
// EnumItem
'others': [ 'others': [
{ {
'path': 'doc_alias', 'path': 'doc_alias',
@ -98,6 +103,7 @@ const EXPECTED = [
], ],
}, },
{ {
// VariantItem
'others': [ 'others': [
{ {
'path': 'doc_alias::Enum', 'path': 'doc_alias::Enum',
@ -109,6 +115,7 @@ const EXPECTED = [
], ],
}, },
{ {
// EnumMethodItem
'others': [ 'others': [
{ {
'path': 'doc_alias::Enum', 'path': 'doc_alias::Enum',
@ -120,6 +127,7 @@ const EXPECTED = [
], ],
}, },
{ {
// TypedefItem
'others': [ 'others': [
{ {
'path': 'doc_alias', 'path': 'doc_alias',
@ -131,6 +139,7 @@ const EXPECTED = [
], ],
}, },
{ {
// TraitItem
'others': [ 'others': [
{ {
'path': 'doc_alias', 'path': 'doc_alias',
@ -142,6 +151,7 @@ const EXPECTED = [
], ],
}, },
{ {
// TraitTypeItem
'others': [ 'others': [
{ {
'path': 'doc_alias::Trait', 'path': 'doc_alias::Trait',
@ -153,6 +163,7 @@ const EXPECTED = [
], ],
}, },
{ {
// AssociatedConstItem
'others': [ 'others': [
{ {
'path': 'doc_alias::Trait', 'path': 'doc_alias::Trait',
@ -164,6 +175,7 @@ const EXPECTED = [
], ],
}, },
{ {
// TraitFunctionItem
'others': [ 'others': [
{ {
'path': 'doc_alias::Trait', 'path': 'doc_alias::Trait',
@ -175,6 +187,7 @@ const EXPECTED = [
], ],
}, },
{ {
// FunctionItem
'others': [ 'others': [
{ {
'path': 'doc_alias', 'path': 'doc_alias',
@ -186,6 +199,7 @@ const EXPECTED = [
], ],
}, },
{ {
// ModuleItem
'others': [ 'others': [
{ {
'path': 'doc_alias', 'path': 'doc_alias',
@ -197,6 +211,7 @@ const EXPECTED = [
], ],
}, },
{ {
// ConstItem
'others': [ 'others': [
{ {
'path': 'doc_alias', 'path': 'doc_alias',
@ -212,6 +227,7 @@ const EXPECTED = [
], ],
}, },
{ {
// StaticItem
'others': [ 'others': [
{ {
'path': 'doc_alias', 'path': 'doc_alias',
@ -223,6 +239,7 @@ const EXPECTED = [
], ],
}, },
{ {
// UnionItem
'others': [ 'others': [
{ {
'path': 'doc_alias', 'path': 'doc_alias',
@ -240,6 +257,7 @@ const EXPECTED = [
], ],
}, },
{ {
// UnionFieldItem
'others': [ 'others': [
{ {
'path': 'doc_alias::Union', 'path': 'doc_alias::Union',
@ -251,6 +269,7 @@ const EXPECTED = [
], ],
}, },
{ {
// UnionMethodItem
'others': [ 'others': [
{ {
'path': 'doc_alias::Union', 'path': 'doc_alias::Union',
@ -262,6 +281,7 @@ const EXPECTED = [
], ],
}, },
{ {
// MacroItem
'others': [ 'others': [
{ {
'path': 'doc_alias', 'path': 'doc_alias',

View file

@ -1,16 +1,18 @@
// exact-check // exact-check
const QUERY = [ const QUERY = [
'"R<P>"', 'R<P>',
'"P"', '"P"',
'P', 'P',
'"ExtraCreditStructMulti<ExtraCreditInnerMulti, ExtraCreditInnerMulti>"', 'ExtraCreditStructMulti<ExtraCreditInnerMulti, ExtraCreditInnerMulti>',
'TraitCat', 'TraitCat',
'TraitDog', 'TraitDog',
'Result<String>',
]; ];
const EXPECTED = [ const EXPECTED = [
{ {
// R<P>
'returned': [ 'returned': [
{ 'path': 'generics', 'name': 'alef' }, { 'path': 'generics', 'name': 'alef' },
], ],
@ -19,6 +21,7 @@ const EXPECTED = [
], ],
}, },
{ {
// "P"
'others': [ 'others': [
{ 'path': 'generics', 'name': 'P' }, { 'path': 'generics', 'name': 'P' },
], ],
@ -30,29 +33,41 @@ const EXPECTED = [
], ],
}, },
{ {
// P
'returned': [ 'returned': [
{ 'path': 'generics', 'name': 'alef' }, { 'path': 'generics', 'name': 'alef' },
{ 'path': 'generics', 'name': 'bet' },
], ],
'in_args': [ 'in_args': [
{ 'path': 'generics', 'name': 'alpha' }, { 'path': 'generics', 'name': 'alpha' },
{ 'path': 'generics', 'name': 'beta' },
], ],
}, },
{ {
// "ExtraCreditStructMulti"<ExtraCreditInnerMulti, ExtraCreditInnerMulti>
'in_args': [ 'in_args': [
{ 'path': 'generics', 'name': 'extracreditlabhomework' }, { 'path': 'generics', 'name': 'extracreditlabhomework' },
], ],
'returned': [], 'returned': [],
}, },
{ {
// TraitCat
'in_args': [ 'in_args': [
{ 'path': 'generics', 'name': 'gamma' }, { 'path': 'generics', 'name': 'gamma' },
], ],
}, },
{ {
// TraitDog
'in_args': [ 'in_args': [
{ 'path': 'generics', 'name': 'gamma' }, { 'path': 'generics', 'name': 'gamma' },
], ],
}, },
{
// Result<String>
'others': [],
'returned': [
{ 'path': 'generics', 'name': 'super_soup' },
],
'in_args': [
{ 'path': 'generics', 'name': 'super_soup' },
],
},
]; ];

View file

@ -24,3 +24,5 @@ pub trait TraitCat {}
pub trait TraitDog {} pub trait TraitDog {}
pub fn gamma<T: TraitCat + TraitDog>(t: T) {} pub fn gamma<T: TraitCat + TraitDog>(t: T) {}
pub fn super_soup(s: Result<String, i32>) -> Result<String, i32> { s }

View file

@ -1,5 +1,5 @@
error: implementation of `FnOnce` is not general enough error: implementation of `FnOnce` is not general enough
--> $DIR/rfc1623.rs:36:8 --> $DIR/rfc1623.rs:32:8
| |
LL | f: &id, LL | f: &id,
| ^^^ implementation of `FnOnce` is not general enough | ^^^ implementation of `FnOnce` is not general enough

View file

@ -1,63 +1,35 @@
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/rfc1623.rs:29:35 --> $DIR/rfc1623.rs:32:8
| |
LL | static SOME_STRUCT: &SomeStruct = &SomeStruct { LL | f: &id,
| ___________________________________^ | ^^^ one type is more general than the other
LL | |
LL | |
LL | |
... |
LL | |
LL | | };
| |_^ one type is more general than the other
| |
= note: expected type `for<'a, 'b> Fn<(&'a Foo<'b>,)>` = note: expected type `for<'a, 'b> Fn<(&'a Foo<'b>,)>`
found type `Fn<(&Foo<'_>,)>` found type `Fn<(&Foo<'_>,)>`
error[E0308]: mismatched types error[E0308]: mismatched types
--> $DIR/rfc1623.rs:29:35 --> $DIR/rfc1623.rs:32:8
| |
LL | static SOME_STRUCT: &SomeStruct = &SomeStruct { LL | f: &id,
| ___________________________________^ | ^^^ one type is more general than the other
LL | |
LL | |
LL | |
... |
LL | |
LL | | };
| |_^ one type is more general than the other
| |
= note: expected type `for<'a, 'b> Fn<(&'a Foo<'b>,)>` = note: expected type `for<'a, 'b> Fn<(&'a Foo<'b>,)>`
found type `Fn<(&Foo<'_>,)>` found type `Fn<(&Foo<'_>,)>`
error: implementation of `FnOnce` is not general enough error: implementation of `FnOnce` is not general enough
--> $DIR/rfc1623.rs:29:35 --> $DIR/rfc1623.rs:32:8
| |
LL | static SOME_STRUCT: &SomeStruct = &SomeStruct { LL | f: &id,
| ___________________________________^ | ^^^ implementation of `FnOnce` is not general enough
LL | |
LL | |
LL | |
... |
LL | |
LL | | };
| |_^ implementation of `FnOnce` is not general enough
| |
= note: `fn(&'2 Foo<'_>) -> &'2 Foo<'_> {id::<&'2 Foo<'_>>}` must implement `FnOnce<(&'1 Foo<'b>,)>`, for any lifetime `'1`... = note: `fn(&'2 Foo<'_>) -> &'2 Foo<'_> {id::<&'2 Foo<'_>>}` must implement `FnOnce<(&'1 Foo<'b>,)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&'2 Foo<'_>,)>`, for some specific lifetime `'2` = note: ...but it actually implements `FnOnce<(&'2 Foo<'_>,)>`, for some specific lifetime `'2`
error: implementation of `FnOnce` is not general enough error: implementation of `FnOnce` is not general enough
--> $DIR/rfc1623.rs:29:35 --> $DIR/rfc1623.rs:32:8
| |
LL | static SOME_STRUCT: &SomeStruct = &SomeStruct { LL | f: &id,
| ___________________________________^ | ^^^ implementation of `FnOnce` is not general enough
LL | |
LL | |
LL | |
... |
LL | |
LL | | };
| |_^ implementation of `FnOnce` is not general enough
| |
= note: `fn(&Foo<'2>) -> &Foo<'2> {id::<&Foo<'2>>}` must implement `FnOnce<(&'a Foo<'1>,)>`, for any lifetime `'1`... = note: `fn(&Foo<'2>) -> &Foo<'2> {id::<&Foo<'2>>}` must implement `FnOnce<(&'a Foo<'1>,)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&Foo<'2>,)>`, for some specific lifetime `'2` = note: ...but it actually implements `FnOnce<(&Foo<'2>,)>`, for some specific lifetime `'2`

View file

@ -27,14 +27,14 @@ fn id<T>(t: T) -> T {
} }
static SOME_STRUCT: &SomeStruct = &SomeStruct { static SOME_STRUCT: &SomeStruct = &SomeStruct {
//[nll]~^ ERROR mismatched types
//[nll]~| ERROR mismatched types
//[nll]~| ERROR implementation of `FnOnce` is not general enough
//[nll]~| ERROR implementation of `FnOnce` is not general enough
foo: &Foo { bools: &[false, true] }, foo: &Foo { bools: &[false, true] },
bar: &Bar { bools: &[true, true] }, bar: &Bar { bools: &[true, true] },
f: &id, f: &id,
//[base]~^ ERROR implementation of `FnOnce` is not general enough //[base]~^ ERROR implementation of `FnOnce` is not general enough
//[nll]~^^ ERROR mismatched types
//[nll]~| ERROR mismatched types
//[nll]~| ERROR implementation of `FnOnce` is not general enough
//[nll]~| ERROR implementation of `FnOnce` is not general enough
}; };
// very simple test for a 'static static with default lifetime // very simple test for a 'static static with default lifetime

View file

@ -58,7 +58,8 @@ function extractFunction(content, functionName) {
} while (pos < content.length && content[pos] !== '/' && content[pos - 1] !== '*'); } while (pos < content.length && content[pos] !== '/' && content[pos - 1] !== '*');
// Eat quoted strings // Eat quoted strings
} else if (content[pos] === '"' || content[pos] === "'" || content[pos] === "`") { } else if ((content[pos] === '"' || content[pos] === "'" || content[pos] === "`") &&
(pos === 0 || content[pos - 1] !== '/')) {
stop = content[pos]; stop = content[pos];
do { do {
if (content[pos] === '\\') { if (content[pos] === '\\') {
@ -269,8 +270,13 @@ function loadSearchJsAndIndex(searchJs, searchIndex, storageJs, crate) {
// execQuery last parameter is built in buildIndex. // execQuery last parameter is built in buildIndex.
// buildIndex requires the hashmap from search-index. // buildIndex requires the hashmap from search-index.
var functionsToLoad = ["buildHrefAndPath", "pathSplitter", "levenshtein", "validateResult", var functionsToLoad = ["buildHrefAndPath", "pathSplitter", "levenshtein", "validateResult",
"handleAliases", "getQuery", "buildIndex", "execQuery", "execSearch", "buildIndex", "execQuery", "parseQuery", "createQueryResults",
"removeEmptyStringsFromArray"]; "isWhitespace", "isSpecialStartCharacter", "isStopCharacter",
"parseInput", "getItemsBefore", "getNextElem", "createQueryElement",
"isReturnArrow", "isPathStart", "getStringElem", "newParsedQuery",
"itemTypeFromName", "isEndCharacter", "isErrorCharacter",
"isIdentCharacter", "isSeparatorCharacter", "getIdentEndPosition",
"checkExtraTypeFilterCharacters", "isWhitespaceCharacter"];
const functions = ["hasOwnPropertyRustdoc", "onEach"]; const functions = ["hasOwnPropertyRustdoc", "onEach"];
ALIASES = {}; ALIASES = {};
@ -286,12 +292,99 @@ function loadSearchJsAndIndex(searchJs, searchIndex, storageJs, crate) {
return [loaded, index]; return [loaded, index];
} }
// This function checks if `expected` has all the required fields needed for the checks.
function checkNeededFields(fullPath, expected, error_text, queryName, position) {
let fieldsToCheck;
if (fullPath.length === 0) {
fieldsToCheck = [
"foundElems",
"original",
"returned",
"typeFilter",
"userQuery",
"error",
];
} else if (fullPath.endsWith("elems") || fullPath.endsWith("generics")) {
fieldsToCheck = [
"name",
"fullPath",
"pathWithoutLast",
"pathLast",
"generics",
];
} else {
fieldsToCheck = [];
}
for (var i = 0; i < fieldsToCheck.length; ++i) {
const field = fieldsToCheck[i];
if (!expected.hasOwnProperty(field)) {
let text = `${queryName}==> Mandatory key \`${field}\` is not present`;
if (fullPath.length > 0) {
text += ` in field \`${fullPath}\``;
if (position != null) {
text += ` (position ${position})`;
}
}
error_text.push(text);
}
}
}
function valueCheck(fullPath, expected, result, error_text, queryName) {
if (Array.isArray(expected)) {
for (var i = 0; i < expected.length; ++i) {
checkNeededFields(fullPath, expected[i], error_text, queryName, i);
if (i >= result.length) {
error_text.push(`${queryName}==> EXPECTED has extra value in array from field ` +
`\`${fullPath}\` (position ${i}): \`${JSON.stringify(expected[i])}\``);
} else {
valueCheck(fullPath + '[' + i + ']', expected[i], result[i], error_text, queryName);
}
}
for (; i < result.length; ++i) {
error_text.push(`${queryName}==> RESULT has extra value in array from field ` +
`\`${fullPath}\` (position ${i}): \`${JSON.stringify(result[i])}\` ` +
'compared to EXPECTED');
}
} else if (expected !== null && typeof expected !== "undefined" &&
expected.constructor == Object)
{
for (const key in expected) {
if (!expected.hasOwnProperty(key)) {
continue;
}
if (!result.hasOwnProperty(key)) {
error_text.push('==> Unknown key "' + key + '"');
break;
}
const obj_path = fullPath + (fullPath.length > 0 ? '.' : '') + key;
valueCheck(obj_path, expected[key], result[key], error_text, queryName);
}
} else {
expectedValue = JSON.stringify(expected);
resultValue = JSON.stringify(result);
if (expectedValue != resultValue) {
error_text.push(`${queryName}==> Different values for field \`${fullPath}\`:\n` +
`EXPECTED: \`${expectedValue}\`\nRESULT: \`${resultValue}\``);
}
}
}
function runParser(query, expected, loaded, loadedFile, queryName) {
var error_text = [];
checkNeededFields("", expected, error_text, queryName, null);
if (error_text.length === 0) {
valueCheck('', expected, loaded.parseQuery(query), error_text, queryName);
}
return error_text;
}
function runSearch(query, expected, index, loaded, loadedFile, queryName) { function runSearch(query, expected, index, loaded, loadedFile, queryName) {
const filter_crate = loadedFile.FILTER_CRATE; const filter_crate = loadedFile.FILTER_CRATE;
const ignore_order = loadedFile.ignore_order; const ignore_order = loadedFile.ignore_order;
const exact_check = loadedFile.exact_check; const exact_check = loadedFile.exact_check;
var results = loaded.execSearch(loaded.getQuery(query), index, filter_crate); var results = loaded.execQuery(loaded.parseQuery(query), index, filter_crate);
var error_text = []; var error_text = [];
for (var key in expected) { for (var key in expected) {
@ -353,40 +446,75 @@ function checkResult(error_text, loadedFile, displaySuccess) {
return 1; return 1;
} }
function runChecks(testFile, loaded, index) { function runCheck(loadedFile, key, callback) {
var testFileContent = readFile(testFile) + 'exports.QUERY = QUERY;exports.EXPECTED = EXPECTED;'; const expected = loadedFile[key];
if (testFileContent.indexOf("FILTER_CRATE") !== -1) {
testFileContent += "exports.FILTER_CRATE = FILTER_CRATE;";
} else {
testFileContent += "exports.FILTER_CRATE = null;";
}
var loadedFile = loadContent(testFileContent);
const expected = loadedFile.EXPECTED;
const query = loadedFile.QUERY; const query = loadedFile.QUERY;
if (Array.isArray(query)) { if (Array.isArray(query)) {
if (!Array.isArray(expected)) { if (!Array.isArray(expected)) {
console.log("FAILED"); console.log("FAILED");
console.log("==> If QUERY variable is an array, EXPECTED should be an array too"); console.log(`==> If QUERY variable is an array, ${key} should be an array too`);
return 1; return 1;
} else if (query.length !== expected.length) { } else if (query.length !== expected.length) {
console.log("FAILED"); console.log("FAILED");
console.log("==> QUERY variable should have the same length as EXPECTED"); console.log(`==> QUERY variable should have the same length as ${key}`);
return 1; return 1;
} }
for (var i = 0; i < query.length; ++i) { for (var i = 0; i < query.length; ++i) {
var error_text = runSearch(query[i], expected[i], index, loaded, loadedFile, var error_text = callback(query[i], expected[i], "[ query `" + query[i] + "`]");
"[ query `" + query[i] + "`]");
if (checkResult(error_text, loadedFile, false) !== 0) { if (checkResult(error_text, loadedFile, false) !== 0) {
return 1; return 1;
} }
} }
console.log("OK"); console.log("OK");
return 0; } else {
var error_text = callback(query, expected, "");
if (checkResult(error_text, loadedFile, true) !== 0) {
return 1;
}
} }
var error_text = runSearch(query, expected, index, loaded, loadedFile, ""); return 0;
return checkResult(error_text, loadedFile, true); }
function runChecks(testFile, loaded, index) {
var checkExpected = false;
var checkParsed = false;
var testFileContent = readFile(testFile) + 'exports.QUERY = QUERY;';
if (testFileContent.indexOf("FILTER_CRATE") !== -1) {
testFileContent += "exports.FILTER_CRATE = FILTER_CRATE;";
} else {
testFileContent += "exports.FILTER_CRATE = null;";
}
if (testFileContent.indexOf("\nconst EXPECTED") !== -1) {
testFileContent += 'exports.EXPECTED = EXPECTED;';
checkExpected = true;
}
if (testFileContent.indexOf("\nconst PARSED") !== -1) {
testFileContent += 'exports.PARSED = PARSED;';
checkParsed = true;
}
if (!checkParsed && !checkExpected) {
console.log("FAILED");
console.log("==> At least `PARSED` or `EXPECTED` is needed!");
return 1;
}
const loadedFile = loadContent(testFileContent);
var res = 0;
if (checkExpected) {
res += runCheck(loadedFile, "EXPECTED", (query, expected, text) => {
return runSearch(query, expected, index, loaded, loadedFile, text);
});
}
if (checkParsed) {
res += runCheck(loadedFile, "PARSED", (query, expected, text) => {
return runParser(query, expected, loaded, loadedFile, text);
});
}
return res;
} }
function load_files(doc_folder, resource_suffix, crate) { function load_files(doc_folder, resource_suffix, crate) {