mirror of
https://github.com/rust-lang/rust.git
synced 2026-04-30 14:52:56 +03:00
Auto merge of #96428 - GuillaumeGomez:rollup-4noqr33, r=GuillaumeGomez
Rollup of 8 pull requests Successful merges: - #94022 (Clarify that `Cow::into_owned` returns owned data) - #94703 (Fix codegen bug in "ptx-kernel" abi related to arg passing) - #95949 (Implement Default for AssertUnwindSafe) - #96361 (Switch JS code to ES6) - #96372 (Suggest calling method on nested field when struct is missing method) - #96386 (simplify `describe_field` func in borrowck's diagnostics part) - #96400 (Correct documentation for `Rvalue::ShallowInitBox`) - #96415 (Remove references to git.io) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
@@ -40,6 +40,7 @@
|
||||
crate use region_errors::{ErrorConstraintInfo, RegionErrorKind, RegionErrors};
|
||||
crate use region_name::{RegionName, RegionNameSource};
|
||||
crate use rustc_const_eval::util::CallKind;
|
||||
use rustc_middle::mir::tcx::PlaceTy;
|
||||
|
||||
pub(super) struct IncludingDowncast(pub(super) bool);
|
||||
|
||||
@@ -329,30 +330,20 @@ fn append_local_to_string(&self, local: Local, buf: &mut String) -> Result<(), (
|
||||
|
||||
/// End-user visible description of the `field`nth field of `base`
|
||||
fn describe_field(&self, place: PlaceRef<'tcx>, field: Field) -> String {
|
||||
// FIXME Place2 Make this work iteratively
|
||||
match place {
|
||||
PlaceRef { local, projection: [] } => {
|
||||
let local = &self.body.local_decls[local];
|
||||
self.describe_field_from_ty(local.ty, field, None)
|
||||
}
|
||||
let place_ty = match place {
|
||||
PlaceRef { local, projection: [] } => PlaceTy::from_ty(self.body.local_decls[local].ty),
|
||||
PlaceRef { local, projection: [proj_base @ .., elem] } => match elem {
|
||||
ProjectionElem::Deref => {
|
||||
self.describe_field(PlaceRef { local, projection: proj_base }, field)
|
||||
}
|
||||
ProjectionElem::Downcast(_, variant_index) => {
|
||||
let base_ty = place.ty(self.body, self.infcx.tcx).ty;
|
||||
self.describe_field_from_ty(base_ty, field, Some(*variant_index))
|
||||
}
|
||||
ProjectionElem::Field(_, field_type) => {
|
||||
self.describe_field_from_ty(*field_type, field, None)
|
||||
}
|
||||
ProjectionElem::Index(..)
|
||||
ProjectionElem::Deref
|
||||
| ProjectionElem::Index(..)
|
||||
| ProjectionElem::ConstantIndex { .. }
|
||||
| ProjectionElem::Subslice { .. } => {
|
||||
self.describe_field(PlaceRef { local, projection: proj_base }, field)
|
||||
PlaceRef { local, projection: proj_base }.ty(self.body, self.infcx.tcx)
|
||||
}
|
||||
ProjectionElem::Downcast(..) => place.ty(self.body, self.infcx.tcx),
|
||||
ProjectionElem::Field(_, field_type) => PlaceTy::from_ty(*field_type),
|
||||
},
|
||||
}
|
||||
};
|
||||
self.describe_field_from_ty(place_ty.ty, field, place_ty.variant_index)
|
||||
}
|
||||
|
||||
/// End-user visible description of the `field_index`nth field of `ty`
|
||||
|
||||
@@ -2581,8 +2581,6 @@ pub enum Rvalue<'tcx> {
|
||||
/// This is different from a normal transmute because dataflow analysis will treat the box as
|
||||
/// initialized but its content as uninitialized. Like other pointer casts, this in general
|
||||
/// affects alias analysis.
|
||||
///
|
||||
/// Disallowed after drop elaboration.
|
||||
ShallowInitBox(Operand<'tcx>, Ty<'tcx>),
|
||||
}
|
||||
|
||||
|
||||
@@ -2592,6 +2592,22 @@ fn ty_and_layout_pointee_info_at(
|
||||
|
||||
pointee_info
|
||||
}
|
||||
|
||||
fn is_adt(this: TyAndLayout<'tcx>) -> bool {
|
||||
matches!(this.ty.kind(), ty::Adt(..))
|
||||
}
|
||||
|
||||
fn is_never(this: TyAndLayout<'tcx>) -> bool {
|
||||
this.ty.kind() == &ty::Never
|
||||
}
|
||||
|
||||
fn is_tuple(this: TyAndLayout<'tcx>) -> bool {
|
||||
matches!(this.ty.kind(), ty::Tuple(..))
|
||||
}
|
||||
|
||||
fn is_unit(this: TyAndLayout<'tcx>) -> bool {
|
||||
matches!(this.ty.kind(), ty::Tuple(list) if list.len() == 0)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx> ty::Instance<'tcx> {
|
||||
|
||||
@@ -61,6 +61,10 @@ pub fn empty<'a>() -> &'a List<T> {
|
||||
static EMPTY_SLICE: InOrder<usize, MaxAlign> = InOrder(0, MaxAlign);
|
||||
unsafe { &*(&EMPTY_SLICE as *const _ as *const List<T>) }
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.len
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: Copy> List<T> {
|
||||
|
||||
@@ -696,7 +696,13 @@ pub fn adjust_for_foreign_abi<C>(
|
||||
"sparc" => sparc::compute_abi_info(cx, self),
|
||||
"sparc64" => sparc64::compute_abi_info(cx, self),
|
||||
"nvptx" => nvptx::compute_abi_info(self),
|
||||
"nvptx64" => nvptx64::compute_abi_info(self),
|
||||
"nvptx64" => {
|
||||
if cx.target_spec().adjust_abi(abi) == spec::abi::Abi::PtxKernel {
|
||||
nvptx64::compute_ptx_kernel_abi_info(cx, self)
|
||||
} else {
|
||||
nvptx64::compute_abi_info(self)
|
||||
}
|
||||
}
|
||||
"hexagon" => hexagon::compute_abi_info(self),
|
||||
"riscv32" | "riscv64" => riscv::compute_abi_info(cx, self),
|
||||
"wasm32" | "wasm64" => {
|
||||
|
||||
@@ -1,21 +1,35 @@
|
||||
// Reference: PTX Writer's Guide to Interoperability
|
||||
// https://docs.nvidia.com/cuda/ptx-writers-guide-to-interoperability
|
||||
|
||||
use crate::abi::call::{ArgAbi, FnAbi};
|
||||
use crate::abi::call::{ArgAbi, FnAbi, PassMode, Reg, Size, Uniform};
|
||||
use crate::abi::{HasDataLayout, TyAbiInterface};
|
||||
|
||||
fn classify_ret<Ty>(ret: &mut ArgAbi<'_, Ty>) {
|
||||
if ret.layout.is_aggregate() && ret.layout.size.bits() > 64 {
|
||||
ret.make_indirect();
|
||||
} else {
|
||||
ret.extend_integer_width_to(64);
|
||||
}
|
||||
}
|
||||
|
||||
fn classify_arg<Ty>(arg: &mut ArgAbi<'_, Ty>) {
|
||||
if arg.layout.is_aggregate() && arg.layout.size.bits() > 64 {
|
||||
arg.make_indirect();
|
||||
} else {
|
||||
arg.extend_integer_width_to(64);
|
||||
}
|
||||
}
|
||||
|
||||
fn classify_arg_kernel<'a, Ty, C>(_cx: &C, arg: &mut ArgAbi<'a, Ty>)
|
||||
where
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
if matches!(arg.mode, PassMode::Pair(..)) && (arg.layout.is_adt() || arg.layout.is_tuple()) {
|
||||
let align_bytes = arg.layout.align.abi.bytes();
|
||||
|
||||
let unit = match align_bytes {
|
||||
1 => Reg::i8(),
|
||||
2 => Reg::i16(),
|
||||
4 => Reg::i32(),
|
||||
8 => Reg::i64(),
|
||||
16 => Reg::i128(),
|
||||
_ => unreachable!("Align is given as power of 2 no larger than 16 bytes"),
|
||||
};
|
||||
arg.cast_to(Uniform { unit, total: Size::from_bytes(2 * align_bytes) });
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,3 +45,20 @@ pub fn compute_abi_info<Ty>(fn_abi: &mut FnAbi<'_, Ty>) {
|
||||
classify_arg(arg);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn compute_ptx_kernel_abi_info<'a, Ty, C>(cx: &C, fn_abi: &mut FnAbi<'a, Ty>)
|
||||
where
|
||||
Ty: TyAbiInterface<'a, C> + Copy,
|
||||
C: HasDataLayout,
|
||||
{
|
||||
if !fn_abi.ret.layout.is_unit() && !fn_abi.ret.layout.is_never() {
|
||||
panic!("Kernels should not return anything other than () or !");
|
||||
}
|
||||
|
||||
for arg in &mut fn_abi.args {
|
||||
if arg.is_ignore() {
|
||||
continue;
|
||||
}
|
||||
classify_arg_kernel(cx, arg);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1355,6 +1355,10 @@ fn ty_and_layout_pointee_info_at(
|
||||
cx: &C,
|
||||
offset: Size,
|
||||
) -> Option<PointeeInfo>;
|
||||
fn is_adt(this: TyAndLayout<'a, Self>) -> bool;
|
||||
fn is_never(this: TyAndLayout<'a, Self>) -> bool;
|
||||
fn is_tuple(this: TyAndLayout<'a, Self>) -> bool;
|
||||
fn is_unit(this: TyAndLayout<'a, Self>) -> bool;
|
||||
}
|
||||
|
||||
impl<'a, Ty> TyAndLayout<'a, Ty> {
|
||||
@@ -1396,6 +1400,34 @@ pub fn is_single_fp_element<C>(self, cx: &C) -> bool
|
||||
_ => false,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn is_adt<C>(self) -> bool
|
||||
where
|
||||
Ty: TyAbiInterface<'a, C>,
|
||||
{
|
||||
Ty::is_adt(self)
|
||||
}
|
||||
|
||||
pub fn is_never<C>(self) -> bool
|
||||
where
|
||||
Ty: TyAbiInterface<'a, C>,
|
||||
{
|
||||
Ty::is_never(self)
|
||||
}
|
||||
|
||||
pub fn is_tuple<C>(self) -> bool
|
||||
where
|
||||
Ty: TyAbiInterface<'a, C>,
|
||||
{
|
||||
Ty::is_tuple(self)
|
||||
}
|
||||
|
||||
pub fn is_unit<C>(self) -> bool
|
||||
where
|
||||
Ty: TyAbiInterface<'a, C>,
|
||||
{
|
||||
Ty::is_unit(self)
|
||||
}
|
||||
}
|
||||
|
||||
impl<'a, Ty> TyAndLayout<'a, Ty> {
|
||||
|
||||
@@ -43,7 +43,8 @@ pub fn supported_types(
|
||||
}
|
||||
}
|
||||
|
||||
// The reserved registers are somewhat taken from <https://git.io/JUR1k#L150>.
|
||||
// The reserved registers are somewhat taken from
|
||||
// <https://github.com/llvm/llvm-project/blob/deb8f8bcf31540c657716ea5242183b0792702a1/llvm/lib/Target/Mips/MipsRegisterInfo.cpp#L150>.
|
||||
def_regs! {
|
||||
Mips MipsInlineAsmReg MipsInlineAsmRegClass {
|
||||
r2: reg = ["$2"],
|
||||
|
||||
@@ -2285,14 +2285,17 @@ fn no_such_field_err(
|
||||
// try to add a suggestion in case the field is a nested field of a field of the Adt
|
||||
if let Some((fields, substs)) = self.get_field_candidates(span, expr_t) {
|
||||
for candidate_field in fields.iter() {
|
||||
if let Some(field_path) = self.check_for_nested_field(
|
||||
if let Some(mut field_path) = self.check_for_nested_field_satisfying(
|
||||
span,
|
||||
field,
|
||||
&|candidate_field, _| candidate_field.ident(self.tcx()) == field,
|
||||
candidate_field,
|
||||
substs,
|
||||
vec![],
|
||||
self.tcx.parent_module(id).to_def_id(),
|
||||
) {
|
||||
// field_path includes `field` that we're looking for, so pop it.
|
||||
field_path.pop();
|
||||
|
||||
let field_path_str = field_path
|
||||
.iter()
|
||||
.map(|id| id.name.to_ident_string())
|
||||
@@ -2312,7 +2315,7 @@ fn no_such_field_err(
|
||||
err
|
||||
}
|
||||
|
||||
fn get_field_candidates(
|
||||
crate fn get_field_candidates(
|
||||
&self,
|
||||
span: Span,
|
||||
base_t: Ty<'tcx>,
|
||||
@@ -2337,49 +2340,42 @@ fn get_field_candidates(
|
||||
|
||||
/// This method is called after we have encountered a missing field error to recursively
|
||||
/// search for the field
|
||||
fn check_for_nested_field(
|
||||
crate fn check_for_nested_field_satisfying(
|
||||
&self,
|
||||
span: Span,
|
||||
target_field: Ident,
|
||||
matches: &impl Fn(&ty::FieldDef, Ty<'tcx>) -> bool,
|
||||
candidate_field: &ty::FieldDef,
|
||||
subst: SubstsRef<'tcx>,
|
||||
mut field_path: Vec<Ident>,
|
||||
id: DefId,
|
||||
) -> Option<Vec<Ident>> {
|
||||
debug!(
|
||||
"check_for_nested_field(span: {:?}, candidate_field: {:?}, field_path: {:?}",
|
||||
"check_for_nested_field_satisfying(span: {:?}, candidate_field: {:?}, field_path: {:?}",
|
||||
span, candidate_field, field_path
|
||||
);
|
||||
|
||||
if candidate_field.ident(self.tcx) == target_field {
|
||||
Some(field_path)
|
||||
} else if field_path.len() > 3 {
|
||||
if field_path.len() > 3 {
|
||||
// For compile-time reasons and to avoid infinite recursion we only check for fields
|
||||
// up to a depth of three
|
||||
None
|
||||
} else {
|
||||
// recursively search fields of `candidate_field` if it's a ty::Adt
|
||||
|
||||
field_path.push(candidate_field.ident(self.tcx).normalize_to_macros_2_0());
|
||||
let field_ty = candidate_field.ty(self.tcx, subst);
|
||||
if let Some((nested_fields, subst)) = self.get_field_candidates(span, field_ty) {
|
||||
for field in nested_fields.iter() {
|
||||
let accessible = field.vis.is_accessible_from(id, self.tcx);
|
||||
if accessible {
|
||||
let ident = field.ident(self.tcx).normalize_to_macros_2_0();
|
||||
if ident == target_field {
|
||||
if field.vis.is_accessible_from(id, self.tcx) {
|
||||
if matches(candidate_field, field_ty) {
|
||||
return Some(field_path);
|
||||
}
|
||||
let field_path = field_path.clone();
|
||||
if let Some(path) = self.check_for_nested_field(
|
||||
} else if let Some(field_path) = self.check_for_nested_field_satisfying(
|
||||
span,
|
||||
target_field,
|
||||
matches,
|
||||
field,
|
||||
subst,
|
||||
field_path,
|
||||
field_path.clone(),
|
||||
id,
|
||||
) {
|
||||
return Some(path);
|
||||
return Some(field_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,7 +28,7 @@
|
||||
use std::cmp::Ordering;
|
||||
use std::iter;
|
||||
|
||||
use super::probe::Mode;
|
||||
use super::probe::{Mode, ProbeScope};
|
||||
use super::{CandidateSource, MethodError, NoMatchData};
|
||||
|
||||
impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
||||
@@ -1129,6 +1129,46 @@ trait bound{s}",
|
||||
label_span_not_found();
|
||||
}
|
||||
|
||||
if let SelfSource::MethodCall(expr) = source
|
||||
&& let Some((fields, substs)) = self.get_field_candidates(span, actual)
|
||||
{
|
||||
let call_expr =
|
||||
self.tcx.hir().expect_expr(self.tcx.hir().get_parent_node(expr.hir_id));
|
||||
for candidate_field in fields.iter() {
|
||||
if let Some(field_path) = self.check_for_nested_field_satisfying(
|
||||
span,
|
||||
&|_, field_ty| {
|
||||
self.lookup_probe(
|
||||
span,
|
||||
item_name,
|
||||
field_ty,
|
||||
call_expr,
|
||||
ProbeScope::AllTraits,
|
||||
)
|
||||
.is_ok()
|
||||
},
|
||||
candidate_field,
|
||||
substs,
|
||||
vec![],
|
||||
self.tcx.parent_module(expr.hir_id).to_def_id(),
|
||||
) {
|
||||
let field_path_str = field_path
|
||||
.iter()
|
||||
.map(|id| id.name.to_ident_string())
|
||||
.collect::<Vec<String>>()
|
||||
.join(".");
|
||||
debug!("field_path_str: {:?}", field_path_str);
|
||||
|
||||
err.span_suggestion_verbose(
|
||||
item_name.span.shrink_to_lo(),
|
||||
"one of the expressions' fields has a method of the same name",
|
||||
format!("{field_path_str}."),
|
||||
Applicability::MaybeIncorrect,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bound_spans.sort();
|
||||
bound_spans.dedup();
|
||||
for (span, msg) in bound_spans.into_iter() {
|
||||
|
||||
@@ -292,8 +292,7 @@ pub fn to_mut(&mut self) -> &mut <B as ToOwned>::Owned {
|
||||
///
|
||||
/// # Examples
|
||||
///
|
||||
/// Calling `into_owned` on a `Cow::Borrowed` clones the underlying data
|
||||
/// and becomes a `Cow::Owned`:
|
||||
/// Calling `into_owned` on a `Cow::Borrowed` returns a clone of the borrowed data:
|
||||
///
|
||||
/// ```
|
||||
/// use std::borrow::Cow;
|
||||
@@ -307,7 +306,8 @@ pub fn to_mut(&mut self) -> &mut <B as ToOwned>::Owned {
|
||||
/// );
|
||||
/// ```
|
||||
///
|
||||
/// Calling `into_owned` on a `Cow::Owned` is a no-op:
|
||||
/// Calling `into_owned` on a `Cow::Owned` returns the owned data. The data is moved out of the
|
||||
/// `Cow` without being cloned.
|
||||
///
|
||||
/// ```
|
||||
/// use std::borrow::Cow;
|
||||
|
||||
@@ -279,6 +279,13 @@ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "assertunwindsafe_default", since = "1.62.0")]
|
||||
impl<T: Default> Default for AssertUnwindSafe<T> {
|
||||
fn default() -> Self {
|
||||
Self(Default::default())
|
||||
}
|
||||
}
|
||||
|
||||
#[stable(feature = "futures_api", since = "1.36.0")]
|
||||
impl<F: Future> Future for AssertUnwindSafe<F> {
|
||||
type Output = F::Output;
|
||||
|
||||
@@ -35,7 +35,8 @@
|
||||
// Android with api less than 21 define sig* functions inline, so it is not
|
||||
// available for dynamic link. Implementing sigemptyset and sigaddset allow us
|
||||
// to support older Android version (independent of libc version).
|
||||
// The following implementations are based on https://git.io/vSkNf
|
||||
// The following implementations are based on
|
||||
// https://github.com/aosp-mirror/platform_bionic/blob/ad8dcd6023294b646e5a8288c0ed431b0845da49/libc/include/android/legacy_signal_inlines.h
|
||||
cfg_if::cfg_if! {
|
||||
if #[cfg(target_os = "android")] {
|
||||
pub unsafe fn sigemptyset(set: *mut libc::sigset_t) -> libc::c_int {
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
/* eslint-env es6 */
|
||||
/* eslint no-var: "error" */
|
||||
/* eslint prefer-const: "error" */
|
||||
/* global addClass, getNakedUrl, getSettingValue, hasOwnPropertyRustdoc, initSearch, onEach */
|
||||
/* global onEachLazy, removeClass, searchState, hasClass */
|
||||
|
||||
(function() {
|
||||
// This mapping table should match the discriminants of
|
||||
// `rustdoc::formats::item_type::ItemType` type in Rust.
|
||||
var itemTypes = [
|
||||
const itemTypes = [
|
||||
"mod",
|
||||
"externcrate",
|
||||
"import",
|
||||
@@ -34,15 +37,15 @@ var itemTypes = [
|
||||
];
|
||||
|
||||
// used for special search precedence
|
||||
var TY_PRIMITIVE = itemTypes.indexOf("primitive");
|
||||
var TY_KEYWORD = itemTypes.indexOf("keyword");
|
||||
const TY_PRIMITIVE = itemTypes.indexOf("primitive");
|
||||
const TY_KEYWORD = itemTypes.indexOf("keyword");
|
||||
|
||||
// In the search display, allows to switch between tabs.
|
||||
function printTab(nb) {
|
||||
if (nb === 0 || nb === 1 || nb === 2) {
|
||||
searchState.currentTab = nb;
|
||||
}
|
||||
var nb_copy = nb;
|
||||
let nb_copy = nb;
|
||||
onEachLazy(document.getElementById("titles").childNodes, function(elem) {
|
||||
if (nb_copy === 0) {
|
||||
addClass(elem, "selected");
|
||||
@@ -68,14 +71,15 @@ function printTab(nb) {
|
||||
* This code is an unmodified version of the code written by Marco de Wit
|
||||
* and was found at https://stackoverflow.com/a/18514751/745719
|
||||
*/
|
||||
var levenshtein_row2 = [];
|
||||
const levenshtein_row2 = [];
|
||||
function levenshtein(s1, s2) {
|
||||
if (s1 === s2) {
|
||||
return 0;
|
||||
}
|
||||
var s1_len = s1.length, s2_len = s2.length;
|
||||
const s1_len = s1.length, s2_len = s2.length;
|
||||
if (s1_len && s2_len) {
|
||||
var i1 = 0, i2 = 0, a, b, c, c2, row = levenshtein_row2;
|
||||
let i1 = 0, i2 = 0, a, b, c, c2;
|
||||
const row = levenshtein_row2;
|
||||
while (i1 < s1_len) {
|
||||
row[i1] = ++i1;
|
||||
}
|
||||
@@ -97,24 +101,24 @@ function levenshtein(s1, s2) {
|
||||
}
|
||||
|
||||
window.initSearch = function(rawSearchIndex) {
|
||||
var MAX_LEV_DISTANCE = 3;
|
||||
var MAX_RESULTS = 200;
|
||||
var GENERICS_DATA = 2;
|
||||
var NAME = 0;
|
||||
var INPUTS_DATA = 0;
|
||||
var OUTPUT_DATA = 1;
|
||||
var NO_TYPE_FILTER = -1;
|
||||
const MAX_LEV_DISTANCE = 3;
|
||||
const MAX_RESULTS = 200;
|
||||
const GENERICS_DATA = 2;
|
||||
const NAME = 0;
|
||||
const INPUTS_DATA = 0;
|
||||
const OUTPUT_DATA = 1;
|
||||
const NO_TYPE_FILTER = -1;
|
||||
/**
|
||||
* @type {Array<Row>}
|
||||
*/
|
||||
var searchIndex;
|
||||
let searchIndex;
|
||||
/**
|
||||
* @type {Array<string>}
|
||||
*/
|
||||
var searchWords;
|
||||
var currentResults;
|
||||
var ALIASES = {};
|
||||
var params = searchState.getQueryStringParams();
|
||||
let searchWords = [];
|
||||
let currentResults;
|
||||
const ALIASES = {};
|
||||
const params = searchState.getQueryStringParams();
|
||||
|
||||
// Populate search bar with query string search term when provided,
|
||||
// but only if the input bar is empty. This avoid the obnoxious issue
|
||||
@@ -145,7 +149,7 @@ window.initSearch = function(rawSearchIndex) {
|
||||
}
|
||||
|
||||
function itemTypeFromName(typename) {
|
||||
for (var i = 0, len = itemTypes.length; i < len; ++i) {
|
||||
for (let i = 0, len = itemTypes.length; i < len; ++i) {
|
||||
if (itemTypes[i] === typename) {
|
||||
return i;
|
||||
}
|
||||
@@ -176,8 +180,8 @@ window.initSearch = function(rawSearchIndex) {
|
||||
throw new Error("Cannot use literal search when there is more than one element");
|
||||
}
|
||||
parserState.pos += 1;
|
||||
var start = parserState.pos;
|
||||
var end = getIdentEndPosition(parserState);
|
||||
const start = parserState.pos;
|
||||
const end = getIdentEndPosition(parserState);
|
||||
if (parserState.pos >= parserState.length) {
|
||||
throw new Error("Unclosed `\"`");
|
||||
} else if (parserState.userQuery[end] !== "\"") {
|
||||
@@ -264,10 +268,10 @@ window.initSearch = function(rawSearchIndex) {
|
||||
if (query.literalSearch && parserState.totalElems - parserState.genericsElems > 0) {
|
||||
throw new Error("You cannot have more than one element if you use quotes");
|
||||
}
|
||||
var pathSegments = name.split("::");
|
||||
const pathSegments = name.split("::");
|
||||
if (pathSegments.length > 1) {
|
||||
for (var i = 0, len = pathSegments.length; i < len; ++i) {
|
||||
var pathSegment = pathSegments[i];
|
||||
for (let i = 0, len = pathSegments.length; i < len; ++i) {
|
||||
const pathSegment = pathSegments[i];
|
||||
|
||||
if (pathSegment.length === 0) {
|
||||
if (i === 0) {
|
||||
@@ -305,9 +309,9 @@ window.initSearch = function(rawSearchIndex) {
|
||||
* @return {integer}
|
||||
*/
|
||||
function getIdentEndPosition(parserState) {
|
||||
var end = parserState.pos;
|
||||
let end = parserState.pos;
|
||||
while (parserState.pos < parserState.length) {
|
||||
var c = parserState.userQuery[parserState.pos];
|
||||
const c = parserState.userQuery[parserState.pos];
|
||||
if (!isIdentCharacter(c)) {
|
||||
if (isErrorCharacter(c)) {
|
||||
throw new Error(`Unexpected \`${c}\``);
|
||||
@@ -342,10 +346,10 @@ window.initSearch = function(rawSearchIndex) {
|
||||
* @param {boolean} isInGenerics
|
||||
*/
|
||||
function getNextElem(query, parserState, elems, isInGenerics) {
|
||||
var generics = [];
|
||||
const generics = [];
|
||||
|
||||
var start = parserState.pos;
|
||||
var end;
|
||||
let start = parserState.pos;
|
||||
let end;
|
||||
// We handle the strings on their own mostly to make code easier to follow.
|
||||
if (parserState.userQuery[parserState.pos] === "\"") {
|
||||
start += 1;
|
||||
@@ -393,10 +397,10 @@ window.initSearch = function(rawSearchIndex) {
|
||||
* character.
|
||||
*/
|
||||
function getItemsBefore(query, parserState, elems, endChar) {
|
||||
var foundStopChar = true;
|
||||
let foundStopChar = true;
|
||||
|
||||
while (parserState.pos < parserState.length) {
|
||||
var c = parserState.userQuery[parserState.pos];
|
||||
const c = parserState.userQuery[parserState.pos];
|
||||
if (c === endChar) {
|
||||
break;
|
||||
} else if (isSeparatorCharacter(c)) {
|
||||
@@ -406,7 +410,7 @@ window.initSearch = function(rawSearchIndex) {
|
||||
} else if (c === ":" && isPathStart(parserState)) {
|
||||
throw new Error("Unexpected `::`: paths cannot start with `::`");
|
||||
} else if (c === ":" || isEndCharacter(c)) {
|
||||
var extra = "";
|
||||
let extra = "";
|
||||
if (endChar === ">") {
|
||||
extra = "`<`";
|
||||
} else if (endChar === "") {
|
||||
@@ -420,7 +424,7 @@ window.initSearch = function(rawSearchIndex) {
|
||||
}
|
||||
throw new Error(`Expected \`,\` or \` \`, found \`${c}\``);
|
||||
}
|
||||
var posBefore = parserState.pos;
|
||||
const posBefore = parserState.pos;
|
||||
getNextElem(query, parserState, elems, endChar === ">");
|
||||
// This case can be encountered if `getNextElem` encounted a "stop character" right from
|
||||
// the start. For example if you have `,,` or `<>`. In this case, we simply move up the
|
||||
@@ -442,9 +446,9 @@ window.initSearch = function(rawSearchIndex) {
|
||||
* @param {ParserState} parserState
|
||||
*/
|
||||
function checkExtraTypeFilterCharacters(parserState) {
|
||||
var query = parserState.userQuery;
|
||||
const query = parserState.userQuery;
|
||||
|
||||
for (var pos = 0; pos < parserState.pos; ++pos) {
|
||||
for (let pos = 0; pos < parserState.pos; ++pos) {
|
||||
if (!isIdentCharacter(query[pos]) && !isWhitespaceCharacter(query[pos])) {
|
||||
throw new Error(`Unexpected \`${query[pos]}\` in type filter`);
|
||||
}
|
||||
@@ -459,8 +463,8 @@ window.initSearch = function(rawSearchIndex) {
|
||||
* @param {ParserState} parserState
|
||||
*/
|
||||
function parseInput(query, parserState) {
|
||||
var c, before;
|
||||
var foundStopChar = true;
|
||||
let c, before;
|
||||
let foundStopChar = true;
|
||||
|
||||
while (parserState.pos < parserState.length) {
|
||||
c = parserState.userQuery[parserState.pos];
|
||||
@@ -557,7 +561,7 @@ window.initSearch = function(rawSearchIndex) {
|
||||
* @return {string}
|
||||
*/
|
||||
function buildUrl(search, filterCrates) {
|
||||
var extra = "?search=" + encodeURIComponent(search);
|
||||
let extra = "?search=" + encodeURIComponent(search);
|
||||
|
||||
if (filterCrates !== null) {
|
||||
extra += "&filter-crate=" + encodeURIComponent(filterCrates);
|
||||
@@ -571,7 +575,7 @@ window.initSearch = function(rawSearchIndex) {
|
||||
* @return {string|null}
|
||||
*/
|
||||
function getFilterCrates() {
|
||||
var elem = document.getElementById("crate-search");
|
||||
const elem = document.getElementById("crate-search");
|
||||
|
||||
if (elem &&
|
||||
elem.value !== "All crates" &&
|
||||
@@ -650,7 +654,7 @@ window.initSearch = function(rawSearchIndex) {
|
||||
*/
|
||||
function parseQuery(userQuery) {
|
||||
userQuery = userQuery.trim();
|
||||
var parserState = {
|
||||
const parserState = {
|
||||
length: userQuery.length,
|
||||
pos: 0,
|
||||
// Total number of elements (includes generics).
|
||||
@@ -659,12 +663,12 @@ window.initSearch = function(rawSearchIndex) {
|
||||
typeFilter: null,
|
||||
userQuery: userQuery.toLowerCase(),
|
||||
};
|
||||
var query = newParsedQuery(userQuery);
|
||||
let query = newParsedQuery(userQuery);
|
||||
|
||||
try {
|
||||
parseInput(query, parserState);
|
||||
if (parserState.typeFilter !== null) {
|
||||
var typeFilter = parserState.typeFilter;
|
||||
let typeFilter = parserState.typeFilter;
|
||||
if (typeFilter === "const") {
|
||||
typeFilter = "constant";
|
||||
}
|
||||
@@ -715,19 +719,17 @@ window.initSearch = function(rawSearchIndex) {
|
||||
* @return {ResultsTable}
|
||||
*/
|
||||
function execQuery(parsedQuery, searchWords, filterCrates) {
|
||||
var results_others = {}, results_in_args = {}, results_returned = {};
|
||||
const results_others = {}, results_in_args = {}, results_returned = {};
|
||||
|
||||
function transformResults(results) {
|
||||
var duplicates = {};
|
||||
var out = [];
|
||||
|
||||
for (var i = 0, len = results.length; i < len; ++i) {
|
||||
var result = results[i];
|
||||
const duplicates = {};
|
||||
const out = [];
|
||||
|
||||
for (const result of results) {
|
||||
if (result.id > -1) {
|
||||
var obj = searchIndex[result.id];
|
||||
const obj = searchIndex[result.id];
|
||||
obj.lev = result.lev;
|
||||
var res = buildHrefAndPath(obj);
|
||||
const res = buildHrefAndPath(obj);
|
||||
obj.displayPath = pathSplitter(res[0]);
|
||||
obj.fullPath = obj.displayPath + obj.name;
|
||||
// To be sure than it some items aren't considered as duplicate.
|
||||
@@ -749,11 +751,11 @@ window.initSearch = function(rawSearchIndex) {
|
||||
}
|
||||
|
||||
function sortResults(results, isType) {
|
||||
var userQuery = parsedQuery.userQuery;
|
||||
var ar = [];
|
||||
for (var entry in results) {
|
||||
const userQuery = parsedQuery.userQuery;
|
||||
const ar = [];
|
||||
for (const entry in results) {
|
||||
if (hasOwnPropertyRustdoc(results, entry)) {
|
||||
var result = results[entry];
|
||||
const result = results[entry];
|
||||
result.word = searchWords[result.id];
|
||||
result.item = searchIndex[result.id] || {};
|
||||
ar.push(result);
|
||||
@@ -766,7 +768,7 @@ window.initSearch = function(rawSearchIndex) {
|
||||
}
|
||||
|
||||
results.sort(function(aaa, bbb) {
|
||||
var a, b;
|
||||
let a, b;
|
||||
|
||||
// sort by exact match with regard to the last word (mismatch goes later)
|
||||
a = (aaa.word !== userQuery);
|
||||
@@ -832,20 +834,18 @@ window.initSearch = function(rawSearchIndex) {
|
||||
return 0;
|
||||
});
|
||||
|
||||
var nameSplit = null;
|
||||
let nameSplit = null;
|
||||
if (parsedQuery.elems.length === 1) {
|
||||
var hasPath = typeof parsedQuery.elems[0].path === "undefined";
|
||||
const hasPath = typeof parsedQuery.elems[0].path === "undefined";
|
||||
nameSplit = hasPath ? null : parsedQuery.elems[0].path;
|
||||
}
|
||||
|
||||
for (var i = 0, len = results.length; i < len; ++i) {
|
||||
result = results[i];
|
||||
|
||||
for (const result of results) {
|
||||
// this validation does not make sense when searching by types
|
||||
if (result.dontValidate) {
|
||||
continue;
|
||||
}
|
||||
var name = result.item.name.toLowerCase(),
|
||||
const name = result.item.name.toLowerCase(),
|
||||
path = result.item.path.toLowerCase(),
|
||||
parent = result.item.parent;
|
||||
|
||||
@@ -877,15 +877,14 @@ window.initSearch = function(rawSearchIndex) {
|
||||
}
|
||||
// The names match, but we need to be sure that all generics kinda
|
||||
// match as well.
|
||||
var elem_name;
|
||||
let elem_name;
|
||||
if (elem.generics.length > 0 && row[GENERICS_DATA].length >= elem.generics.length) {
|
||||
var elems = Object.create(null);
|
||||
for (var x = 0, length = row[GENERICS_DATA].length; x < length; ++x) {
|
||||
elem_name = row[GENERICS_DATA][x][NAME];
|
||||
const elems = Object.create(null);
|
||||
for (const entry of row[GENERICS_DATA]) {
|
||||
elem_name = entry[NAME];
|
||||
if (elem_name === "") {
|
||||
// Pure generic, needs to check into it.
|
||||
if (checkGenerics(
|
||||
row[GENERICS_DATA][x], elem, MAX_LEV_DISTANCE + 1) !== 0) {
|
||||
if (checkGenerics(entry, elem, MAX_LEV_DISTANCE + 1) !== 0) {
|
||||
return MAX_LEV_DISTANCE + 1;
|
||||
}
|
||||
continue;
|
||||
@@ -897,9 +896,8 @@ window.initSearch = function(rawSearchIndex) {
|
||||
}
|
||||
// We need to find the type that matches the most to remove it in order
|
||||
// to move forward.
|
||||
for (x = 0, length = elem.generics.length; x < length; ++x) {
|
||||
var generic = elem.generics[x];
|
||||
var match = null;
|
||||
for (const generic of elem.generics) {
|
||||
let match = null;
|
||||
if (elems[generic.name]) {
|
||||
match = generic.name;
|
||||
} else {
|
||||
@@ -936,12 +934,12 @@ window.initSearch = function(rawSearchIndex) {
|
||||
* @return {integer} - Returns a Levenshtein distance to the best match.
|
||||
*/
|
||||
function checkIfInGenerics(row, elem) {
|
||||
var lev = MAX_LEV_DISTANCE + 1;
|
||||
for (var x = 0, length = row[GENERICS_DATA].length; x < length && lev !== 0; ++x) {
|
||||
lev = Math.min(
|
||||
checkType(row[GENERICS_DATA][x], elem, true),
|
||||
lev
|
||||
);
|
||||
let lev = MAX_LEV_DISTANCE + 1;
|
||||
for (const entry of row[GENERICS_DATA]) {
|
||||
lev = Math.min(checkType(entry, elem, true), lev);
|
||||
if (lev === 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return lev;
|
||||
}
|
||||
@@ -966,12 +964,12 @@ window.initSearch = function(rawSearchIndex) {
|
||||
return MAX_LEV_DISTANCE + 1;
|
||||
}
|
||||
|
||||
var lev = levenshtein(row[NAME], elem.name);
|
||||
let lev = levenshtein(row[NAME], elem.name);
|
||||
if (literalSearch) {
|
||||
if (lev !== 0) {
|
||||
// The name didn't match, let's try to check if the generics do.
|
||||
if (elem.generics.length === 0) {
|
||||
var checkGeneric = (row.length > GENERICS_DATA &&
|
||||
const checkGeneric = (row.length > GENERICS_DATA &&
|
||||
row[GENERICS_DATA].length > 0);
|
||||
if (checkGeneric && row[GENERICS_DATA].findIndex(function(tmp_elem) {
|
||||
return tmp_elem[NAME] === elem.name;
|
||||
@@ -1004,7 +1002,7 @@ window.initSearch = function(rawSearchIndex) {
|
||||
} else {
|
||||
// At this point, the name kinda match and we have generics to check, so
|
||||
// let's go!
|
||||
var tmp_lev = checkGenerics(row, elem, lev);
|
||||
const tmp_lev = checkGenerics(row, elem, lev);
|
||||
if (tmp_lev > MAX_LEV_DISTANCE) {
|
||||
return MAX_LEV_DISTANCE + 1;
|
||||
}
|
||||
@@ -1032,16 +1030,14 @@ window.initSearch = function(rawSearchIndex) {
|
||||
* match, returns `MAX_LEV_DISTANCE + 1`.
|
||||
*/
|
||||
function findArg(row, elem, typeFilter) {
|
||||
var lev = MAX_LEV_DISTANCE + 1;
|
||||
let lev = MAX_LEV_DISTANCE + 1;
|
||||
|
||||
if (row && row.type && row.type[INPUTS_DATA] && row.type[INPUTS_DATA].length > 0) {
|
||||
var length = row.type[INPUTS_DATA].length;
|
||||
for (var i = 0; i < length; i++) {
|
||||
var tmp = row.type[INPUTS_DATA][i];
|
||||
if (!typePassesFilter(typeFilter, tmp[1])) {
|
||||
for (const input of row.type[INPUTS_DATA]) {
|
||||
if (!typePassesFilter(typeFilter, input[1])) {
|
||||
continue;
|
||||
}
|
||||
lev = Math.min(lev, checkType(tmp, elem, parsedQuery.literalSearch));
|
||||
lev = Math.min(lev, checkType(input, elem, parsedQuery.literalSearch));
|
||||
if (lev === 0) {
|
||||
return 0;
|
||||
}
|
||||
@@ -1061,19 +1057,18 @@ window.initSearch = function(rawSearchIndex) {
|
||||
* match, returns `MAX_LEV_DISTANCE + 1`.
|
||||
*/
|
||||
function checkReturned(row, elem, typeFilter) {
|
||||
var lev = MAX_LEV_DISTANCE + 1;
|
||||
let lev = MAX_LEV_DISTANCE + 1;
|
||||
|
||||
if (row && row.type && row.type.length > OUTPUT_DATA) {
|
||||
var ret = row.type[OUTPUT_DATA];
|
||||
let ret = row.type[OUTPUT_DATA];
|
||||
if (typeof ret[0] === "string") {
|
||||
ret = [ret];
|
||||
}
|
||||
for (var x = 0, len = ret.length; x < len; ++x) {
|
||||
var tmp = ret[x];
|
||||
if (!typePassesFilter(typeFilter, tmp[1])) {
|
||||
for (const ret_ty of ret) {
|
||||
if (!typePassesFilter(typeFilter, ret_ty[1])) {
|
||||
continue;
|
||||
}
|
||||
lev = Math.min(lev, checkType(tmp, elem, parsedQuery.literalSearch));
|
||||
lev = Math.min(lev, checkType(ret_ty, elem, parsedQuery.literalSearch));
|
||||
if (lev === 0) {
|
||||
return 0;
|
||||
}
|
||||
@@ -1086,26 +1081,26 @@ window.initSearch = function(rawSearchIndex) {
|
||||
if (contains.length === 0) {
|
||||
return 0;
|
||||
}
|
||||
var ret_lev = MAX_LEV_DISTANCE + 1;
|
||||
var path = ty.path.split("::");
|
||||
let ret_lev = MAX_LEV_DISTANCE + 1;
|
||||
const path = ty.path.split("::");
|
||||
|
||||
if (ty.parent && ty.parent.name) {
|
||||
path.push(ty.parent.name.toLowerCase());
|
||||
}
|
||||
|
||||
var length = path.length;
|
||||
var clength = contains.length;
|
||||
const length = path.length;
|
||||
const clength = contains.length;
|
||||
if (clength > length) {
|
||||
return MAX_LEV_DISTANCE + 1;
|
||||
}
|
||||
for (var i = 0; i < length; ++i) {
|
||||
for (let i = 0; i < length; ++i) {
|
||||
if (i + clength > length) {
|
||||
break;
|
||||
}
|
||||
var lev_total = 0;
|
||||
var aborted = false;
|
||||
for (var x = 0; x < clength; ++x) {
|
||||
var lev = levenshtein(path[i + x], contains[x]);
|
||||
let lev_total = 0;
|
||||
let aborted = false;
|
||||
for (let x = 0; x < clength; ++x) {
|
||||
const lev = levenshtein(path[i + x], contains[x]);
|
||||
if (lev > MAX_LEV_DISTANCE) {
|
||||
aborted = true;
|
||||
break;
|
||||
@@ -1124,7 +1119,7 @@ window.initSearch = function(rawSearchIndex) {
|
||||
if (filter <= NO_TYPE_FILTER || filter === type) return true;
|
||||
|
||||
// Match related items
|
||||
var name = itemTypes[type];
|
||||
const name = itemTypes[type];
|
||||
switch (itemTypes[filter]) {
|
||||
case "constant":
|
||||
return name === "associatedconstant";
|
||||
@@ -1154,33 +1149,31 @@ window.initSearch = function(rawSearchIndex) {
|
||||
}
|
||||
|
||||
function handleAliases(ret, query, filterCrates) {
|
||||
var lowerQuery = query.toLowerCase();
|
||||
const lowerQuery = query.toLowerCase();
|
||||
// We separate aliases and crate aliases because we want to have current crate
|
||||
// aliases to be before the others in the displayed results.
|
||||
var aliases = [];
|
||||
var crateAliases = [];
|
||||
const aliases = [];
|
||||
const crateAliases = [];
|
||||
if (filterCrates !== null) {
|
||||
if (ALIASES[filterCrates] && ALIASES[filterCrates][lowerQuery]) {
|
||||
var query_aliases = ALIASES[filterCrates][lowerQuery];
|
||||
var len = query_aliases.length;
|
||||
for (var i = 0; i < len; ++i) {
|
||||
aliases.push(createAliasFromItem(searchIndex[query_aliases[i]]));
|
||||
const query_aliases = ALIASES[filterCrates][lowerQuery];
|
||||
for (const alias of query_aliases) {
|
||||
aliases.push(createAliasFromItem(searchIndex[alias]));
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Object.keys(ALIASES).forEach(function(crate) {
|
||||
if (ALIASES[crate][lowerQuery]) {
|
||||
var pushTo = crate === window.currentCrate ? crateAliases : aliases;
|
||||
var query_aliases = ALIASES[crate][lowerQuery];
|
||||
var len = query_aliases.length;
|
||||
for (var i = 0; i < len; ++i) {
|
||||
pushTo.push(createAliasFromItem(searchIndex[query_aliases[i]]));
|
||||
const pushTo = crate === window.currentCrate ? crateAliases : aliases;
|
||||
const query_aliases = ALIASES[crate][lowerQuery];
|
||||
for (const alias of query_aliases) {
|
||||
pushTo.push(createAliasFromItem(searchIndex[alias]));
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
var sortFunc = function(aaa, bbb) {
|
||||
const sortFunc = function(aaa, bbb) {
|
||||
if (aaa.path < bbb.path) {
|
||||
return 1;
|
||||
} else if (aaa.path === bbb.path) {
|
||||
@@ -1191,9 +1184,9 @@ window.initSearch = function(rawSearchIndex) {
|
||||
crateAliases.sort(sortFunc);
|
||||
aliases.sort(sortFunc);
|
||||
|
||||
var pushFunc = function(alias) {
|
||||
const pushFunc = function(alias) {
|
||||
alias.alias = query;
|
||||
var res = buildHrefAndPath(alias);
|
||||
const res = buildHrefAndPath(alias);
|
||||
alias.displayPath = pathSplitter(res[0]);
|
||||
alias.fullPath = alias.displayPath + alias.name;
|
||||
alias.href = res[1];
|
||||
@@ -1230,7 +1223,7 @@ window.initSearch = function(rawSearchIndex) {
|
||||
function addIntoResults(results, fullId, id, index, lev) {
|
||||
if (lev === 0 || (!parsedQuery.literalSearch && lev <= MAX_LEV_DISTANCE)) {
|
||||
if (results[fullId] !== undefined) {
|
||||
var result = results[fullId];
|
||||
const result = results[fullId];
|
||||
if (result.dontValidate || result.lev <= lev) {
|
||||
return;
|
||||
}
|
||||
@@ -1270,11 +1263,11 @@ window.initSearch = function(rawSearchIndex) {
|
||||
if (!row || (filterCrates !== null && row.crate !== filterCrates)) {
|
||||
return;
|
||||
}
|
||||
var lev, lev_add = 0, index = -1;
|
||||
var fullId = row.id;
|
||||
let lev, lev_add = 0, index = -1;
|
||||
const fullId = row.id;
|
||||
|
||||
var in_args = findArg(row, elem, parsedQuery.typeFilter);
|
||||
var returned = checkReturned(row, elem, parsedQuery.typeFilter);
|
||||
const in_args = findArg(row, elem, parsedQuery.typeFilter);
|
||||
const returned = checkReturned(row, elem, parsedQuery.typeFilter);
|
||||
|
||||
addIntoResults(results_in_args, fullId, pos, index, in_args);
|
||||
addIntoResults(results_returned, fullId, pos, index, returned);
|
||||
@@ -1282,7 +1275,7 @@ window.initSearch = function(rawSearchIndex) {
|
||||
if (!typePassesFilter(parsedQuery.typeFilter, row.ty)) {
|
||||
return;
|
||||
}
|
||||
var searchWord = searchWords[pos];
|
||||
const searchWord = searchWords[pos];
|
||||
|
||||
if (parsedQuery.literalSearch) {
|
||||
if (searchWord === elem.name) {
|
||||
@@ -1352,16 +1345,14 @@ window.initSearch = function(rawSearchIndex) {
|
||||
return;
|
||||
}
|
||||
|
||||
var totalLev = 0;
|
||||
var nbLev = 0;
|
||||
var lev;
|
||||
let totalLev = 0;
|
||||
let nbLev = 0;
|
||||
|
||||
// If the result is too "bad", we return false and it ends this search.
|
||||
function checkArgs(elems, callback) {
|
||||
for (var i = 0, len = elems.length; i < len; ++i) {
|
||||
var elem = elems[i];
|
||||
for (const elem of elems) {
|
||||
// There is more than one parameter to the query so all checks should be "exact"
|
||||
lev = callback(row, elem, NO_TYPE_FILTER);
|
||||
const lev = callback(row, elem, NO_TYPE_FILTER);
|
||||
if (lev <= 1) {
|
||||
nbLev += 1;
|
||||
totalLev += lev;
|
||||
@@ -1381,12 +1372,12 @@ window.initSearch = function(rawSearchIndex) {
|
||||
if (nbLev === 0) {
|
||||
return;
|
||||
}
|
||||
lev = Math.round(totalLev / nbLev);
|
||||
const lev = Math.round(totalLev / nbLev);
|
||||
addIntoResults(results, row.id, pos, 0, lev);
|
||||
}
|
||||
|
||||
function innerRunQuery() {
|
||||
var elem, i, nSearchWords, in_returned, row;
|
||||
let elem, i, nSearchWords, in_returned, row;
|
||||
|
||||
if (parsedQuery.foundElems === 1) {
|
||||
if (parsedQuery.elems.length === 1) {
|
||||
@@ -1413,7 +1404,7 @@ window.initSearch = function(rawSearchIndex) {
|
||||
}
|
||||
}
|
||||
} else if (parsedQuery.foundElems > 0) {
|
||||
var container = results_others;
|
||||
let container = results_others;
|
||||
// In the special case where only a "returned" information is available, we want to
|
||||
// put the information into the "results_returned" dict.
|
||||
if (parsedQuery.returned.length !== 0 && parsedQuery.elems.length === 0) {
|
||||
@@ -1429,7 +1420,7 @@ window.initSearch = function(rawSearchIndex) {
|
||||
innerRunQuery();
|
||||
}
|
||||
|
||||
var ret = createQueryResults(
|
||||
const ret = createQueryResults(
|
||||
sortResults(results_in_args, true),
|
||||
sortResults(results_returned, true),
|
||||
sortResults(results_others, false),
|
||||
@@ -1462,18 +1453,18 @@ window.initSearch = function(rawSearchIndex) {
|
||||
if (!keys || !keys.length) {
|
||||
return true;
|
||||
}
|
||||
for (var i = 0, len = keys.length; i < len; ++i) {
|
||||
for (const key of keys) {
|
||||
// each check is for validation so we negate the conditions and invalidate
|
||||
if (!(
|
||||
// check for an exact name match
|
||||
name.indexOf(keys[i]) > -1 ||
|
||||
name.indexOf(key) > -1 ||
|
||||
// then an exact path match
|
||||
path.indexOf(keys[i]) > -1 ||
|
||||
path.indexOf(key) > -1 ||
|
||||
// next if there is a parent, check for exact parent match
|
||||
(parent !== undefined && parent.name !== undefined &&
|
||||
parent.name.toLowerCase().indexOf(keys[i]) > -1) ||
|
||||
parent.name.toLowerCase().indexOf(key) > -1) ||
|
||||
// lastly check to see if the name was a levenshtein match
|
||||
levenshtein(name, keys[i]) <= MAX_LEV_DISTANCE)) {
|
||||
levenshtein(name, key) <= MAX_LEV_DISTANCE)) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1481,7 +1472,7 @@ window.initSearch = function(rawSearchIndex) {
|
||||
}
|
||||
|
||||
function nextTab(direction) {
|
||||
var next = (searchState.currentTab + direction + 3) % searchState.focusedByTab.length;
|
||||
const next = (searchState.currentTab + direction + 3) % searchState.focusedByTab.length;
|
||||
searchState.focusedByTab[searchState.currentTab] = document.activeElement;
|
||||
printTab(next);
|
||||
focusSearchResult();
|
||||
@@ -1490,7 +1481,7 @@ window.initSearch = function(rawSearchIndex) {
|
||||
// Focus the first search result on the active tab, or the result that
|
||||
// was focused last time this tab was active.
|
||||
function focusSearchResult() {
|
||||
var target = searchState.focusedByTab[searchState.currentTab] ||
|
||||
const target = searchState.focusedByTab[searchState.currentTab] ||
|
||||
document.querySelectorAll(".search-results.active a").item(0) ||
|
||||
document.querySelectorAll("#titles > button").item(searchState.currentTab);
|
||||
if (target) {
|
||||
@@ -1499,11 +1490,11 @@ window.initSearch = function(rawSearchIndex) {
|
||||
}
|
||||
|
||||
function buildHrefAndPath(item) {
|
||||
var displayPath;
|
||||
var href;
|
||||
var type = itemTypes[item.ty];
|
||||
var name = item.name;
|
||||
var path = item.path;
|
||||
let displayPath;
|
||||
let href;
|
||||
const type = itemTypes[item.ty];
|
||||
const name = item.name;
|
||||
let path = item.path;
|
||||
|
||||
if (type === "mod") {
|
||||
displayPath = path + "::";
|
||||
@@ -1517,19 +1508,19 @@ window.initSearch = function(rawSearchIndex) {
|
||||
displayPath = "";
|
||||
href = window.rootPath + name + "/index.html";
|
||||
} else if (item.parent !== undefined) {
|
||||
var myparent = item.parent;
|
||||
var anchor = "#" + type + "." + name;
|
||||
var parentType = itemTypes[myparent.ty];
|
||||
var pageType = parentType;
|
||||
var pageName = myparent.name;
|
||||
const myparent = item.parent;
|
||||
let anchor = "#" + type + "." + name;
|
||||
const parentType = itemTypes[myparent.ty];
|
||||
let pageType = parentType;
|
||||
let pageName = myparent.name;
|
||||
|
||||
if (parentType === "primitive") {
|
||||
displayPath = myparent.name + "::";
|
||||
} else if (type === "structfield" && parentType === "variant") {
|
||||
// Structfields belonging to variants are special: the
|
||||
// final path element is the enum name.
|
||||
var enumNameIdx = item.path.lastIndexOf("::");
|
||||
var enumName = item.path.substr(enumNameIdx + 2);
|
||||
const enumNameIdx = item.path.lastIndexOf("::");
|
||||
const enumName = item.path.substr(enumNameIdx + 2);
|
||||
path = item.path.substr(0, enumNameIdx);
|
||||
displayPath = path + "::" + enumName + "::" + myparent.name + "::";
|
||||
anchor = "#variant." + myparent.name + ".field." + name;
|
||||
@@ -1551,13 +1542,13 @@ window.initSearch = function(rawSearchIndex) {
|
||||
}
|
||||
|
||||
function escape(content) {
|
||||
var h1 = document.createElement("h1");
|
||||
const h1 = document.createElement("h1");
|
||||
h1.textContent = content;
|
||||
return h1.innerHTML;
|
||||
}
|
||||
|
||||
function pathSplitter(path) {
|
||||
var tmp = "<span>" + path.replace(/::/g, "::</span><span>");
|
||||
const tmp = "<span>" + path.replace(/::/g, "::</span><span>");
|
||||
if (tmp.endsWith("<span>")) {
|
||||
return tmp.slice(0, tmp.length - 6);
|
||||
}
|
||||
@@ -1571,42 +1562,42 @@ window.initSearch = function(rawSearchIndex) {
|
||||
* @param {boolean} display - True if this is the active tab
|
||||
*/
|
||||
function addTab(array, query, display) {
|
||||
var extraClass = "";
|
||||
let extraClass = "";
|
||||
if (display === true) {
|
||||
extraClass = " active";
|
||||
}
|
||||
|
||||
var output = document.createElement("div");
|
||||
var length = 0;
|
||||
const output = document.createElement("div");
|
||||
let length = 0;
|
||||
if (array.length > 0) {
|
||||
output.className = "search-results " + extraClass;
|
||||
|
||||
array.forEach(function(item) {
|
||||
var name = item.name;
|
||||
var type = itemTypes[item.ty];
|
||||
const name = item.name;
|
||||
const type = itemTypes[item.ty];
|
||||
|
||||
length += 1;
|
||||
|
||||
var extra = "";
|
||||
let extra = "";
|
||||
if (type === "primitive") {
|
||||
extra = " <i>(primitive type)</i>";
|
||||
} else if (type === "keyword") {
|
||||
extra = " <i>(keyword)</i>";
|
||||
}
|
||||
|
||||
var link = document.createElement("a");
|
||||
const link = document.createElement("a");
|
||||
link.className = "result-" + type;
|
||||
link.href = item.href;
|
||||
|
||||
var wrapper = document.createElement("div");
|
||||
var resultName = document.createElement("div");
|
||||
const wrapper = document.createElement("div");
|
||||
const resultName = document.createElement("div");
|
||||
resultName.className = "result-name";
|
||||
|
||||
if (item.is_alias) {
|
||||
var alias = document.createElement("span");
|
||||
const alias = document.createElement("span");
|
||||
alias.className = "alias";
|
||||
|
||||
var bold = document.createElement("b");
|
||||
const bold = document.createElement("b");
|
||||
bold.innerText = item.alias;
|
||||
alias.appendChild(bold);
|
||||
|
||||
@@ -1621,9 +1612,9 @@ window.initSearch = function(rawSearchIndex) {
|
||||
item.displayPath + "<span class=\"" + type + "\">" + name + extra + "</span>");
|
||||
wrapper.appendChild(resultName);
|
||||
|
||||
var description = document.createElement("div");
|
||||
const description = document.createElement("div");
|
||||
description.className = "desc";
|
||||
var spanDesc = document.createElement("span");
|
||||
const spanDesc = document.createElement("span");
|
||||
spanDesc.insertAdjacentHTML("beforeend", item.desc);
|
||||
|
||||
description.appendChild(spanDesc);
|
||||
@@ -1664,7 +1655,7 @@ window.initSearch = function(rawSearchIndex) {
|
||||
* @param {string} filterCrates
|
||||
*/
|
||||
function showResults(results, go_to_first, filterCrates) {
|
||||
var search = searchState.outputElement();
|
||||
const search = searchState.outputElement();
|
||||
if (go_to_first || (results.others.length === 1
|
||||
&& getSettingValue("go-to-only-result") === "true"
|
||||
// By default, the search DOM element is "empty" (meaning it has no children not
|
||||
@@ -1672,7 +1663,7 @@ window.initSearch = function(rawSearchIndex) {
|
||||
// ESC or empty the search input (which also "cancels" the search).
|
||||
&& (!search.firstChild || search.firstChild.innerText !== searchState.loadingText)))
|
||||
{
|
||||
var elem = document.createElement("a");
|
||||
const elem = document.createElement("a");
|
||||
elem.href = results.others[0].href;
|
||||
removeClass(elem, "active");
|
||||
// For firefox, we need the element to be in the DOM so it can be clicked.
|
||||
@@ -1686,14 +1677,14 @@ window.initSearch = function(rawSearchIndex) {
|
||||
|
||||
currentResults = results.query.userQuery;
|
||||
|
||||
var ret_others = addTab(results.others, results.query, true);
|
||||
var ret_in_args = addTab(results.in_args, results.query, false);
|
||||
var ret_returned = addTab(results.returned, results.query, false);
|
||||
const ret_others = addTab(results.others, results.query, true);
|
||||
const ret_in_args = addTab(results.in_args, results.query, false);
|
||||
const ret_returned = addTab(results.returned, results.query, false);
|
||||
|
||||
// Navigate to the relevant tab if the current tab is empty, like in case users search
|
||||
// for "-> String". If they had selected another tab previously, they have to click on
|
||||
// it again.
|
||||
var currentTab = searchState.currentTab;
|
||||
let currentTab = searchState.currentTab;
|
||||
if ((currentTab === 0 && ret_others[1] === 0) ||
|
||||
(currentTab === 1 && ret_in_args[1] === 0) ||
|
||||
(currentTab === 2 && ret_returned[1] === 0)) {
|
||||
@@ -1709,18 +1700,18 @@ window.initSearch = function(rawSearchIndex) {
|
||||
let crates = "";
|
||||
if (window.ALL_CRATES.length > 1) {
|
||||
crates = ` in <select id="crate-search"><option value="All crates">All crates</option>`;
|
||||
for (let c of window.ALL_CRATES) {
|
||||
for (const c of window.ALL_CRATES) {
|
||||
crates += `<option value="${c}" ${c == filterCrates && "selected"}>${c}</option>`;
|
||||
}
|
||||
crates += `</select>`;
|
||||
}
|
||||
|
||||
var typeFilter = "";
|
||||
let typeFilter = "";
|
||||
if (results.query.typeFilter !== NO_TYPE_FILTER) {
|
||||
typeFilter = " (type: " + escape(itemTypes[results.query.typeFilter]) + ")";
|
||||
}
|
||||
|
||||
var output = `<div id="search-settings">` +
|
||||
let output = `<div id="search-settings">` +
|
||||
`<h1 class="search-results-title">Results for ${escape(results.query.userQuery)}` +
|
||||
`${typeFilter}</h1> in ${crates} </div>`;
|
||||
if (results.query.error !== null) {
|
||||
@@ -1732,14 +1723,14 @@ window.initSearch = function(rawSearchIndex) {
|
||||
makeTabHeader(2, "In Return Types", ret_returned[1]) +
|
||||
"</div>";
|
||||
|
||||
var resultsElem = document.createElement("div");
|
||||
const resultsElem = document.createElement("div");
|
||||
resultsElem.id = "results";
|
||||
resultsElem.appendChild(ret_others[0]);
|
||||
resultsElem.appendChild(ret_in_args[0]);
|
||||
resultsElem.appendChild(ret_returned[0]);
|
||||
|
||||
search.innerHTML = output;
|
||||
let crateSearch = document.getElementById("crate-search");
|
||||
const crateSearch = document.getElementById("crate-search");
|
||||
if (crateSearch) {
|
||||
crateSearch.addEventListener("input", updateCrate);
|
||||
}
|
||||
@@ -1747,7 +1738,7 @@ window.initSearch = function(rawSearchIndex) {
|
||||
// Reset focused elements.
|
||||
searchState.focusedByTab = [null, null, null];
|
||||
searchState.showResults(search);
|
||||
var elems = document.getElementById("titles").childNodes;
|
||||
const elems = document.getElementById("titles").childNodes;
|
||||
elems[0].onclick = function() { printTab(0); };
|
||||
elems[1].onclick = function() { printTab(1); };
|
||||
elems[2].onclick = function() { printTab(2); };
|
||||
@@ -1761,8 +1752,8 @@ window.initSearch = function(rawSearchIndex) {
|
||||
* @param {boolean} [forced]
|
||||
*/
|
||||
function search(e, forced) {
|
||||
var params = searchState.getQueryStringParams();
|
||||
var query = parseQuery(searchState.input.value.trim());
|
||||
const params = searchState.getQueryStringParams();
|
||||
const query = parseQuery(searchState.input.value.trim());
|
||||
|
||||
if (e) {
|
||||
e.preventDefault();
|
||||
@@ -1775,7 +1766,7 @@ window.initSearch = function(rawSearchIndex) {
|
||||
return;
|
||||
}
|
||||
|
||||
var filterCrates = getFilterCrates();
|
||||
let filterCrates = getFilterCrates();
|
||||
|
||||
// In case we have no information about the saved crate and there is a URL query parameter,
|
||||
// we override it with the URL query parameter.
|
||||
@@ -1789,7 +1780,7 @@ window.initSearch = function(rawSearchIndex) {
|
||||
// Because searching is incremental by character, only the most
|
||||
// recent search query is added to the browser history.
|
||||
if (searchState.browserSupportsHistoryApi()) {
|
||||
var newURL = buildUrl(query.original, filterCrates);
|
||||
const newURL = buildUrl(query.original, filterCrates);
|
||||
if (!history.state && !params.search) {
|
||||
history.pushState(null, "", newURL);
|
||||
} else {
|
||||
@@ -1808,17 +1799,17 @@ window.initSearch = function(rawSearchIndex) {
|
||||
/**
|
||||
* @type {Array<string>}
|
||||
*/
|
||||
var searchWords = [];
|
||||
var i, word;
|
||||
var currentIndex = 0;
|
||||
var id = 0;
|
||||
const searchWords = [];
|
||||
let i, word;
|
||||
let currentIndex = 0;
|
||||
let id = 0;
|
||||
|
||||
for (var crate in rawSearchIndex) {
|
||||
for (const crate in rawSearchIndex) {
|
||||
if (!hasOwnPropertyRustdoc(rawSearchIndex, crate)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
var crateSize = 0;
|
||||
let crateSize = 0;
|
||||
|
||||
/**
|
||||
* The raw search data for a given crate. `n`, `t`, `d`, and `q`, `i`, and `f`
|
||||
@@ -1850,13 +1841,13 @@ window.initSearch = function(rawSearchIndex) {
|
||||
* p: Array<Object>,
|
||||
* }}
|
||||
*/
|
||||
var crateCorpus = rawSearchIndex[crate];
|
||||
const crateCorpus = rawSearchIndex[crate];
|
||||
|
||||
searchWords.push(crate);
|
||||
// This object should have exactly the same set of fields as the "row"
|
||||
// object defined below. Your JavaScript runtime will thank you.
|
||||
// https://mathiasbynens.be/notes/shapes-ics
|
||||
var crateRow = {
|
||||
const crateRow = {
|
||||
crate: crate,
|
||||
ty: 1, // == ExternCrate
|
||||
name: crate,
|
||||
@@ -1872,26 +1863,26 @@ window.initSearch = function(rawSearchIndex) {
|
||||
currentIndex += 1;
|
||||
|
||||
// an array of (Number) item types
|
||||
var itemTypes = crateCorpus.t;
|
||||
const itemTypes = crateCorpus.t;
|
||||
// an array of (String) item names
|
||||
var itemNames = crateCorpus.n;
|
||||
const itemNames = crateCorpus.n;
|
||||
// an array of (String) full paths (or empty string for previous path)
|
||||
var itemPaths = crateCorpus.q;
|
||||
const itemPaths = crateCorpus.q;
|
||||
// an array of (String) descriptions
|
||||
var itemDescs = crateCorpus.d;
|
||||
const itemDescs = crateCorpus.d;
|
||||
// an array of (Number) the parent path index + 1 to `paths`, or 0 if none
|
||||
var itemParentIdxs = crateCorpus.i;
|
||||
const itemParentIdxs = crateCorpus.i;
|
||||
// an array of (Object | null) the type of the function, if any
|
||||
var itemFunctionSearchTypes = crateCorpus.f;
|
||||
const itemFunctionSearchTypes = crateCorpus.f;
|
||||
// an array of [(Number) item type,
|
||||
// (String) name]
|
||||
var paths = crateCorpus.p;
|
||||
const paths = crateCorpus.p;
|
||||
// an array of [(String) alias name
|
||||
// [Number] index to items]
|
||||
var aliases = crateCorpus.a;
|
||||
const aliases = crateCorpus.a;
|
||||
|
||||
// convert `rawPaths` entries into object form
|
||||
var len = paths.length;
|
||||
let len = paths.length;
|
||||
for (i = 0; i < len; ++i) {
|
||||
paths[i] = {ty: paths[i][0], name: paths[i][1]};
|
||||
}
|
||||
@@ -1904,7 +1895,7 @@ window.initSearch = function(rawSearchIndex) {
|
||||
// all other search operations have access to this cached data for
|
||||
// faster analysis operations
|
||||
len = itemTypes.length;
|
||||
var lastPath = "";
|
||||
let lastPath = "";
|
||||
for (i = 0; i < len; ++i) {
|
||||
// This object should have exactly the same set of fields as the "crateRow"
|
||||
// object defined above.
|
||||
@@ -1915,7 +1906,7 @@ window.initSearch = function(rawSearchIndex) {
|
||||
word = "";
|
||||
searchWords.push("");
|
||||
}
|
||||
var row = {
|
||||
const row = {
|
||||
crate: crate,
|
||||
ty: itemTypes[i],
|
||||
name: itemNames[i],
|
||||
@@ -1934,8 +1925,7 @@ window.initSearch = function(rawSearchIndex) {
|
||||
|
||||
if (aliases) {
|
||||
ALIASES[crate] = {};
|
||||
var j, local_aliases;
|
||||
for (var alias_name in aliases) {
|
||||
for (const alias_name in aliases) {
|
||||
if (!hasOwnPropertyRustdoc(aliases, alias_name)) {
|
||||
continue;
|
||||
}
|
||||
@@ -1943,9 +1933,8 @@ window.initSearch = function(rawSearchIndex) {
|
||||
if (!hasOwnPropertyRustdoc(ALIASES[crate], alias_name)) {
|
||||
ALIASES[crate][alias_name] = [];
|
||||
}
|
||||
local_aliases = aliases[alias_name];
|
||||
for (j = 0, len = local_aliases.length; j < len; ++j) {
|
||||
ALIASES[crate][alias_name].push(local_aliases[j] + currentIndex);
|
||||
for (const local_alias of aliases[alias_name]) {
|
||||
ALIASES[crate][alias_name].push(local_alias + currentIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1965,11 +1954,11 @@ window.initSearch = function(rawSearchIndex) {
|
||||
}
|
||||
|
||||
function putBackSearch() {
|
||||
var search_input = searchState.input;
|
||||
const search_input = searchState.input;
|
||||
if (!searchState.input) {
|
||||
return;
|
||||
}
|
||||
var search = searchState.outputElement();
|
||||
const search = searchState.outputElement();
|
||||
if (search_input.value !== "" && hasClass(search, "hidden")) {
|
||||
searchState.showResults(search);
|
||||
if (searchState.browserSupportsHistoryApi()) {
|
||||
@@ -1981,7 +1970,7 @@ window.initSearch = function(rawSearchIndex) {
|
||||
}
|
||||
|
||||
function registerSearchEvents() {
|
||||
var searchAfter500ms = function() {
|
||||
const searchAfter500ms = function() {
|
||||
searchState.clearInputTimeout();
|
||||
if (searchState.input.value.length === 0) {
|
||||
if (searchState.browserSupportsHistoryApi()) {
|
||||
@@ -2019,7 +2008,7 @@ window.initSearch = function(rawSearchIndex) {
|
||||
// up and down arrow select next/previous search result, or the
|
||||
// search box if we're already at the top.
|
||||
if (e.which === 38) { // up
|
||||
var previous = document.activeElement.previousElementSibling;
|
||||
const previous = document.activeElement.previousElementSibling;
|
||||
if (previous) {
|
||||
previous.focus();
|
||||
} else {
|
||||
@@ -2027,11 +2016,11 @@ window.initSearch = function(rawSearchIndex) {
|
||||
}
|
||||
e.preventDefault();
|
||||
} else if (e.which === 40) { // down
|
||||
var next = document.activeElement.nextElementSibling;
|
||||
const next = document.activeElement.nextElementSibling;
|
||||
if (next) {
|
||||
next.focus();
|
||||
}
|
||||
var rect = document.activeElement.getBoundingClientRect();
|
||||
const rect = document.activeElement.getBoundingClientRect();
|
||||
if (window.innerHeight - rect.bottom < rect.height) {
|
||||
window.scrollBy(0, rect.height);
|
||||
}
|
||||
@@ -2064,10 +2053,10 @@ window.initSearch = function(rawSearchIndex) {
|
||||
// history.
|
||||
if (searchState.browserSupportsHistoryApi()) {
|
||||
// Store the previous <title> so we can revert back to it later.
|
||||
var previousTitle = document.title;
|
||||
const previousTitle = document.title;
|
||||
|
||||
window.addEventListener("popstate", function(e) {
|
||||
var params = searchState.getQueryStringParams();
|
||||
const params = searchState.getQueryStringParams();
|
||||
// Revert to the previous title manually since the History
|
||||
// API ignores the title parameter.
|
||||
document.title = previousTitle;
|
||||
@@ -2103,7 +2092,7 @@ window.initSearch = function(rawSearchIndex) {
|
||||
// that try to sync state between the URL and the search input. To work around it,
|
||||
// do a small amount of re-init on page show.
|
||||
window.onpageshow = function(){
|
||||
var qSearch = searchState.getQueryStringParams().search;
|
||||
const qSearch = searchState.getQueryStringParams().search;
|
||||
if (searchState.input.value === "" && qSearch) {
|
||||
searchState.input.value = qSearch;
|
||||
}
|
||||
@@ -2114,8 +2103,8 @@ window.initSearch = function(rawSearchIndex) {
|
||||
function updateCrate(ev) {
|
||||
if (ev.target.value === "All crates") {
|
||||
// If we don't remove it from the URL, it'll be picked up again by the search.
|
||||
var params = searchState.getQueryStringParams();
|
||||
var query = searchState.input.value.trim();
|
||||
const params = searchState.getQueryStringParams();
|
||||
const query = searchState.input.value.trim();
|
||||
if (!history.state && !params.search) {
|
||||
history.pushState(null, "", buildUrl(query, null));
|
||||
} else {
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
// Local js definitions:
|
||||
/* eslint-env es6 */
|
||||
/* eslint no-var: "error" */
|
||||
/* eslint prefer-const: "error" */
|
||||
/* global getSettingValue, getVirtualKey, onEachLazy, updateLocalStorage, updateSystemTheme */
|
||||
/* global addClass, removeClass */
|
||||
|
||||
@@ -55,9 +58,9 @@
|
||||
function setEvents() {
|
||||
updateLightAndDark();
|
||||
onEachLazy(document.getElementsByClassName("slider"), function(elem) {
|
||||
var toggle = elem.previousElementSibling;
|
||||
var settingId = toggle.id;
|
||||
var settingValue = getSettingValue(settingId);
|
||||
const toggle = elem.previousElementSibling;
|
||||
const settingId = toggle.id;
|
||||
const settingValue = getSettingValue(settingId);
|
||||
if (settingValue !== null) {
|
||||
toggle.checked = settingValue === "true";
|
||||
}
|
||||
@@ -68,9 +71,9 @@
|
||||
toggle.onkeyrelease = handleKey;
|
||||
});
|
||||
onEachLazy(document.getElementsByClassName("select-wrapper"), function(elem) {
|
||||
var select = elem.getElementsByTagName("select")[0];
|
||||
var settingId = select.id;
|
||||
var settingValue = getSettingValue(settingId);
|
||||
const select = elem.getElementsByTagName("select")[0];
|
||||
const settingId = select.id;
|
||||
const settingValue = getSettingValue(settingId);
|
||||
if (settingValue !== null) {
|
||||
select.value = settingValue;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,254 @@
|
||||
// assembly-output: ptx-linker
|
||||
// compile-flags: --crate-type cdylib -C target-cpu=sm_86
|
||||
// only-nvptx64
|
||||
// ignore-nvptx64
|
||||
|
||||
// The following ABI tests are made with nvcc 11.6 does.
|
||||
//
|
||||
// The PTX ABI stability is tied to major versions of the PTX ISA
|
||||
// These tests assume major version 7
|
||||
//
|
||||
//
|
||||
// The following correspondence between types are assumed:
|
||||
// u<N> - uint<N>_t
|
||||
// i<N> - int<N>_t
|
||||
// [T, N] - std::array<T, N>
|
||||
// &T - T const*
|
||||
// &mut T - T*
|
||||
|
||||
// CHECK: .version 7
|
||||
|
||||
#![feature(abi_ptx, lang_items, no_core)]
|
||||
#![no_core]
|
||||
|
||||
#[lang = "sized"]
|
||||
trait Sized {}
|
||||
#[lang = "copy"]
|
||||
trait Copy {}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct SingleU8 {
|
||||
f: u8,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct DoubleU8 {
|
||||
f: u8,
|
||||
g: u8,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct TripleU8 {
|
||||
f: u8,
|
||||
g: u8,
|
||||
h: u8,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct TripleU16 {
|
||||
f: u16,
|
||||
g: u16,
|
||||
h: u16,
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct TripleU32 {
|
||||
f: u32,
|
||||
g: u32,
|
||||
h: u32,
|
||||
}
|
||||
#[repr(C)]
|
||||
pub struct TripleU64 {
|
||||
f: u64,
|
||||
g: u64,
|
||||
h: u64,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct DoubleFloat {
|
||||
f: f32,
|
||||
g: f32,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct TripleFloat {
|
||||
f: f32,
|
||||
g: f32,
|
||||
h: f32,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct TripleDouble {
|
||||
f: f64,
|
||||
g: f64,
|
||||
h: f64,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct ManyIntegers {
|
||||
f: u8,
|
||||
g: u16,
|
||||
h: u32,
|
||||
i: u64,
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
pub struct ManyNumerics {
|
||||
f: u8,
|
||||
g: u16,
|
||||
h: u32,
|
||||
i: u64,
|
||||
j: f32,
|
||||
k: f64,
|
||||
}
|
||||
|
||||
// CHECK: .visible .entry f_u8_arg(
|
||||
// CHECK: .param .u8 f_u8_arg_param_0
|
||||
#[no_mangle]
|
||||
pub unsafe extern "ptx-kernel" fn f_u8_arg(_a: u8) {}
|
||||
|
||||
// CHECK: .visible .entry f_u16_arg(
|
||||
// CHECK: .param .u16 f_u16_arg_param_0
|
||||
#[no_mangle]
|
||||
pub unsafe extern "ptx-kernel" fn f_u16_arg(_a: u16) {}
|
||||
|
||||
// CHECK: .visible .entry f_u32_arg(
|
||||
// CHECK: .param .u32 f_u32_arg_param_0
|
||||
#[no_mangle]
|
||||
pub unsafe extern "ptx-kernel" fn f_u32_arg(_a: u32) {}
|
||||
|
||||
// CHECK: .visible .entry f_u64_arg(
|
||||
// CHECK: .param .u64 f_u64_arg_param_0
|
||||
#[no_mangle]
|
||||
pub unsafe extern "ptx-kernel" fn f_u64_arg(_a: u64) {}
|
||||
|
||||
// CHECK: .visible .entry f_u128_arg(
|
||||
// CHECK: .param .align 16 .b8 f_u128_arg_param_0[16]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "ptx-kernel" fn f_u128_arg(_a: u128) {}
|
||||
|
||||
// CHECK: .visible .entry f_i8_arg(
|
||||
// CHECK: .param .u8 f_i8_arg_param_0
|
||||
#[no_mangle]
|
||||
pub unsafe extern "ptx-kernel" fn f_i8_arg(_a: i8) {}
|
||||
|
||||
// CHECK: .visible .entry f_i16_arg(
|
||||
// CHECK: .param .u16 f_i16_arg_param_0
|
||||
#[no_mangle]
|
||||
pub unsafe extern "ptx-kernel" fn f_i16_arg(_a: i16) {}
|
||||
|
||||
// CHECK: .visible .entry f_i32_arg(
|
||||
// CHECK: .param .u32 f_i32_arg_param_0
|
||||
#[no_mangle]
|
||||
pub unsafe extern "ptx-kernel" fn f_i32_arg(_a: i32) {}
|
||||
|
||||
// CHECK: .visible .entry f_i64_arg(
|
||||
// CHECK: .param .u64 f_i64_arg_param_0
|
||||
#[no_mangle]
|
||||
pub unsafe extern "ptx-kernel" fn f_i64_arg(_a: i64) {}
|
||||
|
||||
// CHECK: .visible .entry f_i128_arg(
|
||||
// CHECK: .param .align 16 .b8 f_i128_arg_param_0[16]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "ptx-kernel" fn f_i128_arg(_a: i128) {}
|
||||
|
||||
// CHECK: .visible .entry f_f32_arg(
|
||||
// CHECK: .param .f32 f_f32_arg_param_0
|
||||
#[no_mangle]
|
||||
pub unsafe extern "ptx-kernel" fn f_f32_arg(_a: f32) {}
|
||||
|
||||
// CHECK: .visible .entry f_f64_arg(
|
||||
// CHECK: .param .f64 f_f64_arg_param_0
|
||||
#[no_mangle]
|
||||
pub unsafe extern "ptx-kernel" fn f_f64_arg(_a: f64) {}
|
||||
|
||||
// CHECK: .visible .entry f_single_u8_arg(
|
||||
// CHECK: .param .align 1 .b8 f_single_u8_arg_param_0[1]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "ptx-kernel" fn f_single_u8_arg(_a: SingleU8) {}
|
||||
|
||||
// CHECK: .visible .entry f_double_u8_arg(
|
||||
// CHECK: .param .align 1 .b8 f_double_u8_arg_param_0[2]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "ptx-kernel" fn f_double_u8_arg(_a: DoubleU8) {}
|
||||
|
||||
// CHECK: .visible .entry f_triple_u8_arg(
|
||||
// CHECK: .param .align 1 .b8 f_triple_u8_arg_param_0[3]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "ptx-kernel" fn f_triple_u8_arg(_a: TripleU8) {}
|
||||
|
||||
// CHECK: .visible .entry f_triple_u16_arg(
|
||||
// CHECK: .param .align 2 .b8 f_triple_u16_arg_param_0[6]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "ptx-kernel" fn f_triple_u16_arg(_a: TripleU16) {}
|
||||
|
||||
// CHECK: .visible .entry f_triple_u32_arg(
|
||||
// CHECK: .param .align 4 .b8 f_triple_u32_arg_param_0[12]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "ptx-kernel" fn f_triple_u32_arg(_a: TripleU32) {}
|
||||
|
||||
// CHECK: .visible .entry f_triple_u64_arg(
|
||||
// CHECK: .param .align 8 .b8 f_triple_u64_arg_param_0[24]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "ptx-kernel" fn f_triple_u64_arg(_a: TripleU64) {}
|
||||
|
||||
// CHECK: .visible .entry f_many_integers_arg(
|
||||
// CHECK: .param .align 8 .b8 f_many_integers_arg_param_0[16]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "ptx-kernel" fn f_many_integers_arg(_a: ManyIntegers) {}
|
||||
|
||||
// CHECK: .visible .entry f_double_float_arg(
|
||||
// CHECK: .param .align 4 .b8 f_double_float_arg_param_0[8]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "ptx-kernel" fn f_double_float_arg(_a: DoubleFloat) {}
|
||||
|
||||
// CHECK: .visible .entry f_triple_float_arg(
|
||||
// CHECK: .param .align 4 .b8 f_triple_float_arg_param_0[12]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "ptx-kernel" fn f_triple_float_arg(_a: TripleFloat) {}
|
||||
|
||||
// CHECK: .visible .entry f_triple_double_arg(
|
||||
// CHECK: .param .align 8 .b8 f_triple_double_arg_param_0[24]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "ptx-kernel" fn f_triple_double_arg(_a: TripleDouble) {}
|
||||
|
||||
// CHECK: .visible .entry f_many_numerics_arg(
|
||||
// CHECK: .param .align 8 .b8 f_many_numerics_arg_param_0[32]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "ptx-kernel" fn f_many_numerics_arg(_a: ManyNumerics) {}
|
||||
|
||||
// CHECK: .visible .entry f_byte_array_arg(
|
||||
// CHECK: .param .align 1 .b8 f_byte_array_arg_param_0[5]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "ptx-kernel" fn f_byte_array_arg(_a: [u8; 5]) {}
|
||||
|
||||
// CHECK: .visible .entry f_float_array_arg(
|
||||
// CHECK: .param .align 4 .b8 f_float_array_arg_param_0[20]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "ptx-kernel" fn f_float_array_arg(_a: [f32; 5]) {}
|
||||
|
||||
// CHECK: .visible .entry f_u128_array_arg(
|
||||
// CHECK: .param .align 16 .b8 f_u128_array_arg_param_0[80]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "ptx-kernel" fn f_u128_array_arg(_a: [u128; 5]) {}
|
||||
|
||||
// CHECK: .visible .entry f_u32_slice_arg(
|
||||
// CHECK: .param .u64 f_u32_slice_arg_param_0
|
||||
// CHECK: .param .u64 f_u32_slice_arg_param_1
|
||||
#[no_mangle]
|
||||
pub unsafe extern "ptx-kernel" fn f_u32_slice_arg(_a: &[u32]) {}
|
||||
|
||||
// CHECK: .visible .entry f_tuple_u8_u8_arg(
|
||||
// CHECK: .param .align 1 .b8 f_tuple_u8_u8_arg_param_0[2]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "ptx-kernel" fn f_tuple_u8_u8_arg(_a: (u8, u8)) {}
|
||||
|
||||
// CHECK: .visible .entry f_tuple_u32_u32_arg(
|
||||
// CHECK: .param .align 4 .b8 f_tuple_u32_u32_arg_param_0[8]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "ptx-kernel" fn f_tuple_u32_u32_arg(_a: (u32, u32)) {}
|
||||
|
||||
|
||||
// CHECK: .visible .entry f_tuple_u8_u8_u32_arg(
|
||||
// CHECK: .param .align 4 .b8 f_tuple_u8_u8_u32_arg_param_0[8]
|
||||
#[no_mangle]
|
||||
pub unsafe extern "ptx-kernel" fn f_tuple_u8_u8_u32_arg(_a: (u8, u8, u32)) {}
|
||||
@@ -18,6 +18,10 @@ note: the following trait bounds were not satisfied:
|
||||
|
|
||||
LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
|
||||
| --------- - ^^^^^^ unsatisfied trait bound introduced here
|
||||
help: one of the expressions' fields has a method of the same name
|
||||
|
|
||||
LL | let filter = map.stream.filterx(|x: &_| true);
|
||||
| +++++++
|
||||
|
||||
error[E0599]: the method `countx` exists for struct `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:139:30: 139:42]>`, but its trait bounds were not satisfied
|
||||
--> $DIR/issue-30786.rs:140:24
|
||||
@@ -39,6 +43,10 @@ note: the following trait bounds were not satisfied:
|
||||
|
|
||||
LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
|
||||
| --------- - ^^^^^^ unsatisfied trait bound introduced here
|
||||
help: one of the expressions' fields has a method of the same name
|
||||
|
|
||||
LL | let count = filter.stream.countx();
|
||||
| +++++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
||||
@@ -18,6 +18,10 @@ note: the following trait bounds were not satisfied:
|
||||
|
|
||||
LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
|
||||
| --------- - ^^^^^^ unsatisfied trait bound introduced here
|
||||
help: one of the expressions' fields has a method of the same name
|
||||
|
|
||||
LL | let filter = map.stream.filterx(|x: &_| true);
|
||||
| +++++++
|
||||
|
||||
error[E0599]: the method `countx` exists for struct `Filter<Map<Repeat, for<'r> fn(&'r u64) -> &'r u64 {identity::<u64>}>, [closure@$DIR/issue-30786.rs:139:30: 139:42]>`, but its trait bounds were not satisfied
|
||||
--> $DIR/issue-30786.rs:140:24
|
||||
@@ -39,6 +43,10 @@ note: the following trait bounds were not satisfied:
|
||||
|
|
||||
LL | impl<T> StreamExt for T where for<'a> &'a mut T: Stream {}
|
||||
| --------- - ^^^^^^ unsatisfied trait bound introduced here
|
||||
help: one of the expressions' fields has a method of the same name
|
||||
|
|
||||
LL | let count = filter.stream.countx();
|
||||
| +++++++
|
||||
|
||||
error: aborting due to 2 previous errors
|
||||
|
||||
|
||||
@@ -0,0 +1,23 @@
|
||||
struct Kind;
|
||||
|
||||
struct Ty {
|
||||
kind: Kind,
|
||||
}
|
||||
|
||||
impl Ty {
|
||||
fn kind(&self) -> Kind {
|
||||
todo!()
|
||||
}
|
||||
}
|
||||
|
||||
struct InferOk<T> {
|
||||
value: T,
|
||||
predicates: Vec<()>,
|
||||
}
|
||||
|
||||
fn foo(i: InferOk<Ty>) {
|
||||
let k = i.kind();
|
||||
//~^ no method named `kind` found for struct `InferOk` in the current scope
|
||||
}
|
||||
|
||||
fn main() {}
|
||||
@@ -0,0 +1,17 @@
|
||||
error[E0599]: no method named `kind` found for struct `InferOk` in the current scope
|
||||
--> $DIR/field-has-method.rs:19:15
|
||||
|
|
||||
LL | struct InferOk<T> {
|
||||
| ----------------- method `kind` not found for this
|
||||
...
|
||||
LL | let k = i.kind();
|
||||
| ^^^^ method not found in `InferOk<Ty>`
|
||||
|
|
||||
help: one of the expressions' fields has a method of the same name
|
||||
|
|
||||
LL | let k = i.value.kind();
|
||||
| ++++++
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0599`.
|
||||
@@ -85,8 +85,11 @@ function extractFunction(content, functionName) {
|
||||
}
|
||||
|
||||
// Stupid function extractor for array.
|
||||
function extractArrayVariable(content, arrayName) {
|
||||
var splitter = "var " + arrayName;
|
||||
function extractArrayVariable(content, arrayName, kind) {
|
||||
if (typeof kind === "undefined") {
|
||||
kind = "let ";
|
||||
}
|
||||
var splitter = kind + arrayName;
|
||||
while (true) {
|
||||
var start = content.indexOf(splitter);
|
||||
if (start === -1) {
|
||||
@@ -126,12 +129,18 @@ function extractArrayVariable(content, arrayName) {
|
||||
}
|
||||
content = content.slice(start + 1);
|
||||
}
|
||||
if (kind === "let ") {
|
||||
return extractArrayVariable(content, arrayName, "const ");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
// Stupid function extractor for variable.
|
||||
function extractVariable(content, varName) {
|
||||
var splitter = "var " + varName;
|
||||
function extractVariable(content, varName, kind) {
|
||||
if (typeof kind === "undefined") {
|
||||
kind = "let ";
|
||||
}
|
||||
var splitter = kind + varName;
|
||||
while (true) {
|
||||
var start = content.indexOf(splitter);
|
||||
if (start === -1) {
|
||||
@@ -162,6 +171,9 @@ function extractVariable(content, varName) {
|
||||
}
|
||||
content = content.slice(start + 1);
|
||||
}
|
||||
if (kind === "let ") {
|
||||
return extractVariable(content, varName, "const ");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user