From 5bbf8cf331f9c6140117bb6c2ac385d2e451d26e Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Fri, 7 May 2021 23:49:24 +0200 Subject: [PATCH 01/18] Revert SGX inline asm syntax This was erroneously changed in #83387 --- library/std/src/os/fortanix_sgx/arch.rs | 12 ++++++------ library/std/src/sys/sgx/abi/mem.rs | 4 ++-- 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/library/std/src/os/fortanix_sgx/arch.rs b/library/std/src/os/fortanix_sgx/arch.rs index b0170e67446db..4ce482e23cbfb 100644 --- a/library/std/src/os/fortanix_sgx/arch.rs +++ b/library/std/src/os/fortanix_sgx/arch.rs @@ -33,13 +33,13 @@ pub fn egetkey(request: &Align512<[u8; 512]>) -> Result, u32> asm!( // rbx is reserved by LLVM - "xchg {0}, rbx", + "xchg %rbx, {0}", "enclu", - "mov rbx, {0}", + "mov {0}, %rbx", inout(reg) request => _, inlateout("eax") ENCLU_EGETKEY => error, in("rcx") out.as_mut_ptr(), - options(nostack), + options(att_syntax, nostack), ); match error { @@ -64,14 +64,14 @@ pub fn ereport( asm!( // rbx is reserved by LLVM - "xchg {0}, rbx", + "xchg %rbx, {0}", "enclu", - "mov rbx, {0}", + "mov {0}, %rbx", inout(reg) targetinfo => _, in("eax") ENCLU_EREPORT, in("rcx") reportdata, in("rdx") report.as_mut_ptr(), - options(preserves_flags, nostack), + options(att_syntax, preserves_flags, nostack), ); report.assume_init() diff --git a/library/std/src/sys/sgx/abi/mem.rs b/library/std/src/sys/sgx/abi/mem.rs index 1e743894a9fea..52e8bec937c79 100644 --- a/library/std/src/sys/sgx/abi/mem.rs +++ b/library/std/src/sys/sgx/abi/mem.rs @@ -36,9 +36,9 @@ pub fn image_base() -> u64 { let base: u64; unsafe { asm!( - "lea {}, qword ptr [rip + IMAGE_BASE]", + "lea IMAGE_BASE(%rip), {}", lateout(reg) base, - options(nostack, preserves_flags, nomem, pure), + options(att_syntax, nostack, preserves_flags, nomem, pure), ) }; base From 08d44c2cc314aea420a2945ad16528992fb5b666 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Meier?= Date: Sat, 5 Jun 2021 19:02:38 +0200 Subject: [PATCH 02/18] Implement `Cursor::{remaining, is_empty}` --- library/std/src/io/cursor.rs | 63 +++++++++++++++++++++++++++++++++--- 1 file changed, 59 insertions(+), 4 deletions(-) diff --git a/library/std/src/io/cursor.rs b/library/std/src/io/cursor.rs index 9527254c94793..c0cb75a0eaef2 100644 --- a/library/std/src/io/cursor.rs +++ b/library/std/src/io/cursor.rs @@ -205,6 +205,62 @@ impl Cursor { } } +impl Cursor +where + T: AsRef<[u8]>, +{ + /// Returns the remaining slice. + /// + /// # Examples + /// + /// ``` + /// #![feature(cursor_remaining)] + /// use std::io::Cursor; + /// + /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]); + /// + /// assert_eq!(buff.remaining(), &[1, 2, 3, 4, 5]); + /// + /// buff.set_position(2); + /// assert_eq!(buff.remaining(), &[3, 4, 5]); + /// + /// buff.set_position(4); + /// assert_eq!(buff.remaining(), &[5]); + /// + /// buff.set_position(6); + /// assert_eq!(buff.remaining(), &[]); + /// ``` + #[unstable(feature = "cursor_remaining", issue = "none")] + pub fn remaining(&self) -> &[u8] { + let len = self.pos.min(self.inner.as_ref().len() as u64); + &self.inner.as_ref()[(len as usize)..] + } + + /// Returns `true` if the remaining slice is empty. + /// + /// # Examples + /// + /// ``` + /// #![feature(cursor_remaining)] + /// use std::io::Cursor; + /// + /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]); + /// + /// buff.set_position(2); + /// assert!(!buff.is_empty()); + /// + /// buff.set_position(5); + /// assert!(buff.is_empty()); + /// + /// buff.set_position(10); + /// assert!(buff.is_empty()); + /// ``` + #[unstable(feature = "cursor_remaining", issue = "none")] + pub fn is_empty(&self) -> bool { + self.pos >= self.inner.as_ref().len() as u64 + } +} + #[stable(feature = "rust1", since = "1.0.0")] impl Clone for Cursor where @@ -268,7 +324,7 @@ where T: AsRef<[u8]>, { fn read(&mut self, buf: &mut [u8]) -> io::Result { - let n = Read::read(&mut self.fill_buf()?, buf)?; + let n = Read::read(&mut self.remaining(), buf)?; self.pos += n as u64; Ok(n) } @@ -291,7 +347,7 @@ where fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { let n = buf.len(); - Read::read_exact(&mut self.fill_buf()?, buf)?; + Read::read_exact(&mut self.remaining(), buf)?; self.pos += n as u64; Ok(()) } @@ -308,8 +364,7 @@ where T: AsRef<[u8]>, { fn fill_buf(&mut self) -> io::Result<&[u8]> { - let amt = cmp::min(self.pos, self.inner.as_ref().len() as u64); - Ok(&self.inner.as_ref()[(amt as usize)..]) + Ok(self.remaining()) } fn consume(&mut self, amt: usize) { self.pos += amt as u64; From 5fb298664c5e8f179803ecf1502a7d4f51ba7ed4 Mon Sep 17 00:00:00 2001 From: Ashley Mannix Date: Fri, 4 Dec 2020 15:43:42 +1000 Subject: [PATCH 03/18] format symbols under shared frames --- library/std/src/sys_common/backtrace.rs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/library/std/src/sys_common/backtrace.rs b/library/std/src/sys_common/backtrace.rs index a549770d8b378..5f6318ba5d231 100644 --- a/library/std/src/sys_common/backtrace.rs +++ b/library/std/src/sys_common/backtrace.rs @@ -71,6 +71,7 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt:: let mut hit = false; let mut stop = false; + let mut frame_fmt = bt_fmt.frame(); backtrace_rs::resolve_frame_unsynchronized(frame, |symbol| { hit = true; if print_fmt == PrintFmt::Short { @@ -87,7 +88,7 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt:: } if start { - res = bt_fmt.frame().symbol(frame, symbol); + res = frame_fmt.symbol(frame, symbol); } }); if stop { @@ -95,7 +96,7 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt:: } if !hit { if start { - res = bt_fmt.frame().print_raw(frame.ip(), None, None, None); + res = frame_fmt.print_raw(frame.ip(), None, None, None); } } From 8423a19f66a8b98e34576186f03ce66161cd691b Mon Sep 17 00:00:00 2001 From: Ashley Mannix Date: Wed, 16 Dec 2020 15:07:39 +1000 Subject: [PATCH 04/18] make both panic display formats collapse frames --- library/std/src/backtrace.rs | 5 ++--- library/std/src/sys_common/backtrace.rs | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-) diff --git a/library/std/src/backtrace.rs b/library/std/src/backtrace.rs index 0aae4674b2942..f8884523cf446 100644 --- a/library/std/src/backtrace.rs +++ b/library/std/src/backtrace.rs @@ -399,12 +399,11 @@ impl fmt::Display for Backtrace { let mut f = backtrace_rs::BacktraceFmt::new(fmt, style, &mut print_path); f.add_context()?; for frame in frames { - let mut f = f.frame(); if frame.symbols.is_empty() { - f.print_raw(frame.frame.ip(), None, None, None)?; + f.frame().print_raw(frame.frame.ip(), None, None, None)?; } else { for symbol in frame.symbols.iter() { - f.print_raw_with_column( + f.frame().print_raw_with_column( frame.frame.ip(), symbol.name.as_ref().map(|b| backtrace_rs::SymbolName::new(b)), symbol.filename.as_ref().map(|b| match b { diff --git a/library/std/src/sys_common/backtrace.rs b/library/std/src/sys_common/backtrace.rs index 5f6318ba5d231..a549770d8b378 100644 --- a/library/std/src/sys_common/backtrace.rs +++ b/library/std/src/sys_common/backtrace.rs @@ -71,7 +71,6 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt:: let mut hit = false; let mut stop = false; - let mut frame_fmt = bt_fmt.frame(); backtrace_rs::resolve_frame_unsynchronized(frame, |symbol| { hit = true; if print_fmt == PrintFmt::Short { @@ -88,7 +87,7 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt:: } if start { - res = frame_fmt.symbol(frame, symbol); + res = bt_fmt.frame().symbol(frame, symbol); } }); if stop { @@ -96,7 +95,7 @@ unsafe fn _print_fmt(fmt: &mut fmt::Formatter<'_>, print_fmt: PrintFmt) -> fmt:: } if !hit { if start { - res = frame_fmt.print_raw(frame.ip(), None, None, None); + res = bt_fmt.frame().print_raw(frame.ip(), None, None, None); } } From 6c65a13472c0eccd74634b4e241cac735a078f3a Mon Sep 17 00:00:00 2001 From: zonyitoo Date: Tue, 15 Jun 2021 10:50:17 +0800 Subject: [PATCH 05/18] SocketAddr of Unix Sockets use sun_len as path's length in BSD-like OSes - fixes #69061 --- library/std/src/os/unix/net/addr.rs | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/library/std/src/os/unix/net/addr.rs b/library/std/src/os/unix/net/addr.rs index 459f3590e6470..582bec156cc64 100644 --- a/library/std/src/os/unix/net/addr.rs +++ b/library/std/src/os/unix/net/addr.rs @@ -209,7 +209,26 @@ impl SocketAddr { } else if self.addr.sun_path[0] == 0 { AddressKind::Abstract(&path[1..len]) } else { - AddressKind::Pathname(OsStr::from_bytes(&path[..len - 1]).as_ref()) + cfg_if! { + if #[cfg(any(target_os = "macos", + target_os = "ios", + target_os = "freebsd", + target_os = "dragonfly", + target_os = "openbsd", + target_os = "netbsd"))] { + // BSD-like systems may not include the last '\0' in length, + // because they have a sun_len as the length of sun_path + let sun_len = self.addr.sun_len; + } else { + // Trim the last '\0' + let mut sun_len = len; + while sun_len > 0 && path[sun_len] == 0 { + sun_len -= 1; + } + } + } + + AddressKind::Pathname(OsStr::from_bytes(&path[..sun_len]).as_ref()) } } } From 95c1bf60005085a5c83cc63b33319d6b484a704a Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 14 Jun 2021 17:55:25 +0200 Subject: [PATCH 06/18] Allow to pass arguments to rustdoc-gui tool --- src/bootstrap/test.rs | 3 +++ src/test/rustdoc-gui/README.md | 12 ++++++++++++ src/tools/rust-analyzer | 2 +- src/tools/rustdoc-gui/tester.js | 32 +++++++++++++++++++++++--------- 4 files changed, 39 insertions(+), 10 deletions(-) diff --git a/src/bootstrap/test.rs b/src/bootstrap/test.rs index 0b7a0e25df1ac..997b7f32eb5b5 100644 --- a/src/bootstrap/test.rs +++ b/src/bootstrap/test.rs @@ -877,6 +877,9 @@ impl Step for RustdocGUI { } } } + for test_arg in builder.config.cmd.test_args() { + command.arg(test_arg); + } builder.run(&mut command); } } diff --git a/src/test/rustdoc-gui/README.md b/src/test/rustdoc-gui/README.md index 499a98a3d2237..8efe7a578b8f0 100644 --- a/src/test/rustdoc-gui/README.md +++ b/src/test/rustdoc-gui/README.md @@ -8,5 +8,17 @@ test what's being currently displayed in the web page. You can find more information and its documentation in its [repository][browser-ui-test]. +If you need to have more information on the tests run, you can use `--test-args`: + +```bash +$ ./x.py test src/test/rustdoc-gui --stage 1 --jobs 8 --test-args --debug +``` + +There are three options supported: + + * `--debug`: allows to see puppeteer commands. + * `--no-headless`: disable headless mode so you can see what's going on. + * `--show-text`: by default, text isn't rendered because of issues with fonts, it enables it back. + [browser-ui-test]: https://github.com/GuillaumeGomez/browser-UI-test/ [puppeteer]: https://pptr.dev/ diff --git a/src/tools/rust-analyzer b/src/tools/rust-analyzer index f0618a8f06a46..13da28cc2bc1b 160000 --- a/src/tools/rust-analyzer +++ b/src/tools/rust-analyzer @@ -1 +1 @@ -Subproject commit f0618a8f06a464840079f30b3e25bcdcca3922a3 +Subproject commit 13da28cc2bc1b59f7af817eca36927a71edb023c diff --git a/src/tools/rustdoc-gui/tester.js b/src/tools/rustdoc-gui/tester.js index 8c8d86d5e3817..416d824c5645e 100644 --- a/src/tools/rustdoc-gui/tester.js +++ b/src/tools/rustdoc-gui/tester.js @@ -11,6 +11,9 @@ function showHelp() { console.log("rustdoc-js options:"); console.log(" --doc-folder [PATH] : location of the generated doc folder"); console.log(" --file [PATH] : file to run (can be repeated)"); + console.log(" --debug : show extra information about script run"); + console.log(" --show-text : render font in pages"); + console.log(" --no-headless : disable headless mode"); console.log(" --help : show this message then quit"); console.log(" --tests-folder [PATH] : location of the .GOML tests folder"); } @@ -20,10 +23,16 @@ function parseOptions(args) { "doc_folder": "", "tests_folder": "", "files": [], + "debug": false, + "show_text": false, + "no_headless": false, }; var correspondances = { "--doc-folder": "doc_folder", "--tests-folder": "tests_folder", + "--debug": "debug", + "--show-text": "show_text", + "--no-headless": "no_headless", }; for (var i = 0; i < args.length; ++i) { @@ -43,6 +52,8 @@ function parseOptions(args) { } else if (args[i] === "--help") { showHelp(); process.exit(0); + } else if (correspondances[args[i]]) { + opts[correspondances[args[i]]] = true; } else { console.log("Unknown option `" + args[i] + "`."); console.log("Use `--help` to see the list of options"); @@ -68,17 +79,20 @@ async function main(argv) { const options = new Options(); try { // This is more convenient that setting fields one by one. - options.parseArguments([ + let args = [ "--no-screenshot", - // This option shows what puppeteer "code" is run - // "--debug", - // This option disable the headless mode, allowing you to see what's going on. - // "--no-headless", - // The text isn't rendered by default because of a lot of small differences - // between hosts. - // "--show-text", "--variable", "DOC_PATH", opts["doc_folder"], - ]); + ]; + if (opts["debug"]) { + args.push("--debug"); + } + if (opts["show_text"]) { + args.push("--show-text"); + } + if (opts["no_headless"]) { + args.push("--no-headless"); + } + options.parseArguments(args); } catch (error) { console.error(`invalid argument: ${error}`); process.exit(1); From 212e91a3568b3f65fb504ce23ffe31d8d00bbb90 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Meier?= Date: Wed, 16 Jun 2021 17:25:47 +0200 Subject: [PATCH 07/18] Update tracking issue --- library/std/src/io/cursor.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/io/cursor.rs b/library/std/src/io/cursor.rs index c0cb75a0eaef2..db720531e3abb 100644 --- a/library/std/src/io/cursor.rs +++ b/library/std/src/io/cursor.rs @@ -230,7 +230,7 @@ where /// buff.set_position(6); /// assert_eq!(buff.remaining(), &[]); /// ``` - #[unstable(feature = "cursor_remaining", issue = "none")] + #[unstable(feature = "cursor_remaining", issue = "86369")] pub fn remaining(&self) -> &[u8] { let len = self.pos.min(self.inner.as_ref().len() as u64); &self.inner.as_ref()[(len as usize)..] @@ -255,7 +255,7 @@ where /// buff.set_position(10); /// assert!(buff.is_empty()); /// ``` - #[unstable(feature = "cursor_remaining", issue = "none")] + #[unstable(feature = "cursor_remaining", issue = "86369")] pub fn is_empty(&self) -> bool { self.pos >= self.inner.as_ref().len() as u64 } From 503abc77d27618779556be79a6214e6b4445045a Mon Sep 17 00:00:00 2001 From: Yerkebulan Tulibergenov Date: Wed, 16 Jun 2021 14:05:36 -0700 Subject: [PATCH 08/18] add regression test for issue #39161 --- src/test/ui/consts/issue-39161-bogus-error.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 src/test/ui/consts/issue-39161-bogus-error.rs diff --git a/src/test/ui/consts/issue-39161-bogus-error.rs b/src/test/ui/consts/issue-39161-bogus-error.rs new file mode 100644 index 0000000000000..a954385da41a4 --- /dev/null +++ b/src/test/ui/consts/issue-39161-bogus-error.rs @@ -0,0 +1,13 @@ +// check-pass + +pub struct X { + pub a: i32, + pub b: i32, +} + +fn main() { + const DX: X = X { a: 0, b: 0 }; + const _X1: X = X { a: 1, ..DX }; + let _x2 = X { a: 1, b: 2, ..DX }; + const _X3: X = X { a: 1, b: 2, ..DX }; +} From 636170a1e29356a6e2ca96189f94132a0d6d642f Mon Sep 17 00:00:00 2001 From: Yuki Okushi Date: Thu, 17 Jun 2021 08:56:54 +0900 Subject: [PATCH 09/18] Remove `#[allow(unused_lifetimes)]` which is now unnecessary --- compiler/rustc_data_structures/src/captures.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/compiler/rustc_data_structures/src/captures.rs b/compiler/rustc_data_structures/src/captures.rs index 26b90ebfd5f11..677ccb31454ea 100644 --- a/compiler/rustc_data_structures/src/captures.rs +++ b/compiler/rustc_data_structures/src/captures.rs @@ -3,8 +3,6 @@ /// Basically a workaround; see [this comment] for details. /// /// [this comment]: https://github.com/rust-lang/rust/issues/34511#issuecomment-373423999 -// FIXME(eddyb) false positive, the lifetime parameter is "phantom" but needed. -#[allow(unused_lifetimes)] pub trait Captures<'a> {} impl<'a, T: ?Sized> Captures<'a> for T {} From 664bde0770fcd898a6da97a117996de1366098dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6ren=20Meier?= Date: Thu, 17 Jun 2021 02:14:53 +0200 Subject: [PATCH 10/18] rename `remaining` to `remaining_slice` and add a new `remaining` --- library/std/src/io/cursor.rs | 42 +++++++++++++++++++++++++++++------- 1 file changed, 34 insertions(+), 8 deletions(-) diff --git a/library/std/src/io/cursor.rs b/library/std/src/io/cursor.rs index db720531e3abb..04f13cdeb88e3 100644 --- a/library/std/src/io/cursor.rs +++ b/library/std/src/io/cursor.rs @@ -209,6 +209,32 @@ impl Cursor where T: AsRef<[u8]>, { + /// Returns the remaining length. + /// + /// # Examples + /// + /// ``` + /// #![feature(cursor_remaining)] + /// use std::io::Cursor; + /// + /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]); + /// + /// assert_eq!(buff.remaining(), 5); + /// + /// buff.set_position(2); + /// assert_eq!(buff.remaining(), 3); + /// + /// buff.set_position(4); + /// assert_eq!(buff.remaining(), 1); + /// + /// buff.set_position(6); + /// assert_eq!(buff.remaining(), 0); + /// ``` + #[unstable(feature = "cursor_remaining", issue = "86369")] + pub fn remaining(&self) -> u64 { + (self.inner.as_ref().len() as u64).checked_sub(self.pos).unwrap_or(0) + } + /// Returns the remaining slice. /// /// # Examples @@ -219,19 +245,19 @@ where /// /// let mut buff = Cursor::new(vec![1, 2, 3, 4, 5]); /// - /// assert_eq!(buff.remaining(), &[1, 2, 3, 4, 5]); + /// assert_eq!(buff.remaining_slice(), &[1, 2, 3, 4, 5]); /// /// buff.set_position(2); - /// assert_eq!(buff.remaining(), &[3, 4, 5]); + /// assert_eq!(buff.remaining_slice(), &[3, 4, 5]); /// /// buff.set_position(4); - /// assert_eq!(buff.remaining(), &[5]); + /// assert_eq!(buff.remaining_slice(), &[5]); /// /// buff.set_position(6); - /// assert_eq!(buff.remaining(), &[]); + /// assert_eq!(buff.remaining_slice(), &[]); /// ``` #[unstable(feature = "cursor_remaining", issue = "86369")] - pub fn remaining(&self) -> &[u8] { + pub fn remaining_slice(&self) -> &[u8] { let len = self.pos.min(self.inner.as_ref().len() as u64); &self.inner.as_ref()[(len as usize)..] } @@ -324,7 +350,7 @@ where T: AsRef<[u8]>, { fn read(&mut self, buf: &mut [u8]) -> io::Result { - let n = Read::read(&mut self.remaining(), buf)?; + let n = Read::read(&mut self.remaining_slice(), buf)?; self.pos += n as u64; Ok(n) } @@ -347,7 +373,7 @@ where fn read_exact(&mut self, buf: &mut [u8]) -> io::Result<()> { let n = buf.len(); - Read::read_exact(&mut self.remaining(), buf)?; + Read::read_exact(&mut self.remaining_slice(), buf)?; self.pos += n as u64; Ok(()) } @@ -364,7 +390,7 @@ where T: AsRef<[u8]>, { fn fill_buf(&mut self) -> io::Result<&[u8]> { - Ok(self.remaining()) + Ok(self.remaining_slice()) } fn consume(&mut self, amt: usize) { self.pos += amt as u64; From 13bfbb42530321e528bd10e5301ba83db8973b8f Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Wed, 16 Jun 2021 17:02:52 +0200 Subject: [PATCH 11/18] Fix comment about rustc_inherit_overflow_checks in abs(). --- library/core/src/num/int_macros.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/core/src/num/int_macros.rs b/library/core/src/num/int_macros.rs index a0efe681285b4..2e466106fe553 100644 --- a/library/core/src/num/int_macros.rs +++ b/library/core/src/num/int_macros.rs @@ -1772,9 +1772,9 @@ macro_rules! int_impl { #[inline] #[rustc_inherit_overflow_checks] pub const fn abs(self) -> Self { - // Note that the #[inline] above means that the overflow - // semantics of the subtraction depend on the crate we're being - // inlined into. + // Note that the #[rustc_inherit_overflow_checks] and #[inline] + // above mean that the overflow semantics of the subtraction + // depend on the crate we're being called from. if self.is_negative() { -self } else { From 22029a2ea7ee0a6bc2dcde64a6799aaa5df5c6af Mon Sep 17 00:00:00 2001 From: Yerkebulan Tulibergenov Date: Thu, 17 Jun 2021 21:23:25 -0700 Subject: [PATCH 12/18] add regression test for issue #54685 --- ...function-pointer-comparison-issue-54685.rs | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 src/test/ui/function-pointer/function-pointer-comparison-issue-54685.rs diff --git a/src/test/ui/function-pointer/function-pointer-comparison-issue-54685.rs b/src/test/ui/function-pointer/function-pointer-comparison-issue-54685.rs new file mode 100644 index 0000000000000..a036d10e63902 --- /dev/null +++ b/src/test/ui/function-pointer/function-pointer-comparison-issue-54685.rs @@ -0,0 +1,31 @@ +// min-llvm-version: 12.0 +// compile-flags: -C opt-level=3 +// run-pass + +fn foo(_i: i32) -> i32 { + 1 +} +fn bar(_i: i32) -> i32 { + 1 +} + +fn main() { + let x: fn(i32) -> i32 = foo; + let y: fn(i32) -> i32 = bar; + + let s1; + if x == y { + s1 = "same".to_string(); + } else { + s1 = format!("{:?}, {:?}", x, y); + } + + let s2; + if x == y { + s2 = "same".to_string(); + } else { + s2 = format!("{:?}, {:?}", x, y); + } + + assert_eq!(s1, s2); +} From 4cd2fab8c56b19fa14685a0ceb6d905366913b2c Mon Sep 17 00:00:00 2001 From: Smitty Date: Sun, 20 Jun 2021 13:48:37 -0400 Subject: [PATCH 13/18] Specify if struct/enum in arg mismatch error --- .../rustc_typeck/src/check/fn_ctxt/checks.rs | 28 ++++++-- src/test/ui/span/missing-unit-argument.rs | 2 +- src/test/ui/span/missing-unit-argument.stderr | 2 +- src/test/ui/typeck/struct-enum-wrong-args.rs | 13 ++++ .../ui/typeck/struct-enum-wrong-args.stderr | 67 +++++++++++++++++++ 5 files changed, 106 insertions(+), 6 deletions(-) create mode 100644 src/test/ui/typeck/struct-enum-wrong-args.rs create mode 100644 src/test/ui/typeck/struct-enum-wrong-args.stderr diff --git a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs index d6989b866c1d2..f65cc429fbd48 100644 --- a/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs +++ b/compiler/rustc_typeck/src/check/fn_ctxt/checks.rs @@ -11,7 +11,7 @@ use crate::check::{ use rustc_ast as ast; use rustc_errors::{Applicability, DiagnosticBuilder, DiagnosticId}; use rustc_hir as hir; -use rustc_hir::def::{DefKind, Res}; +use rustc_hir::def::{CtorOf, DefKind, Res}; use rustc_hir::def_id::DefId; use rustc_hir::{ExprKind, Node, QPath}; use rustc_middle::ty::adjustment::AllowTwoPhase; @@ -120,8 +120,22 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { error_code: &str, c_variadic: bool, sugg_unit: bool| { - let (span, start_span, args) = match &expr.kind { - hir::ExprKind::Call(hir::Expr { span, .. }, args) => (*span, *span, &args[..]), + let (span, start_span, args, ctor_of) = match &expr.kind { + hir::ExprKind::Call( + hir::Expr { + span, + kind: + hir::ExprKind::Path(hir::QPath::Resolved( + _, + hir::Path { res: Res::Def(DefKind::Ctor(of, _), _), .. }, + )), + .. + }, + args, + ) => (*span, *span, &args[..], Some(of)), + hir::ExprKind::Call(hir::Expr { span, .. }, args) => { + (*span, *span, &args[..], None) + } hir::ExprKind::MethodCall(path_segment, span, args, _) => ( *span, // `sp` doesn't point at the whole `foo.bar()`, only at `bar`. @@ -137,6 +151,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { }) .unwrap_or(*span), &args[1..], // Skip the receiver. + None, // methods are never ctors ), k => span_bug!(sp, "checking argument types on a non-call: `{:?}`", k), }; @@ -157,7 +172,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let mut err = tcx.sess.struct_span_err_with_code( span, &format!( - "this function takes {}{} but {} {} supplied", + "this {} takes {}{} but {} {} supplied", + match ctor_of { + Some(CtorOf::Struct) => "struct", + Some(CtorOf::Variant) => "enum variant", + None => "function", + }, if c_variadic { "at least " } else { "" }, potentially_plural_count(expected_count, "argument"), potentially_plural_count(arg_count, "argument"), diff --git a/src/test/ui/span/missing-unit-argument.rs b/src/test/ui/span/missing-unit-argument.rs index b8fb332120a4e..5b9861da6e854 100644 --- a/src/test/ui/span/missing-unit-argument.rs +++ b/src/test/ui/span/missing-unit-argument.rs @@ -8,7 +8,7 @@ impl S { } fn main() { - let _: Result<(), String> = Ok(); //~ ERROR this function takes + let _: Result<(), String> = Ok(); //~ ERROR this enum variant takes foo(); //~ ERROR this function takes foo(()); //~ ERROR this function takes bar(); //~ ERROR this function takes diff --git a/src/test/ui/span/missing-unit-argument.stderr b/src/test/ui/span/missing-unit-argument.stderr index b15da2cb47955..7a24ffbd81c88 100644 --- a/src/test/ui/span/missing-unit-argument.stderr +++ b/src/test/ui/span/missing-unit-argument.stderr @@ -1,4 +1,4 @@ -error[E0061]: this function takes 1 argument but 0 arguments were supplied +error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied --> $DIR/missing-unit-argument.rs:11:33 | LL | let _: Result<(), String> = Ok(); diff --git a/src/test/ui/typeck/struct-enum-wrong-args.rs b/src/test/ui/typeck/struct-enum-wrong-args.rs new file mode 100644 index 0000000000000..7204caa09d4d2 --- /dev/null +++ b/src/test/ui/typeck/struct-enum-wrong-args.rs @@ -0,0 +1,13 @@ +struct Wrapper(i32); +struct DoubleWrapper(i32, i32); + +fn main() { + let _ = Some(3, 2); //~ ERROR this enum variant takes + let _ = Ok(3, 6, 2); //~ ERROR this enum variant takes + let _ = Ok(); //~ ERROR this enum variant takes + let _ = Wrapper(); //~ ERROR this struct takes + let _ = Wrapper(5, 2); //~ ERROR this struct takes + let _ = DoubleWrapper(); //~ ERROR this struct takes + let _ = DoubleWrapper(5); //~ ERROR this struct takes + let _ = DoubleWrapper(5, 2, 7); //~ ERROR this struct takes +} diff --git a/src/test/ui/typeck/struct-enum-wrong-args.stderr b/src/test/ui/typeck/struct-enum-wrong-args.stderr new file mode 100644 index 0000000000000..b9c5756d1f903 --- /dev/null +++ b/src/test/ui/typeck/struct-enum-wrong-args.stderr @@ -0,0 +1,67 @@ +error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied + --> $DIR/struct-enum-wrong-args.rs:5:13 + | +LL | let _ = Some(3, 2); + | ^^^^ - - supplied 2 arguments + | | + | expected 1 argument + +error[E0061]: this enum variant takes 1 argument but 3 arguments were supplied + --> $DIR/struct-enum-wrong-args.rs:6:13 + | +LL | let _ = Ok(3, 6, 2); + | ^^ - - - supplied 3 arguments + | | + | expected 1 argument + +error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied + --> $DIR/struct-enum-wrong-args.rs:7:13 + | +LL | let _ = Ok(); + | ^^-- supplied 0 arguments + | | + | expected 1 argument + +error[E0061]: this struct takes 1 argument but 0 arguments were supplied + --> $DIR/struct-enum-wrong-args.rs:8:13 + | +LL | let _ = Wrapper(); + | ^^^^^^^-- supplied 0 arguments + | | + | expected 1 argument + +error[E0061]: this struct takes 1 argument but 2 arguments were supplied + --> $DIR/struct-enum-wrong-args.rs:9:13 + | +LL | let _ = Wrapper(5, 2); + | ^^^^^^^ - - supplied 2 arguments + | | + | expected 1 argument + +error[E0061]: this struct takes 2 arguments but 0 arguments were supplied + --> $DIR/struct-enum-wrong-args.rs:10:13 + | +LL | let _ = DoubleWrapper(); + | ^^^^^^^^^^^^^-- supplied 0 arguments + | | + | expected 2 arguments + +error[E0061]: this struct takes 2 arguments but 1 argument was supplied + --> $DIR/struct-enum-wrong-args.rs:11:13 + | +LL | let _ = DoubleWrapper(5); + | ^^^^^^^^^^^^^ - supplied 1 argument + | | + | expected 2 arguments + +error[E0061]: this struct takes 2 arguments but 3 arguments were supplied + --> $DIR/struct-enum-wrong-args.rs:12:13 + | +LL | let _ = DoubleWrapper(5, 2, 7); + | ^^^^^^^^^^^^^ - - - supplied 3 arguments + | | + | expected 2 arguments + +error: aborting due to 8 previous errors + +For more information about this error, try `rustc --explain E0061`. From 9063edaf3bcf3d0897ee3e73b6468c3984883b18 Mon Sep 17 00:00:00 2001 From: Christiaan Dirkx Date: Thu, 29 Apr 2021 11:40:14 +0200 Subject: [PATCH 14/18] Move `available_concurrency` implementation to `sys` --- library/std/src/sys/hermit/thread.rs | 8 + library/std/src/sys/sgx/thread.rs | 8 + library/std/src/sys/unix/thread.rs | 83 ++++++++++ library/std/src/sys/unsupported/thread.rs | 8 + library/std/src/sys/wasi/thread.rs | 8 + library/std/src/sys/wasm/atomics/thread.rs | 8 + library/std/src/sys/windows/c.rs | 18 ++ library/std/src/sys/windows/thread.rs | 16 ++ .../std/src/thread/available_concurrency.rs | 156 ------------------ library/std/src/thread/mod.rs | 43 ++++- 10 files changed, 194 insertions(+), 162 deletions(-) delete mode 100644 library/std/src/thread/available_concurrency.rs diff --git a/library/std/src/sys/hermit/thread.rs b/library/std/src/sys/hermit/thread.rs index f35a3a8a80fc5..3d00e626e1ac7 100644 --- a/library/std/src/sys/hermit/thread.rs +++ b/library/std/src/sys/hermit/thread.rs @@ -3,6 +3,7 @@ use crate::ffi::CStr; use crate::io; use crate::mem; +use crate::num::NonZeroUsize; use crate::sys::hermit::abi; use crate::sys::hermit::thread_local_dtor::run_dtors; use crate::time::Duration; @@ -95,6 +96,13 @@ impl Thread { } } +pub fn available_concurrency() -> io::Result { + Err(io::Error::new_const( + io::ErrorKind::NotFound, + &"The number of hardware threads is not known for the target platform", + )) +} + pub mod guard { pub type Guard = !; pub unsafe fn current() -> Option { diff --git a/library/std/src/sys/sgx/thread.rs b/library/std/src/sys/sgx/thread.rs index 67e2e8b59d397..b82ae86521a0b 100644 --- a/library/std/src/sys/sgx/thread.rs +++ b/library/std/src/sys/sgx/thread.rs @@ -1,6 +1,7 @@ #![cfg_attr(test, allow(dead_code))] // why is this necessary? use crate::ffi::CStr; use crate::io; +use crate::num::NonZeroUsize; use crate::time::Duration; use super::abi::usercalls; @@ -135,6 +136,13 @@ impl Thread { } } +pub fn available_concurrency() -> io::Result { + Err(io::Error::new_const( + io::ErrorKind::NotFound, + &"The number of hardware threads is not known for the target platform", + )) +} + pub mod guard { pub type Guard = !; pub unsafe fn current() -> Option { diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs index b8f43caec32a3..e49971de940ba 100644 --- a/library/std/src/sys/unix/thread.rs +++ b/library/std/src/sys/unix/thread.rs @@ -2,6 +2,7 @@ use crate::cmp; use crate::ffi::CStr; use crate::io; use crate::mem; +use crate::num::NonZeroUsize; use crate::ptr; use crate::sys::{os, stack_overflow}; use crate::time::Duration; @@ -198,6 +199,88 @@ impl Drop for Thread { } } +pub fn available_concurrency() -> io::Result { + cfg_if::cfg_if! { + if #[cfg(any( + target_os = "android", + target_os = "emscripten", + target_os = "fuchsia", + target_os = "ios", + target_os = "linux", + target_os = "macos", + target_os = "solaris", + target_os = "illumos", + ))] { + match unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) } { + -1 => Err(io::Error::last_os_error()), + 0 => Err(io::Error::new_const(io::ErrorKind::NotFound, &"The number of hardware threads is not known for the target platform")), + cpus => Ok(unsafe { NonZeroUsize::new_unchecked(cpus as usize) }), + } + } else if #[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "netbsd"))] { + use crate::ptr; + + let mut cpus: libc::c_uint = 0; + let mut cpus_size = crate::mem::size_of_val(&cpus); + + unsafe { + cpus = libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as libc::c_uint; + } + + // Fallback approach in case of errors or no hardware threads. + if cpus < 1 { + let mut mib = [libc::CTL_HW, libc::HW_NCPU, 0, 0]; + let res = unsafe { + libc::sysctl( + mib.as_mut_ptr(), + 2, + &mut cpus as *mut _ as *mut _, + &mut cpus_size as *mut _ as *mut _, + ptr::null_mut(), + 0, + ) + }; + + // Handle errors if any. + if res == -1 { + return Err(io::Error::last_os_error()); + } else if cpus == 0 { + return Err(io::Error::new_const(io::ErrorKind::NotFound, &"The number of hardware threads is not known for the target platform")); + } + } + Ok(unsafe { NonZeroUsize::new_unchecked(cpus as usize) }) + } else if #[cfg(target_os = "openbsd")] { + use crate::ptr; + + let mut cpus: libc::c_uint = 0; + let mut cpus_size = crate::mem::size_of_val(&cpus); + let mut mib = [libc::CTL_HW, libc::HW_NCPU, 0, 0]; + + let res = unsafe { + libc::sysctl( + mib.as_mut_ptr(), + 2, + &mut cpus as *mut _ as *mut _, + &mut cpus_size as *mut _ as *mut _, + ptr::null_mut(), + 0, + ) + }; + + // Handle errors if any. + if res == -1 { + return Err(io::Error::last_os_error()); + } else if cpus == 0 { + return Err(io::Error::new_const(io::ErrorKind::NotFound, &"The number of hardware threads is not known for the target platform")); + } + + Ok(unsafe { NonZeroUsize::new_unchecked(cpus as usize) }) + } else { + // FIXME: implement on vxWorks, Redox, Haiku, l4re + Err(io::Error::new_const(io::ErrorKind::NotFound, &"The number of hardware threads is not known for the target platform")) + } + } +} + #[cfg(all( not(target_os = "linux"), not(target_os = "freebsd"), diff --git a/library/std/src/sys/unsupported/thread.rs b/library/std/src/sys/unsupported/thread.rs index cda8510e1baeb..47005ead196a5 100644 --- a/library/std/src/sys/unsupported/thread.rs +++ b/library/std/src/sys/unsupported/thread.rs @@ -1,6 +1,7 @@ use super::unsupported; use crate::ffi::CStr; use crate::io; +use crate::num::NonZeroUsize; use crate::time::Duration; pub struct Thread(!); @@ -30,6 +31,13 @@ impl Thread { } } +pub fn available_concurrency() -> io::Result { + Err(io::Error::new_const( + io::ErrorKind::NotFound, + &"The number of hardware threads is not known for the target platform", + )) +} + pub mod guard { pub type Guard = !; pub unsafe fn current() -> Option { diff --git a/library/std/src/sys/wasi/thread.rs b/library/std/src/sys/wasi/thread.rs index 74515553a8218..959077f7b54b6 100644 --- a/library/std/src/sys/wasi/thread.rs +++ b/library/std/src/sys/wasi/thread.rs @@ -3,6 +3,7 @@ use crate::ffi::CStr; use crate::io; use crate::mem; +use crate::num::NonZeroUsize; use crate::sys::unsupported; use crate::time::Duration; @@ -63,6 +64,13 @@ impl Thread { } } +pub fn available_concurrency() -> io::Result { + Err(io::Error::new_const( + io::ErrorKind::NotFound, + &"The number of hardware threads is not known for the target platform", + )) +} + pub mod guard { pub type Guard = !; pub unsafe fn current() -> Option { diff --git a/library/std/src/sys/wasm/atomics/thread.rs b/library/std/src/sys/wasm/atomics/thread.rs index 54bc877aa7de7..8207a41035db8 100644 --- a/library/std/src/sys/wasm/atomics/thread.rs +++ b/library/std/src/sys/wasm/atomics/thread.rs @@ -1,5 +1,6 @@ use crate::ffi::CStr; use crate::io; +use crate::num::NonZeroUsize; use crate::sys::unsupported; use crate::time::Duration; @@ -39,6 +40,13 @@ impl Thread { pub fn join(self) {} } +pub fn available_concurrency() -> io::Result { + Err(io::Error::new_const( + io::ErrorKind::NotFound, + &"The number of hardware threads is not known for the target platform", + )) +} + pub mod guard { pub type Guard = !; pub unsafe fn current() -> Option { diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs index b64870401f1fd..193c28c7673d7 100644 --- a/library/std/src/sys/windows/c.rs +++ b/library/std/src/sys/windows/c.rs @@ -13,6 +13,7 @@ use libc::{c_void, size_t, wchar_t}; pub use self::EXCEPTION_DISPOSITION::*; pub use self::FILE_INFO_BY_HANDLE_CLASS::*; +pub type DWORD_PTR = ULONG_PTR; pub type DWORD = c_ulong; pub type NonZeroDWORD = NonZero_c_ulong; pub type HANDLE = LPVOID; @@ -53,6 +54,7 @@ pub type LPWSADATA = *mut WSADATA; pub type LPWSAPROTOCOL_INFO = *mut WSAPROTOCOL_INFO; pub type LPWSTR = *mut WCHAR; pub type LPFILETIME = *mut FILETIME; +pub type LPSYSTEM_INFO = *mut SYSTEM_INFO; pub type LPWSABUF = *mut WSABUF; pub type LPWSAOVERLAPPED = *mut c_void; pub type LPWSAOVERLAPPED_COMPLETION_ROUTINE = *mut c_void; @@ -533,6 +535,21 @@ pub struct FILETIME { pub dwHighDateTime: DWORD, } +#[repr(C)] +pub struct SYSTEM_INFO { + pub wProcessorArchitecture: WORD, + pub wReserved: WORD, + pub dwPageSize: DWORD, + pub lpMinimumApplicationAddress: LPVOID, + pub lpMaximumApplicationAddress: LPVOID, + pub dwActiveProcessorMask: DWORD_PTR, + pub dwNumberOfProcessors: DWORD, + pub dwProcessorType: DWORD, + pub dwAllocationGranularity: DWORD, + pub wProcessorLevel: WORD, + pub wProcessorRevision: WORD, +} + #[repr(C)] pub struct OVERLAPPED { pub Internal: *mut c_ulong, @@ -934,6 +951,7 @@ extern "system" { pub fn GetModuleHandleW(lpModuleName: LPCWSTR) -> HMODULE; pub fn GetSystemTimeAsFileTime(lpSystemTimeAsFileTime: LPFILETIME); + pub fn GetSystemInfo(lpSystemInfo: LPSYSTEM_INFO); pub fn CreateEventW( lpEventAttributes: LPSECURITY_ATTRIBUTES, diff --git a/library/std/src/sys/windows/thread.rs b/library/std/src/sys/windows/thread.rs index 38839ea5e90ed..ef7a9733fd880 100644 --- a/library/std/src/sys/windows/thread.rs +++ b/library/std/src/sys/windows/thread.rs @@ -1,5 +1,6 @@ use crate::ffi::CStr; use crate::io; +use crate::num::NonZeroUsize; use crate::ptr; use crate::sys::c; use crate::sys::handle::Handle; @@ -98,6 +99,21 @@ impl Thread { } } +pub fn available_concurrency() -> io::Result { + let res = unsafe { + let mut sysinfo: c::SYSTEM_INFO = crate::mem::zeroed(); + c::GetSystemInfo(&mut sysinfo); + sysinfo.dwNumberOfProcessors as usize + }; + match res { + 0 => Err(io::Error::new_const( + io::ErrorKind::NotFound, + &"The number of hardware threads is not known for the target platform", + )), + cpus => Ok(unsafe { NonZeroUsize::new_unchecked(cpus) }), + } +} + #[cfg_attr(test, allow(dead_code))] pub mod guard { pub type Guard = !; diff --git a/library/std/src/thread/available_concurrency.rs b/library/std/src/thread/available_concurrency.rs deleted file mode 100644 index e8cdde8801459..0000000000000 --- a/library/std/src/thread/available_concurrency.rs +++ /dev/null @@ -1,156 +0,0 @@ -use crate::io; -use crate::num::NonZeroUsize; - -/// Returns the number of hardware threads available to the program. -/// -/// This value should be considered only a hint. -/// -/// # Platform-specific behavior -/// -/// If interpreted as the number of actual hardware threads, it may undercount on -/// Windows systems with more than 64 hardware threads. If interpreted as the -/// available concurrency for that process, it may overcount on Windows systems -/// when limited by a process wide affinity mask or job object limitations, and -/// it may overcount on Linux systems when limited by a process wide affinity -/// mask or affected by cgroups limits. -/// -/// # Errors -/// -/// This function will return an error in the following situations, but is not -/// limited to just these cases: -/// -/// - If the number of hardware threads is not known for the target platform. -/// - The process lacks permissions to view the number of hardware threads -/// available. -/// -/// # Examples -/// -/// ``` -/// # #![allow(dead_code)] -/// #![feature(available_concurrency)] -/// use std::thread; -/// -/// let count = thread::available_concurrency().map(|n| n.get()).unwrap_or(1); -/// ``` -#[unstable(feature = "available_concurrency", issue = "74479")] -pub fn available_concurrency() -> io::Result { - available_concurrency_internal() -} - -cfg_if::cfg_if! { - if #[cfg(windows)] { - #[allow(nonstandard_style)] - fn available_concurrency_internal() -> io::Result { - #[repr(C)] - struct SYSTEM_INFO { - wProcessorArchitecture: u16, - wReserved: u16, - dwPageSize: u32, - lpMinimumApplicationAddress: *mut u8, - lpMaximumApplicationAddress: *mut u8, - dwActiveProcessorMask: *mut u8, - dwNumberOfProcessors: u32, - dwProcessorType: u32, - dwAllocationGranularity: u32, - wProcessorLevel: u16, - wProcessorRevision: u16, - } - extern "system" { - fn GetSystemInfo(info: *mut SYSTEM_INFO) -> i32; - } - let res = unsafe { - let mut sysinfo = crate::mem::zeroed(); - GetSystemInfo(&mut sysinfo); - sysinfo.dwNumberOfProcessors as usize - }; - match res { - 0 => Err(io::Error::new_const(io::ErrorKind::NotFound, &"The number of hardware threads is not known for the target platform")), - cpus => Ok(unsafe { NonZeroUsize::new_unchecked(cpus) }), - } - } - } else if #[cfg(any( - target_os = "android", - target_os = "emscripten", - target_os = "fuchsia", - target_os = "ios", - target_os = "linux", - target_os = "macos", - target_os = "solaris", - target_os = "illumos", - ))] { - fn available_concurrency_internal() -> io::Result { - match unsafe { libc::sysconf(libc::_SC_NPROCESSORS_ONLN) } { - -1 => Err(io::Error::last_os_error()), - 0 => Err(io::Error::new_const(io::ErrorKind::NotFound, &"The number of hardware threads is not known for the target platform")), - cpus => Ok(unsafe { NonZeroUsize::new_unchecked(cpus as usize) }), - } - } - } else if #[cfg(any(target_os = "freebsd", target_os = "dragonfly", target_os = "netbsd"))] { - fn available_concurrency_internal() -> io::Result { - use crate::ptr; - - let mut cpus: libc::c_uint = 0; - let mut cpus_size = crate::mem::size_of_val(&cpus); - - unsafe { - cpus = libc::sysconf(libc::_SC_NPROCESSORS_ONLN) as libc::c_uint; - } - - // Fallback approach in case of errors or no hardware threads. - if cpus < 1 { - let mut mib = [libc::CTL_HW, libc::HW_NCPU, 0, 0]; - let res = unsafe { - libc::sysctl( - mib.as_mut_ptr(), - 2, - &mut cpus as *mut _ as *mut _, - &mut cpus_size as *mut _ as *mut _, - ptr::null_mut(), - 0, - ) - }; - - // Handle errors if any. - if res == -1 { - return Err(io::Error::last_os_error()); - } else if cpus == 0 { - return Err(io::Error::new_const(io::ErrorKind::NotFound, &"The number of hardware threads is not known for the target platform")); - } - } - Ok(unsafe { NonZeroUsize::new_unchecked(cpus as usize) }) - } - } else if #[cfg(target_os = "openbsd")] { - fn available_concurrency_internal() -> io::Result { - use crate::ptr; - - let mut cpus: libc::c_uint = 0; - let mut cpus_size = crate::mem::size_of_val(&cpus); - let mut mib = [libc::CTL_HW, libc::HW_NCPU, 0, 0]; - - let res = unsafe { - libc::sysctl( - mib.as_mut_ptr(), - 2, - &mut cpus as *mut _ as *mut _, - &mut cpus_size as *mut _ as *mut _, - ptr::null_mut(), - 0, - ) - }; - - // Handle errors if any. - if res == -1 { - return Err(io::Error::last_os_error()); - } else if cpus == 0 { - return Err(io::Error::new_const(io::ErrorKind::NotFound, &"The number of hardware threads is not known for the target platform")); - } - - Ok(unsafe { NonZeroUsize::new_unchecked(cpus as usize) }) - } - } else { - // FIXME: implement on vxWorks, Redox, HermitCore, Haiku, l4re - fn available_concurrency_internal() -> io::Result { - Err(io::Error::new_const(io::ErrorKind::NotFound, &"The number of hardware threads is not known for the target platform")) - } - } -} diff --git a/library/std/src/thread/mod.rs b/library/std/src/thread/mod.rs index 30d8c2a1b6fa0..f7e791419038d 100644 --- a/library/std/src/thread/mod.rs +++ b/library/std/src/thread/mod.rs @@ -155,6 +155,7 @@ use crate::fmt; use crate::io; use crate::mem; use crate::num::NonZeroU64; +use crate::num::NonZeroUsize; use crate::panic; use crate::panicking; use crate::str; @@ -174,15 +175,9 @@ use crate::time::Duration; #[macro_use] mod local; -#[unstable(feature = "available_concurrency", issue = "74479")] -mod available_concurrency; - #[stable(feature = "rust1", since = "1.0.0")] pub use self::local::{AccessError, LocalKey}; -#[unstable(feature = "available_concurrency", issue = "74479")] -pub use available_concurrency::available_concurrency; - // The types used by the thread_local! macro to access TLS keys. Note that there // are two types, the "OS" type and the "fast" type. The OS thread local key // type is accessed via platform-specific API calls and is slow, while the fast @@ -1422,3 +1417,39 @@ fn _assert_sync_and_send() { _assert_both::>(); _assert_both::(); } + +/// Returns the number of hardware threads available to the program. +/// +/// This value should be considered only a hint. +/// +/// # Platform-specific behavior +/// +/// If interpreted as the number of actual hardware threads, it may undercount on +/// Windows systems with more than 64 hardware threads. If interpreted as the +/// available concurrency for that process, it may overcount on Windows systems +/// when limited by a process wide affinity mask or job object limitations, and +/// it may overcount on Linux systems when limited by a process wide affinity +/// mask or affected by cgroups limits. +/// +/// # Errors +/// +/// This function will return an error in the following situations, but is not +/// limited to just these cases: +/// +/// - If the number of hardware threads is not known for the target platform. +/// - The process lacks permissions to view the number of hardware threads +/// available. +/// +/// # Examples +/// +/// ``` +/// # #![allow(dead_code)] +/// #![feature(available_concurrency)] +/// use std::thread; +/// +/// let count = thread::available_concurrency().map(|n| n.get()).unwrap_or(1); +/// ``` +#[unstable(feature = "available_concurrency", issue = "74479")] +pub fn available_concurrency() -> io::Result { + imp::available_concurrency() +} From dd90900cf479c0282d023a7c694610e0a2ca3177 Mon Sep 17 00:00:00 2001 From: LeSeulArtichaut Date: Tue, 15 Jun 2021 19:53:50 +0200 Subject: [PATCH 15/18] Resolve type aliases to the type they point to in intra-doc links --- .../passes/collect_intra_doc_links.rs | 51 +++++++++++++++++-- src/test/rustdoc/intra-doc/type-alias.rs | 19 +++++++ 2 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 src/test/rustdoc/intra-doc/type-alias.rs diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index 247a020f2a20d..c6f7e3b53a894 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -544,6 +544,44 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { }) } + /// Convert a DefId to a Res, where possible. + /// + /// This is used for resolving type aliases. + fn def_id_to_res(&self, ty_id: DefId) -> Option { + use PrimitiveType::*; + Some(match *self.cx.tcx.type_of(ty_id).kind() { + ty::Bool => Res::Primitive(Bool), + ty::Char => Res::Primitive(Char), + ty::Int(ity) => Res::Primitive(ity.into()), + ty::Uint(uty) => Res::Primitive(uty.into()), + ty::Float(fty) => Res::Primitive(fty.into()), + ty::Str => Res::Primitive(Str), + ty::Tuple(ref tys) if tys.is_empty() => Res::Primitive(Unit), + ty::Tuple(_) => Res::Primitive(Tuple), + ty::Array(..) => Res::Primitive(Array), + ty::Slice(_) => Res::Primitive(Slice), + ty::RawPtr(_) => Res::Primitive(RawPointer), + ty::Ref(..) => Res::Primitive(Reference), + ty::FnDef(..) => panic!("type alias to a function definition"), + ty::FnPtr(_) => Res::Primitive(Fn), + ty::Never => Res::Primitive(Never), + ty::Adt(&ty::AdtDef { did, .. }, _) | ty::Foreign(did) => { + Res::Def(self.cx.tcx.def_kind(did), did) + } + ty::Projection(_) + | ty::Closure(..) + | ty::Generator(..) + | ty::GeneratorWitness(_) + | ty::Opaque(..) + | ty::Dynamic(..) + | ty::Param(_) + | ty::Bound(..) + | ty::Placeholder(_) + | ty::Infer(_) + | ty::Error(_) => return None, + }) + } + /// Returns: /// - None if no associated item was found /// - Some((_, _, Some(_))) if an item was found and should go through a side channel @@ -559,12 +597,15 @@ impl<'a, 'tcx> LinkCollector<'a, 'tcx> { match root_res { Res::Primitive(prim) => self.resolve_primitive_associated_item(prim, ns, item_name), + Res::Def(DefKind::TyAlias, did) => { + // Resolve the link on the type the alias points to. + // FIXME: if the associated item is defined directly on the type alias, + // it will show up on its documentation page, we should link there instead. + let res = self.def_id_to_res(did)?; + self.resolve_associated_item(res, item_name, ns, module_id) + } Res::Def( - DefKind::Struct - | DefKind::Union - | DefKind::Enum - | DefKind::TyAlias - | DefKind::ForeignTy, + DefKind::Struct | DefKind::Union | DefKind::Enum | DefKind::ForeignTy, did, ) => { debug!("looking for associated item named {} for item {:?}", item_name, did); diff --git a/src/test/rustdoc/intra-doc/type-alias.rs b/src/test/rustdoc/intra-doc/type-alias.rs new file mode 100644 index 0000000000000..f3609ccd0a141 --- /dev/null +++ b/src/test/rustdoc/intra-doc/type-alias.rs @@ -0,0 +1,19 @@ +// Regression test for issue #86120. + +#![deny(broken_intra_doc_links)] +#![crate_name = "foo"] + +pub struct Foo; + +/// You should really try [`Self::bar`]! +pub type Bar = Foo; + +impl Bar { + pub fn bar() {} +} + +/// The minimum is [`Self::MIN`]. +pub type Int = i32; + +// @has foo/type.Bar.html '//a[@href="struct.Foo.html#method.bar"]' 'Self::bar' +// @has foo/type.Int.html '//a[@href="{{channel}}/std/primitive.i32.html#associatedconstant.MIN"]' 'Self::MIN' From 05ec710c8088513f226d129f157b854d65e877c3 Mon Sep 17 00:00:00 2001 From: Christiaan Dirkx Date: Tue, 11 May 2021 14:58:18 +0200 Subject: [PATCH 16/18] Remove tidy exception for `available_concurrency` --- src/tools/tidy/src/pal.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tools/tidy/src/pal.rs b/src/tools/tidy/src/pal.rs index db177f75ceae9..31cdc6865a402 100644 --- a/src/tools/tidy/src/pal.rs +++ b/src/tools/tidy/src/pal.rs @@ -56,7 +56,6 @@ const EXCEPTION_PATHS: &[&str] = &[ "library/std/src/f32.rs", "library/std/src/f64.rs", "library/std/src/path.rs", - "library/std/src/thread/available_concurrency.rs", "library/std/src/sys_common", // Should only contain abstractions over platforms "library/std/src/net/test.rs", // Utility helpers for tests ]; From 888418a079f0daf6447d36ae533366a26eecdbc9 Mon Sep 17 00:00:00 2001 From: Christiaan Dirkx Date: Mon, 21 Jun 2021 11:31:07 +0200 Subject: [PATCH 17/18] Use `Unsupported` on platforms where `available_concurrency` is not implemented. --- library/std/src/sys/hermit/thread.rs | 6 ++---- library/std/src/sys/sgx/thread.rs | 6 ++---- library/std/src/sys/unix/thread.rs | 2 +- library/std/src/sys/unsupported/thread.rs | 5 +---- library/std/src/sys/wasi/thread.rs | 5 +---- library/std/src/sys/wasm/atomics/thread.rs | 6 ++---- 6 files changed, 9 insertions(+), 21 deletions(-) diff --git a/library/std/src/sys/hermit/thread.rs b/library/std/src/sys/hermit/thread.rs index 3d00e626e1ac7..6da79d19f5949 100644 --- a/library/std/src/sys/hermit/thread.rs +++ b/library/std/src/sys/hermit/thread.rs @@ -1,5 +1,6 @@ #![allow(dead_code)] +use super::unsupported; use crate::ffi::CStr; use crate::io; use crate::mem; @@ -97,10 +98,7 @@ impl Thread { } pub fn available_concurrency() -> io::Result { - Err(io::Error::new_const( - io::ErrorKind::NotFound, - &"The number of hardware threads is not known for the target platform", - )) + unsupported() } pub mod guard { diff --git a/library/std/src/sys/sgx/thread.rs b/library/std/src/sys/sgx/thread.rs index b82ae86521a0b..cbb8ba964018a 100644 --- a/library/std/src/sys/sgx/thread.rs +++ b/library/std/src/sys/sgx/thread.rs @@ -1,4 +1,5 @@ #![cfg_attr(test, allow(dead_code))] // why is this necessary? +use super::unsupported; use crate::ffi::CStr; use crate::io; use crate::num::NonZeroUsize; @@ -137,10 +138,7 @@ impl Thread { } pub fn available_concurrency() -> io::Result { - Err(io::Error::new_const( - io::ErrorKind::NotFound, - &"The number of hardware threads is not known for the target platform", - )) + unsupported() } pub mod guard { diff --git a/library/std/src/sys/unix/thread.rs b/library/std/src/sys/unix/thread.rs index e49971de940ba..df2ba0a8bc8e6 100644 --- a/library/std/src/sys/unix/thread.rs +++ b/library/std/src/sys/unix/thread.rs @@ -276,7 +276,7 @@ pub fn available_concurrency() -> io::Result { Ok(unsafe { NonZeroUsize::new_unchecked(cpus as usize) }) } else { // FIXME: implement on vxWorks, Redox, Haiku, l4re - Err(io::Error::new_const(io::ErrorKind::NotFound, &"The number of hardware threads is not known for the target platform")) + Err(io::Error::new_const(io::ErrorKind::Unsupported, &"Getting the number of hardware threads is not supported on the target platform")) } } } diff --git a/library/std/src/sys/unsupported/thread.rs b/library/std/src/sys/unsupported/thread.rs index 47005ead196a5..dc75d4ee6725c 100644 --- a/library/std/src/sys/unsupported/thread.rs +++ b/library/std/src/sys/unsupported/thread.rs @@ -32,10 +32,7 @@ impl Thread { } pub fn available_concurrency() -> io::Result { - Err(io::Error::new_const( - io::ErrorKind::NotFound, - &"The number of hardware threads is not known for the target platform", - )) + unsupported() } pub mod guard { diff --git a/library/std/src/sys/wasi/thread.rs b/library/std/src/sys/wasi/thread.rs index 959077f7b54b6..9ec02bbec2644 100644 --- a/library/std/src/sys/wasi/thread.rs +++ b/library/std/src/sys/wasi/thread.rs @@ -65,10 +65,7 @@ impl Thread { } pub fn available_concurrency() -> io::Result { - Err(io::Error::new_const( - io::ErrorKind::NotFound, - &"The number of hardware threads is not known for the target platform", - )) + unsupported() } pub mod guard { diff --git a/library/std/src/sys/wasm/atomics/thread.rs b/library/std/src/sys/wasm/atomics/thread.rs index 8207a41035db8..0971483510495 100644 --- a/library/std/src/sys/wasm/atomics/thread.rs +++ b/library/std/src/sys/wasm/atomics/thread.rs @@ -1,3 +1,4 @@ +use super::unsupported; use crate::ffi::CStr; use crate::io; use crate::num::NonZeroUsize; @@ -41,10 +42,7 @@ impl Thread { } pub fn available_concurrency() -> io::Result { - Err(io::Error::new_const( - io::ErrorKind::NotFound, - &"The number of hardware threads is not known for the target platform", - )) + unsupported() } pub mod guard { From b8a7bfb9f15b26b81f071d8eb1a039489ffce446 Mon Sep 17 00:00:00 2001 From: Smitty Date: Mon, 21 Jun 2021 11:17:30 -0400 Subject: [PATCH 18/18] Reference issue test originated from --- src/test/ui/typeck/struct-enum-wrong-args.rs | 1 + src/test/ui/typeck/struct-enum-wrong-args.stderr | 16 ++++++++-------- 2 files changed, 9 insertions(+), 8 deletions(-) diff --git a/src/test/ui/typeck/struct-enum-wrong-args.rs b/src/test/ui/typeck/struct-enum-wrong-args.rs index 7204caa09d4d2..19de4d67729fc 100644 --- a/src/test/ui/typeck/struct-enum-wrong-args.rs +++ b/src/test/ui/typeck/struct-enum-wrong-args.rs @@ -1,3 +1,4 @@ +// Regression test of #86481. struct Wrapper(i32); struct DoubleWrapper(i32, i32); diff --git a/src/test/ui/typeck/struct-enum-wrong-args.stderr b/src/test/ui/typeck/struct-enum-wrong-args.stderr index b9c5756d1f903..d77ef73028b0c 100644 --- a/src/test/ui/typeck/struct-enum-wrong-args.stderr +++ b/src/test/ui/typeck/struct-enum-wrong-args.stderr @@ -1,5 +1,5 @@ error[E0061]: this enum variant takes 1 argument but 2 arguments were supplied - --> $DIR/struct-enum-wrong-args.rs:5:13 + --> $DIR/struct-enum-wrong-args.rs:6:13 | LL | let _ = Some(3, 2); | ^^^^ - - supplied 2 arguments @@ -7,7 +7,7 @@ LL | let _ = Some(3, 2); | expected 1 argument error[E0061]: this enum variant takes 1 argument but 3 arguments were supplied - --> $DIR/struct-enum-wrong-args.rs:6:13 + --> $DIR/struct-enum-wrong-args.rs:7:13 | LL | let _ = Ok(3, 6, 2); | ^^ - - - supplied 3 arguments @@ -15,7 +15,7 @@ LL | let _ = Ok(3, 6, 2); | expected 1 argument error[E0061]: this enum variant takes 1 argument but 0 arguments were supplied - --> $DIR/struct-enum-wrong-args.rs:7:13 + --> $DIR/struct-enum-wrong-args.rs:8:13 | LL | let _ = Ok(); | ^^-- supplied 0 arguments @@ -23,7 +23,7 @@ LL | let _ = Ok(); | expected 1 argument error[E0061]: this struct takes 1 argument but 0 arguments were supplied - --> $DIR/struct-enum-wrong-args.rs:8:13 + --> $DIR/struct-enum-wrong-args.rs:9:13 | LL | let _ = Wrapper(); | ^^^^^^^-- supplied 0 arguments @@ -31,7 +31,7 @@ LL | let _ = Wrapper(); | expected 1 argument error[E0061]: this struct takes 1 argument but 2 arguments were supplied - --> $DIR/struct-enum-wrong-args.rs:9:13 + --> $DIR/struct-enum-wrong-args.rs:10:13 | LL | let _ = Wrapper(5, 2); | ^^^^^^^ - - supplied 2 arguments @@ -39,7 +39,7 @@ LL | let _ = Wrapper(5, 2); | expected 1 argument error[E0061]: this struct takes 2 arguments but 0 arguments were supplied - --> $DIR/struct-enum-wrong-args.rs:10:13 + --> $DIR/struct-enum-wrong-args.rs:11:13 | LL | let _ = DoubleWrapper(); | ^^^^^^^^^^^^^-- supplied 0 arguments @@ -47,7 +47,7 @@ LL | let _ = DoubleWrapper(); | expected 2 arguments error[E0061]: this struct takes 2 arguments but 1 argument was supplied - --> $DIR/struct-enum-wrong-args.rs:11:13 + --> $DIR/struct-enum-wrong-args.rs:12:13 | LL | let _ = DoubleWrapper(5); | ^^^^^^^^^^^^^ - supplied 1 argument @@ -55,7 +55,7 @@ LL | let _ = DoubleWrapper(5); | expected 2 arguments error[E0061]: this struct takes 2 arguments but 3 arguments were supplied - --> $DIR/struct-enum-wrong-args.rs:12:13 + --> $DIR/struct-enum-wrong-args.rs:13:13 | LL | let _ = DoubleWrapper(5, 2, 7); | ^^^^^^^^^^^^^ - - - supplied 3 arguments