diff --git a/Cargo.lock b/Cargo.lock index a10eccb1ce51e..80e6dce2d92c3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4783,6 +4783,8 @@ version = "0.0.0" dependencies = [ "arrayvec", "askama", + "base64", + "byteorder", "expect-test", "indexmap", "itertools 0.12.1", diff --git a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs index e0bbd582d88c2..99dbb34226834 100644 --- a/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs +++ b/compiler/rustc_mir_transform/src/coroutine/by_move_body.rs @@ -3,7 +3,7 @@ //! be a coroutine body that takes all of its upvars by-move, and which we stash //! into the `CoroutineInfo` for all coroutines returned by coroutine-closures. -use rustc_data_structures::fx::FxIndexSet; +use rustc_data_structures::unord::UnordSet; use rustc_hir as hir; use rustc_middle::mir::visit::MutVisitor; use rustc_middle::mir::{self, dump_mir, MirPass}; @@ -33,7 +33,7 @@ impl<'tcx> MirPass<'tcx> for ByMoveBody { return; } - let mut by_ref_fields = FxIndexSet::default(); + let mut by_ref_fields = UnordSet::default(); let by_move_upvars = Ty::new_tup_from_iter( tcx, tcx.closure_captures(coroutine_def_id).iter().enumerate().map(|(idx, capture)| { @@ -73,7 +73,7 @@ impl<'tcx> MirPass<'tcx> for ByMoveBody { struct MakeByMoveBody<'tcx> { tcx: TyCtxt<'tcx>, - by_ref_fields: FxIndexSet, + by_ref_fields: UnordSet, by_move_coroutine_ty: Ty<'tcx>, } @@ -89,11 +89,11 @@ impl<'tcx> MutVisitor<'tcx> for MakeByMoveBody<'tcx> { location: mir::Location, ) { if place.local == ty::CAPTURE_STRUCT_LOCAL - && !place.projection.is_empty() - && let mir::ProjectionElem::Field(idx, ty) = place.projection[0] + && let Some((&mir::ProjectionElem::Field(idx, ty), projection)) = + place.projection.split_first() && self.by_ref_fields.contains(&idx) { - let (begin, end) = place.projection[1..].split_first().unwrap(); + let (begin, end) = projection.split_first().unwrap(); // FIXME(async_closures): I'm actually a bit surprised to see that we always // initially deref the by-ref upvars. If this is not actually true, then we // will at least get an ICE that explains why this isn't true :^) diff --git a/src/ci/docker/host-x86_64/mingw-check/Dockerfile b/src/ci/docker/host-x86_64/mingw-check/Dockerfile index e5aa81d83d5a1..6918574814fff 100644 --- a/src/ci/docker/host-x86_64/mingw-check/Dockerfile +++ b/src/ci/docker/host-x86_64/mingw-check/Dockerfile @@ -60,7 +60,7 @@ ENV SCRIPT python3 ../x.py --stage 2 test src/tools/expand-yaml-anchors && \ /scripts/validate-error-codes.sh && \ reuse --include-submodules lint && \ # Runs checks to ensure that there are no ES5 issues in our JS code. - es-check es6 ../src/librustdoc/html/static/js/*.js && \ + es-check es8 ../src/librustdoc/html/static/js/*.js && \ eslint -c ../src/librustdoc/html/static/.eslintrc.js ../src/librustdoc/html/static/js/*.js && \ eslint -c ../src/tools/rustdoc-js/.eslintrc.js ../src/tools/rustdoc-js/tester.js && \ eslint -c ../src/tools/rustdoc-gui/.eslintrc.js ../src/tools/rustdoc-gui/tester.js diff --git a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version index a2b63962ba11e..07feb8234926c 100644 --- a/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version +++ b/src/ci/docker/host-x86_64/x86_64-gnu-tools/browser-ui-test.version @@ -1 +1 @@ -0.16.11 \ No newline at end of file +0.17.0 \ No newline at end of file diff --git a/src/librustdoc/Cargo.toml b/src/librustdoc/Cargo.toml index d43c0cfa96126..9a23811ed3f97 100644 --- a/src/librustdoc/Cargo.toml +++ b/src/librustdoc/Cargo.toml @@ -9,6 +9,8 @@ path = "lib.rs" [dependencies] arrayvec = { version = "0.7", default-features = false } askama = { version = "0.12", default-features = false, features = ["config"] } +base64 = "0.21.7" +byteorder = "1.5" itertools = "0.12" indexmap = "2" minifier = "0.3.0" diff --git a/src/librustdoc/html/render/mod.rs b/src/librustdoc/html/render/mod.rs index 1ddcb3d8728f7..4e46f847fd76a 100644 --- a/src/librustdoc/html/render/mod.rs +++ b/src/librustdoc/html/render/mod.rs @@ -184,40 +184,15 @@ pub(crate) enum RenderTypeId { impl RenderTypeId { pub fn write_to_string(&self, string: &mut String) { - // (sign, value) - let (sign, id): (bool, u32) = match &self { + let id: i32 = match &self { // 0 is a sentinel, everything else is one-indexed // concrete type - RenderTypeId::Index(idx) if *idx >= 0 => (false, (idx + 1isize).try_into().unwrap()), + RenderTypeId::Index(idx) if *idx >= 0 => (idx + 1isize).try_into().unwrap(), // generic type parameter - RenderTypeId::Index(idx) => (true, (-*idx).try_into().unwrap()), + RenderTypeId::Index(idx) => (*idx).try_into().unwrap(), _ => panic!("must convert render types to indexes before serializing"), }; - // zig-zag encoding - let value: u32 = (id << 1) | (if sign { 1 } else { 0 }); - // Self-terminating hex use capital letters for everything but the - // least significant digit, which is lowercase. For example, decimal 17 - // would be `` Aa `` if zig-zag encoding weren't used. - // - // Zig-zag encoding, however, stores the sign bit as the last bit. - // This means, in the last hexit, 1 is actually `c`, -1 is `b` - // (`a` is the imaginary -0), and, because all the bits are shifted - // by one, `` A` `` is actually 8 and `` Aa `` is -8. - // - // https://rust-lang.github.io/rustc-dev-guide/rustdoc-internals/search.html - // describes the encoding in more detail. - let mut shift: u32 = 28; - let mut mask: u32 = 0xF0_00_00_00; - while shift < 32 { - let hexit = (value & mask) >> shift; - if hexit != 0 || shift == 0 { - let hex = - char::try_from(if shift == 0 { '`' } else { '@' } as u32 + hexit).unwrap(); - string.push(hex); - } - shift = shift.wrapping_sub(4); - mask = mask >> 4; - } + search_index::encode::write_vlqhex_to_string(id, string); } } diff --git a/src/librustdoc/html/render/search_index.rs b/src/librustdoc/html/render/search_index.rs index be2786c99ecab..51f90e455001e 100644 --- a/src/librustdoc/html/render/search_index.rs +++ b/src/librustdoc/html/render/search_index.rs @@ -1,3 +1,5 @@ +pub(crate) mod encode; + use std::collections::hash_map::Entry; use std::collections::{BTreeMap, VecDeque}; @@ -17,12 +19,46 @@ use crate::html::format::join_with_double_colon; use crate::html::markdown::short_markdown_summary; use crate::html::render::{self, IndexItem, IndexItemFunctionType, RenderType, RenderTypeId}; +use encode::{bitmap_to_string, write_vlqhex_to_string}; + +/// The serialized search description sharded version +/// +/// The `index` is a JSON-encoded list of names and other information. +/// +/// The desc has newlined descriptions, split up by size into 128KiB shards. +/// For example, `(4, "foo\nbar\nbaz\nquux")`. +/// +/// There is no single, optimal size for these shards, because it depends on +/// configuration values that we can't predict or control, such as the version +/// of HTTP used (HTTP/1.1 would work better with larger files, while HTTP/2 +/// and 3 are more agnostic), transport compression (gzip, zstd, etc), whether +/// the search query is going to produce a large number of results or a small +/// number, the bandwidth delay product of the network... +/// +/// Gzipping some standard library descriptions to guess what transport +/// compression will do, the compressed file sizes can be as small as 4.9KiB +/// or as large as 18KiB (ignoring the final 1.9KiB shard of leftovers). +/// A "reasonable" range for files is for them to be bigger than 1KiB, +/// since that's about the amount of data that can be transferred in a +/// single TCP packet, and 64KiB, the maximum amount of data that +/// TCP can transfer in a single round trip without extensions. +/// +/// [1]: https://en.wikipedia.org/wiki/Maximum_transmission_unit#MTUs_for_common_media +/// [2]: https://en.wikipedia.org/wiki/Sliding_window_protocol#Basic_concept +/// [3]: https://learn.microsoft.com/en-us/troubleshoot/windows-server/networking/description-tcp-features +pub(crate) struct SerializedSearchIndex { + pub(crate) index: String, + pub(crate) desc: Vec<(usize, String)>, +} + +const DESC_INDEX_SHARD_LEN: usize = 128 * 1024; + /// Builds the search index from the collected metadata pub(crate) fn build_index<'tcx>( krate: &clean::Crate, cache: &mut Cache, tcx: TyCtxt<'tcx>, -) -> String { +) -> SerializedSearchIndex { let mut itemid_to_pathid = FxHashMap::default(); let mut primitives = FxHashMap::default(); let mut associated_types = FxHashMap::default(); @@ -319,7 +355,6 @@ pub(crate) fn build_index<'tcx>( .collect::>(); struct CrateData<'a> { - doc: String, items: Vec<&'a IndexItem>, paths: Vec<(ItemType, Vec)>, // The String is alias name and the vec is the list of the elements with this alias. @@ -328,6 +363,11 @@ pub(crate) fn build_index<'tcx>( aliases: &'a BTreeMap>, // Used when a type has more than one impl with an associated item with the same name. associated_item_disambiguators: &'a Vec<(usize, String)>, + // A list of shard lengths encoded as vlqhex. See the comment in write_vlqhex_to_string + // for information on the format. + desc_index: String, + // A list of items with no description. This is eventually turned into a bitmap. + empty_desc: Vec, } struct Paths { @@ -409,7 +449,6 @@ pub(crate) fn build_index<'tcx>( let mut names = Vec::with_capacity(self.items.len()); let mut types = String::with_capacity(self.items.len()); let mut full_paths = Vec::with_capacity(self.items.len()); - let mut descriptions = Vec::with_capacity(self.items.len()); let mut parents = Vec::with_capacity(self.items.len()); let mut functions = String::with_capacity(self.items.len()); let mut deprecated = Vec::with_capacity(self.items.len()); @@ -432,7 +471,6 @@ pub(crate) fn build_index<'tcx>( parents.push(item.parent_idx.map(|x| x + 1).unwrap_or(0)); names.push(item.name.as_str()); - descriptions.push(&item.desc); if !item.path.is_empty() { full_paths.push((index, &item.path)); @@ -444,7 +482,8 @@ pub(crate) fn build_index<'tcx>( } if item.deprecation.is_some() { - deprecated.push(index); + // bitmasks always use 1-indexing for items, with 0 as the crate itself + deprecated.push(u32::try_from(index + 1).unwrap()); } } @@ -455,17 +494,16 @@ pub(crate) fn build_index<'tcx>( let has_aliases = !self.aliases.is_empty(); let mut crate_data = serializer.serialize_struct("CrateData", if has_aliases { 9 } else { 8 })?; - crate_data.serialize_field("doc", &self.doc)?; crate_data.serialize_field("t", &types)?; crate_data.serialize_field("n", &names)?; - // Serialize as an array of item indices and full paths crate_data.serialize_field("q", &full_paths)?; - crate_data.serialize_field("d", &descriptions)?; crate_data.serialize_field("i", &parents)?; crate_data.serialize_field("f", &functions)?; - crate_data.serialize_field("c", &deprecated)?; + crate_data.serialize_field("D", &self.desc_index)?; crate_data.serialize_field("p", &paths)?; crate_data.serialize_field("b", &self.associated_item_disambiguators)?; + crate_data.serialize_field("c", &bitmap_to_string(&deprecated))?; + crate_data.serialize_field("e", &bitmap_to_string(&self.empty_desc))?; if has_aliases { crate_data.serialize_field("a", &self.aliases)?; } @@ -473,16 +511,58 @@ pub(crate) fn build_index<'tcx>( } } - // Collect the index into a string - format!( + let (empty_desc, desc) = { + let mut empty_desc = Vec::new(); + let mut result = Vec::new(); + let mut set = String::new(); + let mut len: usize = 0; + let mut item_index: u32 = 0; + for desc in std::iter::once(&crate_doc).chain(crate_items.iter().map(|item| &item.desc)) { + if desc == "" { + empty_desc.push(item_index); + item_index += 1; + continue; + } + if set.len() >= DESC_INDEX_SHARD_LEN { + result.push((len, std::mem::replace(&mut set, String::new()))); + len = 0; + } else if len != 0 { + set.push('\n'); + } + set.push_str(&desc); + len += 1; + item_index += 1; + } + result.push((len, std::mem::replace(&mut set, String::new()))); + (empty_desc, result) + }; + + let desc_index = { + let mut desc_index = String::with_capacity(desc.len() * 4); + for &(len, _) in desc.iter() { + write_vlqhex_to_string(len.try_into().unwrap(), &mut desc_index); + } + desc_index + }; + + assert_eq!( + crate_items.len() + 1, + desc.iter().map(|(len, _)| *len).sum::() + empty_desc.len() + ); + + // The index, which is actually used to search, is JSON + // It uses `JSON.parse(..)` to actually load, since JSON + // parses faster than the full JavaScript syntax. + let index = format!( r#"["{}",{}]"#, krate.name(tcx), serde_json::to_string(&CrateData { - doc: crate_doc, items: crate_items, paths: crate_paths, aliases: &aliases, associated_item_disambiguators: &associated_item_disambiguators, + desc_index, + empty_desc, }) .expect("failed serde conversion") // All these `replace` calls are because we have to go through JS string for JSON content. @@ -490,7 +570,8 @@ pub(crate) fn build_index<'tcx>( .replace('\'', r"\'") // We need to escape double quotes for the JSON. .replace("\\\"", "\\\\\"") - ) + ); + SerializedSearchIndex { index, desc } } pub(crate) fn get_function_type_for_search<'tcx>( diff --git a/src/librustdoc/html/render/search_index/encode.rs b/src/librustdoc/html/render/search_index/encode.rs new file mode 100644 index 0000000000000..54407c614c4c7 --- /dev/null +++ b/src/librustdoc/html/render/search_index/encode.rs @@ -0,0 +1,243 @@ +use base64::prelude::*; + +pub(crate) fn write_vlqhex_to_string(n: i32, string: &mut String) { + let (sign, magnitude): (bool, u32) = + if n >= 0 { (false, n.try_into().unwrap()) } else { (true, (-n).try_into().unwrap()) }; + // zig-zag encoding + let value: u32 = (magnitude << 1) | (if sign { 1 } else { 0 }); + // Self-terminating hex use capital letters for everything but the + // least significant digit, which is lowercase. For example, decimal 17 + // would be `` Aa `` if zig-zag encoding weren't used. + // + // Zig-zag encoding, however, stores the sign bit as the last bit. + // This means, in the last hexit, 1 is actually `c`, -1 is `b` + // (`a` is the imaginary -0), and, because all the bits are shifted + // by one, `` A` `` is actually 8 and `` Aa `` is -8. + // + // https://rust-lang.github.io/rustc-dev-guide/rustdoc-internals/search.html + // describes the encoding in more detail. + let mut shift: u32 = 28; + let mut mask: u32 = 0xF0_00_00_00; + // first skip leading zeroes + while shift < 32 { + let hexit = (value & mask) >> shift; + if hexit != 0 || shift == 0 { + break; + } + shift = shift.wrapping_sub(4); + mask = mask >> 4; + } + // now write the rest + while shift < 32 { + let hexit = (value & mask) >> shift; + let hex = char::try_from(if shift == 0 { '`' } else { '@' } as u32 + hexit).unwrap(); + string.push(hex); + shift = shift.wrapping_sub(4); + mask = mask >> 4; + } +} + +// Used during bitmap encoding +enum Container { + /// number of ones, bits + Bits(Box<[u64; 1024]>), + /// list of entries + Array(Vec), + /// list of (start, len-1) + Run(Vec<(u16, u16)>), +} +impl Container { + fn popcount(&self) -> u32 { + match self { + Container::Bits(bits) => bits.iter().copied().map(|x| x.count_ones()).sum(), + Container::Array(array) => { + array.len().try_into().expect("array can't be bigger than 2**32") + } + Container::Run(runs) => { + runs.iter().copied().map(|(_, lenm1)| u32::from(lenm1) + 1).sum() + } + } + } + fn push(&mut self, value: u16) { + match self { + Container::Bits(bits) => bits[value as usize >> 6] |= 1 << (value & 0x3F), + Container::Array(array) => { + array.push(value); + if array.len() >= 4096 { + let array = std::mem::replace(array, Vec::new()); + *self = Container::Bits(Box::new([0; 1024])); + for value in array { + self.push(value); + } + } + } + Container::Run(runs) => { + if let Some(r) = runs.last_mut() + && r.0 + r.1 + 1 == value + { + r.1 += 1; + } else { + runs.push((value, 0)); + } + } + } + } + fn try_make_run(&mut self) -> bool { + match self { + Container::Bits(bits) => { + let mut r: u64 = 0; + for (i, chunk) in bits.iter().copied().enumerate() { + let next_chunk = + i.checked_add(1).and_then(|i| bits.get(i)).copied().unwrap_or(0); + r += !chunk & u64::from((chunk << 1).count_ones()); + r += !next_chunk & u64::from((chunk >> 63).count_ones()); + } + if (2 + 4 * r) >= 8192 { + return false; + } + let bits = std::mem::replace(bits, Box::new([0; 1024])); + *self = Container::Run(Vec::new()); + for (i, bits) in bits.iter().copied().enumerate() { + if bits == 0 { + continue; + } + for j in 0..64 { + let value = (u16::try_from(i).unwrap() << 6) | j; + if bits & (1 << j) != 0 { + self.push(value); + } + } + } + true + } + Container::Array(array) if array.len() <= 5 => false, + Container::Array(array) => { + let mut r = 0; + let mut prev = None; + for value in array.iter().copied() { + if value.checked_sub(1) != prev { + r += 1; + } + prev = Some(value); + } + if 2 + 4 * r >= 2 * array.len() + 2 { + return false; + } + let array = std::mem::replace(array, Vec::new()); + *self = Container::Run(Vec::new()); + for value in array { + self.push(value); + } + true + } + Container::Run(_) => true, + } + } +} + +// checked against roaring-rs in +// https://gitlab.com/notriddle/roaring-test +pub(crate) fn write_bitmap_to_bytes( + domain: &[u32], + mut out: impl std::io::Write, +) -> std::io::Result<()> { + // https://arxiv.org/pdf/1603.06549.pdf + let mut keys = Vec::::new(); + let mut containers = Vec::::new(); + let mut key: u16; + let mut domain_iter = domain.into_iter().copied().peekable(); + let mut has_run = false; + while let Some(entry) = domain_iter.next() { + key = (entry >> 16).try_into().expect("shifted off the top 16 bits, so it should fit"); + let value: u16 = (entry & 0x00_00_FF_FF).try_into().expect("AND 16 bits, so it should fit"); + let mut container = Container::Array(vec![value]); + while let Some(entry) = domain_iter.peek().copied() { + let entry_key: u16 = + (entry >> 16).try_into().expect("shifted off the top 16 bits, so it should fit"); + if entry_key != key { + break; + } + domain_iter.next().expect("peeking just succeeded"); + container + .push((entry & 0x00_00_FF_FF).try_into().expect("AND 16 bits, so it should fit")); + } + keys.push(key); + has_run = container.try_make_run() || has_run; + containers.push(container); + } + // https://github.com/RoaringBitmap/RoaringFormatSpec + use byteorder::{WriteBytesExt, LE}; + const SERIAL_COOKIE_NO_RUNCONTAINER: u32 = 12346; + const SERIAL_COOKIE: u32 = 12347; + const NO_OFFSET_THRESHOLD: u32 = 4; + let size: u32 = containers.len().try_into().unwrap(); + let start_offset = if has_run { + out.write_u32::(SERIAL_COOKIE | ((size - 1) << 16))?; + for set in containers.chunks(8) { + let mut b = 0; + for (i, container) in set.iter().enumerate() { + if matches!(container, &Container::Run(..)) { + b |= 1 << i; + } + } + out.write_u8(b)?; + } + if size < NO_OFFSET_THRESHOLD { + 4 + 4 * size + ((size + 7) / 8) + } else { + 4 + 8 * size + ((size + 7) / 8) + } + } else { + out.write_u32::(SERIAL_COOKIE_NO_RUNCONTAINER)?; + out.write_u32::(containers.len().try_into().unwrap())?; + 4 + 4 + 4 * size + 4 * size + }; + for (&key, container) in keys.iter().zip(&containers) { + // descriptive header + let key: u32 = key.into(); + let count: u32 = container.popcount() - 1; + out.write_u32::((count << 16) | key)?; + } + if !has_run || size >= NO_OFFSET_THRESHOLD { + // offset header + let mut starting_offset = start_offset; + for container in &containers { + out.write_u32::(starting_offset)?; + starting_offset += match container { + Container::Bits(_) => 8192u32, + Container::Array(array) => u32::try_from(array.len()).unwrap() * 2, + Container::Run(runs) => 2 + u32::try_from(runs.len()).unwrap() * 4, + }; + } + } + for container in &containers { + match container { + Container::Bits(bits) => { + for chunk in bits.iter() { + out.write_u64::(*chunk)?; + } + } + Container::Array(array) => { + for value in array.iter() { + out.write_u16::(*value)?; + } + } + Container::Run(runs) => { + out.write_u16::((runs.len()).try_into().unwrap())?; + for (start, lenm1) in runs.iter().copied() { + out.write_u16::(start)?; + out.write_u16::(lenm1)?; + } + } + } + } + Ok(()) +} + +pub(crate) fn bitmap_to_string(domain: &[u32]) -> String { + let mut buf = Vec::new(); + let mut strbuf = String::new(); + write_bitmap_to_bytes(&domain, &mut buf).unwrap(); + BASE64_STANDARD.encode_string(&buf, &mut strbuf); + strbuf +} diff --git a/src/librustdoc/html/render/write_shared.rs b/src/librustdoc/html/render/write_shared.rs index fbd45b2b48ef9..c806bf1cc66f3 100644 --- a/src/librustdoc/html/render/write_shared.rs +++ b/src/librustdoc/html/render/write_shared.rs @@ -24,6 +24,7 @@ use crate::formats::cache::Cache; use crate::formats::item_type::ItemType; use crate::formats::Impl; use crate::html::format::Buffer; +use crate::html::render::search_index::SerializedSearchIndex; use crate::html::render::{AssocItemLink, ImplRenderingParameters}; use crate::html::{layout, static_files}; use crate::visit::DocVisitor; @@ -46,7 +47,7 @@ use crate::{try_err, try_none}; pub(super) fn write_shared( cx: &mut Context<'_>, krate: &Crate, - search_index: String, + search_index: SerializedSearchIndex, options: &RenderOptions, ) -> Result<(), Error> { // Write out the shared files. Note that these are shared among all rustdoc @@ -312,7 +313,7 @@ pub(super) fn write_shared( let dst = cx.dst.join(&format!("search-index{}.js", cx.shared.resource_suffix)); let (mut all_indexes, mut krates) = try_err!(collect_json(&dst, krate.name(cx.tcx()).as_str()), &dst); - all_indexes.push(search_index); + all_indexes.push(search_index.index); krates.push(krate.name(cx.tcx()).to_string()); krates.sort(); @@ -335,6 +336,32 @@ else if (window.initSearch) window.initSearch(searchIndex); Ok(v.into_bytes()) })?; + let search_desc_dir = cx.dst.join(format!("search.desc/{krate}", krate = krate.name(cx.tcx()))); + if Path::new(&search_desc_dir).exists() { + try_err!(std::fs::remove_dir_all(&search_desc_dir), &search_desc_dir); + } + try_err!(std::fs::create_dir_all(&search_desc_dir), &search_desc_dir); + let kratename = krate.name(cx.tcx()).to_string(); + for (i, (_, data)) in search_index.desc.into_iter().enumerate() { + let output_filename = static_files::suffix_path( + &format!("{kratename}-desc-{i}-.js"), + &cx.shared.resource_suffix, + ); + let path = search_desc_dir.join(output_filename); + try_err!( + std::fs::write( + &path, + &format!( + r##"searchState.loadedDescShard({kratename}, {i}, {data})"##, + kratename = serde_json::to_string(&kratename).unwrap(), + data = serde_json::to_string(&data).unwrap(), + ) + .into_bytes() + ), + &path + ); + } + write_invocation_specific("crates.js", &|| { let krates = krates.iter().map(|k| format!("\"{k}\"")).join(","); Ok(format!("window.ALL_CRATES = [{krates}];").into_bytes()) diff --git a/src/librustdoc/html/static/.eslintrc.js b/src/librustdoc/html/static/.eslintrc.js index 1a34530c2d16e..a1e9cc6dfa142 100644 --- a/src/librustdoc/html/static/.eslintrc.js +++ b/src/librustdoc/html/static/.eslintrc.js @@ -5,7 +5,7 @@ module.exports = { }, "extends": "eslint:recommended", "parserOptions": { - "ecmaVersion": 2015, + "ecmaVersion": 8, "sourceType": "module" }, "rules": { diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index b9a769a7c6da4..940b62be0c94d 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -329,6 +329,30 @@ function preLoadCss(cssUrl) { search.innerHTML = "

" + searchState.loadingText + "

"; searchState.showResults(search); }, + descShards: new Map(), + loadDesc: async function({descShard, descIndex}) { + if (descShard.promise === null) { + descShard.promise = new Promise((resolve, reject) => { + // The `resolve` callback is stored in the `descShard` + // object, which is itself stored in `this.descShards` map. + // It is called in `loadedDescShard` by the + // search.desc script. + descShard.resolve = resolve; + const ds = descShard; + const fname = `${ds.crate}-desc-${ds.shard}-`; + const url = resourcePath( + `search.desc/${descShard.crate}/${fname}`, + ".js", + ); + loadScript(url, reject); + }); + } + const list = await descShard.promise; + return list[descIndex]; + }, + loadedDescShard: function(crate, shard, data) { + this.descShards.get(crate)[shard].resolve(data.split("\n")); + }, }; const toggleAllDocsId = "toggle-all-docs"; @@ -381,7 +405,7 @@ function preLoadCss(cssUrl) { window.location.replace("#" + item.id); }, 0); } - } + }, ); } } @@ -585,7 +609,7 @@ function preLoadCss(cssUrl) { const script = document .querySelector("script[data-ignore-extern-crates]"); const ignoreExternCrates = new Set( - (script ? script.getAttribute("data-ignore-extern-crates") : "").split(",") + (script ? script.getAttribute("data-ignore-extern-crates") : "").split(","), ); for (const lib of libs) { if (lib === window.currentCrate || ignoreExternCrates.has(lib)) { @@ -1098,7 +1122,7 @@ function preLoadCss(cssUrl) { } else { wrapper.style.setProperty( "--popover-arrow-offset", - (wrapperPos.right - pos.right + 4) + "px" + (wrapperPos.right - pos.right + 4) + "px", ); } wrapper.style.visibility = ""; @@ -1680,7 +1704,7 @@ href="https://doc.rust-lang.org/${channel}/rustdoc/read-documentation/search.htm pendingSidebarResizingFrame = false; document.documentElement.style.setProperty( "--resizing-sidebar-width", - desiredSidebarSize + "px" + desiredSidebarSize + "px", ); }, 100); } diff --git a/src/librustdoc/html/static/js/search.js b/src/librustdoc/html/static/js/search.js index 875ebe2fc90d4..3daf1ad22ded3 100644 --- a/src/librustdoc/html/static/js/search.js +++ b/src/librustdoc/html/static/js/search.js @@ -206,14 +206,14 @@ const editDistanceState = { // insertion this.current[j - 1] + 1, // substitution - this.prev[j - 1] + substitutionCost + this.prev[j - 1] + substitutionCost, ); if ((i > 1) && (j > 1) && (a[aIdx] === b[bIdx - 1]) && (a[aIdx - 1] === b[bIdx])) { // transposition this.current[j] = Math.min( this.current[j], - this.prevPrev[j - 2] + 1 + this.prevPrev[j - 2] + 1, ); } } @@ -242,6 +242,14 @@ function initSearch(rawSearchIndex) { * @type {Array} */ let searchIndex; + /** + * @type {Map} + */ + let searchIndexDeprecated; + /** + * @type {Map} + */ + let searchIndexEmptyDesc; /** * @type {Uint32Array} */ @@ -426,7 +434,7 @@ function initSearch(rawSearchIndex) { return c === "," || c === "="; } -/** + /** * Returns `true` if the given `c` character is a path separator. For example * `:` in `a::b` or a whitespace in `a b`. * @@ -856,8 +864,8 @@ function initSearch(rawSearchIndex) { parserState, parserState.userQuery.slice(start, end), generics, - isInGenerics - ) + isInGenerics, + ), ); } } @@ -1295,7 +1303,7 @@ function initSearch(rawSearchIndex) { * * @return {ResultsTable} */ - function execQuery(parsedQuery, filterCrates, currentCrate) { + async function execQuery(parsedQuery, filterCrates, currentCrate) { const results_others = new Map(), results_in_args = new Map(), results_returned = new Map(); @@ -1342,9 +1350,9 @@ function initSearch(rawSearchIndex) { * @param {Results} results * @param {boolean} isType * @param {string} preferredCrate - * @returns {[ResultObject]} + * @returns {Promise<[ResultObject]>} */ - function sortResults(results, isType, preferredCrate) { + async function sortResults(results, isType, preferredCrate) { const userQuery = parsedQuery.userQuery; const result_list = []; for (const result of results.values()) { @@ -1394,8 +1402,8 @@ function initSearch(rawSearchIndex) { } // sort deprecated items later - a = aaa.item.deprecated; - b = bbb.item.deprecated; + a = searchIndexDeprecated.get(aaa.item.crate).contains(aaa.item.bitIndex); + b = searchIndexDeprecated.get(bbb.item.crate).contains(bbb.item.bitIndex); if (a !== b) { return a - b; } @@ -1422,8 +1430,8 @@ function initSearch(rawSearchIndex) { } // sort by description (no description goes later) - a = (aaa.item.desc === ""); - b = (bbb.item.desc === ""); + a = searchIndexEmptyDesc.get(aaa.item.crate).contains(aaa.item.bitIndex); + b = searchIndexEmptyDesc.get(bbb.item.crate).contains(bbb.item.bitIndex); if (a !== b) { return a - b; } @@ -1446,7 +1454,16 @@ function initSearch(rawSearchIndex) { return 0; }); - return transformResults(result_list); + const transformed = transformResults(result_list); + const descs = await Promise.all(transformed.map(result => { + return searchIndexEmptyDesc.get(result.crate).contains(result.bitIndex) ? + "" : + searchState.loadDesc(result); + })); + for (const [i, result] of transformed.entries()) { + result.desc = descs[i]; + } + return transformed; } /** @@ -1477,7 +1494,7 @@ function initSearch(rawSearchIndex) { whereClause, mgensIn, solutionCb, - unboxingDepth + unboxingDepth, ) { if (unboxingDepth >= UNBOXING_LIMIT) { return false; @@ -1524,7 +1541,7 @@ function initSearch(rawSearchIndex) { queryElem, whereClause, mgens, - unboxingDepth + 1 + unboxingDepth + 1, )) { continue; } @@ -1541,7 +1558,7 @@ function initSearch(rawSearchIndex) { whereClause, mgensScratch, solutionCb, - unboxingDepth + 1 + unboxingDepth + 1, )) { return true; } @@ -1551,7 +1568,7 @@ function initSearch(rawSearchIndex) { whereClause, mgens ? new Map(mgens) : null, solutionCb, - unboxingDepth + 1 + unboxingDepth + 1, )) { return true; } @@ -1625,7 +1642,7 @@ function initSearch(rawSearchIndex) { queryElem, whereClause, mgensScratch, - unboxingDepth + unboxingDepth, ); if (!solution) { return false; @@ -1638,7 +1655,7 @@ function initSearch(rawSearchIndex) { whereClause, simplifiedMgens, solutionCb, - unboxingDepth + unboxingDepth, ); if (passesUnification) { return true; @@ -1646,7 +1663,7 @@ function initSearch(rawSearchIndex) { } return false; }, - unboxingDepth + unboxingDepth, ); if (passesUnification) { return true; @@ -1663,7 +1680,7 @@ function initSearch(rawSearchIndex) { queryElem, whereClause, mgens, - unboxingDepth + 1 + unboxingDepth + 1, )) { continue; } @@ -1689,7 +1706,7 @@ function initSearch(rawSearchIndex) { whereClause, mgensScratch, solutionCb, - unboxingDepth + 1 + unboxingDepth + 1, ); if (passesUnification) { return true; @@ -1820,7 +1837,7 @@ function initSearch(rawSearchIndex) { queryElem, whereClause, mgensIn, - unboxingDepth + unboxingDepth, ) { if (fnType.bindings.size < queryElem.bindings.size) { return false; @@ -1849,7 +1866,7 @@ function initSearch(rawSearchIndex) { // possible solutions return false; }, - unboxingDepth + unboxingDepth, ); return newSolutions; }); @@ -1887,7 +1904,7 @@ function initSearch(rawSearchIndex) { queryElem, whereClause, mgens, - unboxingDepth + unboxingDepth, ) { if (unboxingDepth >= UNBOXING_LIMIT) { return false; @@ -1914,7 +1931,7 @@ function initSearch(rawSearchIndex) { queryElem, whereClause, mgensTmp, - unboxingDepth + unboxingDepth, ); } else if (fnType.generics.length > 0 || fnType.bindings.size > 0) { const simplifiedGenerics = [ @@ -1926,7 +1943,7 @@ function initSearch(rawSearchIndex) { queryElem, whereClause, mgens, - unboxingDepth + unboxingDepth, ); } return false; @@ -1975,7 +1992,7 @@ function initSearch(rawSearchIndex) { elem, whereClause, mgens, - unboxingDepth + 1 + unboxingDepth + 1, ); } if (row.id > 0 && elem.id > 0 && elem.pathWithoutLast.length === 0 && @@ -1989,7 +2006,7 @@ function initSearch(rawSearchIndex) { elem, whereClause, mgens, - unboxingDepth + unboxingDepth, ); } } @@ -2007,7 +2024,7 @@ function initSearch(rawSearchIndex) { return 0; } const maxPathEditDistance = Math.floor( - contains.reduce((acc, next) => acc + next.length, 0) / 3 + contains.reduce((acc, next) => acc + next.length, 0) / 3, ); let ret_dist = maxPathEditDistance + 1; const path = ty.path.split("::"); @@ -2066,12 +2083,13 @@ function initSearch(rawSearchIndex) { crate: item.crate, name: item.name, path: item.path, - desc: item.desc, + descShard: item.descShard, + descIndex: item.descIndex, ty: item.ty, parent: item.parent, type: item.type, is_alias: true, - deprecated: item.deprecated, + bitIndex: item.bitIndex, implDisambiguator: item.implDisambiguator, }; } @@ -2192,7 +2210,7 @@ function initSearch(rawSearchIndex) { results_others, results_in_args, results_returned, - maxEditDistance + maxEditDistance, ) { if (!row || (filterCrates !== null && row.crate !== filterCrates)) { return; @@ -2204,7 +2222,7 @@ function initSearch(rawSearchIndex) { // atoms in the function not present in the query const tfpDist = compareTypeFingerprints( fullId, - parsedQuery.typeFingerprint + parsedQuery.typeFingerprint, ); if (tfpDist !== null) { const in_args = row.type && row.type.inputs @@ -2276,7 +2294,7 @@ function initSearch(rawSearchIndex) { const tfpDist = compareTypeFingerprints( row.id, - parsedQuery.typeFingerprint + parsedQuery.typeFingerprint, ); if (tfpDist === null) { return; @@ -2298,10 +2316,10 @@ function initSearch(rawSearchIndex) { row.type.where_clause, mgens, null, - 0 // unboxing depth + 0, // unboxing depth ); }, - 0 // unboxing depth + 0, // unboxing depth )) { return; } @@ -2419,7 +2437,7 @@ function initSearch(rawSearchIndex) { } return [typeNameIdMap.get(name).id, constraints]; - }) + }), ); } @@ -2446,7 +2464,7 @@ function initSearch(rawSearchIndex) { results_others, results_in_args, results_returned, - maxEditDistance + maxEditDistance, ); } } @@ -2477,10 +2495,15 @@ function initSearch(rawSearchIndex) { innerRunQuery(); } - const ret = createQueryResults( + const [sorted_in_args, sorted_returned, sorted_others] = await Promise.all([ sortResults(results_in_args, true, currentCrate), sortResults(results_returned, true, currentCrate), sortResults(results_others, false, currentCrate), + ]); + const ret = createQueryResults( + sorted_in_args, + sorted_returned, + sorted_others, parsedQuery); handleAliases(ret, parsedQuery.original.replace(/"/g, ""), filterCrates, currentCrate); if (parsedQuery.error !== null && ret.others.length !== 0) { @@ -2581,14 +2604,14 @@ function initSearch(rawSearchIndex) { * @param {ParsedQuery} query * @param {boolean} display - True if this is the active tab */ - function addTab(array, query, display) { + async function addTab(array, query, display) { const extraClass = display ? " active" : ""; const output = document.createElement("div"); if (array.length > 0) { output.className = "search-results " + extraClass; - array.forEach(item => { + for (const item of array) { const name = item.name; const type = itemTypes[item.ty]; const longType = longItemTypes[item.ty]; @@ -2624,7 +2647,7 @@ ${item.displayPath}${name}\ link.appendChild(description); output.appendChild(link); - }); + } } else if (query.error === null) { output.className = "search-failed" + extraClass; output.innerHTML = "No results :(
" + @@ -2666,7 +2689,7 @@ ${item.displayPath}${name}\ * @param {boolean} go_to_first * @param {string} filterCrates */ - function showResults(results, go_to_first, filterCrates) { + async function showResults(results, go_to_first, filterCrates) { const search = searchState.outputElement(); if (go_to_first || (results.others.length === 1 && getSettingValue("go-to-only-result") === "true") @@ -2699,9 +2722,11 @@ ${item.displayPath}${name}\ currentResults = results.query.userQuery; - 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); + const [ret_others, ret_in_args, ret_returned] = await Promise.all([ + addTab(results.others, results.query, true), + addTab(results.in_args, results.query, false), + 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 @@ -2822,7 +2847,7 @@ ${item.displayPath}${name}\ * and display the results. * @param {boolean} [forced] */ - function search(forced) { + async function search(forced) { const query = parseQuery(searchState.input.value.trim()); let filterCrates = getFilterCrates(); @@ -2850,8 +2875,8 @@ ${item.displayPath}${name}\ // recent search query is added to the browser history. updateSearchHistory(buildUrl(query.original, filterCrates)); - showResults( - execQuery(query, filterCrates, window.currentCrate), + await showResults( + await execQuery(query, filterCrates, window.currentCrate), params.go_to_first, filterCrates); } @@ -2920,7 +2945,7 @@ ${item.displayPath}${name}\ pathIndex = type[PATH_INDEX_DATA]; generics = buildItemSearchTypeAll( type[GENERICS_DATA], - lowercasePaths + lowercasePaths, ); if (type.length > BINDINGS_DATA && type[BINDINGS_DATA].length > 0) { bindings = new Map(type[BINDINGS_DATA].map(binding => { @@ -3030,101 +3055,49 @@ ${item.displayPath}${name}\ * The raw function search type format is generated using serde in * librustdoc/html/render/mod.rs: IndexItemFunctionType::write_to_string * - * @param {{ - * string: string, - * offset: number, - * backrefQueue: FunctionSearchType[] - * }} itemFunctionDecoder * @param {Array<{name: string, ty: number}>} lowercasePaths - * @param {Map} * * @return {null|FunctionSearchType} */ - function buildFunctionSearchType(itemFunctionDecoder, lowercasePaths) { - const c = itemFunctionDecoder.string.charCodeAt(itemFunctionDecoder.offset); - itemFunctionDecoder.offset += 1; - const [zero, ua, la, ob, cb] = ["0", "@", "`", "{", "}"].map(c => c.charCodeAt(0)); - // `` ` `` is used as a sentinel because it's fewer bytes than `null`, and decodes to zero - // `0` is a backref - if (c === la) { - return null; - } - // sixteen characters after "0" are backref - if (c >= zero && c < ua) { - return itemFunctionDecoder.backrefQueue[c - zero]; - } - if (c !== ob) { - throw ["Unexpected ", c, " in function: expected ", "{", "; this is a bug"]; - } - // call after consuming `{` - function decodeList() { - let c = itemFunctionDecoder.string.charCodeAt(itemFunctionDecoder.offset); - const ret = []; - while (c !== cb) { - ret.push(decode()); - c = itemFunctionDecoder.string.charCodeAt(itemFunctionDecoder.offset); - } - itemFunctionDecoder.offset += 1; // eat cb - return ret; - } - // consumes and returns a list or integer - function decode() { - let n = 0; - let c = itemFunctionDecoder.string.charCodeAt(itemFunctionDecoder.offset); - if (c === ob) { - itemFunctionDecoder.offset += 1; - return decodeList(); - } - while (c < la) { - n = (n << 4) | (c & 0xF); - itemFunctionDecoder.offset += 1; - c = itemFunctionDecoder.string.charCodeAt(itemFunctionDecoder.offset); - } - // last character >= la - n = (n << 4) | (c & 0xF); - const [sign, value] = [n & 1, n >> 1]; - itemFunctionDecoder.offset += 1; - return sign ? -value : value; - } - const functionSearchType = decodeList(); - const INPUTS_DATA = 0; - const OUTPUT_DATA = 1; - let inputs, output; - if (typeof functionSearchType[INPUTS_DATA] === "number") { - inputs = [buildItemSearchType(functionSearchType[INPUTS_DATA], lowercasePaths)]; - } else { - inputs = buildItemSearchTypeAll( - functionSearchType[INPUTS_DATA], - lowercasePaths - ); - } - if (functionSearchType.length > 1) { - if (typeof functionSearchType[OUTPUT_DATA] === "number") { - output = [buildItemSearchType(functionSearchType[OUTPUT_DATA], lowercasePaths)]; + function buildFunctionSearchTypeCallback(lowercasePaths) { + return functionSearchType => { + if (functionSearchType === 0) { + return null; + } + const INPUTS_DATA = 0; + const OUTPUT_DATA = 1; + let inputs, output; + if (typeof functionSearchType[INPUTS_DATA] === "number") { + inputs = [buildItemSearchType(functionSearchType[INPUTS_DATA], lowercasePaths)]; } else { - output = buildItemSearchTypeAll( - functionSearchType[OUTPUT_DATA], - lowercasePaths + inputs = buildItemSearchTypeAll( + functionSearchType[INPUTS_DATA], + lowercasePaths, ); } - } else { - output = []; - } - const where_clause = []; - const l = functionSearchType.length; - for (let i = 2; i < l; ++i) { - where_clause.push(typeof functionSearchType[i] === "number" - ? [buildItemSearchType(functionSearchType[i], lowercasePaths)] - : buildItemSearchTypeAll(functionSearchType[i], lowercasePaths)); - } - const ret = { - inputs, output, where_clause, + if (functionSearchType.length > 1) { + if (typeof functionSearchType[OUTPUT_DATA] === "number") { + output = [buildItemSearchType(functionSearchType[OUTPUT_DATA], lowercasePaths)]; + } else { + output = buildItemSearchTypeAll( + functionSearchType[OUTPUT_DATA], + lowercasePaths, + ); + } + } else { + output = []; + } + const where_clause = []; + const l = functionSearchType.length; + for (let i = 2; i < l; ++i) { + where_clause.push(typeof functionSearchType[i] === "number" + ? [buildItemSearchType(functionSearchType[i], lowercasePaths)] + : buildItemSearchTypeAll(functionSearchType[i], lowercasePaths)); + } + return { + inputs, output, where_clause, + }; }; - itemFunctionDecoder.backrefQueue.unshift(ret); - if (itemFunctionDecoder.backrefQueue.length > 16) { - itemFunctionDecoder.backrefQueue.pop(); - } - return ret; } /** @@ -3245,6 +3218,185 @@ ${item.displayPath}${name}\ return functionTypeFingerprint[(fullId * 4) + 3]; } + class VlqHexDecoder { + constructor(string, cons) { + this.string = string; + this.cons = cons; + this.offset = 0; + this.backrefQueue = []; + } + // call after consuming `{` + decodeList() { + const cb = "}".charCodeAt(0); + let c = this.string.charCodeAt(this.offset); + const ret = []; + while (c !== cb) { + ret.push(this.decode()); + c = this.string.charCodeAt(this.offset); + } + this.offset += 1; // eat cb + return ret; + } + // consumes and returns a list or integer + decode() { + const [ob, la] = ["{", "`"].map(c => c.charCodeAt(0)); + let n = 0; + let c = this.string.charCodeAt(this.offset); + if (c === ob) { + this.offset += 1; + return this.decodeList(); + } + while (c < la) { + n = (n << 4) | (c & 0xF); + this.offset += 1; + c = this.string.charCodeAt(this.offset); + } + // last character >= la + n = (n << 4) | (c & 0xF); + const [sign, value] = [n & 1, n >> 1]; + this.offset += 1; + return sign ? -value : value; + } + next() { + const c = this.string.charCodeAt(this.offset); + const [zero, ua, la] = ["0", "@", "`"].map(c => c.charCodeAt(0)); + // sixteen characters after "0" are backref + if (c >= zero && c < ua) { + this.offset += 1; + return this.backrefQueue[c - zero]; + } + // special exception: 0 doesn't use backref encoding + // it's already one character, and it's always nullish + if (c === la) { + this.offset += 1; + return this.cons(0); + } + const result = this.cons(this.decode()); + this.backrefQueue.unshift(result); + if (this.backrefQueue.length > 16) { + this.backrefQueue.pop(); + } + return result; + } + } + class RoaringBitmap { + constructor(str) { + const strdecoded = atob(str); + const u8array = new Uint8Array(strdecoded.length); + for (let j = 0; j < strdecoded.length; ++j) { + u8array[j] = strdecoded.charCodeAt(j); + } + const has_runs = u8array[0] === 0x3b; + const size = has_runs ? + ((u8array[2] | (u8array[3] << 8)) + 1) : + ((u8array[4] | (u8array[5] << 8) | (u8array[6] << 16) | (u8array[7] << 24))); + let i = has_runs ? 4 : 8; + let is_run; + if (has_runs) { + const is_run_len = Math.floor((size + 7) / 8); + is_run = u8array.slice(i, i + is_run_len); + i += is_run_len; + } else { + is_run = new Uint8Array(); + } + this.keys = []; + this.cardinalities = []; + for (let j = 0; j < size; ++j) { + this.keys.push(u8array[i] | (u8array[i + 1] << 8)); + i += 2; + this.cardinalities.push((u8array[i] | (u8array[i + 1] << 8)) + 1); + i += 2; + } + this.containers = []; + let offsets = null; + if (!has_runs || this.keys.length >= 4) { + offsets = []; + for (let j = 0; j < size; ++j) { + offsets.push(u8array[i] | (u8array[i + 1] << 8) | (u8array[i + 2] << 16) | + (u8array[i + 3] << 24)); + i += 4; + } + } + for (let j = 0; j < size; ++j) { + if (offsets && offsets[j] !== i) { + console.log(this.containers); + throw new Error(`corrupt bitmap ${j}: ${i} / ${offsets[j]}`); + } + if (is_run[j >> 3] & (1 << (j & 0x7))) { + const runcount = (u8array[i] | (u8array[i + 1] << 8)); + i += 2; + this.containers.push(new RoaringBitmapRun( + runcount, + u8array.slice(i, i + (runcount * 4)), + )); + i += runcount * 4; + } else if (this.cardinalities[j] >= 4096) { + this.containers.push(new RoaringBitmapBits(u8array.slice(i, i + 8192))); + i += 8192; + } else { + const end = this.cardinalities[j] * 2; + this.containers.push(new RoaringBitmapArray( + this.cardinalities[j], + u8array.slice(i, i + end), + )); + i += end; + } + } + } + contains(keyvalue) { + const key = keyvalue >> 16; + const value = keyvalue & 0xFFFF; + for (let i = 0; i < this.keys.length; ++i) { + if (this.keys[i] === key) { + return this.containers[i].contains(value); + } + } + return false; + } + } + + class RoaringBitmapRun { + constructor(runcount, array) { + this.runcount = runcount; + this.array = array; + } + contains(value) { + const l = this.runcount * 4; + for (let i = 0; i < l; i += 4) { + const start = this.array[i] | (this.array[i + 1] << 8); + const lenm1 = this.array[i + 2] | (this.array[i + 3] << 8); + if (value >= start && value <= (start + lenm1)) { + return true; + } + } + return false; + } + } + class RoaringBitmapArray { + constructor(cardinality, array) { + this.cardinality = cardinality; + this.array = array; + } + contains(value) { + const l = this.cardinality * 2; + for (let i = 0; i < l; i += 2) { + const start = this.array[i] | (this.array[i + 1] << 8); + if (value === start) { + return true; + } + } + return false; + } + } + class RoaringBitmapBits { + constructor(array) { + this.array = array; + } + contains(value) { + return !!(this.array[value >> 3] & (1 << (value & 7))); + } + } + /** * Convert raw search index into in-memory search index. * @@ -3252,6 +3404,8 @@ ${item.displayPath}${name}\ */ function buildIndex(rawSearchIndex) { searchIndex = []; + searchIndexDeprecated = new Map(); + searchIndexEmptyDesc = new Map(); const charA = "A".charCodeAt(0); let currentIndex = 0; let id = 0; @@ -3271,26 +3425,48 @@ ${item.displayPath}${name}\ id = 0; for (const [crate, crateCorpus] of rawSearchIndex) { + // a string representing the lengths of each description shard + // a string representing the list of function types + const itemDescShardDecoder = new VlqHexDecoder(crateCorpus.D, noop => noop); + let descShard = { + crate, + shard: 0, + start: 0, + len: itemDescShardDecoder.next(), + promise: null, + resolve: null, + }; + const descShardList = [ descShard ]; + + // Deprecated items and items with no description + searchIndexDeprecated.set(crate, new RoaringBitmap(crateCorpus.c)); + searchIndexEmptyDesc.set(crate, new RoaringBitmap(crateCorpus.e)); + let descIndex = 0; + // 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 const crateRow = { - crate: crate, + crate, ty: 3, // == ExternCrate name: crate, path: "", - desc: crateCorpus.doc, + descShard, + descIndex, parent: undefined, type: null, - id: id, + id, word: crate, normalizedName: crate.indexOf("_") === -1 ? crate : crate.replace(/_/g, ""), - deprecated: null, + bitIndex: 0, implDisambiguator: null, }; id += 1; searchIndex.push(crateRow); currentIndex += 1; + if (!searchIndexEmptyDesc.get(crate).contains(0)) { + descIndex += 1; + } // a String of one character item type codes const itemTypes = crateCorpus.t; @@ -3302,19 +3478,9 @@ ${item.displayPath}${name}\ // i.e. if indices 4 and 11 are present, but 5-10 and 12-13 are not present, // 5-10 will fall back to the path for 4 and 12-13 will fall back to the path for 11 const itemPaths = new Map(crateCorpus.q); - // an array of (String) descriptions - const itemDescs = crateCorpus.d; // an array of (Number) the parent path index + 1 to `paths`, or 0 if none const itemParentIdxs = crateCorpus.i; - // a string representing the list of function types - const itemFunctionDecoder = { - string: crateCorpus.f, - offset: 0, - backrefQueue: [], - }; - // an array of (Number) indices for the deprecated items - const deprecatedItems = new Set(crateCorpus.c); - // an array of (Number) indices for the deprecated items + // a map Number, string for impl disambiguators const implDisambiguator = new Map(crateCorpus.b); // an array of [(Number) item type, // (String) name] @@ -3326,6 +3492,12 @@ ${item.displayPath}${name}\ // an array of [{name: String, ty: Number}] const lowercasePaths = []; + // a string representing the list of function types + const itemFunctionDecoder = new VlqHexDecoder( + crateCorpus.f, + buildFunctionSearchTypeCallback(lowercasePaths), + ); + // convert `rawPaths` entries into object form // generate normalizedPaths for function search mode let len = paths.length; @@ -3354,12 +3526,26 @@ ${item.displayPath}${name}\ lastPath = ""; len = itemTypes.length; for (let i = 0; i < len; ++i) { + const bitIndex = i + 1; + if (descIndex >= descShard.len && + !searchIndexEmptyDesc.get(crate).contains(bitIndex)) { + descShard = { + crate, + shard: descShard.shard + 1, + start: descShard.start + descShard.len, + len: itemDescShardDecoder.next(), + promise: null, + resolve: null, + }; + descIndex = 0; + descShardList.push(descShard); + } let word = ""; if (typeof itemNames[i] === "string") { word = itemNames[i].toLowerCase(); } const path = itemPaths.has(i) ? itemPaths.get(i) : lastPath; - const type = buildFunctionSearchType(itemFunctionDecoder, lowercasePaths); + const type = itemFunctionDecoder.next(); if (type !== null) { if (type) { const fp = functionTypeFingerprint.subarray(id * 4, (id + 1) * 4); @@ -3380,22 +3566,26 @@ ${item.displayPath}${name}\ // This object should have exactly the same set of fields as the "crateRow" // object defined above. const row = { - crate: crate, + crate, ty: itemTypes.charCodeAt(i) - charA, name: itemNames[i], - path: path, - desc: itemDescs[i], + path, + descShard, + descIndex, parent: itemParentIdxs[i] > 0 ? paths[itemParentIdxs[i] - 1] : undefined, type, - id: id, + id, word, normalizedName: word.indexOf("_") === -1 ? word : word.replace(/_/g, ""), - deprecated: deprecatedItems.has(i), + bitIndex, implDisambiguator: implDisambiguator.has(i) ? implDisambiguator.get(i) : null, }; id += 1; searchIndex.push(row); lastPath = row.path; + if (!searchIndexEmptyDesc.get(crate).contains(bitIndex)) { + descIndex += 1; + } } if (aliases) { @@ -3419,6 +3609,7 @@ ${item.displayPath}${name}\ } } currentIndex += itemTypes.length; + searchState.descShards.set(crate, descShardList); } // Drop the (rather large) hash table used for reusing function items TYPES_POOL = new Map(); diff --git a/src/librustdoc/html/static/js/storage.js b/src/librustdoc/html/static/js/storage.js index bda7b3c647e7e..73c543567c078 100644 --- a/src/librustdoc/html/static/js/storage.js +++ b/src/librustdoc/html/static/js/storage.js @@ -211,14 +211,14 @@ function updateSidebarWidth() { if (desktopSidebarWidth && desktopSidebarWidth !== "null") { document.documentElement.style.setProperty( "--desktop-sidebar-width", - desktopSidebarWidth + "px" + desktopSidebarWidth + "px", ); } const srcSidebarWidth = getSettingValue("src-sidebar-width"); if (srcSidebarWidth && srcSidebarWidth !== "null") { document.documentElement.style.setProperty( "--src-sidebar-width", - srcSidebarWidth + "px" + srcSidebarWidth + "px", ); } } diff --git a/src/tools/rustdoc-js/.eslintrc.js b/src/tools/rustdoc-js/.eslintrc.js index 4ab3a31573309..b9d0e251c242b 100644 --- a/src/tools/rustdoc-js/.eslintrc.js +++ b/src/tools/rustdoc-js/.eslintrc.js @@ -6,7 +6,7 @@ module.exports = { }, "extends": "eslint:recommended", "parserOptions": { - "ecmaVersion": 2015, + "ecmaVersion": 8, "sourceType": "module" }, "rules": { diff --git a/src/tools/rustdoc-js/tester.js b/src/tools/rustdoc-js/tester.js index 86881ef362e9f..43a22f358c31f 100644 --- a/src/tools/rustdoc-js/tester.js +++ b/src/tools/rustdoc-js/tester.js @@ -1,3 +1,4 @@ +/* global globalThis */ const fs = require("fs"); const path = require("path"); @@ -133,7 +134,7 @@ function valueCheck(fullPath, expected, result, error_text, queryName) { expected_value, result.get(key), error_text, - queryName + queryName, ); } else { error_text.push(`${queryName}==> EXPECTED has extra key in map from field ` + @@ -212,11 +213,11 @@ function runParser(query, expected, parseQuery, queryName) { return error_text; } -function runSearch(query, expected, doSearch, loadedFile, queryName) { +async function runSearch(query, expected, doSearch, loadedFile, queryName) { const ignore_order = loadedFile.ignore_order; const exact_check = loadedFile.exact_check; - const results = doSearch(query, loadedFile.FILTER_CRATE); + const results = await doSearch(query, loadedFile.FILTER_CRATE); const error_text = []; for (const key in expected) { @@ -238,7 +239,7 @@ function runSearch(query, expected, doSearch, loadedFile, queryName) { } let prev_pos = -1; - entry.forEach((elem, index) => { + for (const [index, elem] of entry.entries()) { const entry_pos = lookForEntry(elem, results[key]); if (entry_pos === -1) { error_text.push(queryName + "==> Result not found in '" + key + "': '" + @@ -260,13 +261,13 @@ function runSearch(query, expected, doSearch, loadedFile, queryName) { } else { prev_pos = entry_pos; } - }); + } } return error_text; } -function runCorrections(query, corrections, getCorrections, loadedFile) { - const qc = getCorrections(query, loadedFile.FILTER_CRATE); +async function runCorrections(query, corrections, getCorrections, loadedFile) { + const qc = await getCorrections(query, loadedFile.FILTER_CRATE); const error_text = []; if (corrections === null) { @@ -299,18 +300,27 @@ function checkResult(error_text, loadedFile, displaySuccess) { return 1; } -function runCheckInner(callback, loadedFile, entry, getCorrections, extra) { +async function runCheckInner(callback, loadedFile, entry, getCorrections, extra) { if (typeof entry.query !== "string") { console.log("FAILED"); console.log("==> Missing `query` field"); return false; } - let error_text = callback(entry.query, entry, extra ? "[ query `" + entry.query + "`]" : ""); + let error_text = await callback( + entry.query, + entry, + extra ? "[ query `" + entry.query + "`]" : "", + ); if (checkResult(error_text, loadedFile, false) !== 0) { return false; } if (entry.correction !== undefined) { - error_text = runCorrections(entry.query, entry.correction, getCorrections, loadedFile); + error_text = await runCorrections( + entry.query, + entry.correction, + getCorrections, + loadedFile, + ); if (checkResult(error_text, loadedFile, false) !== 0) { return false; } @@ -318,16 +328,16 @@ function runCheckInner(callback, loadedFile, entry, getCorrections, extra) { return true; } -function runCheck(loadedFile, key, getCorrections, callback) { +async function runCheck(loadedFile, key, getCorrections, callback) { const expected = loadedFile[key]; if (Array.isArray(expected)) { for (const entry of expected) { - if (!runCheckInner(callback, loadedFile, entry, getCorrections, true)) { + if (!await runCheckInner(callback, loadedFile, entry, getCorrections, true)) { return 1; } } - } else if (!runCheckInner(callback, loadedFile, expected, getCorrections, false)) { + } else if (!await runCheckInner(callback, loadedFile, expected, getCorrections, false)) { return 1; } console.log("OK"); @@ -338,7 +348,7 @@ function hasCheck(content, checkName) { return content.startsWith(`const ${checkName}`) || content.includes(`\nconst ${checkName}`); } -function runChecks(testFile, doSearch, parseQuery, getCorrections) { +async function runChecks(testFile, doSearch, parseQuery, getCorrections) { let checkExpected = false; let checkParsed = false; let testFileContent = readFile(testFile); @@ -367,12 +377,12 @@ function runChecks(testFile, doSearch, parseQuery, getCorrections) { let res = 0; if (checkExpected) { - res += runCheck(loadedFile, "EXPECTED", getCorrections, (query, expected, text) => { + res += await runCheck(loadedFile, "EXPECTED", getCorrections, (query, expected, text) => { return runSearch(query, expected, doSearch, loadedFile, text); }); } if (checkParsed) { - res += runCheck(loadedFile, "PARSED", getCorrections, (query, expected, text) => { + res += await runCheck(loadedFile, "PARSED", getCorrections, (query, expected, text) => { return runParser(query, expected, parseQuery, text); }); } @@ -393,6 +403,35 @@ function loadSearchJS(doc_folder, resource_suffix) { const searchIndexJs = path.join(doc_folder, "search-index" + resource_suffix + ".js"); const searchIndex = require(searchIndexJs); + globalThis.searchState = { + descShards: new Map(), + loadDesc: async function({descShard, descIndex}) { + if (descShard.promise === null) { + descShard.promise = new Promise((resolve, reject) => { + descShard.resolve = resolve; + const ds = descShard; + const fname = `${ds.crate}-desc-${ds.shard}-${resource_suffix}.js`; + fs.readFile( + `${doc_folder}/search.desc/${descShard.crate}/${fname}`, + (err, data) => { + if (err) { + reject(err); + } else { + eval(data.toString("utf8")); + } + }, + ); + }); + } + const list = await descShard.promise; + return list[descIndex]; + }, + loadedDescShard: function(crate, shard, data) { + //console.log(this.descShards); + this.descShards.get(crate)[shard].resolve(data.split("\n")); + }, + }; + const staticFiles = path.join(doc_folder, "static.files"); const searchJs = fs.readdirSync(staticFiles).find(f => f.match(/search.*\.js$/)); const searchModule = require(path.join(staticFiles, searchJs)); @@ -474,7 +513,7 @@ function parseOptions(args) { return null; } -function main(argv) { +async function main(argv) { const opts = parseOptions(argv.slice(2)); if (opts === null) { return 1; @@ -482,7 +521,7 @@ function main(argv) { const parseAndSearch = loadSearchJS( opts["doc_folder"], - opts["resource_suffix"] + opts["resource_suffix"], ); let errors = 0; @@ -494,21 +533,29 @@ function main(argv) { }; if (opts["test_file"].length !== 0) { - opts["test_file"].forEach(file => { + for (const file of opts["test_file"]) { process.stdout.write(`Testing ${file} ... `); - errors += runChecks(file, doSearch, parseAndSearch.parseQuery, getCorrections); - }); + errors += await runChecks(file, doSearch, parseAndSearch.parseQuery, getCorrections); + } } else if (opts["test_folder"].length !== 0) { - fs.readdirSync(opts["test_folder"]).forEach(file => { + for (const file of fs.readdirSync(opts["test_folder"])) { if (!file.endsWith(".js")) { - return; + continue; } process.stdout.write(`Testing ${file} ... `); - errors += runChecks(path.join(opts["test_folder"], file), doSearch, + errors += await runChecks(path.join(opts["test_folder"], file), doSearch, parseAndSearch.parseQuery, getCorrections); - }); + } } return errors > 0 ? 1 : 0; } -process.exit(main(process.argv)); +main(process.argv).catch(e => { + console.log(e); + process.exit(1); +}).then(x => process.exit(x)); + +process.on("beforeExit", () => { + console.log("process did not complete"); + process.exit(1); +}); diff --git a/tests/rustdoc-gui/anchors.goml b/tests/rustdoc-gui/anchors.goml index 72e0bcd77e08c..3239e54a866b5 100644 --- a/tests/rustdoc-gui/anchors.goml +++ b/tests/rustdoc-gui/anchors.goml @@ -2,7 +2,7 @@ define-function: ( "check-colors", - (theme, main_color, title_color, main_heading_color, main_heading_type_color, src_link_color, sidebar_link_color), + [theme, main_color, title_color, main_heading_color, main_heading_type_color, src_link_color, sidebar_link_color], block { go-to: "file://" + |DOC_PATH| + "/staged_api/struct.Foo.html" // This is needed to ensure that the text color is computed. diff --git a/tests/rustdoc-gui/code-color.goml b/tests/rustdoc-gui/code-color.goml index 92bdfb25b001c..e17af5e7f1fa4 100644 --- a/tests/rustdoc-gui/code-color.goml +++ b/tests/rustdoc-gui/code-color.goml @@ -8,7 +8,7 @@ show-text: true define-function: ( "check-colors", - (theme, doc_code_color, doc_inline_code_color), + [theme, doc_code_color, doc_inline_code_color], block { // Set the theme. set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} diff --git a/tests/rustdoc-gui/codeblock-tooltip.goml b/tests/rustdoc-gui/codeblock-tooltip.goml index 7be5e39ba4727..19e3927f64293 100644 --- a/tests/rustdoc-gui/codeblock-tooltip.goml +++ b/tests/rustdoc-gui/codeblock-tooltip.goml @@ -4,7 +4,7 @@ show-text: true define-function: ( "check-colors", - (theme, background, color, border), + [theme, background, color, border], block { // Setting the theme. set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} diff --git a/tests/rustdoc-gui/cursor.goml b/tests/rustdoc-gui/cursor.goml index 27c955f5a13ac..9412987fc3238 100644 --- a/tests/rustdoc-gui/cursor.goml +++ b/tests/rustdoc-gui/cursor.goml @@ -8,7 +8,7 @@ assert-css: ("#toggle-all-docs", {"cursor": "pointer"}) assert-css: ("#copy-path", {"cursor": "pointer"}) // the search tabs -write: (".search-input", "Foo") +write-into: (".search-input", "Foo") // To be SURE that the search will be run. press-key: 'Enter' // Waiting for the search results to appear... diff --git a/tests/rustdoc-gui/docblock-code-block-line-number.goml b/tests/rustdoc-gui/docblock-code-block-line-number.goml index a50449e17010f..cb7bdaab4c8db 100644 --- a/tests/rustdoc-gui/docblock-code-block-line-number.goml +++ b/tests/rustdoc-gui/docblock-code-block-line-number.goml @@ -10,7 +10,7 @@ assert-false: "pre.example-line-numbers" // Let's now check some CSS properties... define-function: ( "check-colors", - (theme, color), + [theme, color], block { // We now set the setting to show the line numbers on code examples. set-local-storage: { diff --git a/tests/rustdoc-gui/docblock-table.goml b/tests/rustdoc-gui/docblock-table.goml index 678b302f22e3b..db6d065a4b338 100644 --- a/tests/rustdoc-gui/docblock-table.goml +++ b/tests/rustdoc-gui/docblock-table.goml @@ -6,7 +6,7 @@ compare-elements-css: (".impl-items .docblock table td", ".top-doc .docblock tab define-function: ( "check-colors", - (theme, border_color, zebra_stripe_color), + [theme, border_color, zebra_stripe_color], block { set-local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": |theme|} reload: diff --git a/tests/rustdoc-gui/escape-key.goml b/tests/rustdoc-gui/escape-key.goml index 3ea20fd118e6a..ff8557b9b81ca 100644 --- a/tests/rustdoc-gui/escape-key.goml +++ b/tests/rustdoc-gui/escape-key.goml @@ -2,7 +2,7 @@ // current content displayed. go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" // First, we check that the search results are hidden when the Escape key is pressed. -write: (".search-input", "test") +write-into: (".search-input", "test") // To be SURE that the search will be run. press-key: 'Enter' wait-for: "#search h1" // The search element is empty before the first search diff --git a/tests/rustdoc-gui/globals.goml b/tests/rustdoc-gui/globals.goml index c01c8bb101913..f8c495ec18a69 100644 --- a/tests/rustdoc-gui/globals.goml +++ b/tests/rustdoc-gui/globals.goml @@ -10,7 +10,7 @@ assert-window-property: {"srcIndex": null} // Form input go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" -write: (".search-input", "Foo") +write-into: (".search-input", "Foo") press-key: 'Enter' wait-for: "#search-tabs" assert-window-property-false: {"searchIndex": null} diff --git a/tests/rustdoc-gui/go-to-collapsed-elem.goml b/tests/rustdoc-gui/go-to-collapsed-elem.goml index 80e9791775e47..e56e7ba08cd81 100644 --- a/tests/rustdoc-gui/go-to-collapsed-elem.goml +++ b/tests/rustdoc-gui/go-to-collapsed-elem.goml @@ -9,14 +9,14 @@ set-property: ("#implementations-list .implementors-toggle", {"open": "false"}) click: "//*[@class='sidebar']//a[@href='#method.must_use']" assert-property: ("#implementations-list .implementors-toggle", {"open": "true"}) -define-function: ("collapsed-from-search", (), block { +define-function: ("collapsed-from-search", [], block { // Now we do the same through search result. // First we reload the page without the anchor in the URL. go-to: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html" // Then we collapse the section again... set-property: ("#implementations-list .implementors-toggle", {"open": "false"}) // Then we run the search. - write: (".search-input", "foo::must_use") + write-into: (".search-input", "foo::must_use") wait-for: "//*[@id='search']//a[@href='../test_docs/struct.Foo.html#method.must_use']" click: "//*[@id='search']//a[@href='../test_docs/struct.Foo.html#method.must_use']" assert-property: ("#implementations-list .implementors-toggle", {"open": "true"}) diff --git a/tests/rustdoc-gui/headers-color.goml b/tests/rustdoc-gui/headers-color.goml index 80d11c9c849cf..2a181c0669fe9 100644 --- a/tests/rustdoc-gui/headers-color.goml +++ b/tests/rustdoc-gui/headers-color.goml @@ -2,7 +2,7 @@ define-function: ( "check-colors", - (theme, color, code_header_color, focus_background_color, headings_color), + [theme, color, code_header_color, focus_background_color, headings_color], block { go-to: "file://" + |DOC_PATH| + "/test_docs/struct.Foo.html" // This is needed so that the text color is computed. diff --git a/tests/rustdoc-gui/headings-anchor.goml b/tests/rustdoc-gui/headings-anchor.goml index f568caa3b07fe..9d52c2ac4b5c8 100644 --- a/tests/rustdoc-gui/headings-anchor.goml +++ b/tests/rustdoc-gui/headings-anchor.goml @@ -4,7 +4,7 @@ show-text: true define-function: ( "check-heading-anchor", - (heading_id), + [heading_id], block { // The anchor should not be displayed by default. assert-css: ("#" + |heading_id| + " .doc-anchor", { "display": "none" }) @@ -27,6 +27,6 @@ move-cursor-to: "#top-doc-prose-title" // to prevent it from overlapping with the `[-]` element. assert-css: ("#top-doc-prose-title:hover .doc-anchor", { "display": "none" }) -call-function: ("check-heading-anchor", ("top-doc-prose-sub-heading")) -call-function: ("check-heading-anchor", ("top-doc-prose-sub-sub-heading")) -call-function: ("check-heading-anchor", ("you-know-the-drill")) +call-function: ("check-heading-anchor", {"heading_id": "top-doc-prose-sub-heading"}) +call-function: ("check-heading-anchor", {"heading_id": "top-doc-prose-sub-sub-heading"}) +call-function: ("check-heading-anchor", {"heading_id": "you-know-the-drill"}) diff --git a/tests/rustdoc-gui/headings.goml b/tests/rustdoc-gui/headings.goml index 102b699b1dd1d..cdc61e36be200 100644 --- a/tests/rustdoc-gui/headings.goml +++ b/tests/rustdoc-gui/headings.goml @@ -156,7 +156,7 @@ go-to: "file://" + |DOC_PATH| + "/test_docs/struct.HeavilyDocumentedStruct.html" define-function: ( "check-colors", - (theme, heading_color, small_heading_color, heading_border_color), + [theme, heading_color, small_heading_color, heading_border_color], block { set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} reload: @@ -220,7 +220,7 @@ call-function: ( define-function: ( "check-since-color", - (theme), + [theme], block { set-local-storage: {"rustdoc-theme": |theme|} reload: @@ -229,6 +229,6 @@ define-function: ( ) go-to: "file://" + |DOC_PATH| + "/staged_api/struct.Foo.html" -call-function: ("check-since-color", ("ayu")) -call-function: ("check-since-color", ("dark")) -call-function: ("check-since-color", ("light")) +call-function: ("check-since-color", {"theme": "ayu"}) +call-function: ("check-since-color", {"theme": "dark"}) +call-function: ("check-since-color", {"theme": "light"}) diff --git a/tests/rustdoc-gui/help-page.goml b/tests/rustdoc-gui/help-page.goml index 84c20355500ab..9a7247a737ba9 100644 --- a/tests/rustdoc-gui/help-page.goml +++ b/tests/rustdoc-gui/help-page.goml @@ -7,17 +7,17 @@ assert-css: ("#help dd", {"font-size": "16px"}) click: "#help-button > a" assert-css: ("#help", {"display": "block"}) compare-elements-property: (".sub", "#help", ["offsetWidth"]) -compare-elements-position: (".sub", "#help", ("x")) +compare-elements-position: (".sub", "#help", ["x"]) set-window-size: (500, 1000) // Try mobile next. assert-css: ("#help", {"display": "block"}) compare-elements-property: (".sub", "#help", ["offsetWidth"]) -compare-elements-position: (".sub", "#help", ("x")) +compare-elements-position: (".sub", "#help", ["x"]) // Checking the color of the elements of the help menu. show-text: true define-function: ( "check-colors", - (theme, color, background, box_shadow), + [theme, color, background, box_shadow], block { // Setting the theme. set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} @@ -60,7 +60,7 @@ assert-css: ("#help dd", {"font-size": "16px"}) click: "#help-button > a" assert-css: ("#help", {"display": "none"}) compare-elements-property-false: (".sub", "#help", ["offsetWidth"]) -compare-elements-position-false: (".sub", "#help", ("x")) +compare-elements-position-false: (".sub", "#help", ["x"]) // This test ensures that the "the rustdoc book" anchor link within the help popover works. go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" diff --git a/tests/rustdoc-gui/highlight-colors.goml b/tests/rustdoc-gui/highlight-colors.goml index d162674fa6976..48bef319d42f8 100644 --- a/tests/rustdoc-gui/highlight-colors.goml +++ b/tests/rustdoc-gui/highlight-colors.goml @@ -4,7 +4,7 @@ show-text: true define-function: ( "check-colors", - ( + [ theme, kw, kw2, @@ -20,7 +20,7 @@ define-function: ( question_mark, comment, doc_comment, - ), + ], block { set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} reload: diff --git a/tests/rustdoc-gui/item-decl-colors.goml b/tests/rustdoc-gui/item-decl-colors.goml index 7bbd20c4ee006..e68d206a51181 100644 --- a/tests/rustdoc-gui/item-decl-colors.goml +++ b/tests/rustdoc-gui/item-decl-colors.goml @@ -6,7 +6,7 @@ fail-on-request-error: false define-function: ( "check-colors", - ( + [ theme, attr_color, trait_color, @@ -16,7 +16,7 @@ define-function: ( constant_color, fn_color, assoc_type_color, - ), + ], block { go-to: "file://" + |DOC_PATH| + "/test_docs/struct.WithGenerics.html" show-text: true diff --git a/tests/rustdoc-gui/item-decl-comment-highlighting.goml b/tests/rustdoc-gui/item-decl-comment-highlighting.goml index 60772693d6c5c..056b6a5b1e811 100644 --- a/tests/rustdoc-gui/item-decl-comment-highlighting.goml +++ b/tests/rustdoc-gui/item-decl-comment-highlighting.goml @@ -4,7 +4,7 @@ show-text: true define-function: ( "check-item-decl-comment", - (theme, url, comment_color), + [theme, url, comment_color], block { go-to: |url| set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} @@ -15,7 +15,7 @@ define-function: ( define-function: ( "check-items-for-theme", - (theme, comment_color), + [theme, comment_color], block { call-function: ("check-item-decl-comment", { "theme": |theme|, diff --git a/tests/rustdoc-gui/item-info-alignment.goml b/tests/rustdoc-gui/item-info-alignment.goml index 6fc365d1f1942..cd0624056b9a1 100644 --- a/tests/rustdoc-gui/item-info-alignment.goml +++ b/tests/rustdoc-gui/item-info-alignment.goml @@ -4,7 +4,7 @@ go-to: "file://" + |DOC_PATH| + "/lib2/struct.ItemInfoAlignmentTest.html" // First, we try it in "desktop" mode. set-window-size: (1200, 870) -compare-elements-position: (".impl-items > .item-info", "summary > .item-info", ("x")) +compare-elements-position: (".impl-items > .item-info", "summary > .item-info", ["x"]) // Next, we try it in "mobile" mode (max-width: 700px). set-window-size: (650, 650) -compare-elements-position: (".impl-items > .item-info", "summary > .item-info", ("x")) +compare-elements-position: (".impl-items > .item-info", "summary > .item-info", ["x"]) diff --git a/tests/rustdoc-gui/item-info.goml b/tests/rustdoc-gui/item-info.goml index b46d4255ee519..1eb46e832b70b 100644 --- a/tests/rustdoc-gui/item-info.goml +++ b/tests/rustdoc-gui/item-info.goml @@ -31,13 +31,13 @@ assert-count: ("#main-content > .item-info .stab", 2) compare-elements-position-false: ( "#main-content > .item-info .stab:nth-of-type(1)", "#main-content > .item-info .stab:nth-of-type(2)", - ("y"), + ["y"], ) // But they should have the same `x` position. compare-elements-position: ( "#main-content > .item-info .stab:nth-of-type(1)", "#main-content > .item-info .stab:nth-of-type(2)", - ("x"), + ["x"], ) // They are supposed to have the same height too. compare-elements-css: ( diff --git a/tests/rustdoc-gui/jump-to-def-background.goml b/tests/rustdoc-gui/jump-to-def-background.goml index fa7ed3586dd52..ae9c0c560cf30 100644 --- a/tests/rustdoc-gui/jump-to-def-background.goml +++ b/tests/rustdoc-gui/jump-to-def-background.goml @@ -3,7 +3,7 @@ go-to: "file://" + |DOC_PATH| + "/src/link_to_definition/lib.rs.html" define-function: ( "check-background-color", - (theme, background_color), + [theme, background_color], block { // Set the theme. set-local-storage: { "rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false" } @@ -17,6 +17,15 @@ define-function: ( }, ) -call-function: ("check-background-color", ("ayu", "#333")) -call-function: ("check-background-color", ("dark", "#333")) -call-function: ("check-background-color", ("light", "#eee")) +call-function: ("check-background-color", { + "theme": "ayu", + "background_color": "#333", +}) +call-function: ("check-background-color", { + "theme": "dark", + "background_color": "#333", +}) +call-function: ("check-background-color", { + "theme": "light", + "background_color": "#eee", +}) diff --git a/tests/rustdoc-gui/label-next-to-symbol.goml b/tests/rustdoc-gui/label-next-to-symbol.goml index d23f9114d3616..9a7de60bf38e1 100644 --- a/tests/rustdoc-gui/label-next-to-symbol.goml +++ b/tests/rustdoc-gui/label-next-to-symbol.goml @@ -27,14 +27,14 @@ compare-elements-position-near: ( compare-elements-position: ( ".item-name .stab.deprecated", ".item-name .stab.portability", - ("y"), + ["y"], ) // Ensure no wrap compare-elements-position: ( "//*[@class='item-name']//a[text()='replaced_function']/..", "//*[@class='desc docblock-short'][text()='a thing with a label']", - ("y"), + ["y"], ) // Mobile view @@ -49,19 +49,19 @@ compare-elements-position-near: ( compare-elements-position: ( ".item-name .stab.deprecated", ".item-name .stab.portability", - ("y"), + ["y"], ) // Ensure wrap compare-elements-position-false: ( "//*[@class='item-name']//a[text()='replaced_function']/..", "//*[@class='desc docblock-short'][text()='a thing with a label']", - ("y"), + ["y"], ) compare-elements-position-false: ( ".item-name .stab.deprecated", "//*[@class='desc docblock-short'][text()='a thing with a label']", - ("y"), + ["y"], ) // Ensure it doesn't expand. @@ -72,5 +72,5 @@ go-to: "file://" + |DOC_PATH| + "/test_docs/cfgs/index.html" compare-elements-position-false: ( "//*[@class='stab portability']/code[text()='appservice-api-c']", "//*[@class='stab portability']/code[text()='server']", - ("y"), + ["y"], ) diff --git a/tests/rustdoc-gui/links-color.goml b/tests/rustdoc-gui/links-color.goml index d88ebfb40d7a8..a1fb619a5d34c 100644 --- a/tests/rustdoc-gui/links-color.goml +++ b/tests/rustdoc-gui/links-color.goml @@ -6,8 +6,8 @@ show-text: true define-function: ( "check-colors", - (theme, mod, macro, struct, enum, trait, fn, type, union, keyword, - sidebar, sidebar_current, sidebar_current_background), + [theme, mod, macro, struct, enum, trait, fn, type, union, keyword, + sidebar, sidebar_current, sidebar_current_background], block { set-local-storage: { "rustdoc-theme": |theme|, diff --git a/tests/rustdoc-gui/notable-trait.goml b/tests/rustdoc-gui/notable-trait.goml index e10bb538f0780..0b1c6622596a1 100644 --- a/tests/rustdoc-gui/notable-trait.goml +++ b/tests/rustdoc-gui/notable-trait.goml @@ -7,13 +7,13 @@ set-window-size: (1100, 600) compare-elements-position: ( "//*[@id='method.create_an_iterator_from_read']//a[text()='NotableStructWithLongName']", "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", - ("y"), + ["y"], ) // Checking they don't have the same x position. compare-elements-position-false: ( "//*[@id='method.create_an_iterator_from_read']//a[text()='NotableStructWithLongName']", "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", - ("x"), + ["x"], ) // The `i` should be *after* the type. assert-position: ( @@ -37,7 +37,7 @@ compare-elements-position-near: ( compare-elements-position-false: ( "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", "//*[@class='tooltip popover']", - ("x") + ["x"] ) click: "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']" move-cursor-to: "//h1" @@ -48,7 +48,7 @@ set-window-size: (1055, 600) compare-elements-position-false: ( "//*[@id='method.create_an_iterator_from_read']//a[text()='NotableStructWithLongName']", "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", - ("y", "x"), + ["y", "x"], ) // Now both the `i` and the struct name should be on the next line. @@ -57,13 +57,13 @@ set-window-size: (980, 600) compare-elements-position: ( "//*[@id='method.create_an_iterator_from_read']//a[text()='NotableStructWithLongName']", "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", - ("y"), + ["y"], ) // Checking they don't have the same x position. compare-elements-position-false: ( "//*[@id='method.create_an_iterator_from_read']//a[text()='NotableStructWithLongName']", "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", - ("x"), + ["x"], ) // The `i` should be *after* the type. assert-position: ( @@ -81,13 +81,13 @@ set-window-size: (650, 600) compare-elements-position: ( "//*[@id='method.create_an_iterator_from_read']//a[text()='NotableStructWithLongName']", "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", - ("y"), + ["y"], ) // Checking they don't have the same x position. compare-elements-position-false: ( "//*[@id='method.create_an_iterator_from_read']//a[text()='NotableStructWithLongName']", "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", - ("x"), + ["x"], ) // The `i` should be *after* the type. assert-position: ( @@ -109,7 +109,7 @@ compare-elements-position-near: ( compare-elements-position-false: ( "//*[@id='method.create_an_iterator_from_read']//*[@class='tooltip']", "//*[@class='tooltip popover']", - ("x") + ["x"] ) assert-position: ( "//*[@class='tooltip popover']", @@ -122,7 +122,7 @@ assert-count: ("//*[@class='tooltip popover']", 0) // Now check the colors. define-function: ( "check-colors", - (theme, header_color, content_color, type_color, trait_color, link_color), + [theme, header_color, content_color, type_color, trait_color, link_color], block { go-to: "file://" + |DOC_PATH| + "/test_docs/struct.NotableStructWithLongName.html" // This is needed to ensure that the text color is computed. diff --git a/tests/rustdoc-gui/pocket-menu.goml b/tests/rustdoc-gui/pocket-menu.goml index 404e574030591..b16150cd0d368 100644 --- a/tests/rustdoc-gui/pocket-menu.goml +++ b/tests/rustdoc-gui/pocket-menu.goml @@ -31,7 +31,7 @@ assert-css: ("#settings-menu .popover", {"display": "none"}) define-function: ( "check-popover-colors", - (theme, border_color), + [theme, border_color], block { set-local-storage: { "rustdoc-theme": |theme|, diff --git a/tests/rustdoc-gui/run-on-hover.goml b/tests/rustdoc-gui/run-on-hover.goml index 1f87febcec6b6..19b15afbac3ca 100644 --- a/tests/rustdoc-gui/run-on-hover.goml +++ b/tests/rustdoc-gui/run-on-hover.goml @@ -7,7 +7,7 @@ show-text: true define-function: ( "check-run-button", - (theme, color, background, hover_color, hover_background), + [theme, color, background, hover_color, hover_background], block { set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} reload: diff --git a/tests/rustdoc-gui/rust-logo.goml b/tests/rustdoc-gui/rust-logo.goml index dcf3d6bab6382..a3b420e5eb92c 100644 --- a/tests/rustdoc-gui/rust-logo.goml +++ b/tests/rustdoc-gui/rust-logo.goml @@ -3,7 +3,7 @@ go-to: "file://" + |DOC_PATH| + "/staged_api/index.html" define-function: ( "check-logo", - (theme, filter), + [theme, filter], block { // Going to the doc page. go-to: "file://" + |DOC_PATH| + "/staged_api/index.html" diff --git a/tests/rustdoc-gui/scrape-examples-color.goml b/tests/rustdoc-gui/scrape-examples-color.goml index 0052d18dc560d..b1675a5f1fd7e 100644 --- a/tests/rustdoc-gui/scrape-examples-color.goml +++ b/tests/rustdoc-gui/scrape-examples-color.goml @@ -4,8 +4,8 @@ show-text: true define-function: ( "check-colors", - (theme, highlight, highlight_focus, help_border, help_color, help_hover_border, - help_hover_color), + [theme, highlight, highlight_focus, help_border, help_color, help_hover_border, + help_hover_color], block { set-local-storage: { "rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false", } reload: @@ -64,7 +64,7 @@ go-to: "file://" + |DOC_PATH| + "/scrape_examples/fn.test.html" define-function: ( "check-background", - (theme, background_color_start, background_color_end), + [theme, background_color_start, background_color_end], block { set-local-storage: { "rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false", } reload: diff --git a/tests/rustdoc-gui/scrape-examples-toggle.goml b/tests/rustdoc-gui/scrape-examples-toggle.goml index f742b3186e5b2..ea645d2892444 100644 --- a/tests/rustdoc-gui/scrape-examples-toggle.goml +++ b/tests/rustdoc-gui/scrape-examples-toggle.goml @@ -5,7 +5,7 @@ go-to: "file://" + |DOC_PATH| + "/scrape_examples/fn.test_many.html" show-text: true define-function: ( "check-color", - (theme, toggle_line_color, toggle_line_hover_color), + [theme, toggle_line_color, toggle_line_hover_color], block { set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} reload: diff --git a/tests/rustdoc-gui/search-corrections.goml b/tests/rustdoc-gui/search-corrections.goml index aeb3c9b31a3fd..b81b1f382a957 100644 --- a/tests/rustdoc-gui/search-corrections.goml +++ b/tests/rustdoc-gui/search-corrections.goml @@ -4,7 +4,7 @@ // First, try a search-by-name go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" // Intentionally wrong spelling of "NotableStructWithLongName" -write: (".search-input", "NotableStructWithLongNamr") +write-into: (".search-input", "NotableStructWithLongNamr") // To be SURE that the search will be run. press-key: 'Enter' // Waiting for the search results to appear... @@ -41,7 +41,7 @@ assert-text: ( // Now, explicit return values go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" // Intentionally wrong spelling of "NotableStructWithLongName" -write: (".search-input", "-> NotableStructWithLongNamr") +write-into: (".search-input", "-> NotableStructWithLongNamr") // To be SURE that the search will be run. press-key: 'Enter' // Waiting for the search results to appear... @@ -58,7 +58,7 @@ assert-text: ( // Now, generic correction go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" // Intentionally wrong spelling of "NotableStructWithLongName" -write: (".search-input", "NotableStructWithLongNamr, NotableStructWithLongNamr") +write-into: (".search-input", "NotableStructWithLongNamr, NotableStructWithLongNamr") // To be SURE that the search will be run. press-key: 'Enter' // Waiting for the search results to appear... @@ -75,7 +75,7 @@ assert-text: ( // Now, generic correction plus error go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" // Intentionally wrong spelling of "NotableStructWithLongName" -write: (".search-input", "Foo,y") +write-into: (".search-input", "Foo,y") // To be SURE that the search will be run. press-key: 'Enter' // Waiting for the search results to appear... @@ -91,7 +91,7 @@ assert-text: ( go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" // Intentionally wrong spelling of "NotableStructWithLongName" -write: (".search-input", "generic:NotableStructWithLongNamr,y") +write-into: (".search-input", "generic:NotableStructWithLongNamr,y") // To be SURE that the search will be run. press-key: 'Enter' // Waiting for the search results to appear... diff --git a/tests/rustdoc-gui/search-error.goml b/tests/rustdoc-gui/search-error.goml index 70aeda1769aee..d3de77b5635ca 100644 --- a/tests/rustdoc-gui/search-error.goml +++ b/tests/rustdoc-gui/search-error.goml @@ -4,7 +4,7 @@ show-text: true define-function: ( "check-colors", - (theme, error_background), + [theme, error_background], block { // Setting the theme. set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} diff --git a/tests/rustdoc-gui/search-filter.goml b/tests/rustdoc-gui/search-filter.goml index 9e2855b5e02f9..8c50322fcd4e4 100644 --- a/tests/rustdoc-gui/search-filter.goml +++ b/tests/rustdoc-gui/search-filter.goml @@ -1,7 +1,7 @@ // Checks that the crate search filtering is handled correctly and changes the results. go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" show-text: true -write: (".search-input", "test") +write-into: (".search-input", "test") // To be SURE that the search will be run. press-key: 'Enter' // Waiting for the search results to appear... diff --git a/tests/rustdoc-gui/search-form-elements.goml b/tests/rustdoc-gui/search-form-elements.goml index 0ea61a4f0eb86..2fc66259291cd 100644 --- a/tests/rustdoc-gui/search-form-elements.goml +++ b/tests/rustdoc-gui/search-form-elements.goml @@ -4,10 +4,10 @@ show-text: true define-function: ( "check-search-colors", - ( + [ theme, border, background, search_input_color, search_input_border_focus, menu_button_border, menu_button_a_color, menu_button_a_border_hover, menu_a_color, - ), + ], block { set-local-storage: { "rustdoc-theme": |theme|, diff --git a/tests/rustdoc-gui/search-keyboard.goml b/tests/rustdoc-gui/search-keyboard.goml index f1d8024616bba..707bb8f5faa82 100644 --- a/tests/rustdoc-gui/search-keyboard.goml +++ b/tests/rustdoc-gui/search-keyboard.goml @@ -1,7 +1,7 @@ // Checks that the search tab results work correctly with function signature syntax // First, try a search-by-name go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" -write: (".search-input", "Foo") +write-into: (".search-input", "Foo") // To be SURE that the search will be run. press-key: 'Enter' // Waiting for the search results to appear... diff --git a/tests/rustdoc-gui/search-no-result.goml b/tests/rustdoc-gui/search-no-result.goml index e7c6479125633..dda50ec3fb64b 100644 --- a/tests/rustdoc-gui/search-no-result.goml +++ b/tests/rustdoc-gui/search-no-result.goml @@ -4,7 +4,7 @@ show-text: true define-function: ( "check-no-result", - (theme, link, link_hover), + [theme, link, link_hover], block { // Changing theme. set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} diff --git a/tests/rustdoc-gui/search-reexport.goml b/tests/rustdoc-gui/search-reexport.goml index b9d2c8f15cee1..2e7c967d5c333 100644 --- a/tests/rustdoc-gui/search-reexport.goml +++ b/tests/rustdoc-gui/search-reexport.goml @@ -6,7 +6,7 @@ reload: // First we check that the reexport has the correct ID and no background color. assert-text: ("//*[@id='reexport.TheStdReexport']", "pub use ::std as TheStdReexport;") assert-css: ("//*[@id='reexport.TheStdReexport']", {"background-color": "rgba(0, 0, 0, 0)"}) -write: (".search-input", "TheStdReexport") +write-into: (".search-input", "TheStdReexport") // To be SURE that the search will be run. press-key: 'Enter' wait-for: "//a[@class='result-import']" @@ -22,7 +22,7 @@ wait-for-css: ("//*[@id='reexport.TheStdReexport']", {"background-color": "#494a // We now check that the alias is working as well on the reexport. // To be SURE that the search will be run. press-key: 'Enter' -write: (".search-input", "AliasForTheStdReexport") +write-into: (".search-input", "AliasForTheStdReexport") wait-for: "//a[@class='result-import']" assert-text: ( "a.result-import .result-name", diff --git a/tests/rustdoc-gui/search-result-color.goml b/tests/rustdoc-gui/search-result-color.goml index 44677dfbfef43..1a19ea2d84327 100644 --- a/tests/rustdoc-gui/search-result-color.goml +++ b/tests/rustdoc-gui/search-result-color.goml @@ -2,7 +2,7 @@ define-function: ( "check-result-color", - (result_kind, color, hover_color), + [result_kind, color, hover_color], block { assert-css: (".result-" + |result_kind| + " ." + |result_kind|, {"color": |color|}, ALL) assert-css: ( @@ -78,60 +78,60 @@ store-value: (hover_background_color, "#3c3c3c") // hover background color store-value: (grey, "#999") call-function: ( - "check-result-color", ( - "keyword", // item kind - "#39afd7", // color of item kind - "#39afd7", // color of hovered/focused item kind - ), + "check-result-color", { + "result_kind": "keyword", + "color": "#39afd7", + "hover_color": "#39afd7", + }, ) call-function: ( - "check-result-color", ( - "struct", // item kind - "#ffa0a5", // color of item kind - "#ffa0a5", // color of hovered/focused item kind - ), + "check-result-color", { + "result_kind": "struct", + "color": "#ffa0a5", + "hover_color": "#ffa0a5", + }, ) call-function: ( - "check-result-color", ( - "associatedtype", // item kind - "#39afd7", // color of item kind - "#39afd7", // color of hovered/focused item kind - ), + "check-result-color", { + "result_kind": "associatedtype", + "color": "#39afd7", + "hover_color": "#39afd7", + }, ) call-function: ( - "check-result-color", ( - "tymethod", // item kind - "#fdd687", // color of item kind - "#fdd687", // color of hovered/focused item kind - ), + "check-result-color", { + "result_kind": "tymethod", + "color": "#fdd687", + "hover_color": "#fdd687", + }, ) call-function: ( - "check-result-color", ( - "method", // item kind - "#fdd687", // color of item kind - "#fdd687", // color of hovered/focused item kind - ), + "check-result-color", { + "result_kind": "method", + "color": "#fdd687", + "hover_color": "#fdd687", + }, ) call-function: ( - "check-result-color", ( - "structfield", // item kind - "#0096cf", // color of item kind - "#fff", // color of hovered/focused item kind - ), + "check-result-color", { + "result_kind": "structfield", + "color": "#0096cf", + "hover_color": "#fff", + }, ) call-function: ( - "check-result-color", ( - "macro", // item kind - "#a37acc", // color of item kind - "#a37acc", // color of hovered/focused item kind - ), + "check-result-color", { + "result_kind": "macro", + "color": "#a37acc", + "hover_color": "#a37acc", + }, ) call-function: ( - "check-result-color", ( - "fn", // item kind - "#fdd687", // color of item kind - "#fdd687", // color of hovered/focused item kind - ), + "check-result-color", { + "result_kind": "fn", + "color": "#fdd687", + "hover_color": "#fdd687", + }, ) // Checking the `` container. @@ -190,60 +190,60 @@ store-value: (hover_background_color, "#616161") // hover background color store-value: (grey, "#ccc") call-function: ( - "check-result-color", ( - "keyword", // item kind - "#d2991d", // color of item kind - "#d2991d", // color of hovered/focused item kind - ), + "check-result-color", { + "result_kind": "keyword", + "color": "#d2991d", + "hover_color": "#d2991d", + }, ) call-function: ( - "check-result-color", ( - "struct", // item kind - "#2dbfb8", // color of item kind - "#2dbfb8", // color of hovered/focused item kind - ), + "check-result-color", { + "result_kind": "struct", + "color": "#2dbfb8", + "hover_color": "#2dbfb8", + }, ) call-function: ( - "check-result-color", ( - "associatedtype", // item kind - "#d2991d", // color of item kind - "#d2991d", // color of hovered/focused item kind - ), + "check-result-color", { + "result_kind": "associatedtype", + "color": "#d2991d", + "hover_color": "#d2991d", + }, ) call-function: ( - "check-result-color", ( - "tymethod", // item kind - "#2bab63", // color of item kind - "#2bab63", // color of hovered/focused item kind - ), + "check-result-color", { + "result_kind": "tymethod", + "color": "#2bab63", + "hover_color": "#2bab63", + }, ) call-function: ( - "check-result-color", ( - "method", // item kind - "#2bab63", // color of item kind - "#2bab63", // color of hovered/focused item kind - ), + "check-result-color", { + "result_kind": "method", + "color": "#2bab63", + "hover_color": "#2bab63", + }, ) call-function: ( - "check-result-color", ( - "structfield", // item kind - "#ddd", // color of item kind - "#ddd", // color of hovered/focused item kind - ), + "check-result-color", { + "result_kind": "structfield", + "color": "#ddd", + "hover_color": "#ddd", + }, ) call-function: ( - "check-result-color", ( - "macro", // item kind - "#09bd00", // color of item kind - "#09bd00", // color of hovered/focused item kind - ), + "check-result-color", { + "result_kind": "macro", + "color": "#09bd00", + "hover_color": "#09bd00", + }, ) call-function: ( - "check-result-color", ( - "fn", // item kind - "#2bab63", // color of item kind - "#2bab63", // color of hovered/focused item kind - ), + "check-result-color", { + "result_kind": "fn", + "color": "#2bab63", + "hover_color": "#2bab63", + }, ) // Checking the `` container. @@ -287,60 +287,60 @@ store-value: (hover_background_color, "#ccc") // hover background color store-value: (grey, "#999") call-function: ( - "check-result-color", ( - "keyword", // item kind - "#3873ad", // color of item kind - "#3873ad", // color of hovered/focused item kind - ), + "check-result-color", { + "result_kind": "keyword", + "color": "#3873ad", + "hover_color": "#3873ad", + }, ) call-function: ( - "check-result-color", ( - "struct", // item kind - "#ad378a", // color of item kind - "#ad378a", // color of hovered/focused item kind - ), + "check-result-color", { + "result_kind": "struct", + "color": "#ad378a", + "hover_color": "#ad378a", + }, ) call-function: ( - "check-result-color", ( - "associatedtype", // item kind - "#3873ad", // color of item kind - "#3873ad", // color of hovered/focused item kind - ), + "check-result-color", { + "result_kind": "associatedtype", + "color": "#3873ad", + "hover_color": "#3873ad", + }, ) call-function: ( - "check-result-color", ( - "tymethod", // item kind - "#ad7c37", // color of item kind - "#ad7c37", // color of hovered/focused item kind - ), + "check-result-color", { + "result_kind": "tymethod", + "color": "#ad7c37", + "hover_color": "#ad7c37", + }, ) call-function: ( - "check-result-color", ( - "method", // item kind - "#ad7c37", // color of item kind - "#ad7c37", // color of hovered/focused item kind - ), + "check-result-color", { + "result_kind": "method", + "color": "#ad7c37", + "hover_color": "#ad7c37", + }, ) call-function: ( - "check-result-color", ( - "structfield", // item kind - "#000", // color of item kind - "#000", // color of hovered/focused item kind - ), + "check-result-color", { + "result_kind": "structfield", + "color": "#000", + "hover_color": "#000", + }, ) call-function: ( - "check-result-color", ( - "macro", // item kind - "#068000", // color of item kind - "#068000", // color of hovered/focused item kind - ), + "check-result-color", { + "result_kind": "macro", + "color": "#068000", + "hover_color": "#068000", + }, ) call-function: ( - "check-result-color", ( - "fn", // item kind - "#ad7c37", // color of item kind - "#ad7c37", // color of hovered/focused item kind - ), + "check-result-color", { + "result_kind": "fn", + "color": "#ad7c37", + "hover_color": "#ad7c37", + }, ) // Checking the `` container. @@ -358,11 +358,11 @@ show-text: true define-function: ( "check-alias", - (theme, alias, grey), + [theme, alias, grey], block { set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} reload: - write: (".search-input", "thisisanalias") + write-into: (".search-input", "thisisanalias") // To be SURE that the search will be run. press-key: 'Enter' // Waiting for the search results to appear... diff --git a/tests/rustdoc-gui/search-result-display.goml b/tests/rustdoc-gui/search-result-display.goml index 6ce13b8c3d30f..b1a5548808e01 100644 --- a/tests/rustdoc-gui/search-result-display.goml +++ b/tests/rustdoc-gui/search-result-display.goml @@ -2,7 +2,7 @@ // Checks that the search results have the expected width. go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" set-window-size: (900, 1000) -write: (".search-input", "test") +write-into: (".search-input", "test") // To be SURE that the search will be run. press-key: 'Enter' wait-for: "#crate-search" @@ -69,7 +69,7 @@ assert-css: ("#search", {"width": "640px"}) show-text: true define-function: ( "check-filter", - (theme, border, filter, hover_border, hover_filter), + [theme, border, filter, hover_border, hover_filter], block { set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} reload: diff --git a/tests/rustdoc-gui/search-result-impl-disambiguation.goml b/tests/rustdoc-gui/search-result-impl-disambiguation.goml index 6d12032e891b6..3e49ac33025ee 100644 --- a/tests/rustdoc-gui/search-result-impl-disambiguation.goml +++ b/tests/rustdoc-gui/search-result-impl-disambiguation.goml @@ -5,7 +5,7 @@ go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" // This should link to the inherent impl -write: (".search-input", "ZyxwvutMethodDisambiguation -> bool") +write-into: (".search-input", "ZyxwvutMethodDisambiguation -> bool") // To be SURE that the search will be run. press-key: 'Enter' // Waiting for the search results to appear... @@ -25,7 +25,7 @@ assert: "section:target" go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" // This should link to the trait impl -write: (".search-input", "ZyxwvutMethodDisambiguation, usize -> usize") +write-into: (".search-input", "ZyxwvutMethodDisambiguation, usize -> usize") // To be SURE that the search will be run. press-key: 'Enter' // Waiting for the search results to appear... diff --git a/tests/rustdoc-gui/search-result-keyword.goml b/tests/rustdoc-gui/search-result-keyword.goml index 1b2be6d4e3e22..370edce2ddd04 100644 --- a/tests/rustdoc-gui/search-result-keyword.goml +++ b/tests/rustdoc-gui/search-result-keyword.goml @@ -1,6 +1,6 @@ // Checks that the "keyword" results have the expected text alongside them. go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" -write: (".search-input", "CookieMonster") +write-into: (".search-input", "CookieMonster") // To be SURE that the search will be run. press-key: 'Enter' // Waiting for the search results to appear... diff --git a/tests/rustdoc-gui/search-tab-change-title-fn-sig.goml b/tests/rustdoc-gui/search-tab-change-title-fn-sig.goml index 156d8d03ca2d1..7e26229ec6e51 100644 --- a/tests/rustdoc-gui/search-tab-change-title-fn-sig.goml +++ b/tests/rustdoc-gui/search-tab-change-title-fn-sig.goml @@ -1,7 +1,7 @@ // Checks that the search tab results work correctly with function signature syntax // First, try a search-by-name go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" -write: (".search-input", "Foo") +write-into: (".search-input", "Foo") // To be SURE that the search will be run. press-key: 'Enter' // Waiting for the search results to appear... @@ -23,7 +23,7 @@ wait-for-attribute: ("#search-tabs > button:nth-of-type(3)", {"class": "selected // Now try search-by-return go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" -write: (".search-input", "-> String") +write-into: (".search-input", "-> String") // To be SURE that the search will be run. press-key: 'Enter' // Waiting for the search results to appear... @@ -45,7 +45,7 @@ wait-for-attribute: ("#search-tabs > button:nth-of-type(1)", {"class": "selected // Try with a search-by-return with no results go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" -write: (".search-input", "-> Something") +write-into: (".search-input", "-> Something") // To be SURE that the search will be run. press-key: 'Enter' // Waiting for the search results to appear... @@ -55,7 +55,7 @@ assert-text: ("#search-tabs > button:nth-of-type(1)", "In Function Return Types" // Try with a search-by-parameter go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" -write: (".search-input", "usize,pattern") +write-into: (".search-input", "usize,pattern") // To be SURE that the search will be run. press-key: 'Enter' // Waiting for the search results to appear... @@ -65,7 +65,7 @@ assert-text: ("#search-tabs > button:nth-of-type(1)", "In Function Parameters", // Try with a search-by-parameter-and-return go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" -write: (".search-input", "pattern -> str") +write-into: (".search-input", "pattern -> str") // To be SURE that the search will be run. press-key: 'Enter' // Waiting for the search results to appear... diff --git a/tests/rustdoc-gui/search-tab.goml b/tests/rustdoc-gui/search-tab.goml index b52bb0688c1b5..c33866593c355 100644 --- a/tests/rustdoc-gui/search-tab.goml +++ b/tests/rustdoc-gui/search-tab.goml @@ -4,9 +4,9 @@ show-text: true define-function: ( "check-colors", - (theme, background, background_selected, background_hover, border_bottom, + [theme, background, background_selected, background_hover, border_bottom, border_bottom_selected, border_bottom_hover, border_top, border_top_selected, - border_top_hover), + border_top_hover], block { // Setting the theme. set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} @@ -93,12 +93,12 @@ assert-property: ("#search-tabs > button:nth-child(3) > .count", {"offsetWidth": compare-elements-position: ( "#search-tabs > button:nth-child(1) > .count", "#search-tabs > button:nth-child(2) > .count", - ("y") + ["y"] ) compare-elements-position: ( "#search-tabs > button:nth-child(2) > .count", "#search-tabs > button:nth-child(3) > .count", - ("y") + ["y"] ) // Check that counts are beside the titles and haven't wrapped compare-elements-position-near: ( @@ -135,12 +135,12 @@ assert-property: ("#search-tabs > button:nth-child(3) > .count", {"offsetWidth": compare-elements-position: ( "#search-tabs > button:nth-child(1) > .count", "#search-tabs > button:nth-child(2) > .count", - ("y") + ["y"] ) compare-elements-position: ( "#search-tabs > button:nth-child(2) > .count", "#search-tabs > button:nth-child(3) > .count", - ("y") + ["y"] ) // Check that counts are NOT beside the titles; now they have wrapped compare-elements-position-near-false: ( diff --git a/tests/rustdoc-gui/setting-auto-hide-content-large-items.goml b/tests/rustdoc-gui/setting-auto-hide-content-large-items.goml index b55a1cfd92bc5..9afde7c61da69 100644 --- a/tests/rustdoc-gui/setting-auto-hide-content-large-items.goml +++ b/tests/rustdoc-gui/setting-auto-hide-content-large-items.goml @@ -6,7 +6,7 @@ fail-on-request-error: false define-function: ( "check-setting", - (storage_value, setting_attribute_value, toggle_attribute_value), + [storage_value, setting_attribute_value, toggle_attribute_value], block { assert-local-storage: {"rustdoc-auto-hide-large-items": |storage_value|} click: "#settings-menu" diff --git a/tests/rustdoc-gui/setting-auto-hide-item-methods-docs.goml b/tests/rustdoc-gui/setting-auto-hide-item-methods-docs.goml index 5210ad8f793b1..644396ed57826 100644 --- a/tests/rustdoc-gui/setting-auto-hide-item-methods-docs.goml +++ b/tests/rustdoc-gui/setting-auto-hide-item-methods-docs.goml @@ -3,7 +3,7 @@ define-function: ( "check-setting", - (storage_value, setting_attribute_value, toggle_attribute_value), + [storage_value, setting_attribute_value, toggle_attribute_value], block { assert-local-storage: {"rustdoc-auto-hide-method-docs": |storage_value|} click: "#settings-menu" diff --git a/tests/rustdoc-gui/setting-auto-hide-trait-implementations.goml b/tests/rustdoc-gui/setting-auto-hide-trait-implementations.goml index ecadd8fa80ede..3c09198dae509 100644 --- a/tests/rustdoc-gui/setting-auto-hide-trait-implementations.goml +++ b/tests/rustdoc-gui/setting-auto-hide-trait-implementations.goml @@ -2,7 +2,7 @@ define-function: ( "check-setting", - (storage_value, setting_attribute_value, toggle_attribute_value), + [storage_value, setting_attribute_value, toggle_attribute_value], block { assert-local-storage: {"rustdoc-auto-hide-trait-implementations": |storage_value|} click: "#settings-menu" diff --git a/tests/rustdoc-gui/setting-go-to-only-result.goml b/tests/rustdoc-gui/setting-go-to-only-result.goml index 45e0b349051ee..f8535477c22d0 100644 --- a/tests/rustdoc-gui/setting-go-to-only-result.goml +++ b/tests/rustdoc-gui/setting-go-to-only-result.goml @@ -2,7 +2,7 @@ define-function: ( "check-setting", - (storage_value, setting_attribute_value), + [storage_value, setting_attribute_value], block { assert-local-storage: {"rustdoc-go-to-only-result": |storage_value|} click: "#settings-menu" @@ -32,7 +32,7 @@ assert-local-storage: {"rustdoc-go-to-only-result": "true"} go-to: "file://" + |DOC_PATH| + "/lib2/index.html" // We enter it into the search. -write: (".search-input", "HasALongTraitWithParams") +write-into: (".search-input", "HasALongTraitWithParams") wait-for-document-property: {"title": "HasALongTraitWithParams in lib2 - Rust"} assert-window-property: ({"location": "/lib2/struct.HasALongTraitWithParams.html"}, ENDS_WITH) diff --git a/tests/rustdoc-gui/settings.goml b/tests/rustdoc-gui/settings.goml index e40c637dcf7dd..0bb21c28cb529 100644 --- a/tests/rustdoc-gui/settings.goml +++ b/tests/rustdoc-gui/settings.goml @@ -304,7 +304,7 @@ wait-for: "#settings" assert-css: (".setting-radio", {"cursor": "pointer"}) assert-attribute-false: ("#settings", {"class": "popover"}, CONTAINS) -compare-elements-position: (".sub form", "#settings", ("x")) +compare-elements-position: (".sub form", "#settings", ["x"]) // Check that setting-line has the same margin in this mode as in the popover. assert-css: (".setting-line", {"margin": |setting_line_margin|}) diff --git a/tests/rustdoc-gui/sidebar-links-color.goml b/tests/rustdoc-gui/sidebar-links-color.goml index 774fbcac1e2c4..0edffc51a816d 100644 --- a/tests/rustdoc-gui/sidebar-links-color.goml +++ b/tests/rustdoc-gui/sidebar-links-color.goml @@ -6,12 +6,12 @@ show-text: true define-function: ( "check-colors", - ( + [ theme, struct, struct_hover, struct_hover_background, enum, enum_hover, enum_hover_background, union, union_hover, union_hover_background, trait, trait_hover, trait_hover_background, fn, fn_hover, fn_hover_background, type, type_hover, type_hover_background, keyword, keyword_hover, keyword_hover_background, - ), + ], block { set-local-storage: { "rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false" } reload: diff --git a/tests/rustdoc-gui/sidebar-mobile.goml b/tests/rustdoc-gui/sidebar-mobile.goml index d3a82d9ebe6fc..8843de8d7e943 100644 --- a/tests/rustdoc-gui/sidebar-mobile.goml +++ b/tests/rustdoc-gui/sidebar-mobile.goml @@ -57,7 +57,7 @@ show-text: true define-function: ( "check-colors", - (theme, color, background), + [theme, color, background], block { set-local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": |theme|} reload: diff --git a/tests/rustdoc-gui/sidebar-source-code-display.goml b/tests/rustdoc-gui/sidebar-source-code-display.goml index 5149d4991f731..41c8e45f4a6d3 100644 --- a/tests/rustdoc-gui/sidebar-source-code-display.goml +++ b/tests/rustdoc-gui/sidebar-source-code-display.goml @@ -30,9 +30,9 @@ show-text: true define-function: ( "check-colors", - ( + [ theme, color, color_hover, background, background_hover, background_toggle, - ), + ], block { set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} reload: diff --git a/tests/rustdoc-gui/sidebar-source-code.goml b/tests/rustdoc-gui/sidebar-source-code.goml index d7de43a2243ab..3f7ef643d18e7 100644 --- a/tests/rustdoc-gui/sidebar-source-code.goml +++ b/tests/rustdoc-gui/sidebar-source-code.goml @@ -6,7 +6,7 @@ show-text: true // First, check the sidebar colors. define-function: ( "check-colors", - (theme, color, background_color), + [theme, color, background_color], block { set-local-storage: { "rustdoc-theme": |theme|, diff --git a/tests/rustdoc-gui/sidebar.goml b/tests/rustdoc-gui/sidebar.goml index 82b4f2e9429c6..115b1eb323c4d 100644 --- a/tests/rustdoc-gui/sidebar.goml +++ b/tests/rustdoc-gui/sidebar.goml @@ -6,7 +6,7 @@ show-text: true // First, check the sidebar colors. define-function: ( "check-colors", - (theme, color, background_color), + [theme, color, background_color], block { set-local-storage: { "rustdoc-theme": |theme|, diff --git a/tests/rustdoc-gui/source-code-page.goml b/tests/rustdoc-gui/source-code-page.goml index 8b4d7617e0cdb..e29d123d2270b 100644 --- a/tests/rustdoc-gui/source-code-page.goml +++ b/tests/rustdoc-gui/source-code-page.goml @@ -21,7 +21,7 @@ assert-attribute-false: (".src-line-numbers > a:nth-child(7)", {"class": "line-h define-function: ( "check-colors", - (theme, color, background_color, highlight_color, highlight_background_color), + [theme, color, background_color, highlight_color, highlight_background_color], block { set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} reload: @@ -61,7 +61,7 @@ call-function: ("check-colors", { }) // This is to ensure that the content is correctly align with the line numbers. -compare-elements-position: ("//*[@id='1']", ".rust > code > span", ("y")) +compare-elements-position: ("//*[@id='1']", ".rust > code > span", ["y"]) // Check the `href` property so that users can treat anchors as links. assert-property: (".src-line-numbers > a:nth-child(1)", { "href": |DOC_PATH| + "/src/test_docs/lib.rs.html#1" @@ -122,7 +122,7 @@ store-property: ( ) define-function: ( "check-sidebar-dir-entry", - (x, y), + [x, y], block { assert: "details:first-of-type.dir-entry[open] > summary::marker" assert-css: ("#src-sidebar > details:first-of-type.dir-entry", {"padding-left": "4px"}) diff --git a/tests/rustdoc-gui/stab-badge.goml b/tests/rustdoc-gui/stab-badge.goml index bb3d2aaa3dca0..46df0946c4592 100644 --- a/tests/rustdoc-gui/stab-badge.goml +++ b/tests/rustdoc-gui/stab-badge.goml @@ -3,7 +3,7 @@ go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" show-text: true define-function: ( "check-badge", - (theme, background, color), + [theme, background, color], block { set-local-storage: {"rustdoc-use-system-theme": "false", "rustdoc-theme": |theme|} go-to: "file://" + |DOC_PATH| + "/test_docs/index.html" diff --git a/tests/rustdoc-gui/target.goml b/tests/rustdoc-gui/target.goml index 26071df8d044e..0f8f770936356 100644 --- a/tests/rustdoc-gui/target.goml +++ b/tests/rustdoc-gui/target.goml @@ -7,7 +7,7 @@ assert: "#method\.a_method:target" define-function: ( "check-style", - (theme, background, border), + [theme, background, border], block { set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} reload: diff --git a/tests/rustdoc-gui/toggle-docs.goml b/tests/rustdoc-gui/toggle-docs.goml index 9ea6d9b18f4c7..cfd18bd2e14f3 100644 --- a/tests/rustdoc-gui/toggle-docs.goml +++ b/tests/rustdoc-gui/toggle-docs.goml @@ -49,7 +49,7 @@ assert-attribute: ("details.toggle", {"open": ""}, ALL) show-text: true define-function: ( "check-color", - (theme, filter), + [theme, filter], block { // Setting the theme. set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} diff --git a/tests/rustdoc-gui/type-declation-overflow.goml b/tests/rustdoc-gui/type-declation-overflow.goml index a97cc98897ae2..3709aa102661f 100644 --- a/tests/rustdoc-gui/type-declation-overflow.goml +++ b/tests/rustdoc-gui/type-declation-overflow.goml @@ -47,18 +47,18 @@ assert-css: (".mobile-topbar h2", {"overflow-x": "hidden"}) // On desktop, they wrap when too big. set-window-size: (1100, 800) go-to: "file://" + |DOC_PATH| + "/lib2/too_long/struct.SuperIncrediblyLongLongLongLongLongLongLongGigaGigaGigaMegaLongLongLongStructName.html" -compare-elements-position-false: (".main-heading h1", ".main-heading .out-of-band", ("y")) +compare-elements-position-false: (".main-heading h1", ".main-heading .out-of-band", ["y"]) go-to: "file://" + |DOC_PATH| + "/lib2/index.html" -compare-elements-position: (".main-heading h1", ".main-heading .out-of-band", ("y")) +compare-elements-position: (".main-heading h1", ".main-heading .out-of-band", ["y"]) // make sure there is a gap between them compare-elements-position-near-false: (".main-heading h1", ".main-heading .out-of-band", {"x": 550}) // On mobile, they always wrap. set-window-size: (600, 600) go-to: "file://" + |DOC_PATH| + "/lib2/too_long/struct.SuperIncrediblyLongLongLongLongLongLongLongGigaGigaGigaMegaLongLongLongStructName.html" -compare-elements-position-false: (".main-heading h1", ".main-heading .out-of-band", ("y")) +compare-elements-position-false: (".main-heading h1", ".main-heading .out-of-band", ["y"]) go-to: "file://" + |DOC_PATH| + "/lib2/index.html" -compare-elements-position-false: (".main-heading h1", ".main-heading .out-of-band", ("y")) +compare-elements-position-false: (".main-heading h1", ".main-heading .out-of-band", ["y"]) // Now we will check that the scrolling is working. // First on an item with "hidden methods". diff --git a/tests/rustdoc-gui/unsafe-fn.goml b/tests/rustdoc-gui/unsafe-fn.goml index 8d26f15f37f1b..83503121a0469 100644 --- a/tests/rustdoc-gui/unsafe-fn.goml +++ b/tests/rustdoc-gui/unsafe-fn.goml @@ -13,7 +13,7 @@ define-function: ( "sup-check", // `theme` is the theme being tested. // `color` is the expected color of the `` element. - (theme, color), + [theme, color], block { // Set the theme. set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} @@ -23,6 +23,15 @@ define-function: ( }, ) -call-function: ("sup-check", ("ayu", "#c5c5c5")) -call-function: ("sup-check", ("dark", "#ddd")) -call-function: ("sup-check", ("light", "black")) +call-function: ("sup-check", { + "theme": "ayu", + "color": "#c5c5c5", +}) +call-function: ("sup-check", { + "theme": "dark", + "color": "#ddd", +}) +call-function: ("sup-check", { + "theme": "light", + "color": "black", +}) diff --git a/tests/rustdoc-gui/warning-block.goml b/tests/rustdoc-gui/warning-block.goml index 10e206049f53c..a5a47f868db22 100644 --- a/tests/rustdoc-gui/warning-block.goml +++ b/tests/rustdoc-gui/warning-block.goml @@ -5,7 +5,7 @@ show-text: true store-value: (default_y_pos, 5) define-function: ( "check-warning", - (theme, color, border_color), + [theme, color, border_color], block { set-local-storage: {"rustdoc-theme": |theme|, "rustdoc-use-system-theme": "false"} reload: diff --git a/tests/rustdoc-gui/where-whitespace.goml b/tests/rustdoc-gui/where-whitespace.goml index da104fa40116f..823ce9704076b 100644 --- a/tests/rustdoc-gui/where-whitespace.goml +++ b/tests/rustdoc-gui/where-whitespace.goml @@ -3,25 +3,25 @@ go-to: "file://" + |DOC_PATH| + "/lib2/trait.Whitespace.html" show-text: true // First, we check in the trait definition if the where clause is "on its own" (not on the same // line than "pub trait Whitespace"). -compare-elements-position-false: (".item-decl code", "div.where", ("y")) +compare-elements-position-false: (".item-decl code", "div.where", ["y"]) // And that the code following it isn't on the same line either. -compare-elements-position-false: (".item-decl .fn", "div.where", ("y")) +compare-elements-position-false: (".item-decl .fn", "div.where", ["y"]) go-to: "file://" + |DOC_PATH| + "/lib2/struct.WhereWhitespace.html" // We make the screen a bit wider to ensure that the trait impl is on one line. set-window-size: (915, 915) -compare-elements-position-false: ("#method\.new .fn", "#method\.new div.where", ("y")) +compare-elements-position-false: ("#method\.new .fn", "#method\.new div.where", ["y"]) // We ensure that both the trait name and the struct name are on the same line in // "impl Whitespace<&K> for WhereWhitespace". compare-elements-position: ( "#trait-implementations-list .impl h3 .trait", "#trait-implementations-list .impl h3 .struct", - ("y"), + ["y"], ) // And we now check that the where condition isn't on the same line. compare-elements-position-false: ( "#trait-implementations-list .impl h3 .trait", "#trait-implementations-list .impl h3 div.where", - ("y"), + ["y"], ) diff --git a/tests/rustdoc/search-index-summaries.rs b/tests/rustdoc/search-index-summaries.rs index efd366405bfeb..529b42d0ca903 100644 --- a/tests/rustdoc/search-index-summaries.rs +++ b/tests/rustdoc/search-index-summaries.rs @@ -1,6 +1,6 @@ #![crate_name = "foo"] -// @hasraw 'search-index.js' 'Foo short link.' +// @hasraw 'search.desc/foo/foo-desc-0-.js' 'Foo short link.' // @!hasraw - 'www.example.com' // @!hasraw - 'More Foo.' diff --git a/tests/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.mir.stderr b/tests/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.mir.stderr deleted file mode 100644 index 34ec8aadbcf3b..0000000000000 --- a/tests/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.mir.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block - --> $DIR/const-extern-fn-requires-unsafe.rs:12:5 - | -LL | foo(); - | ^^^^^ call to unsafe function - | - = note: consult the function's documentation for information on how to avoid undefined behavior - -error[E0133]: call to unsafe function is unsafe and requires unsafe function or block - --> $DIR/const-extern-fn-requires-unsafe.rs:9:17 - | -LL | let a: [u8; foo()]; - | ^^^^^ call to unsafe function - | - = note: consult the function's documentation for information on how to avoid undefined behavior - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0133`. diff --git a/tests/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.thir.stderr b/tests/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.thir.stderr deleted file mode 100644 index e6b8173eb051a..0000000000000 --- a/tests/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.thir.stderr +++ /dev/null @@ -1,19 +0,0 @@ -error[E0133]: call to unsafe function `foo` is unsafe and requires unsafe function or block - --> $DIR/const-extern-fn-requires-unsafe.rs:12:5 - | -LL | foo(); - | ^^^^^ call to unsafe function - | - = note: consult the function's documentation for information on how to avoid undefined behavior - -error[E0133]: call to unsafe function `foo` is unsafe and requires unsafe function or block - --> $DIR/const-extern-fn-requires-unsafe.rs:9:17 - | -LL | let a: [u8; foo()]; - | ^^^^^ call to unsafe function - | - = note: consult the function's documentation for information on how to avoid undefined behavior - -error: aborting due to 2 previous errors - -For more information about this error, try `rustc --explain E0133`. diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.mir.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.mir.stderr deleted file mode 100644 index 7bbd4e158982f..0000000000000 --- a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.mir.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/fn-ptr.rs:11:21 - | -LL | #[target_feature(enable = "sse2")] - | ---------------------------------- `#[target_feature]` added here -... -LL | let foo: fn() = foo; - | ---- ^^^ cannot coerce functions with `#[target_feature]` to safe function pointers - | | - | expected due to this - | - = note: expected fn pointer `fn()` - found fn item `fn() {foo}` - = note: fn items are distinct from fn pointers - = note: functions with `#[target_feature]` can only be coerced to `unsafe` function pointers -help: consider casting to a fn pointer - | -LL | let foo: fn() = foo as fn(); - | ~~~~~~~~~~~ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.thir.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.thir.stderr deleted file mode 100644 index 7bbd4e158982f..0000000000000 --- a/tests/ui/rfcs/rfc-2396-target_feature-11/fn-ptr.thir.stderr +++ /dev/null @@ -1,23 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/fn-ptr.rs:11:21 - | -LL | #[target_feature(enable = "sse2")] - | ---------------------------------- `#[target_feature]` added here -... -LL | let foo: fn() = foo; - | ---- ^^^ cannot coerce functions with `#[target_feature]` to safe function pointers - | | - | expected due to this - | - = note: expected fn pointer `fn()` - found fn item `fn() {foo}` - = note: fn items are distinct from fn pointers - = note: functions with `#[target_feature]` can only be coerced to `unsafe` function pointers -help: consider casting to a fn pointer - | -LL | let foo: fn() = foo as fn(); - | ~~~~~~~~~~~ - -error: aborting due to 1 previous error - -For more information about this error, try `rustc --explain E0308`. diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.mir.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.mir.stderr deleted file mode 100644 index cabc475fa61cf..0000000000000 --- a/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.mir.stderr +++ /dev/null @@ -1,115 +0,0 @@ -error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:28:5 - | -LL | sse2(); - | ^^^^^^ call to function with `#[target_feature]` - | - = help: in order for the call to be safe, the context requires the following additional target feature: sse2 - = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]` - -error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:31:5 - | -LL | avx_bmi2(); - | ^^^^^^^^^^ call to function with `#[target_feature]` - | - = help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2 - -error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:34:5 - | -LL | Quux.avx_bmi2(); - | ^^^^^^^^^^^^^^^ call to function with `#[target_feature]` - | - = help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2 - -error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:41:5 - | -LL | avx_bmi2(); - | ^^^^^^^^^^ call to function with `#[target_feature]` - | - = help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2 - -error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:44:5 - | -LL | Quux.avx_bmi2(); - | ^^^^^^^^^^^^^^^ call to function with `#[target_feature]` - | - = help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2 - -error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:51:5 - | -LL | sse2(); - | ^^^^^^ call to function with `#[target_feature]` - | - = help: in order for the call to be safe, the context requires the following additional target feature: sse2 - = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]` - -error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:54:5 - | -LL | avx_bmi2(); - | ^^^^^^^^^^ call to function with `#[target_feature]` - | - = help: in order for the call to be safe, the context requires the following additional target feature: bmi2 - -error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:57:5 - | -LL | Quux.avx_bmi2(); - | ^^^^^^^^^^^^^^^ call to function with `#[target_feature]` - | - = help: in order for the call to be safe, the context requires the following additional target feature: bmi2 - -error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:65:5 - | -LL | sse2(); - | ^^^^^^ call to function with `#[target_feature]` - | - = help: in order for the call to be safe, the context requires the following additional target feature: sse2 - = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]` - -error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:70:15 - | -LL | const _: () = sse2(); - | ^^^^^^ call to function with `#[target_feature]` - | - = help: in order for the call to be safe, the context requires the following additional target feature: sse2 - = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]` - -error[E0133]: call to function with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:74:15 - | -LL | const _: () = sse2_and_fxsr(); - | ^^^^^^^^^^^^^^^ call to function with `#[target_feature]` - | - = help: in order for the call to be safe, the context requires the following additional target features: sse2 and fxsr - = note: the fxsr and sse2 target features being enabled in the build configuration does not remove the requirement to list them in `#[target_feature]` - -error: call to function with `#[target_feature]` is unsafe and requires unsafe block (error E0133) - --> $DIR/safe-calls.rs:82:5 - | -LL | sse2(); - | ^^^^^^ call to function with `#[target_feature]` - | - = help: in order for the call to be safe, the context requires the following additional target feature: sse2 - = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]` -note: an unsafe function restricts its caller, but its body is safe by default - --> $DIR/safe-calls.rs:81:1 - | -LL | unsafe fn needs_unsafe_block() { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: the lint level is defined here - --> $DIR/safe-calls.rs:78:8 - | -LL | #[deny(unsafe_op_in_unsafe_fn)] - | ^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 12 previous errors - -For more information about this error, try `rustc --explain E0133`. diff --git a/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.thir.stderr b/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.thir.stderr deleted file mode 100644 index 13b58fde862d5..0000000000000 --- a/tests/ui/rfcs/rfc-2396-target_feature-11/safe-calls.thir.stderr +++ /dev/null @@ -1,115 +0,0 @@ -error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:28:5 - | -LL | sse2(); - | ^^^^^^ call to function with `#[target_feature]` - | - = help: in order for the call to be safe, the context requires the following additional target feature: sse2 - = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]` - -error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:31:5 - | -LL | avx_bmi2(); - | ^^^^^^^^^^ call to function with `#[target_feature]` - | - = help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2 - -error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:34:5 - | -LL | Quux.avx_bmi2(); - | ^^^^^^^^^^^^^^^ call to function with `#[target_feature]` - | - = help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2 - -error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:41:5 - | -LL | avx_bmi2(); - | ^^^^^^^^^^ call to function with `#[target_feature]` - | - = help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2 - -error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:44:5 - | -LL | Quux.avx_bmi2(); - | ^^^^^^^^^^^^^^^ call to function with `#[target_feature]` - | - = help: in order for the call to be safe, the context requires the following additional target features: avx and bmi2 - -error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:51:5 - | -LL | sse2(); - | ^^^^^^ call to function with `#[target_feature]` - | - = help: in order for the call to be safe, the context requires the following additional target feature: sse2 - = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]` - -error[E0133]: call to function `avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:54:5 - | -LL | avx_bmi2(); - | ^^^^^^^^^^ call to function with `#[target_feature]` - | - = help: in order for the call to be safe, the context requires the following additional target feature: bmi2 - -error[E0133]: call to function `Quux::avx_bmi2` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:57:5 - | -LL | Quux.avx_bmi2(); - | ^^^^^^^^^^^^^^^ call to function with `#[target_feature]` - | - = help: in order for the call to be safe, the context requires the following additional target feature: bmi2 - -error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:65:5 - | -LL | sse2(); - | ^^^^^^ call to function with `#[target_feature]` - | - = help: in order for the call to be safe, the context requires the following additional target feature: sse2 - = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]` - -error[E0133]: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:70:15 - | -LL | const _: () = sse2(); - | ^^^^^^ call to function with `#[target_feature]` - | - = help: in order for the call to be safe, the context requires the following additional target feature: sse2 - = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]` - -error[E0133]: call to function `sse2_and_fxsr` with `#[target_feature]` is unsafe and requires unsafe function or block - --> $DIR/safe-calls.rs:74:15 - | -LL | const _: () = sse2_and_fxsr(); - | ^^^^^^^^^^^^^^^ call to function with `#[target_feature]` - | - = help: in order for the call to be safe, the context requires the following additional target features: sse2 and fxsr - = note: the fxsr and sse2 target features being enabled in the build configuration does not remove the requirement to list them in `#[target_feature]` - -error: call to function `sse2` with `#[target_feature]` is unsafe and requires unsafe block (error E0133) - --> $DIR/safe-calls.rs:82:5 - | -LL | sse2(); - | ^^^^^^ call to function with `#[target_feature]` - | - = help: in order for the call to be safe, the context requires the following additional target feature: sse2 - = note: the sse2 target feature being enabled in the build configuration does not remove the requirement to list it in `#[target_feature]` -note: an unsafe function restricts its caller, but its body is safe by default - --> $DIR/safe-calls.rs:81:1 - | -LL | unsafe fn needs_unsafe_block() { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -note: the lint level is defined here - --> $DIR/safe-calls.rs:78:8 - | -LL | #[deny(unsafe_op_in_unsafe_fn)] - | ^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 12 previous errors - -For more information about this error, try `rustc --explain E0133`.