Auto merge of #93645 - matthiaskrgr:rollup-eua2621, r=matthiaskrgr
Rollup of 11 pull requests Successful merges: - #92735 (Add crate filter parameter in URL) - #93402 (Windows: Disable LLVM crash dialog boxes.) - #93508 (Add rustdoc info to jsondocck output) - #93551 (Add package.json in gitignore) - #93555 (Link `try_exists` docs to `Path::exists`) - #93585 (Missing tests for #92630) - #93593 (Fix ret > 1 bound if shadowed by const) - #93630 (clippy::perf fixes) - #93631 (rustc_mir_dataflow: use iter::once instead of Some().into_iter) - #93632 (rustdoc: clippy::complexity fixes) - #93638 (rustdoc: remove unused Hash impl) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
This commit is contained in:
commit
cb18e83e85
1
.gitignore
vendored
1
.gitignore
vendored
@ -71,6 +71,7 @@ __pycache__/
|
||||
## Node
|
||||
node_modules
|
||||
package-lock.json
|
||||
package.json
|
||||
|
||||
## Rustdoc GUI tests
|
||||
src/test/rustdoc-gui/src/**.lock
|
||||
|
@ -219,7 +219,7 @@ fn inject_dll_import_lib(
|
||||
|
||||
match result {
|
||||
Err(e) => {
|
||||
self.config.sess.fatal(&format!("Error calling dlltool: {}", e.to_string()));
|
||||
self.config.sess.fatal(&format!("Error calling dlltool: {}", e));
|
||||
}
|
||||
Ok(output) if !output.status.success() => self.config.sess.fatal(&format!(
|
||||
"Dlltool could not create import library: {}\n{}",
|
||||
|
@ -987,6 +987,7 @@ pub fn from_generic(kind: rustc_session::config::DebugInfo) -> Self {
|
||||
|
||||
extern "C" {
|
||||
pub fn LLVMRustInstallFatalErrorHandler();
|
||||
pub fn LLVMRustDisableSystemDialogsOnCrash();
|
||||
|
||||
// Create and destroy contexts.
|
||||
pub fn LLVMRustContextCreate(shouldDiscardNames: bool) -> &'static mut Context;
|
||||
|
@ -46,6 +46,12 @@ unsafe fn configure_llvm(sess: &Session) {
|
||||
let mut llvm_args = Vec::with_capacity(n_args + 1);
|
||||
|
||||
llvm::LLVMRustInstallFatalErrorHandler();
|
||||
// On Windows, an LLVM assertion will open an Abort/Retry/Ignore dialog
|
||||
// box for the purpose of launching a debugger. However, on CI this will
|
||||
// cause it to hang until it times out, which can take several hours.
|
||||
if std::env::var_os("CI").is_some() {
|
||||
llvm::LLVMRustDisableSystemDialogsOnCrash();
|
||||
}
|
||||
|
||||
fn llvm_arg_to_arg_name(full_arg: &str) -> &str {
|
||||
full_arg.trim().split(|c: char| c == '=' || c.is_whitespace()).next().unwrap_or("")
|
||||
|
@ -126,7 +126,7 @@ macro_rules! error {
|
||||
|
||||
// If the user tried to use a key="value" flag, but is missing the quotes, provide
|
||||
// a hint about how to resolve this.
|
||||
if s.contains("=") && !s.contains("=\"") && !s.ends_with("\"") {
|
||||
if s.contains('=') && !s.contains("=\"") && !s.ends_with('"') {
|
||||
error!(concat!(
|
||||
r#"expected `key` or `key="value"`, ensure escaping is appropriate"#,
|
||||
r#" for your shell, try 'key="value"' or key=\"value\""#
|
||||
|
@ -76,6 +76,10 @@ extern "C" void LLVMRustInstallFatalErrorHandler() {
|
||||
install_fatal_error_handler(FatalErrorHandler);
|
||||
}
|
||||
|
||||
extern "C" void LLVMRustDisableSystemDialogsOnCrash() {
|
||||
sys::DisableSystemDialogsOnCrash();
|
||||
}
|
||||
|
||||
extern "C" char *LLVMRustGetLastError(void) {
|
||||
char *Ret = LastError;
|
||||
LastError = nullptr;
|
||||
|
@ -160,12 +160,11 @@ pub fn find_by_name_and_kinds(
|
||||
&self,
|
||||
tcx: TyCtxt<'_>,
|
||||
ident: Ident,
|
||||
// Sorted in order of what kinds to look at
|
||||
kinds: &[AssocKind],
|
||||
parent_def_id: DefId,
|
||||
) -> Option<&ty::AssocItem> {
|
||||
self.filter_by_name_unhygienic(ident.name)
|
||||
.filter(|item| kinds.contains(&item.kind))
|
||||
.find(|item| tcx.hygienic_eq(ident, item.ident(tcx), parent_def_id))
|
||||
kinds.iter().find_map(|kind| self.find_by_name_and_kind(tcx, ident, *kind, parent_def_id))
|
||||
}
|
||||
|
||||
/// Returns the associated item with the given name in the given `Namespace`, if one exists.
|
||||
|
@ -8,7 +8,7 @@
|
||||
use rustc_middle::ty::util::IntTypeExt;
|
||||
use rustc_middle::ty::{self, Ty, TyCtxt};
|
||||
use rustc_target::abi::VariantIdx;
|
||||
use std::fmt;
|
||||
use std::{fmt, iter};
|
||||
|
||||
/// The value of an inserted drop flag.
|
||||
#[derive(Debug, PartialEq, Eq, Copy, Clone)]
|
||||
@ -329,8 +329,7 @@ fn drop_halfladder(
|
||||
mut succ: BasicBlock,
|
||||
fields: &[(Place<'tcx>, Option<D::Path>)],
|
||||
) -> Vec<BasicBlock> {
|
||||
Some(succ)
|
||||
.into_iter()
|
||||
iter::once(succ)
|
||||
.chain(fields.iter().rev().zip(unwind_ladder).map(|(&(place, path), &unwind_succ)| {
|
||||
succ = self.drop_subpath(place, path, succ, unwind_succ);
|
||||
succ
|
||||
|
@ -1702,11 +1702,11 @@ fn looks_like_width_suffix(first_chars: &[char], s: &str) -> bool {
|
||||
|
||||
// Try to lowercase the prefix if it's a valid base prefix.
|
||||
fn fix_base_capitalisation(s: &str) -> Option<String> {
|
||||
if let Some(stripped) = s.strip_prefix("B") {
|
||||
if let Some(stripped) = s.strip_prefix('B') {
|
||||
Some(format!("0b{stripped}"))
|
||||
} else if let Some(stripped) = s.strip_prefix("O") {
|
||||
} else if let Some(stripped) = s.strip_prefix('O') {
|
||||
Some(format!("0o{stripped}"))
|
||||
} else if let Some(stripped) = s.strip_prefix("X") {
|
||||
} else if let Some(stripped) = s.strip_prefix('X') {
|
||||
Some(format!("0x{stripped}"))
|
||||
} else {
|
||||
None
|
||||
|
@ -887,15 +887,10 @@ fn trait_defines_associated_type_named(&self, trait_def_id: DefId, assoc_name: I
|
||||
.find_by_name_and_kind(self.tcx(), assoc_name, ty::AssocKind::Type, trait_def_id)
|
||||
.is_some()
|
||||
}
|
||||
fn trait_defines_associated_named(&self, trait_def_id: DefId, assoc_name: Ident) -> bool {
|
||||
fn trait_defines_associated_const_named(&self, trait_def_id: DefId, assoc_name: Ident) -> bool {
|
||||
self.tcx()
|
||||
.associated_items(trait_def_id)
|
||||
.find_by_name_and_kinds(
|
||||
self.tcx(),
|
||||
assoc_name,
|
||||
&[ty::AssocKind::Type, ty::AssocKind::Const],
|
||||
trait_def_id,
|
||||
)
|
||||
.find_by_name_and_kind(self.tcx(), assoc_name, ty::AssocKind::Const, trait_def_id)
|
||||
.is_some()
|
||||
}
|
||||
|
||||
@ -1145,13 +1140,13 @@ fn add_predicates_for_ast_type_binding(
|
||||
|
||||
// We have already adjusted the item name above, so compare with `ident.normalize_to_macros_2_0()` instead
|
||||
// of calling `filter_by_name_and_kind`.
|
||||
let assoc_item = tcx
|
||||
.associated_items(candidate.def_id())
|
||||
.filter_by_name_unhygienic(assoc_ident.name)
|
||||
.find(|i| {
|
||||
(i.kind == ty::AssocKind::Type || i.kind == ty::AssocKind::Const)
|
||||
&& i.ident(tcx).normalize_to_macros_2_0() == assoc_ident
|
||||
})
|
||||
let find_item_of_kind = |kind| {
|
||||
tcx.associated_items(candidate.def_id())
|
||||
.filter_by_name_unhygienic(assoc_ident.name)
|
||||
.find(|i| i.kind == kind && i.ident(tcx).normalize_to_macros_2_0() == assoc_ident)
|
||||
};
|
||||
let assoc_item = find_item_of_kind(ty::AssocKind::Type)
|
||||
.or_else(|| find_item_of_kind(ty::AssocKind::Const))
|
||||
.expect("missing associated type");
|
||||
|
||||
if !assoc_item.vis.is_accessible_from(def_scope, tcx) {
|
||||
@ -1657,11 +1652,14 @@ fn one_bound_for_assoc_type<I>(
|
||||
I: Iterator<Item = ty::PolyTraitRef<'tcx>>,
|
||||
{
|
||||
let mut matching_candidates = all_candidates()
|
||||
.filter(|r| self.trait_defines_associated_named(r.def_id(), assoc_name));
|
||||
.filter(|r| self.trait_defines_associated_type_named(r.def_id(), assoc_name));
|
||||
let mut const_candidates = all_candidates()
|
||||
.filter(|r| self.trait_defines_associated_const_named(r.def_id(), assoc_name));
|
||||
|
||||
let bound = match matching_candidates.next() {
|
||||
Some(bound) => bound,
|
||||
None => {
|
||||
let (bound, next_cand) = match (matching_candidates.next(), const_candidates.next()) {
|
||||
(Some(bound), _) => (bound, matching_candidates.next()),
|
||||
(None, Some(bound)) => (bound, const_candidates.next()),
|
||||
(None, None) => {
|
||||
self.complain_about_assoc_type_not_found(
|
||||
all_candidates,
|
||||
&ty_param_name(),
|
||||
@ -1671,10 +1669,9 @@ fn one_bound_for_assoc_type<I>(
|
||||
return Err(ErrorReported);
|
||||
}
|
||||
};
|
||||
|
||||
debug!("one_bound_for_assoc_type: bound = {:?}", bound);
|
||||
|
||||
if let Some(bound2) = matching_candidates.next() {
|
||||
if let Some(bound2) = next_cand {
|
||||
debug!("one_bound_for_assoc_type: bound2 = {:?}", bound2);
|
||||
|
||||
let is_equality = is_equality();
|
||||
@ -1759,6 +1756,7 @@ fn one_bound_for_assoc_type<I>(
|
||||
return Err(ErrorReported);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(bound)
|
||||
}
|
||||
|
||||
@ -1893,14 +1891,17 @@ pub fn associated_path_to_ty(
|
||||
|
||||
// We have already adjusted the item name above, so compare with `ident.normalize_to_macros_2_0()` instead
|
||||
// of calling `filter_by_name_and_kind`.
|
||||
let item = tcx
|
||||
.associated_items(trait_did)
|
||||
.in_definition_order()
|
||||
.find(|i| {
|
||||
i.kind.namespace() == Namespace::TypeNS
|
||||
&& i.ident(tcx).normalize_to_macros_2_0() == assoc_ident
|
||||
})
|
||||
.expect("missing associated type");
|
||||
let item = tcx.associated_items(trait_did).in_definition_order().find(|i| {
|
||||
i.kind.namespace() == Namespace::TypeNS
|
||||
&& i.ident(tcx).normalize_to_macros_2_0() == assoc_ident
|
||||
});
|
||||
// Assume that if it's not matched, there must be a const defined with the same name
|
||||
// but it was used in a type position.
|
||||
let Some(item) = item else {
|
||||
let msg = format!("found associated const `{assoc_ident}` when type was expected");
|
||||
tcx.sess.struct_span_err(span, &msg).emit();
|
||||
return Err(ErrorReported);
|
||||
};
|
||||
|
||||
let ty = self.projected_ty_from_poly_trait_ref(span, item.def_id, assoc_segment, bound);
|
||||
let ty = self.normalize_ty(span, ty);
|
||||
|
@ -1587,10 +1587,10 @@ fn report_missing_fields(
|
||||
) {
|
||||
let len = remaining_fields.len();
|
||||
|
||||
let mut displayable_field_names =
|
||||
remaining_fields.keys().map(|ident| ident.as_str()).collect::<Vec<_>>();
|
||||
|
||||
displayable_field_names.sort();
|
||||
let mut displayable_field_names: Vec<&str> =
|
||||
remaining_fields.keys().map(|ident| ident.as_str()).collect();
|
||||
// sorting &str primitives here, sort_unstable is ok
|
||||
displayable_field_names.sort_unstable();
|
||||
|
||||
let mut truncated_fields_error = String::new();
|
||||
let remaining_fields_names = match &displayable_field_names[..] {
|
||||
|
@ -118,3 +118,11 @@ fn wake(self: Arc<Self>) {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// just tests by whether or not this compiles
|
||||
fn _pending_impl_all_auto_traits<T>() {
|
||||
use std::panic::{RefUnwindSafe, UnwindSafe};
|
||||
fn all_auto_traits<T: Send + Sync + Unpin + UnwindSafe + RefUnwindSafe>() {}
|
||||
|
||||
all_auto_traits::<std::future::Pending<T>>();
|
||||
}
|
||||
|
@ -146,3 +146,11 @@ fn test_build_hasher_object_safe() {
|
||||
|
||||
let _: &dyn BuildHasher<Hasher = DefaultHasher> = &RandomState::new();
|
||||
}
|
||||
|
||||
// just tests by whether or not this compiles
|
||||
fn _build_hasher_default_impl_all_auto_traits<T>() {
|
||||
use std::panic::{RefUnwindSafe, UnwindSafe};
|
||||
fn all_auto_traits<T: Send + Sync + Unpin + UnwindSafe + RefUnwindSafe>() {}
|
||||
|
||||
all_auto_traits::<std::hash::BuildHasherDefault<T>>();
|
||||
}
|
||||
|
@ -496,3 +496,11 @@ fn test_collect() {
|
||||
let b: Vec<isize> = a.iter().cloned().collect();
|
||||
assert!(a == b);
|
||||
}
|
||||
|
||||
// just tests by whether or not this compiles
|
||||
fn _empty_impl_all_auto_traits<T>() {
|
||||
use std::panic::{RefUnwindSafe, UnwindSafe};
|
||||
fn all_auto_traits<T: Send + Sync + Unpin + UnwindSafe + RefUnwindSafe>() {}
|
||||
|
||||
all_auto_traits::<std::iter::Empty<T>>();
|
||||
}
|
||||
|
@ -2288,7 +2288,7 @@ fn as_inner_mut(&mut self) -> &mut fs_imp::DirBuilder {
|
||||
/// This function will traverse symbolic links to query information about the
|
||||
/// destination file. In case of broken symbolic links this will return `Ok(false)`.
|
||||
///
|
||||
/// As opposed to the `exists()` method, this one doesn't silently ignore errors
|
||||
/// As opposed to the [`Path::exists`] method, this one doesn't silently ignore errors
|
||||
/// unrelated to the path not existing. (E.g. it will return `Err(_)` in case of permission
|
||||
/// denied on some of the parent directories.)
|
||||
///
|
||||
@ -2301,6 +2301,8 @@ fn as_inner_mut(&mut self) -> &mut fs_imp::DirBuilder {
|
||||
/// assert!(!fs::try_exists("does_not_exist.txt").expect("Can't check existence of file does_not_exist.txt"));
|
||||
/// assert!(fs::try_exists("/root/secret_file.txt").is_err());
|
||||
/// ```
|
||||
///
|
||||
/// [`Path::exists`]: crate::path::Path::exists
|
||||
// FIXME: stabilization should modify documentation of `exists()` to recommend this method
|
||||
// instead.
|
||||
#[unstable(feature = "path_try_exists", issue = "83186")]
|
||||
|
@ -2730,7 +2730,7 @@ pub fn exists(&self) -> bool {
|
||||
/// This function will traverse symbolic links to query information about the
|
||||
/// destination file. In case of broken symbolic links this will return `Ok(false)`.
|
||||
///
|
||||
/// As opposed to the `exists()` method, this one doesn't silently ignore errors
|
||||
/// As opposed to the [`exists()`] method, this one doesn't silently ignore errors
|
||||
/// unrelated to the path not existing. (E.g. it will return `Err(_)` in case of permission
|
||||
/// denied on some of the parent directories.)
|
||||
///
|
||||
@ -2743,6 +2743,8 @@ pub fn exists(&self) -> bool {
|
||||
/// assert!(!Path::new("does_not_exist.txt").try_exists().expect("Can't check existence of file does_not_exist.txt"));
|
||||
/// assert!(Path::new("/root/secret_file.txt").try_exists().is_err());
|
||||
/// ```
|
||||
///
|
||||
/// [`exists()`]: Self::exists
|
||||
// FIXME: stabilization should modify documentation of `exists()` to recommend this method
|
||||
// instead.
|
||||
#[unstable(feature = "path_try_exists", issue = "83186")]
|
||||
|
@ -1533,9 +1533,7 @@ fn clean(&self, cx: &mut DocContext<'_>) -> Type {
|
||||
for pb in obj.projection_bounds() {
|
||||
bindings.push(TypeBinding {
|
||||
name: cx.tcx.associated_item(pb.item_def_id()).name,
|
||||
kind: TypeBindingKind::Equality {
|
||||
term: pb.skip_binder().term.clean(cx).into(),
|
||||
},
|
||||
kind: TypeBindingKind::Equality { term: pb.skip_binder().term.clean(cx) },
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -953,7 +953,7 @@ fn add_doc_fragment(out: &mut String, frag: &DocFragment) {
|
||||
/// A link that has not yet been rendered.
|
||||
///
|
||||
/// This link will be turned into a rendered link by [`Item::links`].
|
||||
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
|
||||
#[derive(Clone, Debug, PartialEq, Eq)]
|
||||
crate struct ItemLink {
|
||||
/// The original link written in the markdown
|
||||
crate link: String,
|
||||
@ -1036,8 +1036,7 @@ impl Attributes {
|
||||
// Additional documentation should be shown before the original documentation
|
||||
let other_attrs = additional_attrs
|
||||
.into_iter()
|
||||
.map(|(attrs, id)| attrs.iter().map(move |attr| (attr, Some(id))))
|
||||
.flatten()
|
||||
.flat_map(|(attrs, id)| attrs.iter().map(move |attr| (attr, Some(id))))
|
||||
.chain(attrs.iter().map(|attr| (attr, None)))
|
||||
.filter_map(clean_attr)
|
||||
.collect();
|
||||
|
@ -439,13 +439,12 @@ fn println_condition(condition: Condition) {
|
||||
matches
|
||||
.opt_str("default-theme")
|
||||
.iter()
|
||||
.map(|theme| {
|
||||
.flat_map(|theme| {
|
||||
vec![
|
||||
("use-system-theme".to_string(), "false".to_string()),
|
||||
("theme".to_string(), theme.to_string()),
|
||||
]
|
||||
})
|
||||
.flatten()
|
||||
.collect(),
|
||||
matches
|
||||
.opt_strs("default-setting")
|
||||
|
@ -76,7 +76,7 @@ fn write_char(&mut self, c: char) -> fmt::Result {
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn write_fmt(self: &mut Self, args: fmt::Arguments<'_>) -> fmt::Result {
|
||||
fn write_fmt(&mut self, args: fmt::Arguments<'_>) -> fmt::Result {
|
||||
self.buffer.write_fmt(args)
|
||||
}
|
||||
}
|
||||
|
@ -274,8 +274,7 @@ fn new(info: DecorationInfo) -> Self {
|
||||
let (mut starts, mut ends): (Vec<_>, Vec<_>) = info
|
||||
.0
|
||||
.into_iter()
|
||||
.map(|(kind, ranges)| ranges.into_iter().map(move |(lo, hi)| ((lo, kind), hi)))
|
||||
.flatten()
|
||||
.flat_map(|(kind, ranges)| ranges.into_iter().map(move |(lo, hi)| ((lo, kind), hi)))
|
||||
.unzip();
|
||||
|
||||
// Sort the sequences in document order.
|
||||
|
@ -81,7 +81,7 @@
|
||||
lastpathid += 1;
|
||||
|
||||
if let Some(&(ref fqp, short)) = paths.get(&defid) {
|
||||
crate_paths.push((short, fqp.last().unwrap().clone()));
|
||||
crate_paths.push((short, *fqp.last().unwrap()));
|
||||
Some(pathid)
|
||||
} else {
|
||||
None
|
||||
|
@ -54,7 +54,6 @@ function resourcePath(basename, extension) {
|
||||
return getVar("root-path") + basename + getVar("resource-suffix") + extension;
|
||||
}
|
||||
|
||||
|
||||
(function () {
|
||||
window.rootPath = getVar("root-path");
|
||||
window.currentCrate = getVar("current-crate");
|
||||
@ -232,7 +231,7 @@ function hideThemeButtonState() {
|
||||
document.title = searchState.titleBeforeSearch;
|
||||
// We also remove the query parameter from the URL.
|
||||
if (searchState.browserSupportsHistoryApi()) {
|
||||
history.replaceState("", window.currentCrate + " - Rust",
|
||||
history.replaceState(null, window.currentCrate + " - Rust",
|
||||
getNakedUrl() + window.location.hash);
|
||||
}
|
||||
},
|
||||
@ -246,18 +245,6 @@ function hideThemeButtonState() {
|
||||
});
|
||||
return params;
|
||||
},
|
||||
putBackSearch: function(search_input) {
|
||||
var search = searchState.outputElement();
|
||||
if (search_input.value !== "" && hasClass(search, "hidden")) {
|
||||
searchState.showResults(search);
|
||||
if (searchState.browserSupportsHistoryApi()) {
|
||||
var extra = "?search=" + encodeURIComponent(search_input.value);
|
||||
history.replaceState(search_input.value, "",
|
||||
getNakedUrl() + extra + window.location.hash);
|
||||
}
|
||||
document.title = searchState.title;
|
||||
}
|
||||
},
|
||||
browserSupportsHistoryApi: function() {
|
||||
return window.history && typeof window.history.pushState === "function";
|
||||
},
|
||||
@ -282,14 +269,10 @@ function hideThemeButtonState() {
|
||||
}
|
||||
|
||||
search_input.addEventListener("focus", function() {
|
||||
searchState.putBackSearch(this);
|
||||
search_input.origPlaceholder = searchState.input.placeholder;
|
||||
search_input.origPlaceholder = search_input.placeholder;
|
||||
search_input.placeholder = "Type your search here.";
|
||||
loadSearch();
|
||||
});
|
||||
search_input.addEventListener("blur", function() {
|
||||
search_input.placeholder = searchState.input.origPlaceholder;
|
||||
});
|
||||
|
||||
if (search_input.value != '') {
|
||||
loadSearch();
|
||||
@ -330,7 +313,7 @@ function hideThemeButtonState() {
|
||||
var hash = ev.newURL.slice(ev.newURL.indexOf("#") + 1);
|
||||
if (searchState.browserSupportsHistoryApi()) {
|
||||
// `window.location.search`` contains all the query parameters, not just `search`.
|
||||
history.replaceState(hash, "",
|
||||
history.replaceState(null, "",
|
||||
getNakedUrl() + window.location.search + "#" + hash);
|
||||
}
|
||||
elem = document.getElementById(hash);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/* global addClass, getNakedUrl, getSettingValue, hasOwnPropertyRustdoc, initSearch, onEach */
|
||||
/* global onEachLazy, removeClass, searchState, updateLocalStorage */
|
||||
/* global onEachLazy, removeClass, searchState, hasClass */
|
||||
|
||||
(function() {
|
||||
// This mapping table should match the discriminants of
|
||||
@ -133,6 +133,39 @@ window.initSearch = function(rawSearchIndex) {
|
||||
searchState.input.value = params.search || "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Build an URL with search parameters.
|
||||
*
|
||||
* @param {string} search - The current search being performed.
|
||||
* @param {string|null} filterCrates - The current filtering crate (if any).
|
||||
* @return {string}
|
||||
*/
|
||||
function buildUrl(search, filterCrates) {
|
||||
var extra = "?search=" + encodeURIComponent(search);
|
||||
|
||||
if (filterCrates !== null) {
|
||||
extra += "&filter-crate=" + encodeURIComponent(filterCrates);
|
||||
}
|
||||
return getNakedUrl() + extra + window.location.hash;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the filtering crate or `null` if there is none.
|
||||
*
|
||||
* @return {string|null}
|
||||
*/
|
||||
function getFilterCrates() {
|
||||
var elem = document.getElementById("crate-search");
|
||||
|
||||
if (elem &&
|
||||
elem.value !== "All crates" &&
|
||||
hasOwnPropertyRustdoc(rawSearchIndex, elem.value))
|
||||
{
|
||||
return elem.value;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Executes the query and returns a list of results for each results tab.
|
||||
* @param {Object} query - The user query
|
||||
@ -595,7 +628,7 @@ window.initSearch = function(rawSearchIndex) {
|
||||
// aliases to be before the others in the displayed results.
|
||||
var aliases = [];
|
||||
var crateAliases = [];
|
||||
if (filterCrates !== undefined) {
|
||||
if (filterCrates !== null) {
|
||||
if (ALIASES[filterCrates] && ALIASES[filterCrates][query.search]) {
|
||||
var query_aliases = ALIASES[filterCrates][query.search];
|
||||
var len = query_aliases.length;
|
||||
@ -694,7 +727,7 @@ window.initSearch = function(rawSearchIndex) {
|
||||
{
|
||||
val = extractGenerics(val.substr(1, val.length - 2));
|
||||
for (i = 0; i < nSearchWords; ++i) {
|
||||
if (filterCrates !== undefined && searchIndex[i].crate !== filterCrates) {
|
||||
if (filterCrates !== null && searchIndex[i].crate !== filterCrates) {
|
||||
continue;
|
||||
}
|
||||
in_args = findArg(searchIndex[i], val, true, typeFilter);
|
||||
@ -725,7 +758,7 @@ window.initSearch = function(rawSearchIndex) {
|
||||
var output = extractGenerics(parts[1]);
|
||||
|
||||
for (i = 0; i < nSearchWords; ++i) {
|
||||
if (filterCrates !== undefined && searchIndex[i].crate !== filterCrates) {
|
||||
if (filterCrates !== null && searchIndex[i].crate !== filterCrates) {
|
||||
continue;
|
||||
}
|
||||
var type = searchIndex[i].type;
|
||||
@ -781,7 +814,7 @@ window.initSearch = function(rawSearchIndex) {
|
||||
var lev, j;
|
||||
for (j = 0; j < nSearchWords; ++j) {
|
||||
ty = searchIndex[j];
|
||||
if (!ty || (filterCrates !== undefined && ty.crate !== filterCrates)) {
|
||||
if (!ty || (filterCrates !== null && ty.crate !== filterCrates)) {
|
||||
continue;
|
||||
}
|
||||
var lev_add = 0;
|
||||
@ -1279,17 +1312,6 @@ window.initSearch = function(rawSearchIndex) {
|
||||
};
|
||||
}
|
||||
|
||||
function getFilterCrates() {
|
||||
var elem = document.getElementById("crate-search");
|
||||
|
||||
if (elem && elem.value !== "All crates" &&
|
||||
hasOwnPropertyRustdoc(rawSearchIndex, elem.value))
|
||||
{
|
||||
return elem.value;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
/**
|
||||
* Perform a search based on the current state of the search input element
|
||||
* and display the results.
|
||||
@ -1309,27 +1331,34 @@ window.initSearch = function(rawSearchIndex) {
|
||||
}
|
||||
if (!forced && query.id === currentResults) {
|
||||
if (query.query.length > 0) {
|
||||
searchState.putBackSearch(searchState.input);
|
||||
putBackSearch();
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
var filterCrates = getFilterCrates();
|
||||
|
||||
// In case we have no information about the saved crate and there is a URL query parameter,
|
||||
// we override it with the URL query parameter.
|
||||
if (filterCrates === null && params["filter-crate"] !== undefined) {
|
||||
filterCrates = params["filter-crate"];
|
||||
}
|
||||
|
||||
// Update document title to maintain a meaningful browser history
|
||||
searchState.title = "Results for " + query.query + " - Rust";
|
||||
|
||||
// Because searching is incremental by character, only the most
|
||||
// recent search query is added to the browser history.
|
||||
if (searchState.browserSupportsHistoryApi()) {
|
||||
var newURL = getNakedUrl() + "?search=" + encodeURIComponent(query.raw) +
|
||||
window.location.hash;
|
||||
var newURL = buildUrl(query.raw, filterCrates);
|
||||
|
||||
if (!history.state && !params.search) {
|
||||
history.pushState(query, "", newURL);
|
||||
history.pushState(null, "", newURL);
|
||||
} else {
|
||||
history.replaceState(query, "", newURL);
|
||||
history.replaceState(null, "", newURL);
|
||||
}
|
||||
}
|
||||
|
||||
var filterCrates = getFilterCrates();
|
||||
showResults(execSearch(query, searchWords, filterCrates),
|
||||
params["go_to_first"], filterCrates);
|
||||
}
|
||||
@ -1495,12 +1524,28 @@ window.initSearch = function(rawSearchIndex) {
|
||||
search();
|
||||
}
|
||||
|
||||
function putBackSearch() {
|
||||
var search_input = searchState.input;
|
||||
if (!searchState.input) {
|
||||
return;
|
||||
}
|
||||
var search = searchState.outputElement();
|
||||
if (search_input.value !== "" && hasClass(search, "hidden")) {
|
||||
searchState.showResults(search);
|
||||
if (searchState.browserSupportsHistoryApi()) {
|
||||
history.replaceState(null, "",
|
||||
buildUrl(search_input.value, getFilterCrates()));
|
||||
}
|
||||
document.title = searchState.title;
|
||||
}
|
||||
}
|
||||
|
||||
function registerSearchEvents() {
|
||||
var searchAfter500ms = function() {
|
||||
searchState.clearInputTimeout();
|
||||
if (searchState.input.value.length === 0) {
|
||||
if (searchState.browserSupportsHistoryApi()) {
|
||||
history.replaceState("", window.currentCrate + " - Rust",
|
||||
history.replaceState(null, window.currentCrate + " - Rust",
|
||||
getNakedUrl() + window.location.hash);
|
||||
}
|
||||
searchState.hideResults();
|
||||
@ -1567,6 +1612,14 @@ window.initSearch = function(rawSearchIndex) {
|
||||
}
|
||||
});
|
||||
|
||||
searchState.input.addEventListener("focus", function() {
|
||||
putBackSearch();
|
||||
});
|
||||
|
||||
searchState.input.addEventListener("blur", function() {
|
||||
searchState.input.placeholder = searchState.input.origPlaceholder;
|
||||
});
|
||||
|
||||
// Push and pop states are used to add search results to the browser
|
||||
// history.
|
||||
if (searchState.browserSupportsHistoryApi()) {
|
||||
@ -1619,7 +1672,16 @@ window.initSearch = function(rawSearchIndex) {
|
||||
}
|
||||
|
||||
function updateCrate(ev) {
|
||||
updateLocalStorage("rustdoc-saved-filter-crate", ev.target.value);
|
||||
if (ev.target.value === "All crates") {
|
||||
// If we don't remove it from the URL, it'll be picked up again by the search.
|
||||
var params = searchState.getQueryStringParams();
|
||||
var query = searchState.input.value.trim();
|
||||
if (!history.state && !params.search) {
|
||||
history.pushState(null, "", buildUrl(query, null));
|
||||
} else {
|
||||
history.replaceState(null, "", buildUrl(query, null));
|
||||
}
|
||||
}
|
||||
// In case you "cut" the entry from the search input, then change the crate filter
|
||||
// before paste back the previous search, you get the old search results without
|
||||
// the filter. To prevent this, we need to remove the previous results.
|
||||
@ -1629,10 +1691,15 @@ window.initSearch = function(rawSearchIndex) {
|
||||
|
||||
searchWords = buildIndex(rawSearchIndex);
|
||||
registerSearchEvents();
|
||||
// If there's a search term in the URL, execute the search now.
|
||||
if (searchState.getQueryStringParams().search) {
|
||||
search();
|
||||
|
||||
function runSearchIfNeeded() {
|
||||
// If there's a search term in the URL, execute the search now.
|
||||
if (searchState.getQueryStringParams().search) {
|
||||
search();
|
||||
}
|
||||
}
|
||||
|
||||
runSearchIfNeeded();
|
||||
};
|
||||
|
||||
if (window.searchIndex !== undefined) {
|
||||
|
@ -4,7 +4,7 @@
|
||||
|
||||
(function () {
|
||||
function changeSetting(settingName, value) {
|
||||
updateLocalStorage("rustdoc-" + settingName, value);
|
||||
updateLocalStorage(settingName, value);
|
||||
|
||||
switch (settingName) {
|
||||
case "theme":
|
||||
|
@ -82,11 +82,11 @@ function toggleSidebar() {
|
||||
if (child.innerText === ">") {
|
||||
sidebar.classList.add("expanded");
|
||||
child.innerText = "<";
|
||||
updateLocalStorage("rustdoc-source-sidebar-show", "true");
|
||||
updateLocalStorage("source-sidebar-show", "true");
|
||||
} else {
|
||||
sidebar.classList.remove("expanded");
|
||||
child.innerText = ">";
|
||||
updateLocalStorage("rustdoc-source-sidebar-show", "false");
|
||||
updateLocalStorage("source-sidebar-show", "false");
|
||||
}
|
||||
}
|
||||
|
||||
@ -97,7 +97,7 @@ function createSidebarToggle() {
|
||||
|
||||
var inner = document.createElement("div");
|
||||
|
||||
if (getCurrentValue("rustdoc-source-sidebar-show") === "true") {
|
||||
if (getCurrentValue("source-sidebar-show") === "true") {
|
||||
inner.innerText = "<";
|
||||
} else {
|
||||
inner.innerText = ">";
|
||||
@ -120,7 +120,7 @@ function createSourceSidebar() {
|
||||
|
||||
var sidebar = document.createElement("div");
|
||||
sidebar.id = "source-sidebar";
|
||||
if (getCurrentValue("rustdoc-source-sidebar-show") !== "true") {
|
||||
if (getCurrentValue("source-sidebar-show") !== "true") {
|
||||
container.classList.remove("expanded");
|
||||
} else {
|
||||
container.classList.add("expanded");
|
||||
|
@ -15,7 +15,7 @@ var settingsDataset = (function () {
|
||||
})();
|
||||
|
||||
function getSettingValue(settingName) {
|
||||
var current = getCurrentValue('rustdoc-' + settingName);
|
||||
var current = getCurrentValue(settingName);
|
||||
if (current !== null) {
|
||||
return current;
|
||||
}
|
||||
@ -106,7 +106,7 @@ function hasOwnPropertyRustdoc(obj, property) {
|
||||
|
||||
function updateLocalStorage(name, value) {
|
||||
try {
|
||||
window.localStorage.setItem(name, value);
|
||||
window.localStorage.setItem("rustdoc-" + name, value);
|
||||
} catch(e) {
|
||||
// localStorage is not accessible, do nothing
|
||||
}
|
||||
@ -114,7 +114,7 @@ function updateLocalStorage(name, value) {
|
||||
|
||||
function getCurrentValue(name) {
|
||||
try {
|
||||
return window.localStorage.getItem(name);
|
||||
return window.localStorage.getItem("rustdoc-" + name);
|
||||
} catch(e) {
|
||||
return null;
|
||||
}
|
||||
@ -127,7 +127,7 @@ function switchTheme(styleElem, mainStyleElem, newTheme, saveTheme) {
|
||||
// If this new value comes from a system setting or from the previously
|
||||
// saved theme, no need to save it.
|
||||
if (saveTheme) {
|
||||
updateLocalStorage("rustdoc-theme", newTheme);
|
||||
updateLocalStorage("theme", newTheme);
|
||||
}
|
||||
|
||||
if (styleElem.href === newHref) {
|
||||
@ -158,7 +158,7 @@ function useSystemTheme(value) {
|
||||
value = true;
|
||||
}
|
||||
|
||||
updateLocalStorage("rustdoc-use-system-theme", value);
|
||||
updateLocalStorage("use-system-theme", value);
|
||||
|
||||
// update the toggle if we're on the settings page
|
||||
var toggle = document.getElementById("use-system-theme");
|
||||
@ -231,7 +231,7 @@ if (getSettingValue("use-system-theme") !== "false" && window.matchMedia) {
|
||||
if (getSettingValue("use-system-theme") === null
|
||||
&& getSettingValue("preferred-dark-theme") === null
|
||||
&& darkThemes.indexOf(localStoredTheme) >= 0) {
|
||||
updateLocalStorage("rustdoc-preferred-dark-theme", localStoredTheme);
|
||||
updateLocalStorage("preferred-dark-theme", localStoredTheme);
|
||||
}
|
||||
|
||||
// call the function to initialize the theme at least once!
|
||||
|
@ -247,8 +247,7 @@ fn visit_expr(&mut self, ex: &'tcx hir::Expr<'tcx>) {
|
||||
let target_crates = options
|
||||
.target_crates
|
||||
.into_iter()
|
||||
.map(|target| all_crates.iter().filter(move |(_, name)| name.as_str() == target))
|
||||
.flatten()
|
||||
.flat_map(|target| all_crates.iter().filter(move |(_, name)| name.as_str() == target))
|
||||
.map(|(crate_num, _)| **crate_num)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
|
@ -11,8 +11,38 @@ wait-for: "#crate-search"
|
||||
click: "#crate-search"
|
||||
// We select "lib2" option then press enter to change the filter.
|
||||
press-key: "ArrowDown"
|
||||
press-key: "ArrowDown"
|
||||
press-key: "Enter"
|
||||
// Waiting for the search results to appear...
|
||||
wait-for: "#titles"
|
||||
// We check that there is no more "test_docs" appearing.
|
||||
assert-false: "#results .externcrate"
|
||||
// We also check that "lib2" is the filter crate.
|
||||
assert-property: ("#crate-search", {"value": "lib2"})
|
||||
|
||||
// Now we check that leaving the search results and putting them back keeps the
|
||||
// crate filtering.
|
||||
press-key: "Escape"
|
||||
wait-for: 100
|
||||
assert-css: ("#main-content", {"display": "block"})
|
||||
focus: ".search-input"
|
||||
wait-for: 100
|
||||
assert-css: ("#main-content", {"display": "none"})
|
||||
// We check that there is no more "test_docs" appearing.
|
||||
assert-false: "#results .externcrate"
|
||||
assert-property: ("#crate-search", {"value": "lib2"})
|
||||
|
||||
// Selecting back "All crates"
|
||||
click: "#crate-search"
|
||||
press-key: "ArrowUp"
|
||||
press-key: "ArrowUp"
|
||||
press-key: "Enter"
|
||||
// Waiting for the search results to appear...
|
||||
wait-for: "#titles"
|
||||
assert-property: ("#crate-search", {"value": "All crates"})
|
||||
|
||||
// Checking that the URL parameter is taken into account for crate filtering.
|
||||
goto: file://|DOC_PATH|/test_docs/index.html?search=test&filter-crate=lib2
|
||||
wait-for: "#crate-search"
|
||||
assert-property: ("#crate-search", {"value": "lib2"})
|
||||
assert-false: "#results .externcrate"
|
||||
|
23
src/test/ui/associated-consts/shadowed-const.rs
Normal file
23
src/test/ui/associated-consts/shadowed-const.rs
Normal file
@ -0,0 +1,23 @@
|
||||
// Checking that none of these ICE, which was introduced in
|
||||
// https://github.com/rust-lang/rust/issues/93553
|
||||
trait Foo {
|
||||
type Bar;
|
||||
}
|
||||
|
||||
trait Baz: Foo {
|
||||
const Bar: Self::Bar;
|
||||
}
|
||||
|
||||
trait Baz2: Foo {
|
||||
const Bar: u32;
|
||||
|
||||
fn foo() -> Self::Bar;
|
||||
}
|
||||
|
||||
trait Baz3 {
|
||||
const BAR: usize;
|
||||
const QUX: Self::BAR;
|
||||
//~^ ERROR found associated const
|
||||
}
|
||||
|
||||
fn main() {}
|
8
src/test/ui/associated-consts/shadowed-const.stderr
Normal file
8
src/test/ui/associated-consts/shadowed-const.stderr
Normal file
@ -0,0 +1,8 @@
|
||||
error: found associated const `BAR` when type was expected
|
||||
--> $DIR/shadowed-const.rs:19:14
|
||||
|
|
||||
LL | const QUX: Self::BAR;
|
||||
| ^^^^^^^^^
|
||||
|
||||
error: aborting due to previous error
|
||||
|
@ -2424,7 +2424,10 @@ fn run_rustdoc_json_test(&self) {
|
||||
);
|
||||
|
||||
if !res.status.success() {
|
||||
self.fatal_proc_rec("jsondocck failed!", &res)
|
||||
self.fatal_proc_rec_with_ctx("jsondocck failed!", &res, |_| {
|
||||
println!("Rustdoc Output:");
|
||||
proc_res.print_info();
|
||||
})
|
||||
}
|
||||
|
||||
let mut json_out = out_dir.join(self.testpaths.file.file_stem().unwrap());
|
||||
@ -3738,10 +3741,7 @@ pub struct ProcRes {
|
||||
}
|
||||
|
||||
impl ProcRes {
|
||||
pub fn fatal(&self, err: Option<&str>, on_failure: impl FnOnce()) -> ! {
|
||||
if let Some(e) = err {
|
||||
println!("\nerror: {}", e);
|
||||
}
|
||||
pub fn print_info(&self) {
|
||||
print!(
|
||||
"\
|
||||
status: {}\n\
|
||||
@ -3760,6 +3760,13 @@ pub fn fatal(&self, err: Option<&str>, on_failure: impl FnOnce()) -> ! {
|
||||
json::extract_rendered(&self.stdout),
|
||||
json::extract_rendered(&self.stderr),
|
||||
);
|
||||
}
|
||||
|
||||
pub fn fatal(&self, err: Option<&str>, on_failure: impl FnOnce()) -> ! {
|
||||
if let Some(e) = err {
|
||||
println!("\nerror: {}", e);
|
||||
}
|
||||
self.print_info();
|
||||
on_failure();
|
||||
// Use resume_unwind instead of panic!() to prevent a panic message + backtrace from
|
||||
// compiletest, which is unnecessary noise.
|
||||
|
@ -357,6 +357,8 @@ function runChecks(testFile, loaded, index) {
|
||||
var testFileContent = readFile(testFile) + 'exports.QUERY = QUERY;exports.EXPECTED = EXPECTED;';
|
||||
if (testFileContent.indexOf("FILTER_CRATE") !== -1) {
|
||||
testFileContent += "exports.FILTER_CRATE = FILTER_CRATE;";
|
||||
} else {
|
||||
testFileContent += "exports.FILTER_CRATE = null;";
|
||||
}
|
||||
var loadedFile = loadContent(testFileContent);
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user