Auto merge of #123372 - GuillaumeGomez:rollup-nwxdzev, r=GuillaumeGomez
Rollup of 4 pull requests Successful merges: - #122614 (rustdoc-search: shard the search result descriptions) - #123338 (Update to new browser-ui-test version) - #123366 (Minor by_move_body impl cleanups) - #123371 (Remove dangling `.mir.stderr` and `.thir.stderr` test files) r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
029cb1b13b
80 changed files with 1103 additions and 807 deletions
|
@ -4783,6 +4783,8 @@ version = "0.0.0"
|
|||
dependencies = [
|
||||
"arrayvec",
|
||||
"askama",
|
||||
"base64",
|
||||
"byteorder",
|
||||
"expect-test",
|
||||
"indexmap",
|
||||
"itertools 0.12.1",
|
||||
|
|
|
@ -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<FieldIdx>,
|
||||
by_ref_fields: UnordSet<FieldIdx>,
|
||||
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 :^)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -1 +1 @@
|
|||
0.16.11
|
||||
0.17.0
|
|
@ -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"
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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::<Vec<_>>();
|
||||
|
||||
struct CrateData<'a> {
|
||||
doc: String,
|
||||
items: Vec<&'a IndexItem>,
|
||||
paths: Vec<(ItemType, Vec<Symbol>)>,
|
||||
// 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<String, Vec<usize>>,
|
||||
// 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<u32>,
|
||||
}
|
||||
|
||||
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::<usize>() + 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>(
|
||||
|
|
243
src/librustdoc/html/render/search_index/encode.rs
Normal file
243
src/librustdoc/html/render/search_index/encode.rs
Normal file
|
@ -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<u16>),
|
||||
/// 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::<u16>::new();
|
||||
let mut containers = Vec::<Container>::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::<LE>(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::<LE>(SERIAL_COOKIE_NO_RUNCONTAINER)?;
|
||||
out.write_u32::<LE>(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::<LE>((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::<LE>(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::<LE>(*chunk)?;
|
||||
}
|
||||
}
|
||||
Container::Array(array) => {
|
||||
for value in array.iter() {
|
||||
out.write_u16::<LE>(*value)?;
|
||||
}
|
||||
}
|
||||
Container::Run(runs) => {
|
||||
out.write_u16::<LE>((runs.len()).try_into().unwrap())?;
|
||||
for (start, lenm1) in runs.iter().copied() {
|
||||
out.write_u16::<LE>(start)?;
|
||||
out.write_u16::<LE>(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
|
||||
}
|
|
@ -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())
|
||||
|
|
|
@ -5,7 +5,7 @@ module.exports = {
|
|||
},
|
||||
"extends": "eslint:recommended",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2015,
|
||||
"ecmaVersion": 8,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"rules": {
|
||||
|
|
|
@ -329,6 +329,30 @@ function preLoadCss(cssUrl) {
|
|||
search.innerHTML = "<h3 class=\"search-loading\">" + searchState.loadingText + "</h3>";
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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<Row>}
|
||||
*/
|
||||
let searchIndex;
|
||||
/**
|
||||
* @type {Map<String, RoaringBitmap>}
|
||||
*/
|
||||
let searchIndexDeprecated;
|
||||
/**
|
||||
* @type {Map<String, RoaringBitmap>}
|
||||
*/
|
||||
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}<span class="${type}">${name}</span>\
|
|||
|
||||
link.appendChild(description);
|
||||
output.appendChild(link);
|
||||
});
|
||||
}
|
||||
} else if (query.error === null) {
|
||||
output.className = "search-failed" + extraClass;
|
||||
output.innerHTML = "No results :(<br/>" +
|
||||
|
@ -2666,7 +2689,7 @@ ${item.displayPath}<span class="${type}">${name}</span>\
|
|||
* @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}<span class="${type}">${name}</span>\
|
|||
|
||||
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}<span class="${type}">${name}</span>\
|
|||
* 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}<span class="${type}">${name}</span>\
|
|||
// 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}<span class="${type}">${name}</span>\
|
|||
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}<span class="${type}">${name}</span>\
|
|||
* 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<string, integer>}
|
||||
*
|
||||
* @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);
|
||||
function buildFunctionSearchTypeCallback(lowercasePaths) {
|
||||
return functionSearchType => {
|
||||
if (functionSearchType === 0) {
|
||||
return null;
|
||||
}
|
||||
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)];
|
||||
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}<span class="${type}">${name}</span>\
|
|||
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}<span class="${type}">${name}</span>\
|
|||
*/
|
||||
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}<span class="${type}">${name}</span>\
|
|||
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}<span class="${type}">${name}</span>\
|
|||
// 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}<span class="${type}">${name}</span>\
|
|||
// 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}<span class="${type}">${name}</span>\
|
|||
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}<span class="${type}">${name}</span>\
|
|||
// 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}<span class="${type}">${name}</span>\
|
|||
}
|
||||
}
|
||||
currentIndex += itemTypes.length;
|
||||
searchState.descShards.set(crate, descShardList);
|
||||
}
|
||||
// Drop the (rather large) hash table used for reusing function items
|
||||
TYPES_POOL = new Map();
|
||||
|
|
|
@ -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",
|
||||
);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ module.exports = {
|
|||
},
|
||||
"extends": "eslint:recommended",
|
||||
"parserOptions": {
|
||||
"ecmaVersion": 2015,
|
||||
"ecmaVersion": 8,
|
||||
"sourceType": "module"
|
||||
},
|
||||
"rules": {
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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"}
|
||||
|
|
|
@ -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"}
|
||||
|
|
|
@ -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...
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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}
|
||||
|
|
|
@ -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"})
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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"})
|
||||
|
|
|
@ -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"})
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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|,
|
||||
|
|
|
@ -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"])
|
||||
|
|
|
@ -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: (
|
||||
|
|
|
@ -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",
|
||||
})
|
||||
|
|
|
@ -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"],
|
||||
)
|
||||
|
|
|
@ -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|,
|
||||
|
|
|
@ -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.
|
||||
|
|
|
@ -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|,
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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<NotableStructWithLongNamr>,y")
|
||||
write-into: (".search-input", "Foo<NotableStructWithLongNamr>,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<x>,y")
|
||||
write-into: (".search-input", "generic:NotableStructWithLongNamr<x>,y")
|
||||
// To be SURE that the search will be run.
|
||||
press-key: 'Enter'
|
||||
// Waiting for the search results to appear...
|
||||
|
|
|
@ -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"}
|
||||
|
|
|
@ -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...
|
||||
|
|
|
@ -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|,
|
||||
|
|
|
@ -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...
|
||||
|
|
|
@ -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"}
|
||||
|
|
|
@ -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",
|
||||
|
|
|
@ -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 `<a>` 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 `<a>` 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 `<a>` 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...
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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...
|
||||
|
|
|
@ -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...
|
||||
|
|
|
@ -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...
|
||||
|
|
|
@ -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: (
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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)
|
||||
|
||||
|
|
|
@ -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|})
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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|,
|
||||
|
|
|
@ -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|,
|
||||
|
|
|
@ -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"})
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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"}
|
||||
|
|
|
@ -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".
|
||||
|
|
|
@ -13,7 +13,7 @@ define-function: (
|
|||
"sup-check",
|
||||
// `theme` is the theme being tested.
|
||||
// `color` is the expected color of the `<sup>` 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",
|
||||
})
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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<Idx>").
|
||||
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<K, T> Whitespace<&K> for WhereWhitespace<T>".
|
||||
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"],
|
||||
)
|
||||
|
|
|
@ -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.'
|
||||
|
||||
|
|
|
@ -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`.
|
|
@ -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`.
|
|
@ -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`.
|
|
@ -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`.
|
|
@ -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`.
|
|
@ -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`.
|
Loading…
Add table
Reference in a new issue