diff options
Diffstat (limited to 'src')
17 files changed, 283 insertions, 44 deletions
diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 8ee6d49da8f..3f551dc119b 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -744,6 +744,7 @@ impl<'a> Builder<'a> { install::RustDemangler, install::Clippy, install::Miri, + install::LlvmTools, install::Analysis, install::Src, install::Rustc diff --git a/src/bootstrap/format.rs b/src/bootstrap/format.rs index 5e7264fe765..b2f6afead79 100644 --- a/src/bootstrap/format.rs +++ b/src/bootstrap/format.rs @@ -8,7 +8,7 @@ use std::path::{Path, PathBuf}; use std::process::{Command, Stdio}; use std::sync::mpsc::SyncSender; -fn rustfmt(src: &Path, rustfmt: &Path, paths: &[PathBuf], check: bool) -> impl FnMut() { +fn rustfmt(src: &Path, rustfmt: &Path, paths: &[PathBuf], check: bool) -> impl FnMut(bool) -> bool { let mut cmd = Command::new(&rustfmt); // avoid the submodule config paths from coming into play, // we only allow a single global config for the workspace for now @@ -23,7 +23,13 @@ fn rustfmt(src: &Path, rustfmt: &Path, paths: &[PathBuf], check: bool) -> impl F let cmd_debug = format!("{:?}", cmd); let mut cmd = cmd.spawn().expect("running rustfmt"); // poor man's async: return a closure that'll wait for rustfmt's completion - move || { + move |block: bool| -> bool { + if !block { + match cmd.try_wait() { + Ok(Some(_)) => {} + _ => return false, + } + } let status = cmd.wait().unwrap(); if !status.success() { eprintln!( @@ -34,6 +40,7 @@ fn rustfmt(src: &Path, rustfmt: &Path, paths: &[PathBuf], check: bool) -> impl F ); crate::detail_exit(1); } + true } } @@ -146,15 +153,23 @@ pub fn format(build: &Builder<'_>, check: bool, paths: &[PathBuf]) { let child = rustfmt(&src, &rustfmt_path, paths.as_slice(), check); children.push_back(child); + // poll completion before waiting + for i in (0..children.len()).rev() { + if children[i](false) { + children.swap_remove_back(i); + break; + } + } + if children.len() >= max_processes { // await oldest child - children.pop_front().unwrap()(); + children.pop_front().unwrap()(true); } } // await remaining children for mut child in children { - child(); + child(true); } }); diff --git a/src/bootstrap/install.rs b/src/bootstrap/install.rs index 7672b7c9135..c53d0d7e4cb 100644 --- a/src/bootstrap/install.rs +++ b/src/bootstrap/install.rs @@ -205,6 +205,12 @@ install!((self, builder, _config), .expect("missing miri"); install_sh(builder, "miri", self.compiler.stage, Some(self.target), &tarball); }; + LlvmTools, alias = "llvm-tools", Self::should_build(_config), only_hosts: true, { + let tarball = builder + .ensure(dist::LlvmTools { target: self.target }) + .expect("missing llvm-tools"); + install_sh(builder, "llvm-tools", self.compiler.stage, Some(self.target), &tarball); + }; Rustfmt, alias = "rustfmt", Self::should_build(_config), only_hosts: true, { if let Some(tarball) = builder.ensure(dist::Rustfmt { compiler: self.compiler, diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 570fe6484e3..f0c9a948727 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -108,6 +108,7 @@ use std::collections::{HashMap, HashSet}; use std::env; use std::fs::{self, File}; use std::io; +use std::io::ErrorKind; use std::path::{Path, PathBuf}; use std::process::Command; use std::str; @@ -119,7 +120,9 @@ use once_cell::sync::OnceCell; use crate::builder::Kind; use crate::config::{LlvmLibunwind, TargetSelection}; -use crate::util::{exe, libdir, mtime, output, run, run_suppressed, try_run_suppressed, CiEnv}; +use crate::util::{ + exe, libdir, mtime, output, run, run_suppressed, symlink_dir, try_run_suppressed, CiEnv, +}; mod bolt; mod builder; @@ -586,6 +589,20 @@ impl Build { metadata::build(&mut build); } + // Make a symbolic link so we can use a consistent directory in the documentation. + let build_triple = build.out.join(&build.build.triple); + let host = build.out.join("host"); + if let Err(e) = symlink_dir(&build.config, &build_triple, &host) { + if e.kind() != ErrorKind::AlreadyExists { + panic!( + "symlink_dir({} => {}) failed with {}", + host.display(), + build_triple.display(), + e + ); + } + } + build } diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index a65bec37e1d..022ed606cc3 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -2003,7 +2003,6 @@ in storage.js .more-examples-toggle .hide-more { margin-left: 25px; - margin-bottom: 5px; cursor: pointer; } @@ -2031,16 +2030,12 @@ in storage.js height: 100%; } -.more-scraped-examples .scraped-example { - margin-bottom: 20px; -} - -.more-scraped-examples .scraped-example:last-child { - margin-bottom: 0; +.more-scraped-examples .scraped-example, .example-links { + margin-top: 20px; } -.example-links a { - margin-top: 20px; +.more-scraped-examples .scraped-example:first-child { + margin-top: 5px; } .example-links ul { diff --git a/src/test/mir-opt/building/custom/terminators.assert_nonzero.built.after.mir b/src/test/mir-opt/building/custom/terminators.assert_nonzero.built.after.mir new file mode 100644 index 00000000000..a1a27226b4e --- /dev/null +++ b/src/test/mir-opt/building/custom/terminators.assert_nonzero.built.after.mir @@ -0,0 +1,17 @@ +// MIR for `assert_nonzero` after built + +fn assert_nonzero(_1: i32) -> () { + let mut _0: (); // return place in scope 0 at $DIR/terminators.rs:+0:27: +0:27 + + bb0: { + switchInt(_1) -> [0: bb1, otherwise: bb2]; // scope 0 at $DIR/terminators.rs:+3:13: +6:14 + } + + bb1: { + unreachable; // scope 0 at $DIR/terminators.rs:+10:13: +10:26 + } + + bb2: { + return; // scope 0 at $DIR/terminators.rs:+14:13: +14:21 + } +} diff --git a/src/test/mir-opt/building/custom/terminators.direct_call.built.after.mir b/src/test/mir-opt/building/custom/terminators.direct_call.built.after.mir new file mode 100644 index 00000000000..1b2345a965e --- /dev/null +++ b/src/test/mir-opt/building/custom/terminators.direct_call.built.after.mir @@ -0,0 +1,16 @@ +// MIR for `direct_call` after built + +fn direct_call(_1: i32) -> i32 { + let mut _0: i32; // return place in scope 0 at $DIR/terminators.rs:+0:27: +0:30 + + bb0: { + _0 = ident::<i32>(_1) -> bb1; // scope 0 at $DIR/terminators.rs:+3:13: +3:42 + // mir::Constant + // + span: $DIR/terminators.rs:15:33: 15:38 + // + literal: Const { ty: fn(i32) -> i32 {ident::<i32>}, val: Value(<ZST>) } + } + + bb1: { + return; // scope 0 at $DIR/terminators.rs:+7:13: +7:21 + } +} diff --git a/src/test/mir-opt/building/custom/terminators.drop_first.built.after.mir b/src/test/mir-opt/building/custom/terminators.drop_first.built.after.mir new file mode 100644 index 00000000000..c903e594696 --- /dev/null +++ b/src/test/mir-opt/building/custom/terminators.drop_first.built.after.mir @@ -0,0 +1,13 @@ +// MIR for `drop_first` after built + +fn drop_first(_1: WriteOnDrop<'_>, _2: WriteOnDrop<'_>) -> () { + let mut _0: (); // return place in scope 0 at $DIR/terminators.rs:+0:59: +0:59 + + bb0: { + replace(_1 <- move _2) -> bb1; // scope 0 at $DIR/terminators.rs:+3:13: +3:49 + } + + bb1: { + return; // scope 0 at $DIR/terminators.rs:+7:13: +7:21 + } +} diff --git a/src/test/mir-opt/building/custom/terminators.drop_second.built.after.mir b/src/test/mir-opt/building/custom/terminators.drop_second.built.after.mir new file mode 100644 index 00000000000..f14246f2d12 --- /dev/null +++ b/src/test/mir-opt/building/custom/terminators.drop_second.built.after.mir @@ -0,0 +1,13 @@ +// MIR for `drop_second` after built + +fn drop_second(_1: WriteOnDrop<'_>, _2: WriteOnDrop<'_>) -> () { + let mut _0: (); // return place in scope 0 at $DIR/terminators.rs:+0:60: +0:60 + + bb0: { + drop(_2) -> bb1; // scope 0 at $DIR/terminators.rs:+3:13: +3:30 + } + + bb1: { + return; // scope 0 at $DIR/terminators.rs:+7:13: +7:21 + } +} diff --git a/src/test/mir-opt/building/custom/terminators.indirect_call.built.after.mir b/src/test/mir-opt/building/custom/terminators.indirect_call.built.after.mir new file mode 100644 index 00000000000..2f1b14069ab --- /dev/null +++ b/src/test/mir-opt/building/custom/terminators.indirect_call.built.after.mir @@ -0,0 +1,13 @@ +// MIR for `indirect_call` after built + +fn indirect_call(_1: i32, _2: fn(i32) -> i32) -> i32 { + let mut _0: i32; // return place in scope 0 at $DIR/terminators.rs:+0:48: +0:51 + + bb0: { + _0 = _2(_1) -> bb1; // scope 0 at $DIR/terminators.rs:+3:13: +3:38 + } + + bb1: { + return; // scope 0 at $DIR/terminators.rs:+7:13: +7:21 + } +} diff --git a/src/test/mir-opt/building/custom/terminators.rs b/src/test/mir-opt/building/custom/terminators.rs new file mode 100644 index 00000000000..c23233fcf9a --- /dev/null +++ b/src/test/mir-opt/building/custom/terminators.rs @@ -0,0 +1,108 @@ +#![feature(custom_mir, core_intrinsics)] + +extern crate core; +use core::intrinsics::mir::*; + +fn ident<T>(t: T) -> T { + t +} + +// EMIT_MIR terminators.direct_call.built.after.mir +#[custom_mir(dialect = "built")] +fn direct_call(x: i32) -> i32 { + mir!( + { + Call(RET, retblock, ident(x)) + } + + retblock = { + Return() + } + ) +} + +// EMIT_MIR terminators.indirect_call.built.after.mir +#[custom_mir(dialect = "built")] +fn indirect_call(x: i32, f: fn(i32) -> i32) -> i32 { + mir!( + { + Call(RET, retblock, f(x)) + } + + retblock = { + Return() + } + ) +} + +struct WriteOnDrop<'a>(&'a mut i32, i32); + +impl<'a> Drop for WriteOnDrop<'a> { + fn drop(&mut self) { + *self.0 = self.1; + } +} + +// EMIT_MIR terminators.drop_first.built.after.mir +#[custom_mir(dialect = "built")] +fn drop_first<'a>(a: WriteOnDrop<'a>, b: WriteOnDrop<'a>) { + mir!( + { + DropAndReplace(a, Move(b), retblock) + } + + retblock = { + Return() + } + ) +} + +// EMIT_MIR terminators.drop_second.built.after.mir +#[custom_mir(dialect = "built")] +fn drop_second<'a>(a: WriteOnDrop<'a>, b: WriteOnDrop<'a>) { + mir!( + { + Drop(b, retblock) + } + + retblock = { + Return() + } + ) +} + +// EMIT_MIR terminators.assert_nonzero.built.after.mir +#[custom_mir(dialect = "built")] +fn assert_nonzero(a: i32) { + mir!( + { + match a { + 0 => unreachable, + _ => retblock + } + } + + unreachable = { + Unreachable() + } + + retblock = { + Return() + } + ) +} + +fn main() { + assert_eq!(direct_call(5), 5); + assert_eq!(indirect_call(5, ident), 5); + + let mut a = 0; + let mut b = 0; + drop_first(WriteOnDrop(&mut a, 1), WriteOnDrop(&mut b, 1)); + assert_eq!((a, b), (1, 0)); + + let mut a = 0; + let mut b = 0; + drop_second(WriteOnDrop(&mut a, 1), WriteOnDrop(&mut b, 1)); + assert_eq!((a, b), (0, 1)); +} diff --git a/src/test/ui/dropck/dropck_no_diverge_on_nonregular_1.stderr b/src/test/ui/dropck/dropck_no_diverge_on_nonregular_1.stderr index c447e2f7987..3e39d15f9b0 100644 --- a/src/test/ui/dropck/dropck_no_diverge_on_nonregular_1.stderr +++ b/src/test/ui/dropck/dropck_no_diverge_on_nonregular_1.stderr @@ -8,3 +8,4 @@ LL | let ft = error: aborting due to previous error +For more information about this error, try `rustc --explain E0320`. diff --git a/src/test/ui/dropck/dropck_no_diverge_on_nonregular_2.stderr b/src/test/ui/dropck/dropck_no_diverge_on_nonregular_2.stderr index cd4706dd903..dbb74354471 100644 --- a/src/test/ui/dropck/dropck_no_diverge_on_nonregular_2.stderr +++ b/src/test/ui/dropck/dropck_no_diverge_on_nonregular_2.stderr @@ -8,3 +8,4 @@ LL | let ft = error: aborting due to previous error +For more information about this error, try `rustc --explain E0320`. diff --git a/src/test/ui/dropck/dropck_no_diverge_on_nonregular_3.stderr b/src/test/ui/dropck/dropck_no_diverge_on_nonregular_3.stderr index 18cd1b6cd41..deaf116b647 100644 --- a/src/test/ui/dropck/dropck_no_diverge_on_nonregular_3.stderr +++ b/src/test/ui/dropck/dropck_no_diverge_on_nonregular_3.stderr @@ -16,3 +16,4 @@ LL | Some(Wrapper::Simple::<u32>); error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0320`. diff --git a/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr b/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr index 1da29be43db..002dfe115b0 100644 --- a/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr +++ b/src/test/ui/recursion/issue-38591-non-regular-dropck-recursion.stderr @@ -8,3 +8,4 @@ LL | fn f(x: S<u32>) {} error: aborting due to previous error +For more information about this error, try `rustc --explain E0320`. diff --git a/src/tools/tidy/src/main.rs b/src/tools/tidy/src/main.rs index b0b11cafca5..6714c63ee62 100644 --- a/src/tools/tidy/src/main.rs +++ b/src/tools/tidy/src/main.rs @@ -35,15 +35,26 @@ fn main() { let bad = std::sync::Arc::new(AtomicBool::new(false)); + let drain_handles = |handles: &mut VecDeque<ScopedJoinHandle<'_, ()>>| { + // poll all threads for completion before awaiting the oldest one + for i in (0..handles.len()).rev() { + if handles[i].is_finished() { + handles.swap_remove_back(i).unwrap().join().unwrap(); + } + } + + while handles.len() >= concurrency.get() { + handles.pop_front().unwrap().join().unwrap(); + } + }; + scope(|s| { let mut handles: VecDeque<ScopedJoinHandle<'_, ()>> = VecDeque::with_capacity(concurrency.get()); macro_rules! check { ($p:ident $(, $args:expr)* ) => { - while handles.len() >= concurrency.get() { - handles.pop_front().unwrap().join().unwrap(); - } + drain_handles(&mut handles); let handle = s.spawn(|| { let mut flag = false; @@ -97,9 +108,8 @@ fn main() { check!(alphabetical, &library_path); let collected = { - while handles.len() >= concurrency.get() { - handles.pop_front().unwrap().join().unwrap(); - } + drain_handles(&mut handles); + let mut flag = false; let r = features::check(&src_path, &compiler_path, &library_path, &mut flag, verbose); if flag { diff --git a/src/tools/tidy/src/style.rs b/src/tools/tidy/src/style.rs index e3a094caf91..f91e38262f6 100644 --- a/src/tools/tidy/src/style.rs +++ b/src/tools/tidy/src/style.rs @@ -17,7 +17,7 @@ //! `// ignore-tidy-CHECK-NAME`. use crate::walk::{filter_dirs, walk}; -use regex::Regex; +use regex::{Regex, RegexSet}; use std::path::Path; /// Error code markdown is restricted to 80 columns because they can be @@ -225,6 +225,7 @@ pub fn check(path: &Path, bad: &mut bool) { .chain(PROBLEMATIC_CONSTS.iter().map(|v| format!("{:x}", v))) .chain(PROBLEMATIC_CONSTS.iter().map(|v| format!("{:X}", v))) .collect(); + let problematic_regex = RegexSet::new(problematic_consts_strings.as_slice()).unwrap(); walk(path, &mut skip, &mut |entry, contents| { let file = entry.path(); let filename = file.file_name().unwrap().to_string_lossy(); @@ -281,7 +282,27 @@ pub fn check(path: &Path, bad: &mut bool) { let mut trailing_new_lines = 0; let mut lines = 0; let mut last_safety_comment = false; + let is_test = file.components().any(|c| c.as_os_str() == "tests"); + // scanning the whole file for multiple needles at once is more efficient than + // executing lines times needles separate searches. + let any_problematic_line = problematic_regex.is_match(contents); for (i, line) in contents.split('\n').enumerate() { + if line.is_empty() { + if i == 0 { + leading_new_lines = true; + } + trailing_new_lines += 1; + continue; + } else { + trailing_new_lines = 0; + } + + let trimmed = line.trim(); + + if !trimmed.starts_with("//") { + lines += 1; + } + let mut err = |msg: &str| { tidy_error!(bad, "{}:{}: {}", file.display(), i + 1, msg); }; @@ -308,28 +329,29 @@ pub fn check(path: &Path, bad: &mut bool) { suppressible_tidy_err!(err, skip_cr, "CR character"); } if filename != "style.rs" { - if line.contains("TODO") { + if trimmed.contains("TODO") { err("TODO is deprecated; use FIXME") } - if line.contains("//") && line.contains(" XXX") { + if trimmed.contains("//") && trimmed.contains(" XXX") { err("XXX is deprecated; use FIXME") } - for s in problematic_consts_strings.iter() { - if line.contains(s) { - err("Don't use magic numbers that spell things (consider 0x12345678)"); + if any_problematic_line { + for s in problematic_consts_strings.iter() { + if trimmed.contains(s) { + err("Don't use magic numbers that spell things (consider 0x12345678)"); + } } } } - let is_test = || file.components().any(|c| c.as_os_str() == "tests"); // for now we just check libcore - if line.contains("unsafe {") && !line.trim().starts_with("//") && !last_safety_comment { - if file.components().any(|c| c.as_os_str() == "core") && !is_test() { + if trimmed.contains("unsafe {") && !trimmed.starts_with("//") && !last_safety_comment { + if file.components().any(|c| c.as_os_str() == "core") && !is_test { suppressible_tidy_err!(err, skip_undocumented_unsafe, "undocumented unsafe"); } } - if line.contains("// SAFETY:") { + if trimmed.contains("// SAFETY:") { last_safety_comment = true; - } else if line.trim().starts_with("//") || line.trim().is_empty() { + } else if trimmed.starts_with("//") || trimmed.is_empty() { // keep previous value } else { last_safety_comment = false; @@ -337,7 +359,8 @@ pub fn check(path: &Path, bad: &mut bool) { if (line.starts_with("// Copyright") || line.starts_with("# Copyright") || line.starts_with("Copyright")) - && (line.contains("Rust Developers") || line.contains("Rust Project Developers")) + && (trimmed.contains("Rust Developers") + || trimmed.contains("Rust Project Developers")) { suppressible_tidy_err!( err, @@ -351,18 +374,6 @@ pub fn check(path: &Path, bad: &mut bool) { if filename.ends_with(".cpp") && line.contains("llvm_unreachable") { err(LLVM_UNREACHABLE_INFO); } - if line.is_empty() { - if i == 0 { - leading_new_lines = true; - } - trailing_new_lines += 1; - } else { - trailing_new_lines = 0; - } - - if !line.trim().starts_with("//") { - lines += 1; - } } if leading_new_lines { let mut err = |_| { |
