From 3b4861e432fa99f5e169c3956f6e8e4d861c6e64 Mon Sep 17 00:00:00 2001 From: Ryan Hancock Date: Thu, 9 Sep 2021 20:05:48 -0400 Subject: [PATCH 01/12] Clarification of default socket flags used by Rust --- library/std/src/net/mod.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/library/std/src/net/mod.rs b/library/std/src/net/mod.rs index d814e9b25ba9a..7a84b07fdebc8 100644 --- a/library/std/src/net/mod.rs +++ b/library/std/src/net/mod.rs @@ -14,6 +14,10 @@ //! * [`ToSocketAddrs`] is a trait that used for generic address resolution when interacting //! with networking objects like [`TcpListener`], [`TcpStream`] or [`UdpSocket`] //! * Other types are return or parameter types for various methods in this module +//! +//! Rust disables inheritance of socket objects to child processes by default when possible. For +//! example, through the use of the `CLOEXEC` flag in UNIX systems or the `HANDLE_FLAG_INHERIT` +//! flag on Windows. #![stable(feature = "rust1", since = "1.0.0")] From a10f0954c0edb478a8efd4ac000b2abd3cf06ff5 Mon Sep 17 00:00:00 2001 From: Ryan Hancock Date: Thu, 9 Sep 2021 20:11:38 -0400 Subject: [PATCH 02/12] Run fmt --- library/std/src/net/mod.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/net/mod.rs b/library/std/src/net/mod.rs index 7a84b07fdebc8..264d74fefc5ef 100644 --- a/library/std/src/net/mod.rs +++ b/library/std/src/net/mod.rs @@ -15,7 +15,7 @@ //! with networking objects like [`TcpListener`], [`TcpStream`] or [`UdpSocket`] //! * Other types are return or parameter types for various methods in this module //! -//! Rust disables inheritance of socket objects to child processes by default when possible. For +//! Rust disables inheritance of socket objects to child processes by default when possible. For //! example, through the use of the `CLOEXEC` flag in UNIX systems or the `HANDLE_FLAG_INHERIT` //! flag on Windows. From 748cdda776c19593aaf5a3f51eb24179192607d2 Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Fri, 28 Jan 2022 00:54:55 +0100 Subject: [PATCH 03/12] rustdoc: no `shortcut` in `rel="icon"` According to https://html.spec.whatwg.org/multipage/links.html#rel-icon: > For historical reasons, the `icon` keyword may be preceded by > the keyword "`shortcut`". And to https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types: > **Warning:** The `shortcut` link type is often seen before `icon`, > but this link type is non-conforming, ignored and **web authors > must not use it anymore.** While it was removed from the Rust logo case a while ago in commit 085679c8414 ("Use theme-adaptive SVG favicon from other Rust sites"), it is still there for the custom logo case. Signed-off-by: Miguel Ojeda --- src/doc/rustdoc/src/the-doc-attribute.md | 2 +- src/librustdoc/html/templates/page.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/rustdoc/src/the-doc-attribute.md b/src/doc/rustdoc/src/the-doc-attribute.md index a75b6d3893128..c5cc84022e389 100644 --- a/src/doc/rustdoc/src/the-doc-attribute.md +++ b/src/doc/rustdoc/src/the-doc-attribute.md @@ -59,7 +59,7 @@ This form of the `doc` attribute lets you control the favicon of your docs. #![doc(html_favicon_url = "https://example.com/favicon.ico")] ``` -This will put `` into your docs, where +This will put `` into your docs, where the string for the attribute goes into the `{}`. If you don't use this attribute, there will be no favicon. diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html index baadd3c27b446..564731ab7354b 100644 --- a/src/librustdoc/html/templates/page.html +++ b/src/librustdoc/html/templates/page.html @@ -54,7 +54,7 @@ href="{{static_root_path|safe}}theme{{page.resource_suffix}}.css"> {#- -#} {%- endif -%} {%- if !layout.favicon.is_empty() -%} - {#- -#} + {#- -#} {%- else -%} {#- -#} From 30685ed754d398934c62ec9fb9aba0344dcf81de Mon Sep 17 00:00:00 2001 From: Miguel Ojeda Date: Fri, 28 Jan 2022 13:17:01 +0100 Subject: [PATCH 04/12] doc: no `shortcut` in `rel="icon"` According to https://html.spec.whatwg.org/multipage/links.html#rel-icon: > For historical reasons, the `icon` keyword may be preceded by > the keyword "`shortcut`". And to https://developer.mozilla.org/en-US/docs/Web/HTML/Link_types: > **Warning:** The `shortcut` link type is often seen before `icon`, > but this link type is non-conforming, ignored and **web authors > must not use it anymore.** Signed-off-by: Miguel Ojeda --- src/doc/favicon.inc | 2 +- src/doc/redirect.inc | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/doc/favicon.inc b/src/doc/favicon.inc index 8f881657bdc1a..9c330685209be 100644 --- a/src/doc/favicon.inc +++ b/src/doc/favicon.inc @@ -1 +1 @@ - + diff --git a/src/doc/redirect.inc b/src/doc/redirect.inc index 33e3860c2a434..2fb44be014515 100644 --- a/src/doc/redirect.inc +++ b/src/doc/redirect.inc @@ -1,2 +1,2 @@ - + From 398cccd42e82cf2c929e811db56303d184dbf928 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sun, 13 Feb 2022 10:19:42 -0500 Subject: [PATCH 05/12] Make default stdio lock() return 'static handles This also deletes the unstable API surface area previously added to expose this functionality on new methods rather than built into the current set. --- library/std/src/io/mod.rs | 2 - library/std/src/io/stdio.rs | 238 ++---------------------------- library/std/src/io/stdio/tests.rs | 6 +- 3 files changed, 18 insertions(+), 228 deletions(-) diff --git a/library/std/src/io/mod.rs b/library/std/src/io/mod.rs index 71a59fb580321..3fa965d08e698 100644 --- a/library/std/src/io/mod.rs +++ b/library/std/src/io/mod.rs @@ -268,8 +268,6 @@ pub use self::buffered::WriterPanicked; pub use self::stdio::set_output_capture; #[unstable(feature = "print_internals", issue = "none")] pub use self::stdio::{_eprint, _print}; -#[unstable(feature = "stdio_locked", issue = "86845")] -pub use self::stdio::{stderr_locked, stdin_locked, stdout_locked}; #[stable(feature = "rust1", since = "1.0.0")] pub use self::{ buffered::{BufReader, BufWriter, IntoInnerError, LineWriter}, diff --git a/library/std/src/io/stdio.rs b/library/std/src/io/stdio.rs index 3d6de20d86091..5414ff648d4d5 100644 --- a/library/std/src/io/stdio.rs +++ b/library/std/src/io/stdio.rs @@ -307,48 +307,6 @@ pub fn stdin() -> Stdin { } } -/// Constructs a new locked handle to the standard input of the current -/// process. -/// -/// Each handle returned is a guard granting locked access to a shared -/// global buffer whose access is synchronized via a mutex. If you need -/// more explicit control over locking, for example, in a multi-threaded -/// program, use the [`io::stdin`] function to obtain an unlocked handle, -/// along with the [`Stdin::lock`] method. -/// -/// The lock is released when the returned guard goes out of scope. The -/// returned guard also implements the [`Read`] and [`BufRead`] traits for -/// accessing the underlying data. -/// -/// **Note**: The mutex locked by this handle is not reentrant. Even in a -/// single-threaded program, calling other code that accesses [`Stdin`] -/// could cause a deadlock or panic, if this locked handle is held across -/// that call. -/// -/// ### Note: Windows Portability Consideration -/// When operating in a console, the Windows implementation of this stream does not support -/// non-UTF-8 byte sequences. Attempting to read bytes that are not valid UTF-8 will return -/// an error. -/// -/// # Examples -/// -/// ```no_run -/// #![feature(stdio_locked)] -/// use std::io::{self, BufRead}; -/// -/// fn main() -> io::Result<()> { -/// let mut buffer = String::new(); -/// let mut handle = io::stdin_locked(); -/// -/// handle.read_line(&mut buffer)?; -/// Ok(()) -/// } -/// ``` -#[unstable(feature = "stdio_locked", issue = "86845")] -pub fn stdin_locked() -> StdinLock<'static> { - stdin().into_locked() -} - impl Stdin { /// Locks this handle to the standard input stream, returning a readable /// guard. @@ -372,8 +330,10 @@ impl Stdin { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn lock(&self) -> StdinLock<'_> { - self.lock_any() + pub fn lock(&self) -> StdinLock<'static> { + // Locks this handle with 'static lifetime. This depends on the + // implementation detail that the underlying `Mutex` is static. + StdinLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) } } /// Locks this handle and reads a line of input, appending it to the specified buffer. @@ -407,43 +367,6 @@ impl Stdin { self.lock().read_line(buf) } - // Locks this handle with any lifetime. This depends on the - // implementation detail that the underlying `Mutex` is static. - fn lock_any<'a>(&self) -> StdinLock<'a> { - StdinLock { inner: self.inner.lock().unwrap_or_else(|e| e.into_inner()) } - } - - /// Consumes this handle to the standard input stream, locking the - /// shared global buffer associated with the stream and returning a - /// readable guard. - /// - /// The lock is released when the returned guard goes out of scope. The - /// returned guard also implements the [`Read`] and [`BufRead`] traits - /// for accessing the underlying data. - /// - /// It is often simpler to directly get a locked handle using the - /// [`stdin_locked`] function instead, unless nearby code also needs to - /// use an unlocked handle. - /// - /// # Examples - /// - /// ```no_run - /// #![feature(stdio_locked)] - /// use std::io::{self, BufRead}; - /// - /// fn main() -> io::Result<()> { - /// let mut buffer = String::new(); - /// let mut handle = io::stdin().into_locked(); - /// - /// handle.read_line(&mut buffer)?; - /// Ok(()) - /// } - /// ``` - #[unstable(feature = "stdio_locked", issue = "86845")] - pub fn into_locked(self) -> StdinLock<'static> { - self.lock_any() - } - /// Consumes this handle and returns an iterator over input lines. /// /// For detailed semantics of this method, see the documentation on @@ -463,7 +386,7 @@ impl Stdin { #[must_use = "`self` will be dropped if the result is not used"] #[unstable(feature = "stdin_forwarders", issue = "87096")] pub fn lines(self) -> Lines> { - self.into_locked().lines() + self.lock().lines() } } @@ -649,42 +572,6 @@ pub fn stdout() -> Stdout { } } -/// Constructs a new locked handle to the standard output of the current -/// process. -/// -/// Each handle returned is a guard granting locked access to a shared -/// global buffer whose access is synchronized via a mutex. If you need -/// more explicit control over locking, for example, in a multi-threaded -/// program, use the [`io::stdout`] function to obtain an unlocked handle, -/// along with the [`Stdout::lock`] method. -/// -/// The lock is released when the returned guard goes out of scope. The -/// returned guard also implements the [`Write`] trait for writing data. -/// -/// ### Note: Windows Portability Consideration -/// When operating in a console, the Windows implementation of this stream does not support -/// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return -/// an error. -/// -/// # Examples -/// -/// ```no_run -/// #![feature(stdio_locked)] -/// use std::io::{self, Write}; -/// -/// fn main() -> io::Result<()> { -/// let mut handle = io::stdout_locked(); -/// -/// handle.write_all(b"hello world")?; -/// -/// Ok(()) -/// } -/// ``` -#[unstable(feature = "stdio_locked", issue = "86845")] -pub fn stdout_locked() -> StdoutLock<'static> { - stdout().into_locked() -} - pub fn cleanup() { if let Some(instance) = STDOUT.get() { // Flush the data and disable buffering during shutdown @@ -712,55 +599,20 @@ impl Stdout { /// use std::io::{self, Write}; /// /// fn main() -> io::Result<()> { - /// let stdout = io::stdout(); - /// let mut handle = stdout.lock(); + /// let mut stdout = io::stdout().lock(); /// - /// handle.write_all(b"hello world")?; + /// stdout.write_all(b"hello world")?; /// /// Ok(()) /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn lock(&self) -> StdoutLock<'_> { - self.lock_any() - } - - // Locks this handle with any lifetime. This depends on the - // implementation detail that the underlying `ReentrantMutex` is - // static. - fn lock_any<'a>(&self) -> StdoutLock<'a> { + pub fn lock(&self) -> StdoutLock<'static> { + // Locks this handle with 'static lifetime. This depends on the + // implementation detail that the underlying `ReentrantMutex` is + // static. StdoutLock { inner: self.inner.lock() } } - - /// Consumes this handle to the standard output stream, locking the - /// shared global buffer associated with the stream and returning a - /// writable guard. - /// - /// The lock is released when the returned lock goes out of scope. The - /// returned guard also implements the [`Write`] trait for writing data. - /// - /// It is often simpler to directly get a locked handle using the - /// [`io::stdout_locked`] function instead, unless nearby code also - /// needs to use an unlocked handle. - /// - /// # Examples - /// - /// ```no_run - /// #![feature(stdio_locked)] - /// use std::io::{self, Write}; - /// - /// fn main() -> io::Result<()> { - /// let mut handle = io::stdout().into_locked(); - /// - /// handle.write_all(b"hello world")?; - /// - /// Ok(()) - /// } - /// ``` - #[unstable(feature = "stdio_locked", issue = "86845")] - pub fn into_locked(self) -> StdoutLock<'static> { - self.lock_any() - } } #[stable(feature = "std_debug", since = "1.16.0")] @@ -935,35 +787,6 @@ pub fn stderr() -> Stderr { } } -/// Constructs a new locked handle to the standard error of the current -/// process. -/// -/// This handle is not buffered. -/// -/// ### Note: Windows Portability Consideration -/// When operating in a console, the Windows implementation of this stream does not support -/// non-UTF-8 byte sequences. Attempting to write bytes that are not valid UTF-8 will return -/// an error. -/// -/// # Example -/// -/// ```no_run -/// #![feature(stdio_locked)] -/// use std::io::{self, Write}; -/// -/// fn main() -> io::Result<()> { -/// let mut handle = io::stderr_locked(); -/// -/// handle.write_all(b"hello world")?; -/// -/// Ok(()) -/// } -/// ``` -#[unstable(feature = "stdio_locked", issue = "86845")] -pub fn stderr_locked() -> StderrLock<'static> { - stderr().into_locked() -} - impl Stderr { /// Locks this handle to the standard error stream, returning a writable /// guard. @@ -986,43 +809,12 @@ impl Stderr { /// } /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn lock(&self) -> StderrLock<'_> { - self.lock_any() - } - - // Locks this handle with any lifetime. This depends on the - // implementation detail that the underlying `ReentrantMutex` is - // static. - fn lock_any<'a>(&self) -> StderrLock<'a> { + pub fn lock(&self) -> StderrLock<'static> { + // Locks this handle with 'static lifetime. This depends on the + // implementation detail that the underlying `ReentrantMutex` is + // static. StderrLock { inner: self.inner.lock() } } - - /// Locks and consumes this handle to the standard error stream, - /// returning a writable guard. - /// - /// The lock is released when the returned guard goes out of scope. The - /// returned guard also implements the [`Write`] trait for writing - /// data. - /// - /// # Examples - /// - /// ``` - /// #![feature(stdio_locked)] - /// use std::io::{self, Write}; - /// - /// fn foo() -> io::Result<()> { - /// let stderr = io::stderr(); - /// let mut handle = stderr.into_locked(); - /// - /// handle.write_all(b"hello world")?; - /// - /// Ok(()) - /// } - /// ``` - #[unstable(feature = "stdio_locked", issue = "86845")] - pub fn into_locked(self) -> StderrLock<'static> { - self.lock_any() - } } #[stable(feature = "std_debug", since = "1.16.0")] diff --git a/library/std/src/io/stdio/tests.rs b/library/std/src/io/stdio/tests.rs index b1df6b7131c87..f89fd27ce6c23 100644 --- a/library/std/src/io/stdio/tests.rs +++ b/library/std/src/io/stdio/tests.rs @@ -50,17 +50,17 @@ fn panic_doesnt_poison() { #[test] #[cfg_attr(target_os = "emscripten", ignore)] fn test_lock_stderr() { - test_lock(stderr, stderr_locked); + test_lock(stderr, || stderr().lock()); } #[test] #[cfg_attr(target_os = "emscripten", ignore)] fn test_lock_stdin() { - test_lock(stdin, stdin_locked); + test_lock(stdin, || stdin().lock()); } #[test] #[cfg_attr(target_os = "emscripten", ignore)] fn test_lock_stdout() { - test_lock(stdout, stdout_locked); + test_lock(stdout, || stdout().lock()); } // Helper trait to make lock testing function generic. From 7cee1b4aebf4ac1a9779fa352c249dcd263a6427 Mon Sep 17 00:00:00 2001 From: Amanieu d'Antras Date: Thu, 24 Feb 2022 22:37:53 +0000 Subject: [PATCH 06/12] ARM: Only allow using d16-d31 with asm! when supported by the target Support can be determined by checking for the "d32" LLVM feature. --- compiler/rustc_codegen_ssa/src/target_features.rs | 1 + compiler/rustc_span/src/symbol.rs | 1 + compiler/rustc_target/src/asm/arm.rs | 5 ++++- 3 files changed, 6 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_codegen_ssa/src/target_features.rs b/compiler/rustc_codegen_ssa/src/target_features.rs index 77166c89735e4..14045ad7ff524 100644 --- a/compiler/rustc_codegen_ssa/src/target_features.rs +++ b/compiler/rustc_codegen_ssa/src/target_features.rs @@ -36,6 +36,7 @@ const ARM_ALLOWED_FEATURES: &[(&str, Option)] = &[ // #[target_feature]. ("thumb-mode", Some(sym::arm_target_feature)), ("thumb2", Some(sym::arm_target_feature)), + ("d32", Some(sym::arm_target_feature)), ]; const AARCH64_ALLOWED_FEATURES: &[(&str, Option)] = &[ diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs index 6767593bbc51a..9d452131fa6ac 100644 --- a/compiler/rustc_span/src/symbol.rs +++ b/compiler/rustc_span/src/symbol.rs @@ -539,6 +539,7 @@ symbols! { custom_inner_attributes, custom_test_frameworks, d, + d32, dbg_macro, dead_code, dealloc, diff --git a/compiler/rustc_target/src/asm/arm.rs b/compiler/rustc_target/src/asm/arm.rs index 88f2d3f80d2c3..aaa632333db38 100644 --- a/compiler/rustc_target/src/asm/arm.rs +++ b/compiler/rustc_target/src/asm/arm.rs @@ -50,9 +50,12 @@ impl ArmInlineAsmRegClass { match self { Self::reg => types! { _: I8, I16, I32, F32; }, Self::sreg | Self::sreg_low16 => types! { vfp2: I32, F32; }, - Self::dreg | Self::dreg_low16 | Self::dreg_low8 => types! { + Self::dreg_low16 | Self::dreg_low8 => types! { vfp2: I64, F64, VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF32(2); }, + Self::dreg => types! { + d32: I64, F64, VecI8(8), VecI16(4), VecI32(2), VecI64(1), VecF32(2); + }, Self::qreg | Self::qreg_low8 | Self::qreg_low4 => types! { neon: VecI8(16), VecI16(8), VecI32(4), VecI64(2), VecF32(4); }, From 2f84484aac0b3b780b903a0438f42aadafb6f14f Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Fri, 25 Jun 2021 11:56:14 +0200 Subject: [PATCH 07/12] Remove the everybody loops pass It isn't used anymore by rustdoc --- compiler/rustc_driver/src/pretty.rs | 2 +- compiler/rustc_interface/src/passes.rs | 26 +-- compiler/rustc_interface/src/util.rs | 215 +----------------- compiler/rustc_session/src/config.rs | 7 +- compiler/rustc_session/src/options.rs | 1 - compiler/rustc_typeck/src/check_unused.rs | 3 +- src/test/ui/lint/issue-87308.rs | 12 - src/test/ui/lint/issue-87308.stdout | 14 -- .../ui/repr/issue-83921-pretty.normal.stderr | 9 - .../ui/repr/issue-83921-pretty.pretty.stdout | 18 -- src/test/ui/repr/issue-83921-pretty.rs | 14 -- 11 files changed, 12 insertions(+), 309 deletions(-) delete mode 100644 src/test/ui/lint/issue-87308.rs delete mode 100644 src/test/ui/lint/issue-87308.stdout delete mode 100644 src/test/ui/repr/issue-83921-pretty.normal.stderr delete mode 100644 src/test/ui/repr/issue-83921-pretty.pretty.stdout delete mode 100644 src/test/ui/repr/issue-83921-pretty.rs diff --git a/compiler/rustc_driver/src/pretty.rs b/compiler/rustc_driver/src/pretty.rs index 0c0c61309655c..12bac956adb55 100644 --- a/compiler/rustc_driver/src/pretty.rs +++ b/compiler/rustc_driver/src/pretty.rs @@ -42,7 +42,7 @@ where F: FnOnce(&dyn PrinterSupport) -> A, { match *ppmode { - Normal | EveryBodyLoops | Expanded => { + Normal | Expanded => { let annotation = NoAnn { sess, tcx }; f(&annotation) } diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 3b51f8eb61c8e..35688a6591239 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -3,7 +3,6 @@ use crate::proc_macro_decls; use crate::util; use ast::CRATE_NODE_ID; -use rustc_ast::mut_visit::MutVisitor; use rustc_ast::{self as ast, visit}; use rustc_borrowck as mir_borrowck; use rustc_codegen_ssa::back::link::emit_metadata; @@ -29,7 +28,7 @@ use rustc_plugin_impl as plugin; use rustc_query_impl::{OnDiskCache, Queries as TcxQueries}; use rustc_resolve::{Resolver, ResolverArenas}; use rustc_serialize::json; -use rustc_session::config::{CrateType, Input, OutputFilenames, OutputType, PpMode, PpSourceMode}; +use rustc_session::config::{CrateType, Input, OutputFilenames, OutputType}; use rustc_session::cstore::{MetadataLoader, MetadataLoaderDyn}; use rustc_session::lint; use rustc_session::output::{filename_for_input, filename_for_metadata}; @@ -384,11 +383,6 @@ pub fn configure_and_expand( rustc_builtin_macros::test_harness::inject(sess, resolver, &mut krate) }); - if let Some(PpMode::Source(PpSourceMode::EveryBodyLoops)) = sess.opts.pretty { - tracing::debug!("replacing bodies with loop {{}}"); - util::ReplaceBodyWithLoop::new(resolver).visit_crate(&mut krate); - } - let has_proc_macro_decls = sess.time("AST_validation", || { rustc_ast_passes::ast_validation::check_crate(sess, &krate, resolver.lint_buffer()) }); @@ -457,18 +451,12 @@ pub fn configure_and_expand( }); // Add all buffered lints from the `ParseSess` to the `Session`. - // The ReplaceBodyWithLoop pass may have deleted some AST nodes, potentially - // causing a delay_span_bug later if a buffered lint refers to such a deleted - // AST node (issue #87308). Since everybody_loops is for pretty-printing only, - // anyway, we simply skip all buffered lints here. - if !matches!(sess.opts.pretty, Some(PpMode::Source(PpSourceMode::EveryBodyLoops))) { - sess.parse_sess.buffered_lints.with_lock(|buffered_lints| { - info!("{} parse sess buffered_lints", buffered_lints.len()); - for early_lint in buffered_lints.drain(..) { - resolver.lint_buffer().add_early_lint(early_lint); - } - }); - } + sess.parse_sess.buffered_lints.with_lock(|buffered_lints| { + info!("{} parse sess buffered_lints", buffered_lints.len()); + for early_lint in buffered_lints.drain(..) { + resolver.lint_buffer().add_early_lint(early_lint); + } + }); // Gate identifiers containing invalid Unicode codepoints that were recovered during lexing. sess.parse_sess.bad_unicode_identifiers.with_lock(|identifiers| { diff --git a/compiler/rustc_interface/src/util.rs b/compiler/rustc_interface/src/util.rs index 046f4f9451f58..592cf60e6c3bb 100644 --- a/compiler/rustc_interface/src/util.rs +++ b/compiler/rustc_interface/src/util.rs @@ -1,7 +1,5 @@ use libloading::Library; -use rustc_ast::mut_visit::{visit_clobber, MutVisitor, *}; -use rustc_ast::ptr::P; -use rustc_ast::{self as ast, AttrVec, BlockCheckMode, Term}; +use rustc_ast as ast; use rustc_codegen_ssa::traits::CodegenBackend; use rustc_data_structures::fx::{FxHashMap, FxHashSet}; #[cfg(parallel_compiler)] @@ -13,7 +11,6 @@ use rustc_middle::ty::tls; use rustc_parse::validate_attr; #[cfg(parallel_compiler)] use rustc_query_impl::QueryCtxt; -use rustc_resolve::{self, Resolver}; use rustc_session as session; use rustc_session::config::CheckCfg; use rustc_session::config::{self, CrateType}; @@ -25,12 +22,10 @@ use rustc_span::edition::Edition; use rustc_span::lev_distance::find_best_match_for_name; use rustc_span::source_map::FileLoader; use rustc_span::symbol::{sym, Symbol}; -use smallvec::SmallVec; use std::env; use std::env::consts::{DLL_PREFIX, DLL_SUFFIX}; use std::lazy::SyncOnceCell; use std::mem; -use std::ops::DerefMut; #[cfg(not(parallel_compiler))] use std::panic; use std::path::{Path, PathBuf}; @@ -664,214 +659,6 @@ pub fn non_durable_rename(src: &Path, dst: &Path) -> std::io::Result<()> { std::fs::rename(src, dst) } -/// Replaces function bodies with `loop {}` (an infinite loop). This gets rid of -/// all semantic errors in the body while still satisfying the return type, -/// except in certain cases, see below for more. -/// -/// This pass is known as `everybody_loops`. Very punny. -/// -/// As of March 2021, `everybody_loops` is only used for the -/// `-Z unpretty=everybody_loops` debugging option. -/// -/// FIXME: Currently the `everybody_loops` transformation is not applied to: -/// * `const fn`; support could be added, but hasn't. Originally `const fn` -/// was skipped due to issue #43636 that `loop` was not supported for -/// const evaluation. -/// * `impl Trait`, due to issue #43869 that functions returning impl Trait cannot be diverging. -/// Solving this may require `!` to implement every trait, which relies on the an even more -/// ambitious form of the closed RFC #1637. See also [#34511]. -/// -/// [#34511]: https://github.com/rust-lang/rust/issues/34511#issuecomment-322340401 -pub struct ReplaceBodyWithLoop<'a, 'b> { - within_static_or_const: bool, - nested_blocks: Option>, - resolver: &'a mut Resolver<'b>, -} - -impl<'a, 'b> ReplaceBodyWithLoop<'a, 'b> { - pub fn new(resolver: &'a mut Resolver<'b>) -> ReplaceBodyWithLoop<'a, 'b> { - ReplaceBodyWithLoop { within_static_or_const: false, nested_blocks: None, resolver } - } - - fn run R>(&mut self, is_const: bool, action: F) -> R { - let old_const = mem::replace(&mut self.within_static_or_const, is_const); - let old_blocks = self.nested_blocks.take(); - let ret = action(self); - self.within_static_or_const = old_const; - self.nested_blocks = old_blocks; - ret - } - - fn should_ignore_fn(ret_ty: &ast::FnRetTy) -> bool { - let ast::FnRetTy::Ty(ref ty) = ret_ty else { - return false; - }; - fn involves_impl_trait(ty: &ast::Ty) -> bool { - match ty.kind { - ast::TyKind::ImplTrait(..) => true, - ast::TyKind::Slice(ref subty) - | ast::TyKind::Array(ref subty, _) - | ast::TyKind::Ptr(ast::MutTy { ty: ref subty, .. }) - | ast::TyKind::Rptr(_, ast::MutTy { ty: ref subty, .. }) - | ast::TyKind::Paren(ref subty) => involves_impl_trait(subty), - ast::TyKind::Tup(ref tys) => any_involves_impl_trait(tys.iter()), - ast::TyKind::Path(_, ref path) => { - path.segments.iter().any(|seg| match seg.args.as_deref() { - None => false, - Some(&ast::GenericArgs::AngleBracketed(ref data)) => { - data.args.iter().any(|arg| match arg { - ast::AngleBracketedArg::Arg(arg) => match arg { - ast::GenericArg::Type(ty) => involves_impl_trait(ty), - ast::GenericArg::Lifetime(_) | ast::GenericArg::Const(_) => { - false - } - }, - ast::AngleBracketedArg::Constraint(c) => match c.kind { - ast::AssocConstraintKind::Bound { .. } => true, - ast::AssocConstraintKind::Equality { ref term } => { - match term { - Term::Ty(ty) => involves_impl_trait(ty), - // FIXME(...): This should check if the constant - // involves a trait impl, but for now ignore. - Term::Const(_) => false, - } - } - }, - }) - } - Some(&ast::GenericArgs::Parenthesized(ref data)) => { - any_involves_impl_trait(data.inputs.iter()) - || ReplaceBodyWithLoop::should_ignore_fn(&data.output) - } - }) - } - _ => false, - } - } - - fn any_involves_impl_trait<'a, I: Iterator>>(mut it: I) -> bool { - it.any(|subty| involves_impl_trait(subty)) - } - - involves_impl_trait(ty) - } - - fn is_sig_const(sig: &ast::FnSig) -> bool { - matches!(sig.header.constness, ast::Const::Yes(_)) - || ReplaceBodyWithLoop::should_ignore_fn(&sig.decl.output) - } -} - -impl<'a> MutVisitor for ReplaceBodyWithLoop<'a, '_> { - fn visit_item_kind(&mut self, i: &mut ast::ItemKind) { - let is_const = match i { - ast::ItemKind::Static(..) | ast::ItemKind::Const(..) => true, - ast::ItemKind::Fn(box ast::Fn { ref sig, .. }) => Self::is_sig_const(sig), - _ => false, - }; - self.run(is_const, |s| noop_visit_item_kind(i, s)) - } - - fn flat_map_trait_item(&mut self, i: P) -> SmallVec<[P; 1]> { - let is_const = match i.kind { - ast::AssocItemKind::Const(..) => true, - ast::AssocItemKind::Fn(box ast::Fn { ref sig, .. }) => Self::is_sig_const(sig), - _ => false, - }; - self.run(is_const, |s| noop_flat_map_assoc_item(i, s)) - } - - fn flat_map_impl_item(&mut self, i: P) -> SmallVec<[P; 1]> { - self.flat_map_trait_item(i) - } - - fn visit_anon_const(&mut self, c: &mut ast::AnonConst) { - self.run(true, |s| noop_visit_anon_const(c, s)) - } - - fn visit_block(&mut self, b: &mut P) { - fn stmt_to_block( - rules: ast::BlockCheckMode, - s: Option, - resolver: &mut Resolver<'_>, - ) -> ast::Block { - ast::Block { - stmts: s.into_iter().collect(), - rules, - id: resolver.next_node_id(), - span: rustc_span::DUMMY_SP, - tokens: None, - could_be_bare_literal: false, - } - } - - fn block_to_stmt(b: ast::Block, resolver: &mut Resolver<'_>) -> ast::Stmt { - let expr = P(ast::Expr { - id: resolver.next_node_id(), - kind: ast::ExprKind::Block(P(b), None), - span: rustc_span::DUMMY_SP, - attrs: AttrVec::new(), - tokens: None, - }); - - ast::Stmt { - id: resolver.next_node_id(), - kind: ast::StmtKind::Expr(expr), - span: rustc_span::DUMMY_SP, - } - } - - let empty_block = stmt_to_block(BlockCheckMode::Default, None, self.resolver); - let loop_expr = P(ast::Expr { - kind: ast::ExprKind::Loop(P(empty_block), None), - id: self.resolver.next_node_id(), - span: rustc_span::DUMMY_SP, - attrs: AttrVec::new(), - tokens: None, - }); - - let loop_stmt = ast::Stmt { - id: self.resolver.next_node_id(), - span: rustc_span::DUMMY_SP, - kind: ast::StmtKind::Expr(loop_expr), - }; - - if self.within_static_or_const { - noop_visit_block(b, self) - } else { - visit_clobber(b.deref_mut(), |b| { - let mut stmts = vec![]; - for s in b.stmts { - let old_blocks = self.nested_blocks.replace(vec![]); - - stmts.extend(self.flat_map_stmt(s).into_iter().filter(|s| s.is_item())); - - // we put a Some in there earlier with that replace(), so this is valid - let new_blocks = self.nested_blocks.take().unwrap(); - self.nested_blocks = old_blocks; - stmts.extend(new_blocks.into_iter().map(|b| block_to_stmt(b, self.resolver))); - } - - let mut new_block = ast::Block { stmts, ..b }; - - if let Some(old_blocks) = self.nested_blocks.as_mut() { - //push our fresh block onto the cache and yield an empty block with `loop {}` - if !new_block.stmts.is_empty() { - old_blocks.push(new_block); - } - - stmt_to_block(b.rules, Some(loop_stmt), &mut self.resolver) - } else { - //push `loop {}` onto the end of our fresh block and yield that - new_block.stmts.push(loop_stmt); - - new_block - } - }) - } - } -} - /// Returns a version string such as "1.46.0 (04488afe3 2020-08-24)" pub fn version_str() -> Option<&'static str> { option_env!("CFG_VERSION") diff --git a/compiler/rustc_session/src/config.rs b/compiler/rustc_session/src/config.rs index f9b75690e375f..d1cab6280153d 100644 --- a/compiler/rustc_session/src/config.rs +++ b/compiler/rustc_session/src/config.rs @@ -2509,7 +2509,6 @@ fn parse_pretty(debugging_opts: &DebuggingOptions, efmt: ErrorOutputType) -> Opt let first = match debugging_opts.unpretty.as_deref()? { "normal" => Source(PpSourceMode::Normal), "identified" => Source(PpSourceMode::Identified), - "everybody_loops" => Source(PpSourceMode::EveryBodyLoops), "expanded" => Source(PpSourceMode::Expanded), "expanded,identified" => Source(PpSourceMode::ExpandedIdentified), "expanded,hygiene" => Source(PpSourceMode::ExpandedHygiene), @@ -2645,8 +2644,6 @@ impl fmt::Display for CrateType { pub enum PpSourceMode { /// `-Zunpretty=normal` Normal, - /// `-Zunpretty=everybody_loops` - EveryBodyLoops, /// `-Zunpretty=expanded` Expanded, /// `-Zunpretty=identified` @@ -2678,7 +2675,7 @@ pub enum PpHirMode { #[derive(Copy, Clone, PartialEq, Debug)] pub enum PpMode { /// Options that print the source code, i.e. - /// `-Zunpretty=normal` and `-Zunpretty=everybody_loops` + /// `-Zunpretty=normal` and `-Zunpretty=expanded` Source(PpSourceMode), AstTree(PpAstTreeMode), /// Options that print the HIR, i.e. `-Zunpretty=hir` @@ -2700,7 +2697,7 @@ impl PpMode { match *self { Source(Normal | Identified) | AstTree(PpAstTreeMode::Normal) => false, - Source(Expanded | EveryBodyLoops | ExpandedIdentified | ExpandedHygiene) + Source(Expanded | ExpandedIdentified | ExpandedHygiene) | AstTree(PpAstTreeMode::Expanded) | Hir(_) | HirTree diff --git a/compiler/rustc_session/src/options.rs b/compiler/rustc_session/src/options.rs index c2b13346cd6c9..17eec333e0980 100644 --- a/compiler/rustc_session/src/options.rs +++ b/compiler/rustc_session/src/options.rs @@ -1491,7 +1491,6 @@ options! { `normal`, `identified`, `expanded`, `expanded,identified`, `expanded,hygiene` (with internal representations), - `everybody_loops` (all function bodies replaced with `loop {}`), `ast-tree` (raw AST before expansion), `ast-tree,expanded` (raw AST after expansion), `hir` (the HIR), `hir,identified`, diff --git a/compiler/rustc_typeck/src/check_unused.rs b/compiler/rustc_typeck/src/check_unused.rs index f45cd3ed68948..1826c3f5f7fa5 100644 --- a/compiler/rustc_typeck/src/check_unused.rs +++ b/compiler/rustc_typeck/src/check_unused.rs @@ -82,8 +82,7 @@ fn unused_crates_lint(tcx: TyCtxt<'_>) { // The `def_id` here actually was calculated during resolution (at least // at the time of this writing) and is being shipped to us via a side // channel of the tcx. There may have been extra expansion phases, - // however, which ended up removing the `def_id` *after* expansion such - // as the `ReplaceBodyWithLoop` pass (which is a bit of a hack, but hey) + // however, which ended up removing the `def_id` *after* expansion. // // As a result we need to verify that `def_id` is indeed still valid for // our AST and actually present in the HIR map. If it's not there then diff --git a/src/test/ui/lint/issue-87308.rs b/src/test/ui/lint/issue-87308.rs deleted file mode 100644 index 48fbb2a0139f0..0000000000000 --- a/src/test/ui/lint/issue-87308.rs +++ /dev/null @@ -1,12 +0,0 @@ -// Regression test for issue #87308. - -// compile-flags: -Zunpretty=everybody_loops -// check-pass - -macro_rules! foo { - () => { break 'x; } -} - -pub fn main() { - 'x: loop { foo!() } -} diff --git a/src/test/ui/lint/issue-87308.stdout b/src/test/ui/lint/issue-87308.stdout deleted file mode 100644 index 4f81ee8b7e6bb..0000000000000 --- a/src/test/ui/lint/issue-87308.stdout +++ /dev/null @@ -1,14 +0,0 @@ -#![feature(prelude_import)] -#![no_std] -#[prelude_import] -use ::std::prelude::rust_2015::*; -#[macro_use] -extern crate std; -// Regression test for issue #87308. - -// compile-flags: -Zunpretty=everybody_loops -// check-pass - -macro_rules! foo { () => { break 'x ; } } - -pub fn main() { loop {} } diff --git a/src/test/ui/repr/issue-83921-pretty.normal.stderr b/src/test/ui/repr/issue-83921-pretty.normal.stderr deleted file mode 100644 index 6b7e831ed2f7a..0000000000000 --- a/src/test/ui/repr/issue-83921-pretty.normal.stderr +++ /dev/null @@ -1,9 +0,0 @@ -error[E0565]: meta item in `repr` must be an identifier - --> $DIR/issue-83921-pretty.rs:10:8 - | -LL | #[repr("C")] - | ^^^ - -error: aborting due to previous error - -For more information about this error, try `rustc --explain E0565`. diff --git a/src/test/ui/repr/issue-83921-pretty.pretty.stdout b/src/test/ui/repr/issue-83921-pretty.pretty.stdout deleted file mode 100644 index aaf3993538acf..0000000000000 --- a/src/test/ui/repr/issue-83921-pretty.pretty.stdout +++ /dev/null @@ -1,18 +0,0 @@ -#![feature(prelude_import)] -#![no_std] -#[prelude_import] -use ::std::prelude::rust_2015::*; -#[macro_use] -extern crate std; -// Regression test for #83921. A `delay_span_bug()` call was issued, but the -// error was never reported because the pass responsible for detecting and -// reporting the error does not run in certain modes of pretty-printing. - -// Make sure the error is reported if we do not just pretty-print: -// revisions: pretty normal -// [pretty]compile-flags: -Zunpretty=everybody_loops -// [pretty]check-pass -#[repr("C")] -struct A {} - -fn main() { loop {} } diff --git a/src/test/ui/repr/issue-83921-pretty.rs b/src/test/ui/repr/issue-83921-pretty.rs deleted file mode 100644 index d5d36470f11ac..0000000000000 --- a/src/test/ui/repr/issue-83921-pretty.rs +++ /dev/null @@ -1,14 +0,0 @@ -// Regression test for #83921. A `delay_span_bug()` call was issued, but the -// error was never reported because the pass responsible for detecting and -// reporting the error does not run in certain modes of pretty-printing. - -// Make sure the error is reported if we do not just pretty-print: -// revisions: pretty normal -// [pretty]compile-flags: -Zunpretty=everybody_loops -// [pretty]check-pass - -#[repr("C")] -//[normal]~^ ERROR: meta item in `repr` must be an identifier [E0565] -struct A {} - -fn main() {} From 9c05f0b72c99cc91117282f7f267964824f187bf Mon Sep 17 00:00:00 2001 From: Jon Gjengset Date: Mon, 28 Feb 2022 16:40:08 -0800 Subject: [PATCH 08/12] bootstrap: correct reading of flags for llvm First, this reverts the `CFLAGS`/`CXXFLAGS` of #93918. Those flags are already read by `cc` and populated into `Build` earlier on in the process. We shouldn't be overriding that based on `CFLAGS`, since `cc` also respects overrides like `CFLAGS_{TARGET}` and `HOST_CFLAGS`, which we want to take into account. Second, this adds the same capability to specify target-specific versions of `LDFLAGS` as we have through `cc` for the `C*` flags: https://github.com/alexcrichton/cc-rs#external-configuration-via-environment-variables Note that this also necessitated an update to compiletest to treat CXXFLAGS separately from CFLAGS. --- src/bootstrap/builder.rs | 7 +++--- src/bootstrap/cc_detect.rs | 7 +++--- src/bootstrap/compile.rs | 15 +++++++++---- src/bootstrap/lib.rs | 14 ++++++++++-- src/bootstrap/native.rs | 26 ++++++++++++----------- src/bootstrap/test.rs | 15 ++++++++++--- src/tools/compiletest/src/common.rs | 1 + src/tools/compiletest/src/header/tests.rs | 1 + src/tools/compiletest/src/main.rs | 2 ++ src/tools/compiletest/src/runtest.rs | 11 ++++++++-- 10 files changed, 70 insertions(+), 29 deletions(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index 4f88b5854b692..0d387ff1e37c2 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -26,7 +26,7 @@ use crate::run; use crate::test; use crate::tool::{self, SourceType}; use crate::util::{self, add_dylib_path, add_link_lib_path, exe, libdir}; -use crate::{Build, DocTests, GitRepo, Mode}; +use crate::{Build, CLang, DocTests, GitRepo, Mode}; pub use crate::Compiler; // FIXME: replace with std::lazy after it gets stabilized and reaches beta @@ -1511,7 +1511,7 @@ impl<'a> Builder<'a> { let cc = ccacheify(&self.cc(target)); cargo.env(format!("CC_{}", target.triple), &cc); - let cflags = self.cflags(target, GitRepo::Rustc).join(" "); + let cflags = self.cflags(target, GitRepo::Rustc, CLang::C).join(" "); cargo.env(format!("CFLAGS_{}", target.triple), &cflags); if let Some(ar) = self.ar(target) { @@ -1523,9 +1523,10 @@ impl<'a> Builder<'a> { if let Ok(cxx) = self.cxx(target) { let cxx = ccacheify(&cxx); + let cxxflags = self.cflags(target, GitRepo::Rustc, CLang::Cxx).join(" "); cargo .env(format!("CXX_{}", target.triple), &cxx) - .env(format!("CXXFLAGS_{}", target.triple), cflags); + .env(format!("CXXFLAGS_{}", target.triple), cxxflags); } } diff --git a/src/bootstrap/cc_detect.rs b/src/bootstrap/cc_detect.rs index e750c2963dddc..8c47f625d732b 100644 --- a/src/bootstrap/cc_detect.rs +++ b/src/bootstrap/cc_detect.rs @@ -29,7 +29,7 @@ use std::{env, iter}; use build_helper::output; use crate::config::{Target, TargetSelection}; -use crate::{Build, GitRepo}; +use crate::{Build, CLang, GitRepo}; // The `cc` crate doesn't provide a way to obtain a path to the detected archiver, // so use some simplified logic here. First we respect the environment variable `AR`, then @@ -109,7 +109,7 @@ pub fn find(build: &mut Build) { }; build.cc.insert(target, compiler.clone()); - let cflags = build.cflags(target, GitRepo::Rustc); + let cflags = build.cflags(target, GitRepo::Rustc, CLang::C); // If we use llvm-libunwind, we will need a C++ compiler as well for all targets // We'll need one anyways if the target triple is also a host triple @@ -142,8 +142,9 @@ pub fn find(build: &mut Build) { build.verbose(&format!("CC_{} = {:?}", &target.triple, build.cc(target))); build.verbose(&format!("CFLAGS_{} = {:?}", &target.triple, cflags)); if let Ok(cxx) = build.cxx(target) { + let cxxflags = build.cflags(target, GitRepo::Rustc, CLang::Cxx); build.verbose(&format!("CXX_{} = {:?}", &target.triple, cxx)); - build.verbose(&format!("CXXFLAGS_{} = {:?}", &target.triple, cflags)); + build.verbose(&format!("CXXFLAGS_{} = {:?}", &target.triple, cxxflags)); } if let Some(ar) = ar { build.verbose(&format!("AR_{} = {:?}", &target.triple, ar)); diff --git a/src/bootstrap/compile.rs b/src/bootstrap/compile.rs index b4c6210b38814..9971778034601 100644 --- a/src/bootstrap/compile.rs +++ b/src/bootstrap/compile.rs @@ -28,7 +28,7 @@ use crate::native; use crate::tool::SourceType; use crate::util::{exe, is_debug_info, is_dylib, symlink_dir}; use crate::LLVM_TOOLS; -use crate::{Compiler, DependencyType, GitRepo, Mode}; +use crate::{CLang, Compiler, DependencyType, GitRepo, Mode}; #[derive(Debug, PartialOrd, Ord, Copy, Clone, PartialEq, Eq, Hash)] pub struct Std { @@ -249,7 +249,7 @@ fn copy_self_contained_objects( } } else if target.contains("windows-gnu") { for obj in ["crt2.o", "dllcrt2.o"].iter() { - let src = compiler_file(builder, builder.cc(target), target, obj); + let src = compiler_file(builder, builder.cc(target), target, CLang::C, obj); let target = libdir_self_contained.join(obj); builder.copy(&src, &target); target_deps.push((target, DependencyType::TargetSelfContained)); @@ -727,7 +727,13 @@ pub fn rustc_cargo_env(builder: &Builder<'_>, cargo: &mut Cargo, target: TargetS && !target.contains("msvc") && !target.contains("apple") { - let file = compiler_file(builder, builder.cxx(target).unwrap(), target, "libstdc++.a"); + let file = compiler_file( + builder, + builder.cxx(target).unwrap(), + target, + CLang::Cxx, + "libstdc++.a", + ); cargo.env("LLVM_STATIC_STDCPP", file); } if builder.config.llvm_link_shared { @@ -948,10 +954,11 @@ pub fn compiler_file( builder: &Builder<'_>, compiler: &Path, target: TargetSelection, + c: CLang, file: &str, ) -> PathBuf { let mut cmd = Command::new(compiler); - cmd.args(builder.cflags(target, GitRepo::Rustc)); + cmd.args(builder.cflags(target, GitRepo::Rustc, c)); cmd.arg(format!("-print-file-name={}", file)); let out = output(&mut cmd); PathBuf::from(out.trim()) diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 86339c8d7f88d..abfac2a589793 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -339,6 +339,11 @@ impl Mode { } } +pub enum CLang { + C, + Cxx, +} + impl Build { /// Creates a new set of build configuration from the `flags` on the command /// line and the filesystem `config`. @@ -941,10 +946,15 @@ impl Build { /// Returns a list of flags to pass to the C compiler for the target /// specified. - fn cflags(&self, target: TargetSelection, which: GitRepo) -> Vec { + fn cflags(&self, target: TargetSelection, which: GitRepo, c: CLang) -> Vec { + let base = match c { + CLang::C => &self.cc[&target], + CLang::Cxx => &self.cxx[&target], + }; + // Filter out -O and /O (the optimization flags) that we picked up from // cc-rs because the build scripts will determine that for themselves. - let mut base = self.cc[&target] + let mut base = base .args() .iter() .map(|s| s.to_string_lossy().into_owned()) diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index f00875239040d..a751a6e3ece7f 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -21,7 +21,7 @@ use build_helper::{output, t}; use crate::builder::{Builder, RunConfig, ShouldRun, Step}; use crate::config::TargetSelection; use crate::util::{self, exe}; -use crate::GitRepo; +use crate::{CLang, GitRepo}; use build_helper::up_to_date; pub struct Meta { @@ -529,7 +529,7 @@ fn configure_cmake( } cfg.build_arg("-j").build_arg(builder.jobs().to_string()); - let mut cflags: OsString = builder.cflags(target, GitRepo::Llvm).join(" ").into(); + let mut cflags: OsString = builder.cflags(target, GitRepo::Llvm, CLang::C).join(" ").into(); if let Some(ref s) = builder.config.llvm_cflags { cflags.push(" "); cflags.push(s); @@ -545,12 +545,8 @@ fn configure_cmake( if builder.config.llvm_clang_cl.is_some() { cflags.push(&format!(" --target={}", target)); } - if let Some(flags) = env::var_os("CFLAGS") { - cflags.push(" "); - cflags.push(flags); - } cfg.define("CMAKE_C_FLAGS", cflags); - let mut cxxflags: OsString = builder.cflags(target, GitRepo::Llvm).join(" ").into(); + let mut cxxflags: OsString = builder.cflags(target, GitRepo::Llvm, CLang::Cxx).join(" ").into(); if let Some(ref s) = builder.config.llvm_cxxflags { cxxflags.push(" "); cxxflags.push(s); @@ -558,10 +554,6 @@ fn configure_cmake( if builder.config.llvm_clang_cl.is_some() { cxxflags.push(&format!(" --target={}", target)); } - if let Some(flags) = env::var_os("CXXFLAGS") { - cxxflags.push(" "); - cxxflags.push(flags); - } cfg.define("CMAKE_CXX_FLAGS", cxxflags); if let Some(ar) = builder.ar(target) { if ar.is_absolute() { @@ -583,7 +575,7 @@ fn configure_cmake( ldflags.push_all(flags); } - if let Some(flags) = env::var_os("LDFLAGS") { + if let Some(flags) = get_var("LDFLAGS", &builder.config.build.triple, &target.triple) { ldflags.push_all(&flags); } @@ -596,6 +588,16 @@ fn configure_cmake( } } +// Adapted from https://github.com/alexcrichton/cc-rs/blob/fba7feded71ee4f63cfe885673ead6d7b4f2f454/src/lib.rs#L2347-L2365 +fn get_var(var_base: &str, host: &str, target: &str) -> Option { + let kind = if host == target { "HOST" } else { "TARGET" }; + let target_u = target.replace("-", "_"); + env::var_os(&format!("{}_{}", var_base, target)) + .or_else(|| env::var_os(&format!("{}_{}", var_base, target_u))) + .or_else(|| env::var_os(&format!("{}_{}", kind, var_base))) + .or_else(|| env::var_os(var_base)) +} + #[derive(Debug, Copy, Clone, Hash, PartialEq, Eq)] pub struct Lld { pub target: TargetSelection, diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 176c06114e01d..19d98df3ce902 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -24,7 +24,7 @@ use crate::tool::{self, SourceType, Tool}; use crate::toolstate::ToolState; use crate::util::{self, add_link_lib_path, dylib_path, dylib_path_var}; use crate::Crate as CargoCrate; -use crate::{envify, DocTests, GitRepo, Mode}; +use crate::{envify, CLang, DocTests, GitRepo, Mode}; const ADB_TEST_DIR: &str = "/data/tmp/work"; @@ -1509,7 +1509,9 @@ note: if you're sure you want to do this, please open an issue as to why. In the .arg("--cxx") .arg(builder.cxx(target).unwrap()) .arg("--cflags") - .arg(builder.cflags(target, GitRepo::Rustc).join(" ")); + .arg(builder.cflags(target, GitRepo::Rustc, CLang::C).join(" ")) + .arg("--cxxflags") + .arg(builder.cflags(target, GitRepo::Rustc, CLang::Cxx).join(" ")); copts_passed = true; if let Some(ar) = builder.ar(target) { cmd.arg("--ar").arg(ar); @@ -1520,7 +1522,14 @@ note: if you're sure you want to do this, please open an issue as to why. In the cmd.arg("--llvm-components").arg(""); } if !copts_passed { - cmd.arg("--cc").arg("").arg("--cxx").arg("").arg("--cflags").arg(""); + cmd.arg("--cc") + .arg("") + .arg("--cxx") + .arg("") + .arg("--cflags") + .arg("") + .arg("--cxxflags") + .arg(""); } if builder.remote_tested(target) { diff --git a/src/tools/compiletest/src/common.rs b/src/tools/compiletest/src/common.rs index 82fe790a576ab..1bf6e6d011e5c 100644 --- a/src/tools/compiletest/src/common.rs +++ b/src/tools/compiletest/src/common.rs @@ -357,6 +357,7 @@ pub struct Config { pub cc: String, pub cxx: String, pub cflags: String, + pub cxxflags: String, pub ar: String, pub linker: Option, pub llvm_components: String, diff --git a/src/tools/compiletest/src/header/tests.rs b/src/tools/compiletest/src/header/tests.rs index 157b42e2d17f5..5b144a1020f4c 100644 --- a/src/tools/compiletest/src/header/tests.rs +++ b/src/tools/compiletest/src/header/tests.rs @@ -52,6 +52,7 @@ fn config() -> Config { "--cc=c", "--cxx=c++", "--cflags=", + "--cxxflags=", "--llvm-components=", "--android-cross-path=", "--target=x86_64-unknown-linux-gnu", diff --git a/src/tools/compiletest/src/main.rs b/src/tools/compiletest/src/main.rs index 58cde108b3322..3f2cd3ae232ba 100644 --- a/src/tools/compiletest/src/main.rs +++ b/src/tools/compiletest/src/main.rs @@ -126,6 +126,7 @@ pub fn parse_config(args: Vec) -> Config { .reqopt("", "cc", "path to a C compiler", "PATH") .reqopt("", "cxx", "path to a C++ compiler", "PATH") .reqopt("", "cflags", "flags for the C compiler", "FLAGS") + .reqopt("", "cxxflags", "flags for the CXX compiler", "FLAGS") .optopt("", "ar", "path to an archiver", "PATH") .optopt("", "linker", "path to a linker", "PATH") .reqopt("", "llvm-components", "list of LLVM components built in", "LIST") @@ -288,6 +289,7 @@ pub fn parse_config(args: Vec) -> Config { cc: matches.opt_str("cc").unwrap(), cxx: matches.opt_str("cxx").unwrap(), cflags: matches.opt_str("cflags").unwrap(), + cxxflags: matches.opt_str("cxxflags").unwrap(), ar: matches.opt_str("ar").unwrap_or_else(|| String::from("ar")), linker: matches.opt_str("linker"), llvm_components: matches.opt_str("llvm-components").unwrap(), diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 3f67a64971b67..8431aa7b818df 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2919,15 +2919,22 @@ impl<'test> TestCx<'test> { .map(|s| s.replace("/", "-")) .collect::>() .join(" "); + let cxxflags = self + .config + .cxxflags + .split(' ') + .map(|s| s.replace("/", "-")) + .collect::>() + .join(" "); cmd.env("IS_MSVC", "1") .env("IS_WINDOWS", "1") .env("MSVC_LIB", format!("'{}' -nologo", lib.display())) .env("CC", format!("'{}' {}", self.config.cc, cflags)) - .env("CXX", format!("'{}'", &self.config.cxx)); + .env("CXX", format!("'{}' {}", &self.config.cxx, cxxflags)); } else { cmd.env("CC", format!("{} {}", self.config.cc, self.config.cflags)) - .env("CXX", format!("{} {}", self.config.cxx, self.config.cflags)) + .env("CXX", format!("{} {}", self.config.cxx, self.config.cxxflags)) .env("AR", &self.config.ar); if self.config.target.contains("windows") { From c08a9a4f1d03f48ae38dba885fce96fad785a2de Mon Sep 17 00:00:00 2001 From: pierwill Date: Sat, 26 Feb 2022 14:44:09 -0600 Subject: [PATCH 09/12] Make `Ord`, `PartialOrd` opt-out in `newtype_index` Also remove `step` impl if `ORD_IMPL = off` --- compiler/rustc_macros/src/newtype.rs | 70 ++++++++++++++++++---------- 1 file changed, 46 insertions(+), 24 deletions(-) diff --git a/compiler/rustc_macros/src/newtype.rs b/compiler/rustc_macros/src/newtype.rs index f284e5cdd5c1e..f5968a8a7ea73 100644 --- a/compiler/rustc_macros/src/newtype.rs +++ b/compiler/rustc_macros/src/newtype.rs @@ -10,6 +10,7 @@ mod kw { syn::custom_keyword!(MAX); syn::custom_keyword!(ENCODABLE); syn::custom_keyword!(custom); + syn::custom_keyword!(ORD_IMPL); } #[derive(Debug)] @@ -42,6 +43,7 @@ impl Parse for Newtype { let mut max = None; let mut consts = Vec::new(); let mut encodable = true; + let mut ord = true; // Parse an optional trailing comma let try_comma = || -> Result<()> { @@ -99,13 +101,20 @@ impl Parse for Newtype { encodable = false; continue; } + if body.lookahead1().peek(kw::ORD_IMPL) { + body.parse::()?; + body.parse::()?; + body.parse::()?; + ord = false; + continue; + } // We've parsed everything that the user provided, so we're done if body.is_empty() { break; } - // Otherwise, we are parsng a user-defined constant + // Otherwise, we are parsing a user-defined constant let const_attrs = body.call(Attribute::parse_outer)?; body.parse::()?; let const_name: Ident = body.parse()?; @@ -137,6 +146,40 @@ impl Parse for Newtype { quote! {} }; + if ord { + derive_paths.push(parse_quote!(Ord)); + derive_paths.push(parse_quote!(PartialOrd)); + } + + let step = if ord { + quote! { + impl ::std::iter::Step for #name { + #[inline] + fn steps_between(start: &Self, end: &Self) -> Option { + ::steps_between( + &Self::index(*start), + &Self::index(*end), + ) + } + + #[inline] + fn forward_checked(start: Self, u: usize) -> Option { + Self::index(start).checked_add(u).map(Self::from_usize) + } + + #[inline] + fn backward_checked(start: Self, u: usize) -> Option { + Self::index(start).checked_sub(u).map(Self::from_usize) + } + } + + // Safety: The implementation of `Step` upholds all invariants. + unsafe impl ::std::iter::TrustedStep for #name {} + } + } else { + quote! {} + }; + let debug_impl = match debug_format { DebugFormat::Custom => quote! {}, DebugFormat::Format(format) => { @@ -152,7 +195,7 @@ impl Parse for Newtype { Ok(Self(quote! { #(#attrs)* - #[derive(Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, #(#derive_paths),*)] + #[derive(Clone, Copy, PartialEq, Eq, Hash, #(#derive_paths),*)] #[rustc_layout_scalar_valid_range_end(#max)] #vis struct #name { private: u32, @@ -247,28 +290,7 @@ impl Parse for Newtype { } } - impl ::std::iter::Step for #name { - #[inline] - fn steps_between(start: &Self, end: &Self) -> Option { - ::steps_between( - &Self::index(*start), - &Self::index(*end), - ) - } - - #[inline] - fn forward_checked(start: Self, u: usize) -> Option { - Self::index(start).checked_add(u).map(Self::from_usize) - } - - #[inline] - fn backward_checked(start: Self, u: usize) -> Option { - Self::index(start).checked_sub(u).map(Self::from_usize) - } - } - - // Safety: The implementation of `Step` upholds all invariants. - unsafe impl ::std::iter::TrustedStep for #name {} + #step impl From<#name> for u32 { #[inline] From 35606490abf83f2bd6c4adddc3b3c13a2a8b783b Mon Sep 17 00:00:00 2001 From: Dan Gohman Date: Thu, 3 Mar 2022 11:07:23 -0800 Subject: [PATCH 10/12] Use `HandleOrNull` and `HandleOrInvalid` in the Windows FFI bindings. Use the new `HandleOrNull` and `HandleOrInvalid` types that were introduced as part of [I/O safety] in a few functions in the Windows FFI bindings. This factors out an `unsafe` block and two `unsafe` function calls in the Windows implementation code. And, it helps test `HandleOrNull` and `HandleOrInvalid`, which indeed turned up a bug: `OwnedHandle` also needs to be `#[repr(transparent)]`, as it's used inside of `HandleOrNull` and `HandleOrInvalid` which are also `#[repr(transparent)]`. [I/O safety]: https://github.com/rust-lang/rust/issues/87074 --- library/std/src/os/windows/io/handle.rs | 1 + library/std/src/sys/windows/c.rs | 9 +++++---- library/std/src/sys/windows/fs.rs | 7 ++++--- library/std/src/sys/windows/handle.rs | 12 ++++++------ library/std/src/sys/windows/thread.rs | 10 ++++++---- 5 files changed, 22 insertions(+), 17 deletions(-) diff --git a/library/std/src/os/windows/io/handle.rs b/library/std/src/os/windows/io/handle.rs index d378d591ba3a9..14b94d8dcdf92 100644 --- a/library/std/src/os/windows/io/handle.rs +++ b/library/std/src/os/windows/io/handle.rs @@ -59,6 +59,7 @@ pub struct BorrowedHandle<'handle> { /// [`RegCloseKey`]: https://docs.microsoft.com/en-us/windows/win32/api/winreg/nf-winreg-regclosekey /// /// [here]: https://devblogs.microsoft.com/oldnewthing/20040302-00/?p=40443 +#[repr(transparent)] #[unstable(feature = "io_safety", issue = "87074")] pub struct OwnedHandle { handle: RawHandle, diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs index 2affd7e75b030..9b61b2476d5bb 100644 --- a/library/std/src/sys/windows/c.rs +++ b/library/std/src/sys/windows/c.rs @@ -6,6 +6,7 @@ use crate::mem; use crate::os::raw::{c_char, c_int, c_long, c_longlong, c_uint, c_ulong, c_ushort}; +use crate::os::windows::io::{BorrowedHandle, HandleOrInvalid, HandleOrNull}; use crate::ptr; use core::ffi::NonZero_c_ulong; @@ -886,7 +887,7 @@ extern "system" { lpParameter: LPVOID, dwCreationFlags: DWORD, lpThreadId: LPDWORD, - ) -> HANDLE; + ) -> HandleOrNull; pub fn WaitForSingleObject(hHandle: HANDLE, dwMilliseconds: DWORD) -> DWORD; pub fn SwitchToThread() -> BOOL; pub fn Sleep(dwMilliseconds: DWORD); @@ -950,14 +951,14 @@ extern "system" { dwOptions: DWORD, ) -> BOOL; pub fn ReadFile( - hFile: HANDLE, + hFile: BorrowedHandle<'_>, lpBuffer: LPVOID, nNumberOfBytesToRead: DWORD, lpNumberOfBytesRead: LPDWORD, lpOverlapped: LPOVERLAPPED, ) -> BOOL; pub fn WriteFile( - hFile: HANDLE, + hFile: BorrowedHandle<'_>, lpBuffer: LPVOID, nNumberOfBytesToWrite: DWORD, lpNumberOfBytesWritten: LPDWORD, @@ -981,7 +982,7 @@ extern "system" { dwCreationDisposition: DWORD, dwFlagsAndAttributes: DWORD, hTemplateFile: HANDLE, - ) -> HANDLE; + ) -> HandleOrInvalid; pub fn FindFirstFileW(fileName: LPCWSTR, findFileData: LPWIN32_FIND_DATAW) -> HANDLE; pub fn FindNextFileW(findFile: HANDLE, findFileData: LPWIN32_FIND_DATAW) -> BOOL; diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs index cb83ee2469a1c..d6c40a15329a9 100644 --- a/library/std/src/sys/windows/fs.rs +++ b/library/std/src/sys/windows/fs.rs @@ -1,5 +1,6 @@ use crate::os::windows::prelude::*; +use crate::convert::TryInto; use crate::ffi::OsString; use crate::fmt; use crate::io::{self, Error, IoSlice, IoSliceMut, ReadBuf, SeekFrom}; @@ -294,10 +295,10 @@ impl File { ptr::null_mut(), ) }; - if handle == c::INVALID_HANDLE_VALUE { - Err(Error::last_os_error()) + if let Ok(handle) = handle.try_into() { + Ok(File { handle: Handle::from_inner(handle) }) } else { - unsafe { Ok(File { handle: Handle::from_raw_handle(handle) }) } + Err(Error::last_os_error()) } } diff --git a/library/std/src/sys/windows/handle.rs b/library/std/src/sys/windows/handle.rs index daab39bb00cbc..e5c9567957bc1 100644 --- a/library/std/src/sys/windows/handle.rs +++ b/library/std/src/sys/windows/handle.rs @@ -78,7 +78,7 @@ impl Handle { let len = cmp::min(buf.len(), ::MAX as usize) as c::DWORD; let res = cvt(unsafe { c::ReadFile( - self.as_raw_handle(), + self.as_handle(), buf.as_mut_ptr() as c::LPVOID, len, &mut read, @@ -116,7 +116,7 @@ impl Handle { overlapped.Offset = offset as u32; overlapped.OffsetHigh = (offset >> 32) as u32; cvt(c::ReadFile( - self.as_raw_handle(), + self.as_handle(), buf.as_mut_ptr() as c::LPVOID, len, &mut read, @@ -135,7 +135,7 @@ impl Handle { let len = cmp::min(buf.remaining(), ::MAX as usize) as c::DWORD; let res = cvt(unsafe { c::ReadFile( - self.as_raw_handle(), + self.as_handle(), buf.unfilled_mut().as_mut_ptr() as c::LPVOID, len, &mut read, @@ -171,7 +171,7 @@ impl Handle { let len = cmp::min(buf.len(), ::MAX as usize) as c::DWORD; let mut amt = 0; let res = cvt(c::ReadFile( - self.as_raw_handle(), + self.as_handle(), buf.as_ptr() as c::LPVOID, len, &mut amt, @@ -225,7 +225,7 @@ impl Handle { let len = cmp::min(buf.len(), ::MAX as usize) as c::DWORD; cvt(unsafe { c::WriteFile( - self.as_raw_handle(), + self.as_handle(), buf.as_ptr() as c::LPVOID, len, &mut amt, @@ -252,7 +252,7 @@ impl Handle { overlapped.Offset = offset as u32; overlapped.OffsetHigh = (offset >> 32) as u32; cvt(c::WriteFile( - self.as_raw_handle(), + self.as_handle(), buf.as_ptr() as c::LPVOID, len, &mut written, diff --git a/library/std/src/sys/windows/thread.rs b/library/std/src/sys/windows/thread.rs index e4bba9255d23e..bd304dc57371d 100644 --- a/library/std/src/sys/windows/thread.rs +++ b/library/std/src/sys/windows/thread.rs @@ -1,11 +1,13 @@ +use crate::convert::TryInto; use crate::ffi::CStr; use crate::io; use crate::num::NonZeroUsize; -use crate::os::windows::io::{AsRawHandle, FromRawHandle}; +use crate::os::windows::io::AsRawHandle; use crate::ptr; use crate::sys::c; use crate::sys::handle::Handle; use crate::sys::stack_overflow; +use crate::sys_common::FromInner; use crate::time::Duration; use libc::c_void; @@ -40,13 +42,13 @@ impl Thread { ptr::null_mut(), ); - return if ret as usize == 0 { + return if let Ok(handle) = ret.try_into() { + Ok(Thread { handle: Handle::from_inner(handle) }) + } else { // The thread failed to start and as a result p was not consumed. Therefore, it is // safe to reconstruct the box so that it gets deallocated. drop(Box::from_raw(p)); Err(io::Error::last_os_error()) - } else { - Ok(Thread { handle: Handle::from_raw_handle(ret) }) }; extern "system" fn thread_start(main: *mut c_void) -> c::DWORD { From 08547818613137883b33808dc71039779e95a9fc Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Thu, 3 Mar 2022 14:46:29 -0500 Subject: [PATCH 11/12] CTFE SwitchInt: update comment --- compiler/rustc_const_eval/src/interpret/terminator.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_const_eval/src/interpret/terminator.rs b/compiler/rustc_const_eval/src/interpret/terminator.rs index 8094bf0cf2e2f..d2fbd6a9654f9 100644 --- a/compiler/rustc_const_eval/src/interpret/terminator.rs +++ b/compiler/rustc_const_eval/src/interpret/terminator.rs @@ -39,7 +39,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> { let mut target_block = targets.otherwise(); for (const_int, target) in targets.iter() { - // Compare using binary_op, to also support pointer values + // Compare using MIR BinOp::Eq, to also support pointer values. + // (Avoiding `self.binary_op` as that does some redundant layout computation.) let res = self .overflowing_binary_op( mir::BinOp::Eq, From fc142ebaf8cd18e2e9400e4ee9efb8a4331696d2 Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Fri, 4 Mar 2022 09:26:31 +1100 Subject: [PATCH 12/12] Fix a bug in `x.py fmt` that prevents some files being formatted. If you have a file in the repository root with the same name as a file somewhere within a directory, the latter currently won't get formatted. I have experienced this multiple times and not understood what was happening; I finally figured out the problem today. This commit fixes the problem. --- src/bootstrap/format.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/format.rs b/src/bootstrap/format.rs index 30fe6a7a44695..530cc829320d1 100644 --- a/src/bootstrap/format.rs +++ b/src/bootstrap/format.rs @@ -97,7 +97,12 @@ pub fn format(build: &Build, check: bool, paths: &[PathBuf]) { }); for untracked_path in untracked_paths { eprintln!("skip untracked path {} during rustfmt invocations", untracked_path); - ignore_fmt.add(&format!("!{}", untracked_path)).expect(&untracked_path); + // The leading `/` makes it an exact match against the + // repository root, rather than a glob. Without that, if you + // have `foo.rs` in the repository root it will also match + // against anything like `compiler/rustc_foo/src/foo.rs`, + // preventing the latter from being formatted. + ignore_fmt.add(&format!("!/{}", untracked_path)).expect(&untracked_path); } } else { eprintln!("Not in git tree. Skipping git-aware format checks");