Skip to content

Commit

Permalink
Auto merge of rust-lang#92216 - matthiaskrgr:rollup-luplvuc, r=matthi…
Browse files Browse the repository at this point in the history
…askrgr

Rollup of 7 pull requests

Successful merges:

 - rust-lang#88858 (Allow reverse iteration of lowercase'd/uppercase'd chars)
 - rust-lang#91544 (Fix duplicate derive clone suggestion)
 - rust-lang#92026 (Add some JSDoc comments to rustdoc JS)
 - rust-lang#92117 (kmc-solid: Add `std::sys::solid::fs::File::read_buf`)
 - rust-lang#92139 (Change Backtrace::enabled atomic from SeqCst to Relaxed)
 - rust-lang#92146 (Don't emit shared files when scraping examples from dependencies in Rustdoc)
 - rust-lang#92208 (Quote bat script command line)

Failed merges:

r? `@ghost`
`@rustbot` modify labels: rollup
  • Loading branch information
bors committed Dec 23, 2021
2 parents e983092 + 3afed8f commit 5aa0239
Show file tree
Hide file tree
Showing 18 changed files with 418 additions and 57 deletions.
33 changes: 17 additions & 16 deletions compiler/rustc_typeck/src/check/method/suggest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1195,11 +1195,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
fn suggest_derive(
&self,
err: &mut DiagnosticBuilder<'_>,
unsatisfied_predicates: &Vec<(
unsatisfied_predicates: &[(
ty::Predicate<'tcx>,
Option<ty::Predicate<'tcx>>,
Option<ObligationCause<'tcx>>,
)>,
)],
) {
let mut derives = Vec::<(String, Span, String)>::new();
let mut traits = Vec::<Span>::new();
Expand Down Expand Up @@ -1236,23 +1236,24 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
traits.push(self.tcx.def_span(trait_pred.def_id()));
}
}
derives.sort();
let derives_grouped = derives.into_iter().fold(
Vec::<(String, Span, String)>::new(),
|mut acc, (self_name, self_span, trait_name)| {
if let Some((acc_self_name, _, ref mut traits)) = acc.last_mut() {
if acc_self_name == &self_name {
traits.push_str(format!(", {}", trait_name).as_str());
return acc;
}
}
acc.push((self_name, self_span, trait_name));
acc
},
);
traits.sort();
traits.dedup();

derives.sort();
derives.dedup();

let mut derives_grouped = Vec::<(String, Span, String)>::new();
for (self_name, self_span, trait_name) in derives.into_iter() {
if let Some((last_self_name, _, ref mut last_trait_names)) = derives_grouped.last_mut()
{
if last_self_name == &self_name {
last_trait_names.push_str(format!(", {}", trait_name).as_str());
continue;
}
}
derives_grouped.push((self_name, self_span, trait_name));
}

let len = traits.len();
if len > 0 {
let span: MultiSpan = traits.into();
Expand Down
31 changes: 31 additions & 0 deletions library/alloc/tests/str.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1183,6 +1183,37 @@ fn test_rev_iterator() {
assert_eq!(pos, v.len());
}

#[test]
fn test_to_lowercase_rev_iterator() {
let s = "AÖßÜ💩ΣΤΙΓΜΑΣDžfiİ";
let v = ['\u{307}', 'i', 'fi', 'dž', 'σ', 'α', 'μ', 'γ', 'ι', 'τ', 'σ', '💩', 'ü', 'ß', 'ö', 'a'];

let mut pos = 0;
let it = s.chars().flat_map(|c| c.to_lowercase()).rev();

for c in it {
assert_eq!(c, v[pos]);
pos += 1;
}
assert_eq!(pos, v.len());
}

#[test]
fn test_to_uppercase_rev_iterator() {
let s = "aößü💩στιγμαςDžfiᾀ";
let v =
['Ι', 'Ἀ', 'I', 'F', 'DŽ', 'Σ', 'Α', 'Μ', 'Γ', 'Ι', 'Τ', 'Σ', '💩', 'Ü', 'S', 'S', 'Ö', 'A'];

let mut pos = 0;
let it = s.chars().flat_map(|c| c.to_uppercase()).rev();

for c in it {
assert_eq!(c, v[pos]);
pos += 1;
}
assert_eq!(pos, v.len());
}

#[test]
#[cfg_attr(miri, ignore)] // Miri is too slow
fn test_chars_decoding() {
Expand Down
34 changes: 34 additions & 0 deletions library/core/src/char/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -393,6 +393,13 @@ impl Iterator for ToLowercase {
}
}

#[stable(feature = "case_mapping_double_ended", since = "1.59.0")]
impl DoubleEndedIterator for ToLowercase {
fn next_back(&mut self) -> Option<char> {
self.0.next_back()
}
}

#[stable(feature = "fused", since = "1.26.0")]
impl FusedIterator for ToLowercase {}

Expand Down Expand Up @@ -420,6 +427,13 @@ impl Iterator for ToUppercase {
}
}

