diff --git a/compiler/rustc_borrowck/src/diagnostics/mod.rs b/compiler/rustc_borrowck/src/diagnostics/mod.rs index c2b5c16517af5..b81360fd6aab4 100644 --- a/compiler/rustc_borrowck/src/diagnostics/mod.rs +++ b/compiler/rustc_borrowck/src/diagnostics/mod.rs @@ -40,6 +40,7 @@ crate use outlives_suggestion::OutlivesSuggestionBuilder; 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 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { /// 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` diff --git a/compiler/rustc_middle/src/mir/mod.rs b/compiler/rustc_middle/src/mir/mod.rs index 881f59ae464c9..883fc72cd56c1 100644 --- a/compiler/rustc_middle/src/mir/mod.rs +++ b/compiler/rustc_middle/src/mir/mod.rs @@ -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>), } diff --git a/compiler/rustc_middle/src/ty/layout.rs b/compiler/rustc_middle/src/ty/layout.rs index 7cf2984a63f90..cd4b23fca3932 100644 --- a/compiler/rustc_middle/src/ty/layout.rs +++ b/compiler/rustc_middle/src/ty/layout.rs @@ -2592,6 +2592,22 @@ where 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> { diff --git a/compiler/rustc_middle/src/ty/list.rs b/compiler/rustc_middle/src/ty/list.rs index adba7d131592e..197dc9205b480 100644 --- a/compiler/rustc_middle/src/ty/list.rs +++ b/compiler/rustc_middle/src/ty/list.rs @@ -61,6 +61,10 @@ impl List { static EMPTY_SLICE: InOrder = InOrder(0, MaxAlign); unsafe { &*(&EMPTY_SLICE as *const _ as *const List) } } + + pub fn len(&self) -> usize { + self.len + } } impl List { diff --git a/compiler/rustc_target/src/abi/call/mod.rs b/compiler/rustc_target/src/abi/call/mod.rs index ce564d1455bfc..afce10ff1cbe8 100644 --- a/compiler/rustc_target/src/abi/call/mod.rs +++ b/compiler/rustc_target/src/abi/call/mod.rs @@ -696,7 +696,13 @@ impl<'a, Ty> FnAbi<'a, Ty> { "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" => { diff --git a/compiler/rustc_target/src/abi/call/nvptx64.rs b/compiler/rustc_target/src/abi/call/nvptx64.rs index 16f331b16d561..fc16f1c97a452 100644 --- a/compiler/rustc_target/src/abi/call/nvptx64.rs +++ b/compiler/rustc_target/src/abi/call/nvptx64.rs @@ -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(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(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(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); + } +} diff --git a/compiler/rustc_target/src/abi/mod.rs b/compiler/rustc_target/src/abi/mod.rs index 169167f69bf8c..0e8fd9cc93fd1 100644 --- a/compiler/rustc_target/src/abi/mod.rs +++ b/compiler/rustc_target/src/abi/mod.rs @@ -1355,6 +1355,10 @@ pub trait TyAbiInterface<'a, C>: Sized { cx: &C, offset: Size, ) -> Option; + 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 @@ impl<'a, Ty> TyAndLayout<'a, Ty> { _ => false, } } + + pub fn is_adt(self) -> bool + where + Ty: TyAbiInterface<'a, C>, + { + Ty::is_adt(self) + } + + pub fn is_never(self) -> bool + where + Ty: TyAbiInterface<'a, C>, + { + Ty::is_never(self) + } + + pub fn is_tuple(self) -> bool + where + Ty: TyAbiInterface<'a, C>, + { + Ty::is_tuple(self) + } + + pub fn is_unit(self) -> bool + where + Ty: TyAbiInterface<'a, C>, + { + Ty::is_unit(self) + } } impl<'a, Ty> TyAndLayout<'a, Ty> { diff --git a/compiler/rustc_target/src/asm/mips.rs b/compiler/rustc_target/src/asm/mips.rs index b1e8737b52b90..4e7c2eb1bf88e 100644 --- a/compiler/rustc_target/src/asm/mips.rs +++ b/compiler/rustc_target/src/asm/mips.rs @@ -43,7 +43,8 @@ impl MipsInlineAsmRegClass { } } -// The reserved registers are somewhat taken from . +// The reserved registers are somewhat taken from +// . def_regs! { Mips MipsInlineAsmReg MipsInlineAsmRegClass { r2: reg = ["$2"], diff --git a/compiler/rustc_typeck/src/check/expr.rs b/compiler/rustc_typeck/src/check/expr.rs index 76ac356efd6d5..480a551224929 100644 --- a/compiler/rustc_typeck/src/check/expr.rs +++ b/compiler/rustc_typeck/src/check/expr.rs @@ -2285,14 +2285,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err } - fn get_field_candidates( + crate fn get_field_candidates( &self, span: Span, base_t: Ty<'tcx>, @@ -2337,49 +2340,42 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { /// 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, id: DefId, ) -> Option> { 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); } } } diff --git a/compiler/rustc_typeck/src/check/method/suggest.rs b/compiler/rustc_typeck/src/check/method/suggest.rs index 2921176ca4b38..88e0a4bada845 100644 --- a/compiler/rustc_typeck/src/check/method/suggest.rs +++ b/compiler/rustc_typeck/src/check/method/suggest.rs @@ -28,7 +28,7 @@ use rustc_trait_selection::traits::{ 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 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { 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::>() + .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() { diff --git a/library/alloc/src/borrow.rs b/library/alloc/src/borrow.rs index 8b13e36c4b3c7..cb4e438f8bea2 100644 --- a/library/alloc/src/borrow.rs +++ b/library/alloc/src/borrow.rs @@ -292,8 +292,7 @@ impl Cow<'_, B> { /// /// # 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 @@ impl Cow<'_, B> { /// ); /// ``` /// - /// 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; diff --git a/library/core/src/panic/unwind_safe.rs b/library/core/src/panic/unwind_safe.rs index 95be879e319aa..f2948aac3c235 100644 --- a/library/core/src/panic/unwind_safe.rs +++ b/library/core/src/panic/unwind_safe.rs @@ -279,6 +279,13 @@ impl fmt::Debug for AssertUnwindSafe { } } +#[stable(feature = "assertunwindsafe_default", since = "1.62.0")] +impl Default for AssertUnwindSafe { + fn default() -> Self { + Self(Default::default()) + } +} + #[stable(feature = "futures_api", since = "1.36.0")] impl Future for AssertUnwindSafe { type Output = F::Output; diff --git a/library/std/src/sys/unix/process/process_common.rs b/library/std/src/sys/unix/process/process_common.rs index 27bee714f5b43..bca1b65a7fc05 100644 --- a/library/std/src/sys/unix/process/process_common.rs +++ b/library/std/src/sys/unix/process/process_common.rs @@ -35,7 +35,8 @@ cfg_if::cfg_if! { // 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 { diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 0d4e0a0b3289d..c4e74ea06578d 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -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} */ - var searchIndex; + let searchIndex; /** * @type {Array} */ - 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 = "" + path.replace(/::/g, "::"); + const tmp = "" + path.replace(/::/g, "::"); if (tmp.endsWith("")) { 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 = " (primitive type)"; } else if (type === "keyword") { extra = " (keyword)"; } - 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 + "" + name + extra + ""); 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 `; } - var typeFilter = ""; + let typeFilter = ""; if (results.query.typeFilter !== NO_TYPE_FILTER) { typeFilter = " (type: " + escape(itemTypes[results.query.typeFilter]) + ")"; } - var output = `
` + + let output = `
` + `

Results for ${escape(results.query.userQuery)}` + `${typeFilter}

in ${crates}
`; if (results.query.error !== null) { @@ -1732,14 +1723,14 @@ window.initSearch = function(rawSearchIndex) { makeTabHeader(2, "In Return Types", ret_returned[1]) + "
"; - 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} */ - 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, * }} */ - 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 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 { diff --git a/src/librustdoc/html/static/js/settings.js b/src/librustdoc/html/static/js/settings.js index 139fa5c9a11a6..549d56450d803 100644 --- a/src/librustdoc/html/static/js/settings.js +++ b/src/librustdoc/html/static/js/settings.js @@ -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; } diff --git a/src/test/assembly/nvptx-kernel-abi/nvptx-kernel-args-abi-v7.rs b/src/test/assembly/nvptx-kernel-abi/nvptx-kernel-args-abi-v7.rs new file mode 100644 index 0000000000000..5bf44f949fdf6 --- /dev/null +++ b/src/test/assembly/nvptx-kernel-abi/nvptx-kernel-args-abi-v7.rs @@ -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)) {} diff --git a/src/test/ui/hrtb/issue-30786.migrate.stderr b/src/test/ui/hrtb/issue-30786.migrate.stderr index 7ffe2f4cd7e1c..7157b186fc8ad 100644 --- a/src/test/ui/hrtb/issue-30786.migrate.stderr +++ b/src/test/ui/hrtb/issue-30786.migrate.stderr @@ -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 diff --git a/src/test/ui/hrtb/issue-30786.nll.stderr b/src/test/ui/hrtb/issue-30786.nll.stderr index 7ffe2f4cd7e1c..7157b186fc8ad 100644 --- a/src/test/ui/hrtb/issue-30786.nll.stderr +++ b/src/test/ui/hrtb/issue-30786.nll.stderr @@ -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 diff --git a/src/test/ui/suggestions/field-has-method.rs b/src/test/ui/suggestions/field-has-method.rs new file mode 100644 index 0000000000000..980000151e2f7 --- /dev/null +++ b/src/test/ui/suggestions/field-has-method.rs @@ -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() {} diff --git a/src/test/ui/suggestions/field-has-method.stderr b/src/test/ui/suggestions/field-has-method.stderr new file mode 100644 index 0000000000000..3a57436f200ba --- /dev/null +++ b/src/test/ui/suggestions/field-has-method.stderr @@ -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`. diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js index 1736233835529..98d0f5dc656c1 100644 --- a/src/tools/rustdoc-js/tester.js +++ b/src/tools/rustdoc-js/tester.js @@ -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; }