#[stable(feature = "case_mapping_double_ended", since = "1.59.0")]
impl DoubleEndedIterator for ToUppercase {
fn next_back(&mut self) -> Option<char> {
self.0.next_back()
}
}

#[stable(feature = "fused", since = "1.26.0")]
impl FusedIterator for ToUppercase {}

Expand Down Expand Up @@ -479,6 +493,26 @@ impl Iterator for CaseMappingIter {
}
}

impl DoubleEndedIterator for CaseMappingIter {
fn next_back(&mut self) -> Option<char> {
match *self {
CaseMappingIter::Three(a, b, c) => {
*self = CaseMappingIter::Two(a, b);
Some(c)
}
CaseMappingIter::Two(b, c) => {
*self = CaseMappingIter::One(b);
Some(c)
}
CaseMappingIter::One(c) => {
*self = CaseMappingIter::Zero;
Some(c)
}
CaseMappingIter::Zero => None,
}
}
}

impl fmt::Display for CaseMappingIter {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match *self {
Expand Down
6 changes: 6 additions & 0 deletions library/core/tests/char.rs
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,9 @@ fn test_to_lowercase() {
let iter: String = c.to_lowercase().collect();
let disp: String = c.to_lowercase().to_string();
assert_eq!(iter, disp);
let iter_rev: String = c.to_lowercase().rev().collect();
let disp_rev: String = disp.chars().rev().collect();
assert_eq!(iter_rev, disp_rev);
iter
}
assert_eq!(lower('A'), "a");
Expand Down Expand Up @@ -130,6 +133,9 @@ fn test_to_uppercase() {
let iter: String = c.to_uppercase().collect();
let disp: String = c.to_uppercase().to_string();
assert_eq!(iter, disp);
let iter_rev: String = c.to_uppercase().rev().collect();
let disp_rev: String = disp.chars().rev().collect();
assert_eq!(iter_rev, disp_rev);
iter
}
assert_eq!(upper('a'), "A");
Expand Down
6 changes: 3 additions & 3 deletions library/std/src/backtrace.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ use crate::cell::UnsafeCell;
use crate::env;
use crate::ffi::c_void;
use crate::fmt;
use crate::sync::atomic::{AtomicUsize, Ordering::SeqCst};
use crate::sync::atomic::{AtomicUsize, Ordering::Relaxed};
use crate::sync::Once;
use crate::sys_common::backtrace::{lock, output_filename};
use crate::vec::Vec;
Expand Down Expand Up @@ -256,7 +256,7 @@ impl Backtrace {
// backtrace captures speedy, because otherwise reading environment
// variables every time can be somewhat slow.
static ENABLED: AtomicUsize = AtomicUsize::new(0);
match ENABLED.load(SeqCst) {
match ENABLED.load(Relaxed) {
0 => {}
1 => return false,
_ => return true,
Expand All @@ -268,7 +268,7 @@ impl Backtrace {
Err(_) => false,
},
};
ENABLED.store(enabled as usize + 1, SeqCst);
ENABLED.store(enabled as usize + 1, Relaxed);
enabled
}

Expand Down
19 changes: 19 additions & 0 deletions library/std/src/process/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -420,3 +420,22 @@ fn env_empty() {
let p = Command::new("cmd").args(&["/C", "exit 0"]).env_clear().spawn();
assert!(p.is_ok());
}

// See issue #91991
#[test]
#[cfg(windows)]
fn run_bat_script() {
let tempdir = crate::sys_common::io::test::tmpdir();
let script_path = tempdir.join("hello.cmd");

crate::fs::write(&script_path, "@echo Hello, %~1!").unwrap();
let output = Command::new(&script_path)
.arg("fellow Rustaceans")
.stdout(crate::process::Stdio::piped())
.spawn()
.unwrap()
.wait_with_output()
.unwrap();
assert!(output.status.success());
assert_eq!(String::from_utf8_lossy(&output.stdout).trim(), "Hello, fellow Rustaceans!");
}
28 changes: 27 additions & 1 deletion library/std/src/sys/solid/fs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ use super::{abi, error};
use crate::{
ffi::{CStr, CString, OsStr, OsString},
fmt,
io::{self, IoSlice, IoSliceMut, SeekFrom},
io::{self, IoSlice, IoSliceMut, ReadBuf, SeekFrom},
mem::MaybeUninit,
os::raw::{c_int, c_short},
os::solid::ffi::OsStrExt,
Expand Down Expand Up @@ -339,6 +339,32 @@ impl File {
}
}

pub fn read_buf(&self, buf: &mut ReadBuf<'_>) -> io::Result<()> {
unsafe {
let len = buf.remaining();
let mut out_num_bytes = MaybeUninit::uninit();
error::SolidError::err_if_negative(abi::SOLID_FS_Read(
self.fd.raw(),
buf.unfilled_mut().as_mut_ptr() as *mut u8,
len,
out_num_bytes.as_mut_ptr(),
))
.map_err(|e| e.as_io_error())?;

// Safety: `out_num_bytes` is filled by the successful call to
// `SOLID_FS_Read`
let num_bytes_read = out_num_bytes.assume_init();

// Safety: `num_bytes_read` bytes were written to the unfilled
// portion of the buffer
buf.assume_init(num_bytes_read);

buf.add_filled(num_bytes_read);

Ok(())
}
}

pub fn read_vectored(&self, bufs: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
crate::io::default_read_vectored(|buf| self.read(buf), bufs)
}
Expand Down
16 changes: 16 additions & 0 deletions library/std/src/sys/windows/process.rs
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,19 @@ fn make_command_line(prog: &OsStr, args: &[Arg], force_quotes: bool) -> io::Resu
// Encode the command and arguments in a command line string such
// that the spawned process may recover them using CommandLineToArgvW.
let mut cmd: Vec<u16> = Vec::new();

// CreateFileW has special handling for .bat and .cmd files, which means we
// need to add an extra pair of quotes surrounding the whole command line
// so they are properly passed on to the script.
// See issue #91991.
let is_batch_file = Path::new(prog)
.extension()
.map(|ext| ext.eq_ignore_ascii_case("cmd") || ext.eq_ignore_ascii_case("bat"))
.unwrap_or(false);
if is_batch_file {
cmd.push(b'"' as u16);
}

// Always quote the program name so CreateProcess doesn't interpret args as
// part of the name if the binary wasn't found first time.
append_arg(&mut cmd, prog, Quote::Always)?;
Expand All @@ -715,6 +728,9 @@ fn make_command_line(prog: &OsStr, args: &[Arg], force_quotes: bool) -> io::Resu
};
append_arg(&mut cmd, arg, quote)?;
}
if is_batch_file {
cmd.push(b'"' as u16);
}
return Ok(cmd);

fn append_arg(cmd: &mut Vec<u16>, arg: &OsStr, quote: Quote) -> io::Result<()> {
Expand Down
4 changes: 4 additions & 0 deletions src/librustdoc/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -272,7 +272,10 @@ crate struct RenderOptions {
crate emit: Vec<EmitType>,
/// If `true`, HTML source pages will generate links for items to their definition.
crate generate_link_to_definition: bool,
/// Set of function-call locations to include as examples
crate call_locations: AllCallLocations,
/// If `true`, Context::init will not emit shared files.
crate no_emit_shared: bool,
}

#[derive(Copy, Clone, Debug, PartialEq, Eq)]
Expand Down Expand Up @@ -732,6 +735,7 @@ impl Options {
emit,
generate_link_to_definition,
call_locations,
no_emit_shared: false,
},
crate_name,
output_format,
Expand Down
16 changes: 10 additions & 6 deletions src/librustdoc/html/render/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -397,6 +397,7 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
show_type_layout,
generate_link_to_definition,
call_locations,
no_emit_shared,
..
} = options;

Expand Down Expand Up @@ -516,13 +517,16 @@ impl<'tcx> FormatRenderer<'tcx> for Context<'tcx> {
sources::render(&mut cx, &krate)?;
}

// Build our search index
let index = build_index(&krate, &mut Rc::get_mut(&mut cx.shared).unwrap().cache, tcx);
if !no_emit_shared {
// Build our search index
let index = build_index(&krate, &mut Rc::get_mut(&mut cx.shared).unwrap().cache, tcx);

// Write shared runs within a flock; disable thread dispatching of IO temporarily.
Rc::get_mut(&mut cx.shared).unwrap().fs.set_sync_only(true);
write_shared(&cx, &krate, index, &md_opts)?;
Rc::get_mut(&mut cx.shared).unwrap().fs.set_sync_only(false);
}

// Write shared runs within a flock; disable thread dispatching of IO temporarily.
Rc::get_mut(&mut cx.shared).unwrap().fs.set_sync_only(true);
write_shared(&cx, &krate, index, &md_opts)?;
Rc::get_mut(&mut cx.shared).unwrap().fs.set_sync_only(false);
Ok((cx, krate))
}

Expand Down
15 changes: 15 additions & 0 deletions src/librustdoc/html/static/js/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
# Rustdoc JS

These JavaScript files are incorporated into the rustdoc binary at build time,
and are minified and written to the filesystem as part of the doc build process.

We use the [Closure Compiler](https://github.com/google/closure-compiler/wiki/Annotating-JavaScript-for-the-Closure-Compiler)
dialect of JSDoc to comment our code and annotate params and return types.
To run a check:

./x.py doc library/std
npm i -g google-closure-compiler
google-closure-compiler -W VERBOSE \
build/<YOUR PLATFORM>/doc/{search-index*.js,crates*.js} \
src/librustdoc/html/static/js/{search.js,main.js,storage.js} \
--externs src/librustdoc/html/static/js/externs.js >/dev/null
32 changes: 32 additions & 0 deletions src/librustdoc/html/static/js/externs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
// This file contains type definitions that are processed by the Closure Compiler but are
// not put into the JavaScript we include as part of the documentation. It is used for
// type checking. See README.md in this directory for more info.

/* eslint-disable */
var searchState;
function initSearch(searchIndex){}

/**
* @typedef {{
* raw: string,
* query: string,
* type: string,
* id: string,
* }}
*/
var ParsedQuery;

/**
* @typedef {{
* crate: string,
* desc: string,
* id: number,
* name: string,
* normalizedName: string,
* parent: (Object|null|undefined),
* path: string,
* ty: (Number|null|number),
* type: (Array<?>|null)
* }}
*/
var Row;
Loading

0 comments on commit 5aa0239

Please sign in to comment.