From 6da206b31442ce4cc7693a3550dcd45c2be5168e Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 1 Mar 2019 11:26:19 -0800 Subject: [PATCH 01/58] Add back in MSVC version check for LLVM --- src/llvm-project | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/llvm-project b/src/llvm-project index 38ad31bde8ff6..4fc9fb8245abe 160000 --- a/src/llvm-project +++ b/src/llvm-project @@ -1 +1 @@ -Subproject commit 38ad31bde8ff681d862dc0f96930a5dd9b7a472e +Subproject commit 4fc9fb8245abe24680192535870c4522644a4212 From 02b008599ebe69d2d1b17018cee07e39347c1940 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Tue, 13 Nov 2018 13:42:05 -0800 Subject: [PATCH 02/58] appveyor: Use VS2017 for all our images Originally added in #55935 to test build times, this was reverted in #56201 due to a belief that it caused the exit code 259 spurious errors. We've since learned, however, that the 259 exit code is likely not related to this image update as we're getting it in a number of locations now. VS2017 looks like it may be required to compile LLVm in the near future, notably discovered by #58408 where we attempted to update LLVM. --- appveyor.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 3a0cb8b4fceea..2862c240c277c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,4 +1,7 @@ environment: + # This is required for at least an AArch64 compiler in one image, and is also + # going to soon be required for compiling LLVM. + APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 Preview # By default schannel checks revocation of certificates unlike some other SSL # backends, but we've historically had problems on CI where a revocation @@ -86,7 +89,6 @@ environment: DIST_REQUIRE_ALL_TOOLS: 1 DEPLOY: 1 CI_JOB_NAME: dist-x86_64-msvc - APPVEYOR_BUILD_WORKER_IMAGE: Visual Studio 2017 Preview - RUST_CONFIGURE_ARGS: > --build=i686-pc-windows-msvc --target=i586-pc-windows-msvc From e969de88bb6121ccd99b97377a5fa04b3aaaae28 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sat, 2 Mar 2019 17:17:08 +0100 Subject: [PATCH 03/58] Fix "Auto-hide item methods documentation" setting --- src/librustdoc/html/static/main.js | 69 ++++++++++++++++-------------- 1 file changed, 37 insertions(+), 32 deletions(-) diff --git a/src/librustdoc/html/static/main.js b/src/librustdoc/html/static/main.js index 1849e53d937ad..fef6910f40a57 100644 --- a/src/librustdoc/html/static/main.js +++ b/src/librustdoc/html/static/main.js @@ -2077,16 +2077,22 @@ if (!DOMTokenList.prototype.remove) { } var toggle = createSimpleToggle(false); + var hideMethodDocs = getCurrentValue("rustdoc-method-docs") !== "false"; + var pageId = getPageId(); var func = function(e) { var next = e.nextElementSibling; if (!next) { return; } - if (hasClass(next, "docblock") || - (hasClass(next, "stability") && - hasClass(next.nextElementSibling, "docblock"))) { - insertAfter(toggle.cloneNode(true), e.childNodes[e.childNodes.length - 1]); + if (hasClass(next, "docblock") === true || + (hasClass(next, "stability") === true && + hasClass(next.nextElementSibling, "docblock") === true)) { + var newToggle = toggle.cloneNode(true); + insertAfter(newToggle, e.childNodes[e.childNodes.length - 1]); + if (hideMethodDocs === true && hasClass(e, "method") === true) { + collapseDocs(newToggle, "hide", pageId); + } } }; @@ -2107,17 +2113,16 @@ if (!DOMTokenList.prototype.remove) { onEachLazy(document.getElementsByClassName("associatedconstant"), func); onEachLazy(document.getElementsByClassName("impl"), funcImpl); var impl_call = function() {}; - if (getCurrentValue("rustdoc-method-docs") !== "false") { + if (hideMethodDocs === true) { impl_call = function(e, newToggle, pageId) { if (e.id.match(/^impl(?:-\d+)?$/) === null) { // Automatically minimize all non-inherent impls - if (hasClass(e, "impl")) { + if (hasClass(e, "impl") === true) { collapseDocs(newToggle, "hide", pageId); } } }; } - var pageId = getPageId(); var newToggle = document.createElement("a"); newToggle.href = "javascript:void(0)"; newToggle.className = "collapse-toggle hidden-default collapsed"; @@ -2163,7 +2168,7 @@ if (!DOMTokenList.prototype.remove) { var inner_toggle = newToggle.cloneNode(true); inner_toggle.onclick = toggleClicked; e.insertBefore(inner_toggle, e.firstChild); - impl_call(e, inner_toggle, pageId); + impl_call(e.previousSibling, inner_toggle, pageId); } }); @@ -2265,30 +2270,6 @@ if (!DOMTokenList.prototype.remove) { onEachLazy(document.getElementsByClassName("docblock"), buildToggleWrapper); onEachLazy(document.getElementsByClassName("sub-variant"), buildToggleWrapper); - // In the search display, allows to switch between tabs. - function printTab(nb) { - if (nb === 0 || nb === 1 || nb === 2) { - currentTab = nb; - } - var nb_copy = nb; - onEachLazy(document.getElementById("titles").childNodes, function(elem) { - if (nb_copy === 0) { - addClass(elem, "selected"); - } else { - removeClass(elem, "selected"); - } - nb_copy -= 1; - }); - onEachLazy(document.getElementById("results").childNodes, function(elem) { - if (nb === 0) { - elem.style.display = ""; - } else { - elem.style.display = "none"; - } - nb -= 1; - }); - } - function createToggleWrapper(tog) { var span = document.createElement("span"); span.className = "toggle-label"; @@ -2374,6 +2355,30 @@ if (!DOMTokenList.prototype.remove) { }; }); + // In the search display, allows to switch between tabs. + function printTab(nb) { + if (nb === 0 || nb === 1 || nb === 2) { + currentTab = nb; + } + var nb_copy = nb; + onEachLazy(document.getElementById("titles").childNodes, function(elem) { + if (nb_copy === 0) { + addClass(elem, "selected"); + } else { + removeClass(elem, "selected"); + } + nb_copy -= 1; + }); + onEachLazy(document.getElementById("results").childNodes, function(elem) { + if (nb === 0) { + elem.style.display = ""; + } else { + elem.style.display = "none"; + } + nb -= 1; + }); + } + function putBackSearch(search_input) { if (search_input.value !== "") { addClass(main, "hidden"); From c82a42c155aa4b4825cb8dc21e9e498a752af13f Mon Sep 17 00:00:00 2001 From: Edward Barnard Date: Sun, 3 Mar 2019 19:47:17 +0000 Subject: [PATCH 04/58] Change `std::fs::copy` to use `copyfile` on MacOS and iOS --- src/libstd/fs.rs | 3 +- src/libstd/sys/unix/fs.rs | 87 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 88 insertions(+), 2 deletions(-) diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 25f2dd73504ae..3454f847ef414 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -1581,7 +1581,8 @@ pub fn rename, Q: AsRef>(from: P, to: Q) -> io::Result<()> /// `O_CLOEXEC` is set for returned file descriptors. /// On Windows, this function currently corresponds to `CopyFileEx`. Alternate /// NTFS streams are copied but only the size of the main stream is returned by -/// this function. +/// this function. On MacOS, this function corresponds to `copyfile` with +/// `COPYFILE_ALL` /// Note that, this [may change in the future][changes]. /// /// [changes]: ../io/index.html#platform-specific-behavior diff --git a/src/libstd/sys/unix/fs.rs b/src/libstd/sys/unix/fs.rs index 3b80b475a93db..7ff098bc9e123 100644 --- a/src/libstd/sys/unix/fs.rs +++ b/src/libstd/sys/unix/fs.rs @@ -827,7 +827,10 @@ pub fn canonicalize(p: &Path) -> io::Result { Ok(PathBuf::from(OsString::from_vec(buf))) } -#[cfg(not(any(target_os = "linux", target_os = "android")))] +#[cfg(not(any(target_os = "linux", + target_os = "android", + target_os = "macos", + target_os = "ios")))] pub fn copy(from: &Path, to: &Path) -> io::Result { use crate::fs::File; if !from.is_file() { @@ -937,3 +940,85 @@ pub fn copy(from: &Path, to: &Path) -> io::Result { writer.set_permissions(perm)?; Ok(written) } + +#[cfg(any(target_os = "macos", target_os = "ios"))] +pub fn copy(from: &Path, to: &Path) -> io::Result { + const COPYFILE_ACL: u32 = 1 << 0; + const COPYFILE_STAT: u32 = 1 << 1; + const COPYFILE_XATTR: u32 = 1 << 2; + const COPYFILE_DATA: u32 = 1 << 3; + + const COPYFILE_SECURITY: u32 = COPYFILE_STAT | COPYFILE_ACL; + const COPYFILE_METADATA: u32 = COPYFILE_SECURITY | COPYFILE_XATTR; + const COPYFILE_ALL: u32 = COPYFILE_METADATA | COPYFILE_DATA; + + const COPYFILE_STATE_COPIED: u32 = 8; + + #[allow(non_camel_case_types)] + type copyfile_state_t = *mut libc::c_void; + #[allow(non_camel_case_types)] + type copyfile_flags_t = u32; + + extern "C" { + fn copyfile( + from: *const libc::c_char, + to: *const libc::c_char, + state: copyfile_state_t, + flags: copyfile_flags_t, + ) -> libc::c_int; + fn copyfile_state_alloc() -> copyfile_state_t; + fn copyfile_state_free(state: copyfile_state_t) -> libc::c_int; + fn copyfile_state_get( + state: copyfile_state_t, + flag: u32, + dst: *mut libc::c_void, + ) -> libc::c_int; + } + + struct FreeOnDrop(copyfile_state_t); + impl Drop for FreeOnDrop { + fn drop(&mut self) { + // The code below ensures that `FreeOnDrop` is never a null pointer + unsafe { + // `copyfile_state_free` returns -1 if the `to` or `from` files + // cannot be closed. However, this is not considerd this an + // error. + copyfile_state_free(self.0); + } + } + } + + if !from.is_file() { + return Err(Error::new(ErrorKind::InvalidInput, + "the source path is not an existing regular file")) + } + + // We ensure that `FreeOnDrop` never contains a null pointer so it is + // always safe to call `copyfile_state_free` + let state = unsafe { + let state = copyfile_state_alloc(); + if state.is_null() { + return Err(crate::io::Error::last_os_error()); + } + FreeOnDrop(state) + }; + + cvt(unsafe { + copyfile( + cstr(from)?.as_ptr(), + cstr(to)?.as_ptr(), + state.0, + COPYFILE_ALL, + ) + })?; + + let mut bytes_copied: libc::off_t = 0; + cvt(unsafe { + copyfile_state_get( + state.0, + COPYFILE_STATE_COPIED, + &mut bytes_copied as *mut libc::off_t as *mut libc::c_void, + ) + })?; + Ok(bytes_copied as u64) +} From 0a991e424a794d0d556602e88cd2ebf511b05de7 Mon Sep 17 00:00:00 2001 From: Edward Barnard Date: Mon, 4 Mar 2019 12:35:46 +0000 Subject: [PATCH 05/58] Add test for the behaviour of `fs::copy` when `to` is a symlink --- src/libstd/fs.rs | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 3454f847ef414..7b9b5d4de206c 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -2837,6 +2837,26 @@ mod tests { assert_eq!(check!(out_path.metadata()).len(), copied_len); } + #[test] + fn copy_file_follows_dst_symlink() { + let tmp = tmpdir(); + if !got_symlink_permission(&tmp) { return }; + + let in_path = tmp.join("in.txt"); + let out_path = tmp.join("out.txt"); + let out_path_symlink = tmp.join("out_symlink.txt"); + + check!(fs::write(&in_path, "foo")); + check!(fs::write(&out_path, "bar")); + check!(symlink_file(&out_path, &out_path_symlink)); + + check!(fs::copy(&in_path, &out_path_symlink)); + + assert!(check!(out_path_symlink.symlink_metadata()).file_type().is_symlink()); + assert_eq!(check!(fs::read(&out_path_symlink)), b"foo".to_vec()); + assert_eq!(check!(fs::read(&out_path)), b"foo".to_vec()); + } + #[test] fn symlinks_work() { let tmpdir = tmpdir(); From 124ab2a4d87f2d10b88d668e35286af4c00ec12b Mon Sep 17 00:00:00 2001 From: Edward Barnard Date: Mon, 4 Mar 2019 12:53:54 +0000 Subject: [PATCH 06/58] Fix typo --- src/libstd/fs.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 7b9b5d4de206c..a03f55424a9cd 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -1582,7 +1582,7 @@ pub fn rename, Q: AsRef>(from: P, to: Q) -> io::Result<()> /// On Windows, this function currently corresponds to `CopyFileEx`. Alternate /// NTFS streams are copied but only the size of the main stream is returned by /// this function. On MacOS, this function corresponds to `copyfile` with -/// `COPYFILE_ALL` +/// `COPYFILE_ALL`. /// Note that, this [may change in the future][changes]. /// /// [changes]: ../io/index.html#platform-specific-behavior From 2b49ec0bb676f324806bb271f4115c3a1c0afaf3 Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 5 Mar 2019 09:58:47 +0100 Subject: [PATCH 07/58] Move alloc::prelude::* to alloc::prelude::v1, make alloc a subset of std This was one of the unresolved questions of https://github.com/rust-lang/rfcs/pull/2480. As the RFC says this is maybe not useful in the sense that we are unlikely to ever have a second version, but making the crate a true subset makes one less issue to think about if we stabilize it and later want to merge standard library crates and have Cargo feature flags to enable or disable parts of the `std` crate. See also discussion in https://github.com/rust-lang/rust/pull/58175 --- src/liballoc/prelude/mod.rs | 15 +++++++++++++++ src/liballoc/{prelude.rs => prelude/v1.rs} | 12 ++---------- 2 files changed, 17 insertions(+), 10 deletions(-) create mode 100644 src/liballoc/prelude/mod.rs rename src/liballoc/{prelude.rs => prelude/v1.rs} (60%) diff --git a/src/liballoc/prelude/mod.rs b/src/liballoc/prelude/mod.rs new file mode 100644 index 0000000000000..44a859d31ecb4 --- /dev/null +++ b/src/liballoc/prelude/mod.rs @@ -0,0 +1,15 @@ +//! The alloc Prelude +//! +//! The purpose of this module is to alleviate imports of commonly-used +//! items of the `alloc` crate by adding a glob import to the top of modules: +//! +//! ``` +//! # #![allow(unused_imports)] +//! # #![feature(alloc)] +//! extern crate alloc; +//! use alloc::prelude::v1::*; +//! ``` + +#![unstable(feature = "alloc", issue = "27783")] + +pub mod v1; diff --git a/src/liballoc/prelude.rs b/src/liballoc/prelude/v1.rs similarity index 60% rename from src/liballoc/prelude.rs rename to src/liballoc/prelude/v1.rs index 6767cf89f73ba..2df330d19f8ce 100644 --- a/src/liballoc/prelude.rs +++ b/src/liballoc/prelude/v1.rs @@ -1,14 +1,6 @@ -//! The alloc Prelude +//! The first version of the prelude of `alloc` crate. //! -//! The purpose of this module is to alleviate imports of commonly-used -//! items of the `alloc` crate by adding a glob import to the top of modules: -//! -//! ``` -//! # #![allow(unused_imports)] -//! # #![feature(alloc)] -//! extern crate alloc; -//! use alloc::prelude::*; -//! ``` +//! See the [module-level documentation](../index.html) for more. #![unstable(feature = "alloc", issue = "27783")] From 1243859d402427d90271d646968a6a4e5ad0052b Mon Sep 17 00:00:00 2001 From: Dan Robertson Date: Tue, 5 Mar 2019 13:43:48 +0000 Subject: [PATCH 08/58] core: ensure VaList passes improper_ctypes lint Ensure the core::ffi::VaList structure passes the improper_ctypes lint. --- src/libcore/ffi.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/libcore/ffi.rs b/src/libcore/ffi.rs index d88793f2801e7..5cc9c25c21e0f 100644 --- a/src/libcore/ffi.rs +++ b/src/libcore/ffi.rs @@ -79,9 +79,9 @@ impl fmt::Debug for VaListImpl { all supported platforms", issue = "44930")] struct VaListImpl { - stack: *mut (), - gr_top: *mut (), - vr_top: *mut (), + stack: *mut c_void, + gr_top: *mut c_void, + vr_top: *mut c_void, gr_offs: i32, vr_offs: i32, } @@ -98,8 +98,8 @@ struct VaListImpl { gpr: u8, fpr: u8, reserved: u16, - overflow_arg_area: *mut (), - reg_save_area: *mut (), + overflow_arg_area: *mut c_void, + reg_save_area: *mut c_void, } /// x86_64 ABI implementation of a `va_list`. @@ -113,8 +113,8 @@ struct VaListImpl { struct VaListImpl { gp_offset: i32, fp_offset: i32, - overflow_arg_area: *mut (), - reg_save_area: *mut (), + overflow_arg_area: *mut c_void, + reg_save_area: *mut c_void, } /// A wrapper for a `va_list` From 5d1022ad7b82168aee243d2adcbd83d1e886586f Mon Sep 17 00:00:00 2001 From: Simon Sapin Date: Tue, 5 Mar 2019 11:47:52 +0100 Subject: [PATCH 09/58] Rename the feature gate for alloc::prelude MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit … to separate it from that of the crate. New tracking issue: https://github.com/rust-lang/rust/issues/58935 --- src/liballoc/prelude/mod.rs | 3 ++- src/liballoc/prelude/v1.rs | 12 ++++++------ 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/src/liballoc/prelude/mod.rs b/src/liballoc/prelude/mod.rs index 44a859d31ecb4..33cc51d173203 100644 --- a/src/liballoc/prelude/mod.rs +++ b/src/liballoc/prelude/mod.rs @@ -6,10 +6,11 @@ //! ``` //! # #![allow(unused_imports)] //! # #![feature(alloc)] +//! #![feature(alloc_prelude)] //! extern crate alloc; //! use alloc::prelude::v1::*; //! ``` -#![unstable(feature = "alloc", issue = "27783")] +#![unstable(feature = "alloc_prelude", issue = "58935")] pub mod v1; diff --git a/src/liballoc/prelude/v1.rs b/src/liballoc/prelude/v1.rs index 2df330d19f8ce..b6b01395ad632 100644 --- a/src/liballoc/prelude/v1.rs +++ b/src/liballoc/prelude/v1.rs @@ -2,10 +2,10 @@ //! //! See the [module-level documentation](../index.html) for more. -#![unstable(feature = "alloc", issue = "27783")] +#![unstable(feature = "alloc_prelude", issue = "58935")] -#[unstable(feature = "alloc", issue = "27783")] pub use crate::borrow::ToOwned; -#[unstable(feature = "alloc", issue = "27783")] pub use crate::boxed::Box; -#[unstable(feature = "alloc", issue = "27783")] pub use crate::slice::SliceConcatExt; -#[unstable(feature = "alloc", issue = "27783")] pub use crate::string::{String, ToString}; -#[unstable(feature = "alloc", issue = "27783")] pub use crate::vec::Vec; +#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::borrow::ToOwned; +#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::boxed::Box; +#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::slice::SliceConcatExt; +#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::string::{String, ToString}; +#[unstable(feature = "alloc_prelude", issue = "58935")] pub use crate::vec::Vec; From 72958acd57fb32e0f8027c0d7e76c9a0c7f155d2 Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Fri, 1 Mar 2019 11:47:06 -0800 Subject: [PATCH 10/58] std: Spin for a global malloc lock on wasm32 There's lots of comments in the code, but the main gist of this commit is that the acquisition of the global malloc lock on the `wasm32-unknown-unknown` target when threads are enabled will not spin on contention rather than block. --- src/libstd/sys/wasm/alloc.rs | 95 ++++++++++++++++++++++++++++++------ 1 file changed, 80 insertions(+), 15 deletions(-) diff --git a/src/libstd/sys/wasm/alloc.rs b/src/libstd/sys/wasm/alloc.rs index b9098548b9c1e..c1af6ec12623c 100644 --- a/src/libstd/sys/wasm/alloc.rs +++ b/src/libstd/sys/wasm/alloc.rs @@ -49,7 +49,6 @@ unsafe impl GlobalAlloc for System { #[cfg(target_feature = "atomics")] mod lock { - use crate::arch::wasm32; use crate::sync::atomic::{AtomicI32, Ordering::SeqCst}; static LOCKED: AtomicI32 = AtomicI32::new(0); @@ -61,14 +60,76 @@ mod lock { if LOCKED.swap(1, SeqCst) == 0 { return DropLock } - unsafe { - let r = wasm32::i32_atomic_wait( - &LOCKED as *const AtomicI32 as *mut i32, - 1, // expected value - -1, // timeout - ); - debug_assert!(r == 0 || r == 1); - } + // Ok so here's where things get a little depressing. At this point + // in time we need to synchronously acquire a lock, but we're + // contending with some other thread. Typically we'd execute some + // form of `i32.atomic.wait` like so: + // + // unsafe { + // let r = core::arch::wasm32::i32_atomic_wait( + // &LOCKED as *const AtomicI32 as *mut i32, + // 1, // expected value + // -1, // timeout + // ); + // debug_assert!(r == 0 || r == 1); + // } + // + // Unfortunately though in doing so we would cause issues for the + // main thread. The main thread in a web browser *cannot ever + // block*, no exceptions. This means that the main thread can't + // actually execute the `i32.atomic.wait` instruction. + // + // As a result if we want to work within the context of browsers we + // need to figure out some sort of allocation scheme for the main + // thread where when there's contention on the global malloc lock we + // do... something. + // + // Possible ideas include: + // + // 1. Attempt to acquire the global lock. If it fails, fall back to + // memory allocation via `memory.grow`. Later just ... somehow + // ... inject this raw page back into the main allocator as it + // gets sliced up over time. This strategy has the downside of + // forcing allocation of a page to happen whenever the main + // thread contents with other threads, which is unfortunate. + // + // 2. Maintain a form of "two level" allocator scheme where the main + // thread has its own allocator. Somehow this allocator would + // also be balanced with a global allocator, not only to have + // allocations cross between threads but also to ensure that the + // two allocators stay "balanced" in terms of free'd memory and + // such. This, however, seems significantly complicated. + // + // Out of a lack of other ideas, the current strategy implemented + // here is to simply spin. Typical spin loop algorithms have some + // form of "hint" here to the CPU that it's what we're doing to + // ensure that the CPU doesn't get too hot, but wasm doesn't have + // such an instruction. + // + // To be clear, spinning here is not a great solution. + // Another thread with the lock may take quite a long time to wake + // up. For example it could be in `memory.grow` or it could be + // evicted from the CPU for a timeslice like 10ms. For these periods + // of time our thread will "helpfully" sit here and eat CPU time + // until it itself is evicted or the lock holder finishes. This + // means we're just burning and wasting CPU time to no one's + // benefit. + // + // Spinning does have the nice properties, though, of being + // semantically correct, being fair to all threads for memory + // allocation, and being simple enough to implement. + // + // This will surely (hopefully) be replaced in the future with a + // real memory allocator that can handle the restriction of the main + // thread. + // + // + // FIXME: We can also possibly add an optimization here to detect + // when a thread is the main thread or not and block on all + // non-main-thread threads. Currently, however, we have no way + // of knowing which wasm thread is on the browser main thread, but + // if we could figure out we could at least somewhat mitigate the + // cost of this spinning. } } @@ -76,12 +137,16 @@ mod lock { fn drop(&mut self) { let r = LOCKED.swap(0, SeqCst); debug_assert_eq!(r, 1); - unsafe { - wasm32::atomic_notify( - &LOCKED as *const AtomicI32 as *mut i32, - 1, // only one thread - ); - } + + // Note that due to the above logic we don't actually need to wake + // anyone up, but if we did it'd likely look something like this: + // + // unsafe { + // core::arch::wasm32::atomic_notify( + // &LOCKED as *const AtomicI32 as *mut i32, + // 1, // only one thread + // ); + // } } } } From 710988ad603c52657c72a7f1028415e3e244a97c Mon Sep 17 00:00:00 2001 From: YunQiang Su Date: Tue, 5 Mar 2019 23:28:15 +0800 Subject: [PATCH 11/58] MIPS: add r6 support MIPS r6 is quite different with the previous version. It use some new target triples: mipsisa32r6-unknown-linux-gnu mipsisa32r6el-unknown-linux-gnu mipsisa64r6-unknown-linux-gnuabi64 mipsisa64r6el-unknown-linux-gnuabi64 This patch has been tested with Debian Port for mips64r6el, and the support of these triples also is included in llvm: https://reviews.llvm.org/rGe58c45a695f39004710b6ce940d489fee800dbd3 --- .../spec/mipsisa32r6_unknown_linux_gnu.rs | 23 ++++++++++++++++++ .../spec/mipsisa32r6el_unknown_linux_gnu.rs | 24 +++++++++++++++++++ .../mipsisa64r6_unknown_linux_gnuabi64.rs | 24 +++++++++++++++++++ .../mipsisa64r6el_unknown_linux_gnuabi64.rs | 24 +++++++++++++++++++ src/librustc_target/spec/mod.rs | 4 ++++ src/tools/build-manifest/src/main.rs | 8 +++++++ src/tools/compiletest/src/util.rs | 8 +++++++ 7 files changed, 115 insertions(+) create mode 100644 src/librustc_target/spec/mipsisa32r6_unknown_linux_gnu.rs create mode 100644 src/librustc_target/spec/mipsisa32r6el_unknown_linux_gnu.rs create mode 100644 src/librustc_target/spec/mipsisa64r6_unknown_linux_gnuabi64.rs create mode 100644 src/librustc_target/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs diff --git a/src/librustc_target/spec/mipsisa32r6_unknown_linux_gnu.rs b/src/librustc_target/spec/mipsisa32r6_unknown_linux_gnu.rs new file mode 100644 index 0000000000000..f47291458492e --- /dev/null +++ b/src/librustc_target/spec/mipsisa32r6_unknown_linux_gnu.rs @@ -0,0 +1,23 @@ +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; + +pub fn target() -> TargetResult { + Ok(Target { + llvm_target: "mipsisa32r6-unknown-linux-gnu".to_string(), + target_endian: "big".to_string(), + target_pointer_width: "32".to_string(), + target_c_int_width: "32".to_string(), + data_layout: "E-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".to_string(), + arch: "mips".to_string(), + target_os: "linux".to_string(), + target_env: "gnu".to_string(), + target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, + options: TargetOptions { + cpu: "mips32r6".to_string(), + features: "+mips32r6".to_string(), + max_atomic_width: Some(32), + + ..super::linux_base::opts() + }, + }) +} diff --git a/src/librustc_target/spec/mipsisa32r6el_unknown_linux_gnu.rs b/src/librustc_target/spec/mipsisa32r6el_unknown_linux_gnu.rs new file mode 100644 index 0000000000000..f4f98d33571f0 --- /dev/null +++ b/src/librustc_target/spec/mipsisa32r6el_unknown_linux_gnu.rs @@ -0,0 +1,24 @@ +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; + +pub fn target() -> TargetResult { + Ok(Target { + llvm_target: "mipsisa32r6el-unknown-linux-gnu".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "32".to_string(), + target_c_int_width: "32".to_string(), + data_layout: "e-m:m-p:32:32-i8:8:32-i16:16:32-i64:64-n32-S64".to_string(), + arch: "mips".to_string(), + target_os: "linux".to_string(), + target_env: "gnu".to_string(), + target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, + + options: TargetOptions { + cpu: "mips32r6".to_string(), + features: "+mips32r6".to_string(), + max_atomic_width: Some(32), + + ..super::linux_base::opts() + }, + }) +} diff --git a/src/librustc_target/spec/mipsisa64r6_unknown_linux_gnuabi64.rs b/src/librustc_target/spec/mipsisa64r6_unknown_linux_gnuabi64.rs new file mode 100644 index 0000000000000..7faed3adc79cc --- /dev/null +++ b/src/librustc_target/spec/mipsisa64r6_unknown_linux_gnuabi64.rs @@ -0,0 +1,24 @@ +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; + +pub fn target() -> TargetResult { + Ok(Target { + llvm_target: "mipsisa64r6-unknown-linux-gnuabi64".to_string(), + target_endian: "big".to_string(), + target_pointer_width: "64".to_string(), + target_c_int_width: "32".to_string(), + data_layout: "E-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(), + arch: "mips64".to_string(), + target_os: "linux".to_string(), + target_env: "gnu".to_string(), + target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, + options: TargetOptions { + // NOTE(mips64r6) matches C toolchain + cpu: "mips64r6".to_string(), + features: "+mips64r6".to_string(), + max_atomic_width: Some(64), + + ..super::linux_base::opts() + }, + }) +} diff --git a/src/librustc_target/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs b/src/librustc_target/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs new file mode 100644 index 0000000000000..58a814a759eb8 --- /dev/null +++ b/src/librustc_target/spec/mipsisa64r6el_unknown_linux_gnuabi64.rs @@ -0,0 +1,24 @@ +use crate::spec::{LinkerFlavor, Target, TargetOptions, TargetResult}; + +pub fn target() -> TargetResult { + Ok(Target { + llvm_target: "mipsisa64r6el-unknown-linux-gnuabi64".to_string(), + target_endian: "little".to_string(), + target_pointer_width: "64".to_string(), + target_c_int_width: "32".to_string(), + data_layout: "e-m:e-i8:8:32-i16:16:32-i64:64-n32:64-S128".to_string(), + arch: "mips64".to_string(), + target_os: "linux".to_string(), + target_env: "gnu".to_string(), + target_vendor: "unknown".to_string(), + linker_flavor: LinkerFlavor::Gcc, + options: TargetOptions { + // NOTE(mips64r6) matches C toolchain + cpu: "mips64r6".to_string(), + features: "+mips64r6".to_string(), + max_atomic_width: Some(64), + + ..super::linux_base::opts() + }, + }) +} diff --git a/src/librustc_target/spec/mod.rs b/src/librustc_target/spec/mod.rs index bef2afc7b6292..1020464ca0b06 100644 --- a/src/librustc_target/spec/mod.rs +++ b/src/librustc_target/spec/mod.rs @@ -335,6 +335,10 @@ supported_targets! { ("mips-unknown-linux-gnu", mips_unknown_linux_gnu), ("mips64-unknown-linux-gnuabi64", mips64_unknown_linux_gnuabi64), ("mips64el-unknown-linux-gnuabi64", mips64el_unknown_linux_gnuabi64), + ("mipsisa32r6-unknown-linux-gnu", mipsisa32r6_unknown_linux_gnu), + ("mipsisa32r6el-unknown-linux-gnu", mipsisa32r6el_unknown_linux_gnu), + ("mipsisa64r6-unknown-linux-gnuabi64", mipsisa64r6_unknown_linux_gnuabi64), + ("mipsisa64r6el-unknown-linux-gnuabi64", mipsisa64r6el_unknown_linux_gnuabi64), ("mipsel-unknown-linux-gnu", mipsel_unknown_linux_gnu), ("powerpc-unknown-linux-gnu", powerpc_unknown_linux_gnu), ("powerpc-unknown-linux-gnuspe", powerpc_unknown_linux_gnuspe), diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index 8d87c404d0b28..6eb12ea016186 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -23,6 +23,10 @@ static HOSTS: &'static [&'static str] = &[ "mips64-unknown-linux-gnuabi64", "mips64el-unknown-linux-gnuabi64", "mipsel-unknown-linux-gnu", + "mipsisa32r6-unknown-linux-gnu", + "mipsisa32r6el-unknown-linux-gnu", + "mipsisa64r6-unknown-linux-gnuabi64", + "mipsisa64r6el-unknown-linux-gnuabi64", "powerpc-unknown-linux-gnu", "powerpc64-unknown-linux-gnu", "powerpc64le-unknown-linux-gnu", @@ -77,6 +81,10 @@ static TARGETS: &'static [&'static str] = &[ "mips-unknown-linux-musl", "mips64-unknown-linux-gnuabi64", "mips64el-unknown-linux-gnuabi64", + "mipsisa32r6-unknown-linux-gnu", + "mipsisa32r6el-unknown-linux-gnu", + "mipsisa64r6-unknown-linux-gnuabi64", + "mipsisa64r6el-unknown-linux-gnuabi64", "mipsel-unknown-linux-gnu", "mipsel-unknown-linux-musl", "nvptx64-nvidia-cuda", diff --git a/src/tools/compiletest/src/util.rs b/src/tools/compiletest/src/util.rs index 240287fa248bd..3533dcdc988a1 100644 --- a/src/tools/compiletest/src/util.rs +++ b/src/tools/compiletest/src/util.rs @@ -49,7 +49,15 @@ const ARCH_TABLE: &'static [(&'static str, &'static str)] = &[ ("mips", "mips"), ("mips64", "mips64"), ("mips64el", "mips64"), + ("mipsisa32r6", "mips"), + ("mipsisa32r6el", "mips"), + ("mipsisa64r6", "mips64"), + ("mipsisa64r6el", "mips64"), ("mipsel", "mips"), + ("mipsisa32r6", "mips"), + ("mipsisa32r6el", "mips"), + ("mipsisa64r6", "mips64"), + ("mipsisa64r6el", "mips64"), ("msp430", "msp430"), ("powerpc", "powerpc"), ("powerpc64", "powerpc64"), From 67eabc6bec67e1953cb944f0654fada3151b7e21 Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Tue, 5 Mar 2019 13:32:41 -0800 Subject: [PATCH 12/58] SGX target: Expose thread id function in os module --- src/libstd/os/fortanix_sgx/mod.rs | 5 +++++ src/libstd/sys/sgx/abi/thread.rs | 1 + 2 files changed, 6 insertions(+) diff --git a/src/libstd/os/fortanix_sgx/mod.rs b/src/libstd/os/fortanix_sgx/mod.rs index bca22e717d724..4e30b1edd15e8 100644 --- a/src/libstd/os/fortanix_sgx/mod.rs +++ b/src/libstd/os/fortanix_sgx/mod.rs @@ -43,3 +43,8 @@ pub mod mem { } pub use crate::sys::ext::{io, arch, ffi}; + +/// Functions for querying thread-related information. +pub mod thread { + pub use crate::sys::abi::thread::current; +} diff --git a/src/libstd/sys/sgx/abi/thread.rs b/src/libstd/sys/sgx/abi/thread.rs index 86fe09d003520..c17fa2d00159e 100644 --- a/src/libstd/sys/sgx/abi/thread.rs +++ b/src/libstd/sys/sgx/abi/thread.rs @@ -4,6 +4,7 @@ use fortanix_sgx_abi::Tcs; /// all currently running threads in the enclave, and it is guaranteed to be /// constant for the lifetime of the thread. More specifically for SGX, there /// is a one-to-one correspondence of the ID to the address of the TCS. +#[unstable(feature = "sgx_platform", issue = "56975")] pub fn current() -> Tcs { extern "C" { fn get_tcs_addr() -> Tcs; } unsafe { get_tcs_addr() } From 876258b0fa31fc1d1a79ddc0e5a0c9c5f0e8f85b Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Wed, 6 Mar 2019 19:46:33 +0100 Subject: [PATCH 13/58] Default to integrated `rust-lld` linker for UEFI targets --- src/librustc_target/spec/uefi_base.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/librustc_target/spec/uefi_base.rs b/src/librustc_target/spec/uefi_base.rs index 631966c09a498..956767a22a0e1 100644 --- a/src/librustc_target/spec/uefi_base.rs +++ b/src/librustc_target/spec/uefi_base.rs @@ -59,7 +59,7 @@ pub fn opts() -> TargetOptions { singlethread: true, emit_debug_gdb_scripts: false, - linker: Some("lld-link".to_string()), + linker: Some("rust-lld".to_string()), lld_flavor: LldFlavor::Link, pre_link_args, From ec91f26442aaf51ececcb054f5a4b92f7f5c0615 Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Thu, 7 Mar 2019 18:38:49 -0800 Subject: [PATCH 14/58] Fix SGX implementations of read/write_vectored. --- src/libstd/sys/sgx/net.rs | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/src/libstd/sys/sgx/net.rs b/src/libstd/sys/sgx/net.rs index ab8b2681393f8..cea723f6e48e1 100644 --- a/src/libstd/sys/sgx/net.rs +++ b/src/libstd/sys/sgx/net.rs @@ -103,24 +103,22 @@ impl TcpStream { self.inner.inner.read(buf) } - pub fn read_vectored(&self, buf: &mut [IoVecMut<'_>]) -> io::Result { - let buf = match buf.get_mut(0) { - Some(buf) => buf, - None => return Ok(0), - }; - self.read(buf) + pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result { + match bufs.iter_mut().find(|b| !b.is_empty()) { + Some(buf) => self.read(buf), + None => Ok(0), + } } pub fn write(&self, buf: &[u8]) -> io::Result { self.inner.inner.write(buf) } - pub fn write_vectored(&self, buf: &[IoVec<'_>]) -> io::Result { - let buf = match buf.get(0) { - Some(buf) => buf, - None => return Ok(0), - }; - self.write(buf) + pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result { + match bufs.iter().find(|b| !b.is_empty()) { + Some(buf) => self.write(buf), + None => Ok(0), + } } pub fn peer_addr(&self) -> io::Result { From ab8e1d264e6722169d25d3f52ac2e8de172e205d Mon Sep 17 00:00:00 2001 From: Steven Fackler Date: Thu, 7 Mar 2019 19:31:58 -0800 Subject: [PATCH 15/58] Always call read/write from default vectored io methods --- src/libstd/io/mod.rs | 40 +++++++++++++++++++++++---------- src/libstd/sys/redox/net/tcp.rs | 10 ++------- src/libstd/sys/sgx/net.rs | 10 ++------- 3 files changed, 32 insertions(+), 28 deletions(-) diff --git a/src/libstd/io/mod.rs b/src/libstd/io/mod.rs index e3e2754a7aa09..1a2152a79af5a 100644 --- a/src/libstd/io/mod.rs +++ b/src/libstd/io/mod.rs @@ -390,6 +390,28 @@ fn read_to_end_with_reservation(r: &mut R, ret } +pub(crate) fn default_read_vectored(read: F, bufs: &mut [IoVecMut<'_>]) -> Result +where + F: FnOnce(&mut [u8]) -> Result +{ + let buf = bufs + .iter_mut() + .find(|b| !b.is_empty()) + .map_or(&mut [][..], |b| &mut **b); + read(buf) +} + +pub(crate) fn default_write_vectored(write: F, bufs: &[IoVec<'_>]) -> Result +where + F: FnOnce(&[u8]) -> Result +{ + let buf = bufs + .iter() + .find(|b| !b.is_empty()) + .map_or(&[][..], |b| &**b); + write(buf) +} + /// The `Read` trait allows for reading bytes from a source. /// /// Implementors of the `Read` trait are called 'readers'. @@ -528,14 +550,11 @@ pub trait Read { /// written to possibly being only partially filled. This method must behave /// as a single call to `read` with the buffers concatenated would. /// - /// The default implementation simply passes the first nonempty buffer to - /// `read`. + /// The default implementation calls `read` with either the first nonempty + /// buffer provided, or an empty one if none exists. #[unstable(feature = "iovec", issue = "58452")] fn read_vectored(&mut self, bufs: &mut [IoVecMut<'_>]) -> Result { - match bufs.iter_mut().find(|b| !b.is_empty()) { - Some(buf) => self.read(buf), - None => Ok(0), - } + default_read_vectored(|b| self.read(b), bufs) } /// Determines if this `Read`er can work with buffers of uninitialized @@ -1107,14 +1126,11 @@ pub trait Write { /// read from possibly being only partially consumed. This method must /// behave as a call to `write` with the buffers concatenated would. /// - /// The default implementation simply passes the first nonempty buffer to - /// `write`. + /// The default implementation calls `write` with either the first nonempty + /// buffer provided, or an empty one if none exists. #[unstable(feature = "iovec", issue = "58452")] fn write_vectored(&mut self, bufs: &[IoVec<'_>]) -> Result { - match bufs.iter().find(|b| !b.is_empty()) { - Some(buf) => self.write(buf), - None => Ok(0), - } + default_write_vectored(|b| self.write(b), bufs) } /// Flush this output stream, ensuring that all intermediately buffered diff --git a/src/libstd/sys/redox/net/tcp.rs b/src/libstd/sys/redox/net/tcp.rs index 5081c3de73c5a..3f2f6166a791a 100644 --- a/src/libstd/sys/redox/net/tcp.rs +++ b/src/libstd/sys/redox/net/tcp.rs @@ -35,10 +35,7 @@ impl TcpStream { } pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result { - match bufs.iter_mut().find(|b| !b.is_empty()) { - Some(buf) => self.read(buf), - None => Ok(0), - } + io::default_read_vectored(|b| self.read(b), bufs) } pub fn write(&self, buf: &[u8]) -> Result { @@ -46,10 +43,7 @@ impl TcpStream { } pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result { - match bufs.iter().find(|b| !b.is_empty()) { - Some(buf) => self.write(buf), - None => Ok(0), - } + io::default_write_vectored(|b| self.write(b), bufs) } pub fn take_error(&self) -> Result> { diff --git a/src/libstd/sys/sgx/net.rs b/src/libstd/sys/sgx/net.rs index cea723f6e48e1..6021020e6f03c 100644 --- a/src/libstd/sys/sgx/net.rs +++ b/src/libstd/sys/sgx/net.rs @@ -104,10 +104,7 @@ impl TcpStream { } pub fn read_vectored(&self, bufs: &mut [IoVecMut<'_>]) -> io::Result { - match bufs.iter_mut().find(|b| !b.is_empty()) { - Some(buf) => self.read(buf), - None => Ok(0), - } + io::default_read_vectored(|b| self.read(b), bufs) } pub fn write(&self, buf: &[u8]) -> io::Result { @@ -115,10 +112,7 @@ impl TcpStream { } pub fn write_vectored(&self, bufs: &[IoVec<'_>]) -> io::Result { - match bufs.iter().find(|b| !b.is_empty()) { - Some(buf) => self.write(buf), - None => Ok(0), - } + io::default_write_vectored(|b| self.write(b), bufs) } pub fn peer_addr(&self) -> io::Result { From 90ae8746709df0c09f63ebaff480b82205592b53 Mon Sep 17 00:00:00 2001 From: Alan Somers Date: Tue, 5 Mar 2019 17:43:30 -0700 Subject: [PATCH 16/58] add release notes for PR #56243 Fixes #58907 --- RELEASES.md | 3 +++ 1 file changed, 3 insertions(+) diff --git a/RELEASES.md b/RELEASES.md index 4cda02c5c2ebe..a49e072e9eaa7 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -110,8 +110,11 @@ Compatibility Notes methods instead. - The `Error::cause` method has been deprecated in favor of `Error::source` which supports downcasting. +- [Libtest no longer creates a new thread for each test when + `--test-threads=1`. It also runs the tests in deterministic order][56243] [55982]: https://github.com/rust-lang/rust/pull/55982/ +[56243]: https://github.com/rust-lang/rust/pull/56243 [56303]: https://github.com/rust-lang/rust/pull/56303/ [56351]: https://github.com/rust-lang/rust/pull/56351/ [56362]: https://github.com/rust-lang/rust/pull/56362 From a4ea08420cde12ea0943cafb1505e512c5820f70 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Fri, 8 Mar 2019 21:12:12 -0800 Subject: [PATCH 17/58] Avoid some common false positives in intra doc link checking --- src/librustdoc/passes/collect_intra_doc_links.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/librustdoc/passes/collect_intra_doc_links.rs b/src/librustdoc/passes/collect_intra_doc_links.rs index c346714ab485a..c3d2e63319a95 100644 --- a/src/librustdoc/passes/collect_intra_doc_links.rs +++ b/src/librustdoc/passes/collect_intra_doc_links.rs @@ -291,6 +291,12 @@ impl<'a, 'tcx, 'rcx> DocFolder for LinkCollector<'a, 'tcx, 'rcx> { if ori_link.contains('/') { continue; } + + // [] is mostly likely not supposed to be a link + if ori_link.is_empty() { + continue; + } + let link = ori_link.replace("`", ""); let (def, fragment) = { let mut kind = PathKind::Unknown; From 3a83cb2c9ba2acca0577a5f4a092d7fc5b243faf Mon Sep 17 00:00:00 2001 From: Dan Robertson Date: Sat, 9 Mar 2019 03:39:23 +0000 Subject: [PATCH 18/58] Fix ICE in MIR pretty printing A `Def::Variant` should be considered as a function in mir pretty printing. Each variant has a constructor that we must print. Given the following enum definition: ``` pub enum TestMe { X(usize), } ``` We will need to generate a constructor for the variant `X` with a signature that looks something like the following: ``` fn TestMe::X(_1: usize) -> TestMe; ``` --- src/librustc_mir/util/pretty.rs | 4 +++- src/test/mir-opt/unusual-item-types.rs | 18 ++++++++++++++++++ 2 files changed, 21 insertions(+), 1 deletion(-) diff --git a/src/librustc_mir/util/pretty.rs b/src/librustc_mir/util/pretty.rs index c3fbee3a2a6e5..af49f61ae86c7 100644 --- a/src/librustc_mir/util/pretty.rs +++ b/src/librustc_mir/util/pretty.rs @@ -1,4 +1,5 @@ use rustc::hir::def_id::{DefId, LOCAL_CRATE}; +use rustc::hir::def::CtorKind; use rustc::mir::*; use rustc::mir::visit::Visitor; use rustc::ty::{self, TyCtxt}; @@ -597,7 +598,8 @@ fn write_mir_sig( trace!("write_mir_sig: {:?}", src.instance); let descr = tcx.describe_def(src.def_id()); let is_function = match descr { - Some(Def::Fn(_)) | Some(Def::Method(_)) | Some(Def::StructCtor(..)) => true, + Some(Def::Fn(_)) | Some(Def::Method(_)) | Some(Def::Variant(..)) | + Some(Def::StructCtor(_, CtorKind::Fn)) => true, _ => tcx.is_closure(src.def_id()), }; match (descr, src.promoted) { diff --git a/src/test/mir-opt/unusual-item-types.rs b/src/test/mir-opt/unusual-item-types.rs index fe85baa048e39..ced30381fda68 100644 --- a/src/test/mir-opt/unusual-item-types.rs +++ b/src/test/mir-opt/unusual-item-types.rs @@ -7,11 +7,18 @@ impl A { const ASSOCIATED_CONSTANT: i32 = 2; } +// See #59021 +enum Test { + X(usize), + Y { a: usize }, +} + enum E { V = 5, } fn main() { + let f = Test::X as fn(usize) -> Test; let v = Vec::::new(); } @@ -64,3 +71,14 @@ fn main() { // _3 = const std::ops::Drop::drop(move _2) -> [return: bb6, unwind: bb5]; // } // END rustc.ptr-real_drop_in_place.std__vec__Vec_i32_.AddMovesForPackedDrops.before.mir + +// START rustc.Test-X.mir_map.0.mir +// fn Test::X(_1: usize) -> Test { +// let mut _0: Test; +// +// bb0: { +// _0 = Test::X(move _1,); +// return; +// } +// } +// END rustc.Test-X.mir_map.0.mir From 4888b1fb99f1bf6a58bebaededdfbf4477383634 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 10 Mar 2019 17:45:45 +0100 Subject: [PATCH 19/58] we can now skip should_panic tests with the libtest harness --- src/liballoc/tests/binary_heap.rs | 2 +- src/liballoc/tests/btree/map.rs | 5 ----- src/liballoc/tests/slice.rs | 18 ------------------ src/liballoc/tests/str.rs | 11 ----------- src/liballoc/tests/string.rs | 9 --------- src/liballoc/tests/vec.rs | 12 ------------ src/liballoc/tests/vec_deque.rs | 1 - src/libcore/tests/cell.rs | 3 --- src/libcore/tests/iter.rs | 2 -- src/libcore/tests/num/bignum.rs | 14 -------------- src/libcore/tests/option.rs | 3 --- src/libcore/tests/result.rs | 3 --- src/libcore/tests/slice.rs | 7 ------- src/libcore/tests/time.rs | 2 -- 14 files changed, 1 insertion(+), 91 deletions(-) diff --git a/src/liballoc/tests/binary_heap.rs b/src/liballoc/tests/binary_heap.rs index 1d4a3edc1ac42..a97a790f5a2d8 100644 --- a/src/liballoc/tests/binary_heap.rs +++ b/src/liballoc/tests/binary_heap.rs @@ -282,7 +282,7 @@ fn assert_covariance() { // // Destructors must be called exactly once per element. #[test] -#[cfg(not(miri))] // Miri does not support panics +#[cfg(not(miri))] // Miri does not support entropy fn panic_safe() { static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0); diff --git a/src/liballoc/tests/btree/map.rs b/src/liballoc/tests/btree/map.rs index f14750089c956..844afe870766b 100644 --- a/src/liballoc/tests/btree/map.rs +++ b/src/liballoc/tests/btree/map.rs @@ -226,7 +226,6 @@ fn test_range_equal_empty_cases() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_range_equal_excluded() { let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect(); map.range((Excluded(2), Excluded(2))); @@ -234,7 +233,6 @@ fn test_range_equal_excluded() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_range_backwards_1() { let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect(); map.range((Included(3), Included(2))); @@ -242,7 +240,6 @@ fn test_range_backwards_1() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_range_backwards_2() { let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect(); map.range((Included(3), Excluded(2))); @@ -250,7 +247,6 @@ fn test_range_backwards_2() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_range_backwards_3() { let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect(); map.range((Excluded(3), Included(2))); @@ -258,7 +254,6 @@ fn test_range_backwards_3() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_range_backwards_4() { let map: BTreeMap<_, _> = (0..5).map(|i| (i, i)).collect(); map.range((Excluded(3), Excluded(2))); diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs index feba46b0fad78..fb99c95fc6842 100644 --- a/src/liballoc/tests/slice.rs +++ b/src/liballoc/tests/slice.rs @@ -258,7 +258,6 @@ fn test_swap_remove() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_swap_remove_fail() { let mut v = vec![1]; let _ = v.swap_remove(0); @@ -632,7 +631,6 @@ fn test_insert() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_insert_oob() { let mut a = vec![1, 2, 3]; a.insert(4, 5); @@ -657,7 +655,6 @@ fn test_remove() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_remove_fail() { let mut a = vec![1]; let _ = a.remove(0); @@ -939,7 +936,6 @@ fn test_windowsator() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_windowsator_0() { let v = &[1, 2, 3, 4]; let _it = v.windows(0); @@ -964,7 +960,6 @@ fn test_chunksator() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_chunksator_0() { let v = &[1, 2, 3, 4]; let _it = v.chunks(0); @@ -989,7 +984,6 @@ fn test_chunks_exactator() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_chunks_exactator_0() { let v = &[1, 2, 3, 4]; let _it = v.chunks_exact(0); @@ -1014,7 +1008,6 @@ fn test_rchunksator() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_rchunksator_0() { let v = &[1, 2, 3, 4]; let _it = v.rchunks(0); @@ -1039,7 +1032,6 @@ fn test_rchunks_exactator() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_rchunks_exactator_0() { let v = &[1, 2, 3, 4]; let _it = v.rchunks_exact(0); @@ -1092,7 +1084,6 @@ fn test_vec_default() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_overflow_does_not_cause_segfault() { let mut v = vec![]; v.reserve_exact(!0); @@ -1102,7 +1093,6 @@ fn test_overflow_does_not_cause_segfault() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_overflow_does_not_cause_segfault_managed() { let mut v = vec![Rc::new(1)]; v.reserve_exact(!0); @@ -1278,7 +1268,6 @@ fn test_mut_chunks_rev() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mut_chunks_0() { let mut v = [1, 2, 3, 4]; let _it = v.chunks_mut(0); @@ -1311,7 +1300,6 @@ fn test_mut_chunks_exact_rev() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mut_chunks_exact_0() { let mut v = [1, 2, 3, 4]; let _it = v.chunks_exact_mut(0); @@ -1344,7 +1332,6 @@ fn test_mut_rchunks_rev() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mut_rchunks_0() { let mut v = [1, 2, 3, 4]; let _it = v.rchunks_mut(0); @@ -1377,7 +1364,6 @@ fn test_mut_rchunks_exact_rev() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mut_rchunks_exact_0() { let mut v = [1, 2, 3, 4]; let _it = v.rchunks_exact_mut(0); @@ -1411,7 +1397,6 @@ fn test_box_slice_clone() { #[test] #[allow(unused_must_use)] // here, we care about the side effects of `.clone()` #[cfg_attr(target_os = "emscripten", ignore)] -#[cfg(not(miri))] // Miri does not support panics fn test_box_slice_clone_panics() { use std::sync::Arc; use std::sync::atomic::{AtomicUsize, Ordering}; @@ -1476,7 +1461,6 @@ fn test_copy_from_slice() { #[test] #[should_panic(expected = "destination and source slices have different lengths")] -#[cfg(not(miri))] // Miri does not support panics fn test_copy_from_slice_dst_longer() { let src = [0, 1, 2, 3]; let mut dst = [0; 5]; @@ -1485,7 +1469,6 @@ fn test_copy_from_slice_dst_longer() { #[test] #[should_panic(expected = "destination and source slices have different lengths")] -#[cfg(not(miri))] // Miri does not support panics fn test_copy_from_slice_dst_shorter() { let src = [0, 1, 2, 3]; let mut dst = [0; 3]; @@ -1605,7 +1588,6 @@ thread_local!(static SILENCE_PANIC: Cell = Cell::new(false)); #[test] #[cfg_attr(target_os = "emscripten", ignore)] // no threads -#[cfg(not(miri))] // Miri does not support panics fn panic_safe() { let prev = panic::take_hook(); panic::set_hook(Box::new(move |info| { diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs index b33a564218888..f2dc19a42296a 100644 --- a/src/liballoc/tests/str.rs +++ b/src/liballoc/tests/str.rs @@ -351,7 +351,6 @@ mod slice_index { // to be used in `should_panic`) #[test] #[should_panic(expected = "out of bounds")] - #[cfg(not(miri))] // Miri does not support panics fn assert_range_eq_can_fail_by_panic() { assert_range_eq!("abc", 0..5, "abc"); } @@ -361,7 +360,6 @@ mod slice_index { // to be used in `should_panic`) #[test] #[should_panic(expected = "==")] - #[cfg(not(miri))] // Miri does not support panics fn assert_range_eq_can_fail_by_inequality() { assert_range_eq!("abc", 0..2, "abc"); } @@ -409,7 +407,6 @@ mod slice_index { #[test] #[should_panic(expected = $expect_msg)] - #[cfg(not(miri))] // Miri does not support panics fn index_fail() { let v: String = $data.into(); let v: &str = &v; @@ -418,7 +415,6 @@ mod slice_index { #[test] #[should_panic(expected = $expect_msg)] - #[cfg(not(miri))] // Miri does not support panics fn index_mut_fail() { let mut v: String = $data.into(); let v: &mut str = &mut v; @@ -514,7 +510,6 @@ mod slice_index { #[test] #[should_panic] - #[cfg(not(miri))] // Miri does not support panics fn test_slice_fail() { &"中华Việt Nam"[0..2]; } @@ -666,14 +661,12 @@ mod slice_index { // check the panic includes the prefix of the sliced string #[test] #[should_panic(expected="byte index 1024 is out of bounds of `Lorem ipsum dolor sit amet")] - #[cfg(not(miri))] // Miri does not support panics fn test_slice_fail_truncated_1() { &LOREM_PARAGRAPH[..1024]; } // check the truncation in the panic message #[test] #[should_panic(expected="luctus, im`[...]")] - #[cfg(not(miri))] // Miri does not support panics fn test_slice_fail_truncated_2() { &LOREM_PARAGRAPH[..1024]; } @@ -688,7 +681,6 @@ fn test_str_slice_rangetoinclusive_ok() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_str_slice_rangetoinclusive_notok() { let s = "abcαβγ"; &s[..=3]; @@ -704,7 +696,6 @@ fn test_str_slicemut_rangetoinclusive_ok() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_str_slicemut_rangetoinclusive_notok() { let mut s = "abcαβγ".to_owned(); let s: &mut str = &mut s; @@ -894,7 +885,6 @@ fn test_as_bytes() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_as_bytes_fail() { // Don't double free. (I'm not sure if this exercises the // original problem code path anymore.) @@ -984,7 +974,6 @@ fn test_split_at_mut() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_split_at_boundscheck() { let s = "ศไทย中华Việt Nam"; s.split_at(1); diff --git a/src/liballoc/tests/string.rs b/src/liballoc/tests/string.rs index 7e93d84fe3b97..7e75b8c4f28c8 100644 --- a/src/liballoc/tests/string.rs +++ b/src/liballoc/tests/string.rs @@ -231,7 +231,6 @@ fn test_split_off_empty() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_split_off_past_end() { let orig = "Hello, world!"; let mut split = String::from(orig); @@ -240,7 +239,6 @@ fn test_split_off_past_end() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_split_off_mid_char() { let mut orig = String::from("山"); orig.split_off(1); @@ -289,7 +287,6 @@ fn test_str_truncate_invalid_len() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_str_truncate_split_codepoint() { let mut s = String::from("\u{FC}"); // ü s.truncate(1); @@ -324,7 +321,6 @@ fn remove() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn remove_bad() { "ศ".to_string().remove(1); } @@ -360,13 +356,11 @@ fn insert() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn insert_bad1() { "".to_string().insert(1, 't'); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn insert_bad2() { "ệ".to_string().insert(1, 't'); } @@ -447,7 +441,6 @@ fn test_replace_range() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_replace_range_char_boundary() { let mut s = "Hello, 世界!".to_owned(); s.replace_range(..8, ""); @@ -464,7 +457,6 @@ fn test_replace_range_inclusive_range() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_replace_range_out_of_bounds() { let mut s = String::from("12345"); s.replace_range(5..6, "789"); @@ -472,7 +464,6 @@ fn test_replace_range_out_of_bounds() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_replace_range_inclusive_out_of_bounds() { let mut s = String::from("12345"); s.replace_range(5..=5, "789"); diff --git a/src/liballoc/tests/vec.rs b/src/liballoc/tests/vec.rs index 6e4ca1d90e642..545332bcd6a2f 100644 --- a/src/liballoc/tests/vec.rs +++ b/src/liballoc/tests/vec.rs @@ -368,7 +368,6 @@ fn test_vec_truncate_drop() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_vec_truncate_fail() { struct BadElem(i32); impl Drop for BadElem { @@ -392,7 +391,6 @@ fn test_index() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_index_out_of_bounds() { let vec = vec![1, 2, 3]; let _ = vec[3]; @@ -400,7 +398,6 @@ fn test_index_out_of_bounds() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_slice_out_of_bounds_1() { let x = vec![1, 2, 3, 4, 5]; &x[!0..]; @@ -408,7 +405,6 @@ fn test_slice_out_of_bounds_1() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_slice_out_of_bounds_2() { let x = vec![1, 2, 3, 4, 5]; &x[..6]; @@ -416,7 +412,6 @@ fn test_slice_out_of_bounds_2() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_slice_out_of_bounds_3() { let x = vec![1, 2, 3, 4, 5]; &x[!0..4]; @@ -424,7 +419,6 @@ fn test_slice_out_of_bounds_3() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_slice_out_of_bounds_4() { let x = vec![1, 2, 3, 4, 5]; &x[1..6]; @@ -432,7 +426,6 @@ fn test_slice_out_of_bounds_4() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_slice_out_of_bounds_5() { let x = vec![1, 2, 3, 4, 5]; &x[3..2]; @@ -440,7 +433,6 @@ fn test_slice_out_of_bounds_5() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_swap_remove_empty() { let mut vec = Vec::::new(); vec.swap_remove(0); @@ -511,7 +503,6 @@ fn test_drain_items_zero_sized() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_drain_out_of_bounds() { let mut v = vec![1, 2, 3, 4, 5]; v.drain(5..6); @@ -585,7 +576,6 @@ fn test_drain_max_vec_size() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_drain_inclusive_out_of_bounds() { let mut v = vec![1, 2, 3, 4, 5]; v.drain(5..=5); @@ -615,7 +605,6 @@ fn test_splice_inclusive_range() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_splice_out_of_bounds() { let mut v = vec![1, 2, 3, 4, 5]; let a = [10, 11, 12]; @@ -624,7 +613,6 @@ fn test_splice_out_of_bounds() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_splice_inclusive_out_of_bounds() { let mut v = vec![1, 2, 3, 4, 5]; let a = [10, 11, 12]; diff --git a/src/liballoc/tests/vec_deque.rs b/src/liballoc/tests/vec_deque.rs index 16ddc1444fcf9..e0fe10a55f55c 100644 --- a/src/liballoc/tests/vec_deque.rs +++ b/src/liballoc/tests/vec_deque.rs @@ -108,7 +108,6 @@ fn test_index() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_index_out_of_bounds() { let mut deq = VecDeque::new(); for i in 1..4 { diff --git a/src/libcore/tests/cell.rs b/src/libcore/tests/cell.rs index b16416022c04e..56f295dff8e43 100644 --- a/src/libcore/tests/cell.rs +++ b/src/libcore/tests/cell.rs @@ -109,7 +109,6 @@ fn double_borrow_single_release_no_borrow_mut() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn discard_doesnt_unborrow() { let x = RefCell::new(0); let _b = x.borrow(); @@ -350,7 +349,6 @@ fn refcell_ref_coercion() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn refcell_swap_borrows() { let x = RefCell::new(0); let _b = x.borrow(); @@ -360,7 +358,6 @@ fn refcell_swap_borrows() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn refcell_replace_borrows() { let x = RefCell::new(0); let _b = x.borrow(); diff --git a/src/libcore/tests/iter.rs b/src/libcore/tests/iter.rs index d880abb181c20..4652fc329dc02 100644 --- a/src/libcore/tests/iter.rs +++ b/src/libcore/tests/iter.rs @@ -253,7 +253,6 @@ fn test_iterator_step_by_nth_overflow() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_iterator_step_by_zero() { let mut it = (0..).step_by(0); it.next(); @@ -1414,7 +1413,6 @@ fn test_rposition() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_rposition_panic() { let v: [(Box<_>, Box<_>); 4] = [(box 0, box 0), (box 0, box 0), diff --git a/src/libcore/tests/num/bignum.rs b/src/libcore/tests/num/bignum.rs index 956c22c998219..b873f1dd0652f 100644 --- a/src/libcore/tests/num/bignum.rs +++ b/src/libcore/tests/num/bignum.rs @@ -3,7 +3,6 @@ use core::num::bignum::tests::Big8x3 as Big; #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_from_u64_overflow() { Big::from_u64(0x1000000); } @@ -20,14 +19,12 @@ fn test_add() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_add_overflow_1() { Big::from_small(1).add(&Big::from_u64(0xffffff)); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_add_overflow_2() { Big::from_u64(0xffffff).add(&Big::from_small(1)); } @@ -45,7 +42,6 @@ fn test_add_small() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_add_small_overflow() { Big::from_u64(0xffffff).add_small(1); } @@ -61,14 +57,12 @@ fn test_sub() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_sub_underflow_1() { Big::from_u64(0x10665).sub(&Big::from_u64(0x10666)); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_sub_underflow_2() { Big::from_small(0).sub(&Big::from_u64(0x123456)); } @@ -82,7 +76,6 @@ fn test_mul_small() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_small_overflow() { Big::from_u64(0x800000).mul_small(2); } @@ -101,14 +94,12 @@ fn test_mul_pow2() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_pow2_overflow_1() { Big::from_u64(0x1).mul_pow2(24); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_pow2_overflow_2() { Big::from_u64(0x123).mul_pow2(16); } @@ -127,14 +118,12 @@ fn test_mul_pow5() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_pow5_overflow_1() { Big::from_small(1).mul_pow5(12); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_pow5_overflow_2() { Big::from_small(230).mul_pow5(8); } @@ -152,14 +141,12 @@ fn test_mul_digits() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_digits_overflow_1() { Big::from_u64(0x800000).mul_digits(&[2]); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_mul_digits_overflow_2() { Big::from_u64(0x1000).mul_digits(&[0, 0x10]); } @@ -219,7 +206,6 @@ fn test_get_bit() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_get_bit_out_of_range() { Big::from_small(42).get_bit(24); } diff --git a/src/libcore/tests/option.rs b/src/libcore/tests/option.rs index 87ce2720c5918..b059b134868d9 100644 --- a/src/libcore/tests/option.rs +++ b/src/libcore/tests/option.rs @@ -69,7 +69,6 @@ fn test_option_dance() { } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_option_too_much_dance() { struct A; let mut y = Some(A); @@ -130,7 +129,6 @@ fn test_unwrap() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_unwrap_panic1() { let x: Option = None; x.unwrap(); @@ -138,7 +136,6 @@ fn test_unwrap_panic1() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn test_unwrap_panic2() { let x: Option = None; x.unwrap(); diff --git a/src/libcore/tests/result.rs b/src/libcore/tests/result.rs index bbc8568517667..1fab07526a07f 100644 --- a/src/libcore/tests/result.rs +++ b/src/libcore/tests/result.rs @@ -117,7 +117,6 @@ fn test_unwrap_or_else() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics pub fn test_unwrap_or_else_panic() { fn handler(msg: &'static str) -> isize { if msg == "I got this." { @@ -139,7 +138,6 @@ pub fn test_expect_ok() { } #[test] #[should_panic(expected="Got expected error: \"All good\"")] -#[cfg(not(miri))] // Miri does not support panics pub fn test_expect_err() { let err: Result = Err("All good"); err.expect("Got expected error"); @@ -153,7 +151,6 @@ pub fn test_expect_err_err() { } #[test] #[should_panic(expected="Got expected ok: \"All good\"")] -#[cfg(not(miri))] // Miri does not support panics pub fn test_expect_err_ok() { let err: Result<&'static str, isize> = Ok("All good"); err.expect_err("Got expected ok"); diff --git a/src/libcore/tests/slice.rs b/src/libcore/tests/slice.rs index 31d16e0e32057..ac9c17a0f7c35 100644 --- a/src/libcore/tests/slice.rs +++ b/src/libcore/tests/slice.rs @@ -782,7 +782,6 @@ mod slice_index { // to be used in `should_panic`) #[test] #[should_panic(expected = "out of range")] - #[cfg(not(miri))] // Miri does not support panics fn assert_range_eq_can_fail_by_panic() { assert_range_eq!([0, 1, 2], 0..5, [0, 1, 2]); } @@ -792,7 +791,6 @@ mod slice_index { // to be used in `should_panic`) #[test] #[should_panic(expected = "==")] - #[cfg(not(miri))] // Miri does not support panics fn assert_range_eq_can_fail_by_inequality() { assert_range_eq!([0, 1, 2], 0..2, [0, 1, 2]); } @@ -842,7 +840,6 @@ mod slice_index { #[test] #[should_panic(expected = $expect_msg)] - #[cfg(not(miri))] // Miri does not support panics fn index_fail() { let v = $data; let v: &[_] = &v; @@ -851,7 +848,6 @@ mod slice_index { #[test] #[should_panic(expected = $expect_msg)] - #[cfg(not(miri))] // Miri does not support panics fn index_mut_fail() { let mut v = $data; let v: &mut [_] = &mut v; @@ -1304,7 +1300,6 @@ fn test_copy_within() { #[test] #[should_panic(expected = "src is out of bounds")] -#[cfg(not(miri))] // Miri does not support panics fn test_copy_within_panics_src_too_long() { let mut bytes = *b"Hello, World!"; // The length is only 13, so 14 is out of bounds. @@ -1313,7 +1308,6 @@ fn test_copy_within_panics_src_too_long() { #[test] #[should_panic(expected = "dest is out of bounds")] -#[cfg(not(miri))] // Miri does not support panics fn test_copy_within_panics_dest_too_long() { let mut bytes = *b"Hello, World!"; // The length is only 13, so a slice of length 4 starting at index 10 is out of bounds. @@ -1321,7 +1315,6 @@ fn test_copy_within_panics_dest_too_long() { } #[test] #[should_panic(expected = "src end is before src start")] -#[cfg(not(miri))] // Miri does not support panics fn test_copy_within_panics_src_inverted() { let mut bytes = *b"Hello, World!"; // 2 is greater than 1, so this range is invalid. diff --git a/src/libcore/tests/time.rs b/src/libcore/tests/time.rs index 09aae4583482f..6efd22572dc18 100644 --- a/src/libcore/tests/time.rs +++ b/src/libcore/tests/time.rs @@ -107,14 +107,12 @@ fn checked_sub() { #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn sub_bad1() { let _ = Duration::new(0, 0) - Duration::new(0, 1); } #[test] #[should_panic] -#[cfg(not(miri))] // Miri does not support panics fn sub_bad2() { let _ = Duration::new(0, 0) - Duration::new(1, 0); } From 52d9fa827d3cf5ef5fc0e2042ca1fc7f6dc391ed Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 10 Mar 2019 17:52:45 +0100 Subject: [PATCH 20/58] enabled too many tests --- src/liballoc/tests/binary_heap.rs | 2 +- src/liballoc/tests/slice.rs | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/liballoc/tests/binary_heap.rs b/src/liballoc/tests/binary_heap.rs index a97a790f5a2d8..0930f8dacd494 100644 --- a/src/liballoc/tests/binary_heap.rs +++ b/src/liballoc/tests/binary_heap.rs @@ -282,7 +282,7 @@ fn assert_covariance() { // // Destructors must be called exactly once per element. #[test] -#[cfg(not(miri))] // Miri does not support entropy +#[cfg(not(miri))] // Miri does not support panics nor entropy fn panic_safe() { static DROP_COUNTER: AtomicUsize = AtomicUsize::new(0); diff --git a/src/liballoc/tests/slice.rs b/src/liballoc/tests/slice.rs index fb99c95fc6842..b54c128a0249a 100644 --- a/src/liballoc/tests/slice.rs +++ b/src/liballoc/tests/slice.rs @@ -1397,6 +1397,7 @@ fn test_box_slice_clone() { #[test] #[allow(unused_must_use)] // here, we care about the side effects of `.clone()` #[cfg_attr(target_os = "emscripten", ignore)] +#[cfg(not(miri))] // Miri does not support threads nor entropy fn test_box_slice_clone_panics() { use std::sync::Arc; use std::sync::atomic::{AtomicUsize, Ordering}; @@ -1588,6 +1589,7 @@ thread_local!(static SILENCE_PANIC: Cell = Cell::new(false)); #[test] #[cfg_attr(target_os = "emscripten", ignore)] // no threads +#[cfg(not(miri))] // Miri does not support threads nor entropy fn panic_safe() { let prev = panic::take_hook(); panic::set_hook(Box::new(move |info| { From 8629fd3e4e5184852352ea1bb18bb1c8465ffac3 Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Sat, 9 Feb 2019 22:16:58 +0000 Subject: [PATCH 21/58] Improvements to comments in libstd, libcore, liballoc. --- src/libcore/iter/adapters/mod.rs | 4 ++-- src/libcore/mem.rs | 9 ++++++--- src/libcore/num/dec2flt/algorithm.rs | 2 +- src/libcore/num/dec2flt/mod.rs | 6 +++--- src/libcore/num/dec2flt/parse.rs | 2 +- src/libcore/num/flt2dec/decoder.rs | 2 +- src/libcore/num/flt2dec/mod.rs | 14 +++++++------- src/libcore/pin.rs | 2 +- src/libcore/str/mod.rs | 8 ++++---- src/libcore/task/wake.rs | 2 +- src/libstd/collections/hash/map.rs | 2 +- src/libstd/collections/hash/set.rs | 2 +- src/libstd/fs.rs | 2 +- src/libstd/sync/condvar.rs | 12 ++++++------ src/libstd/sys/windows/pipe.rs | 6 +++--- 15 files changed, 39 insertions(+), 36 deletions(-) diff --git a/src/libcore/iter/adapters/mod.rs b/src/libcore/iter/adapters/mod.rs index d4ad22c16bbfa..cccd51b577930 100644 --- a/src/libcore/iter/adapters/mod.rs +++ b/src/libcore/iter/adapters/mod.rs @@ -1198,7 +1198,7 @@ impl Peekable { } } -/// An iterator that rejects elements while `predicate` is true. +/// An iterator that rejects elements while `predicate` returns `true`. /// /// This `struct` is created by the [`skip_while`] method on [`Iterator`]. See its /// documentation for more. @@ -1286,7 +1286,7 @@ impl Iterator for SkipWhile impl FusedIterator for SkipWhile where I: FusedIterator, P: FnMut(&I::Item) -> bool {} -/// An iterator that only accepts elements while `predicate` is true. +/// An iterator that only accepts elements while `predicate` returns `true`. /// /// This `struct` is created by the [`take_while`] method on [`Iterator`]. See its /// documentation for more. diff --git a/src/libcore/mem.rs b/src/libcore/mem.rs index 90e84d0b28c3b..3d2fcdc979377 100644 --- a/src/libcore/mem.rs +++ b/src/libcore/mem.rs @@ -1111,11 +1111,12 @@ impl DerefMut for ManuallyDrop { /// ``` /// /// The compiler then knows to not make any incorrect assumptions or optimizations on this code. +// // FIXME before stabilizing, explain how to initialize a struct field-by-field. #[allow(missing_debug_implementations)] #[unstable(feature = "maybe_uninit", issue = "53491")] #[derive(Copy)] -// NOTE after stabilizing `MaybeUninit` proceed to deprecate `mem::uninitialized`. +// NOTE: after stabilizing `MaybeUninit`, proceed to deprecate `mem::uninitialized`. pub union MaybeUninit { uninit: (), value: ManuallyDrop, @@ -1125,13 +1126,13 @@ pub union MaybeUninit { impl Clone for MaybeUninit { #[inline(always)] fn clone(&self) -> Self { - // Not calling T::clone(), we cannot know if we are initialized enough for that. + // Not calling `T::clone()`, we cannot know if we are initialized enough for that. *self } } impl MaybeUninit { - /// Create a new `MaybeUninit` initialized with the given value. + /// Creates a new `MaybeUninit` initialized with the given value. /// /// Note that dropping a `MaybeUninit` will never call `T`'s drop code. /// It is your responsibility to make sure `T` gets dropped if it got initialized. @@ -1239,6 +1240,7 @@ impl MaybeUninit { /// let x_vec = unsafe { &*x.as_ptr() }; /// // We have created a reference to an uninitialized vector! This is undefined behavior. /// ``` + /// /// (Notice that the rules around references to uninitialized data are not finalized yet, but /// until they are, it is advisable to avoid them.) #[unstable(feature = "maybe_uninit", issue = "53491")] @@ -1277,6 +1279,7 @@ impl MaybeUninit { /// let x_vec = unsafe { &mut *x.as_mut_ptr() }; /// // We have created a reference to an uninitialized vector! This is undefined behavior. /// ``` + /// /// (Notice that the rules around references to uninitialized data are not finalized yet, but /// until they are, it is advisable to avoid them.) #[unstable(feature = "maybe_uninit", issue = "53491")] diff --git a/src/libcore/num/dec2flt/algorithm.rs b/src/libcore/num/dec2flt/algorithm.rs index 3b57bb7544b35..a83134a6b2ca4 100644 --- a/src/libcore/num/dec2flt/algorithm.rs +++ b/src/libcore/num/dec2flt/algorithm.rs @@ -326,7 +326,7 @@ pub fn algorithm_m(f: &Big, e: i16) -> T { round_by_remainder(v, rem, q, z) } -/// Skip over most Algorithm M iterations by checking the bit length. +/// Skips over most Algorithm M iterations by checking the bit length. fn quick_start(u: &mut Big, v: &mut Big, k: &mut i16) { // The bit length is an estimate of the base two logarithm, and log(u / v) = log(u) - log(v). // The estimate is off by at most 1, but always an under-estimate, so the error on log(u) diff --git a/src/libcore/num/dec2flt/mod.rs b/src/libcore/num/dec2flt/mod.rs index 47ea5aa5ff000..d62cdae0688be 100644 --- a/src/libcore/num/dec2flt/mod.rs +++ b/src/libcore/num/dec2flt/mod.rs @@ -304,8 +304,8 @@ fn simplify(decimal: &mut Decimal) { } } -/// Quick and dirty upper bound on the size (log10) of the largest value that Algorithm R and -/// Algorithm M will compute while working on the given decimal. +/// Returns a quick-an-dirty upper bound on the size (log10) of the largest value that Algorithm R +/// and Algorithm M will compute while working on the given decimal. fn bound_intermediate_digits(decimal: &Decimal, e: i64) -> u64 { // We don't need to worry too much about overflow here thanks to trivial_cases() and the // parser, which filter out the most extreme inputs for us. @@ -324,7 +324,7 @@ fn bound_intermediate_digits(decimal: &Decimal, e: i64) -> u64 { } } -/// Detect obvious overflows and underflows without even looking at the decimal digits. +/// Detects obvious overflows and underflows without even looking at the decimal digits. fn trivial_cases(decimal: &Decimal) -> Option { // There were zeros but they were stripped by simplify() if decimal.integral.is_empty() && decimal.fractional.is_empty() { diff --git a/src/libcore/num/dec2flt/parse.rs b/src/libcore/num/dec2flt/parse.rs index 933f8c1d3f781..f970595452ec9 100644 --- a/src/libcore/num/dec2flt/parse.rs +++ b/src/libcore/num/dec2flt/parse.rs @@ -78,7 +78,7 @@ pub fn parse_decimal(s: &str) -> ParseResult { } } -/// Carve off decimal digits up to the first non-digit character. +/// Carves off decimal digits up to the first non-digit character. fn eat_digits(s: &[u8]) -> (&[u8], &[u8]) { let mut i = 0; while i < s.len() && b'0' <= s[i] && s[i] <= b'9' { diff --git a/src/libcore/num/flt2dec/decoder.rs b/src/libcore/num/flt2dec/decoder.rs index a3bf783976bbd..a8da31d3e4858 100644 --- a/src/libcore/num/flt2dec/decoder.rs +++ b/src/libcore/num/flt2dec/decoder.rs @@ -10,7 +10,7 @@ use num::dec2flt::rawfp::RawFloat; /// /// - Any number from `(mant - minus) * 2^exp` to `(mant + plus) * 2^exp` will /// round to the original value. The range is inclusive only when -/// `inclusive` is true. +/// `inclusive` is `true`. #[derive(Copy, Clone, Debug, PartialEq, Eq)] pub struct Decoded { /// The scaled mantissa. diff --git a/src/libcore/num/flt2dec/mod.rs b/src/libcore/num/flt2dec/mod.rs index f9b46a12f7fef..defd4247f4ea4 100644 --- a/src/libcore/num/flt2dec/mod.rs +++ b/src/libcore/num/flt2dec/mod.rs @@ -315,15 +315,15 @@ fn digits_to_dec_str<'a>(buf: &'a [u8], exp: i16, frac_digits: usize, } } -/// Formats given decimal digits `0.<...buf...> * 10^exp` into the exponential form -/// with at least given number of significant digits. When `upper` is true, +/// Formats the given decimal digits `0.<...buf...> * 10^exp` into the exponential +/// form with at least the given number of significant digits. When `upper` is `true`, /// the exponent will be prefixed by `E`; otherwise that's `e`. The result is /// stored to the supplied parts array and a slice of written parts is returned. /// /// `min_digits` can be less than the number of actual significant digits in `buf`; /// it will be ignored and full digits will be printed. It is only used to print -/// additional zeroes after rendered digits. Thus `min_digits` of 0 means that -/// it will only print given digits and nothing else. +/// additional zeroes after rendered digits. Thus, `min_digits == 0` means that +/// it will only print the given digits and nothing else. fn digits_to_exp_str<'a>(buf: &'a [u8], exp: i16, min_ndigits: usize, upper: bool, parts: &'a mut [Part<'a>]) -> &'a [Part<'a>] { assert!(!buf.is_empty()); @@ -384,7 +384,7 @@ fn determine_sign(sign: Sign, decoded: &FullDecoded, negative: bool) -> &'static } } -/// Formats given floating point number into the decimal form with at least +/// Formats the given floating point number into the decimal form with at least /// given number of fractional digits. The result is stored to the supplied parts /// array while utilizing given byte buffer as a scratch. `upper` is currently /// unused but left for the future decision to change the case of non-finite values, @@ -438,7 +438,7 @@ pub fn to_shortest_str<'a, T, F>(mut format_shortest: F, v: T, } } -/// Formats given floating point number into the decimal form or +/// Formats the given floating point number into the decimal form or /// the exponential form, depending on the resulting exponent. The result is /// stored to the supplied parts array while utilizing given byte buffer /// as a scratch. `upper` is used to determine the case of non-finite values @@ -497,7 +497,7 @@ pub fn to_shortest_exp_str<'a, T, F>(mut format_shortest: F, v: T, } } -/// Returns rather crude approximation (upper bound) for the maximum buffer size +/// Returns a rather crude approximation (upper bound) for the maximum buffer size /// calculated from the given decoded exponent. /// /// The exact limit is: diff --git a/src/libcore/pin.rs b/src/libcore/pin.rs index fb78f5e5a2384..cf55b6c379d04 100644 --- a/src/libcore/pin.rs +++ b/src/libcore/pin.rs @@ -1,4 +1,4 @@ -//! Types which pin data to its location in memory +//! Types that pin data to its location in memory. //! //! It is sometimes useful to have objects that are guaranteed to not move, //! in the sense that their placement in memory does not change, and can thus be relied upon. diff --git a/src/libcore/str/mod.rs b/src/libcore/str/mod.rs index 53334adadb856..528281d317be3 100644 --- a/src/libcore/str/mod.rs +++ b/src/libcore/str/mod.rs @@ -2968,7 +2968,7 @@ impl str { /// /// The returned iterator will be a [`DoubleEndedIterator`] if the pattern /// allows a reverse search and forward/reverse search yields the same - /// elements. This is true for, eg, [`char`] but not for `&str`. + /// elements. This is true for, e.g., [`char`], but not for `&str`. /// /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html /// @@ -3143,7 +3143,7 @@ impl str { /// /// The returned iterator will be a [`DoubleEndedIterator`] if the pattern /// allows a reverse search and forward/reverse search yields the same - /// elements. This is true for, eg, [`char`] but not for `&str`. + /// elements. This is true for, e.g., [`char`], but not for `&str`. /// /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html /// @@ -3326,7 +3326,7 @@ impl str { /// /// The returned iterator will be a [`DoubleEndedIterator`] if the pattern /// allows a reverse search and forward/reverse search yields the same - /// elements. This is true for, eg, [`char`] but not for `&str`. + /// elements. This is true for, e.g., [`char`], but not for `&str`. /// /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html /// @@ -3402,7 +3402,7 @@ impl str { /// /// The returned iterator will be a [`DoubleEndedIterator`] if the pattern /// allows a reverse search and forward/reverse search yields the same - /// elements. This is true for, eg, [`char`] but not for `&str`. + /// elements. This is true for, e.g., [`char`], but not for `&str`. /// /// [`DoubleEndedIterator`]: iter/trait.DoubleEndedIterator.html /// diff --git a/src/libcore/task/wake.rs b/src/libcore/task/wake.rs index 21f0a8cea4168..12f812d3bed3e 100644 --- a/src/libcore/task/wake.rs +++ b/src/libcore/task/wake.rs @@ -108,7 +108,7 @@ impl Waker { unsafe { (self.waker.vtable.wake)(self.waker.data) } } - /// Returns whether or not this `Waker` and other `Waker` have awaken the same task. + /// Returns `true` if this `Waker` and another `Waker` have awoken the same task. /// /// This function works on a best-effort basis, and may return false even /// when the `Waker`s would awaken the same task. However, if this function diff --git a/src/libstd/collections/hash/map.rs b/src/libstd/collections/hash/map.rs index 928de29b297fc..1d45df499d86b 100644 --- a/src/libstd/collections/hash/map.rs +++ b/src/libstd/collections/hash/map.rs @@ -19,7 +19,7 @@ use super::table::{self, Bucket, EmptyBucket, Fallibility, FullBucket, FullBucke use super::table::BucketState::{Empty, Full}; use super::table::Fallibility::{Fallible, Infallible}; -const MIN_NONZERO_RAW_CAPACITY: usize = 32; // must be a power of two +const MIN_NONZERO_RAW_CAPACITY: usize = 32; // must be a power of two /// The default behavior of HashMap implements a maximum load factor of 90.9%. #[derive(Clone)] diff --git a/src/libstd/collections/hash/set.rs b/src/libstd/collections/hash/set.rs index 8a599c11b2095..1e7d1f1ad58fa 100644 --- a/src/libstd/collections/hash/set.rs +++ b/src/libstd/collections/hash/set.rs @@ -8,7 +8,7 @@ use super::Recover; use super::map::{self, HashMap, Keys, RandomState}; // Future Optimization (FIXME!) -// ============================= +// ============================ // // Iteration over zero sized values is a noop. There is no need // for `bucket.val` in the case of HashSet. I suppose we would need HKT diff --git a/src/libstd/fs.rs b/src/libstd/fs.rs index 25f2dd73504ae..93cee50af13e5 100644 --- a/src/libstd/fs.rs +++ b/src/libstd/fs.rs @@ -211,7 +211,7 @@ pub struct DirBuilder { recursive: bool, } -/// How large a buffer to pre-allocate before reading the entire file. +/// Indicates how large a buffer to pre-allocate before reading the entire file. fn initial_buffer_size(file: &File) -> usize { // Allocate one extra byte so the buffer doesn't need to grow before the // final `read` call at the end of the file. Don't worry about `usize` diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs index 5ebb61754e1ff..4ad383aa5b613 100644 --- a/src/libstd/sync/condvar.rs +++ b/src/libstd/sync/condvar.rs @@ -190,7 +190,7 @@ impl Condvar { /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // As long as the value inside the `Mutex` is false, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// while !*started { /// started = cvar.wait(started).unwrap(); /// } @@ -254,7 +254,7 @@ impl Condvar { /// /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; - /// // As long as the value inside the `Mutex` is false, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// let _guard = cvar.wait_until(lock.lock().unwrap(), |started| { *started }).unwrap(); /// ``` #[unstable(feature = "wait_until", issue = "47960")] @@ -311,7 +311,7 @@ impl Condvar { /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // As long as the value inside the `Mutex` is false, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// loop { /// let result = cvar.wait_timeout_ms(started, 10).unwrap(); /// // 10 milliseconds have passed, or maybe the value changed! @@ -384,7 +384,7 @@ impl Condvar { /// // wait for the thread to start up /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // as long as the value inside the `Mutex` is false, we wait + /// // as long as the value inside the `Mutex` is `false`, we wait /// loop { /// let result = cvar.wait_timeout(started, Duration::from_millis(10)).unwrap(); /// // 10 milliseconds have passed, or maybe the value changed! @@ -518,7 +518,7 @@ impl Condvar { /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // As long as the value inside the `Mutex` is false, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// while !*started { /// started = cvar.wait(started).unwrap(); /// } @@ -558,7 +558,7 @@ impl Condvar { /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // As long as the value inside the `Mutex` is false, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// while !*started { /// started = cvar.wait(started).unwrap(); /// } diff --git a/src/libstd/sys/windows/pipe.rs b/src/libstd/sys/windows/pipe.rs index 07f4f5f0e58c4..b38727830f37f 100644 --- a/src/libstd/sys/windows/pipe.rs +++ b/src/libstd/sys/windows/pipe.rs @@ -37,9 +37,9 @@ pub struct Pipes { /// /// The ours/theirs pipes are *not* specifically readable or writable. Each /// one only supports a read or a write, but which is which depends on the -/// boolean flag given. If `ours_readable` is true then `ours` is readable where -/// `theirs` is writable. Conversely if `ours_readable` is false then `ours` is -/// writable where `theirs` is readable. +/// boolean flag given. If `ours_readable` is `true`, then `ours` is readable and +/// `theirs` is writable. Conversely, if `ours_readable` is `false`, then `ours` +/// is writable and `theirs` is readable. /// /// Also note that the `ours` pipe is always a handle opened up in overlapped /// mode. This means that technically speaking it should only ever be used From e25df326caf38c1a8559fc6fa633ad60ab401e12 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 11 Mar 2019 17:53:22 +0300 Subject: [PATCH 22/58] consistent naming for duration_float methods and additional f32 methods --- src/libcore/time.rs | 130 +++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 121 insertions(+), 9 deletions(-) diff --git a/src/libcore/time.rs b/src/libcore/time.rs index 91161ca477e39..c8f23fd90bd7a 100644 --- a/src/libcore/time.rs +++ b/src/libcore/time.rs @@ -22,6 +22,7 @@ const NANOS_PER_MICRO: u32 = 1_000; const MILLIS_PER_SEC: u64 = 1_000; const MICROS_PER_SEC: u64 = 1_000_000; const MAX_NANOS_F64: f64 = ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f64; +const MAX_NANOS_F32: f64 = ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f32; /// A `Duration` type to represent a span of time, typically used for system /// timeouts. @@ -510,15 +511,34 @@ impl Duration { /// use std::time::Duration; /// /// let dur = Duration::new(2, 700_000_000); - /// assert_eq!(dur.as_float_secs(), 2.7); + /// assert_eq!(dur.as_secs_f64(), 2.7); /// ``` #[unstable(feature = "duration_float", issue = "54361")] #[inline] - pub const fn as_float_secs(&self) -> f64 { + pub const fn as_secs_f64(&self) -> f64 { (self.secs as f64) + (self.nanos as f64) / (NANOS_PER_SEC as f64) } - /// Creates a new `Duration` from the specified number of seconds. + /// Returns the number of seconds contained by this `Duration` as `f32`. + /// + /// The returned value does include the fractional (nanosecond) part of the duration. + /// + /// # Examples + /// ``` + /// #![feature(duration_float)] + /// use std::time::Duration; + /// + /// let dur = Duration::new(2, 700_000_000); + /// assert_eq!(dur.as_secs_f32(), 2.7); + /// ``` + #[unstable(feature = "duration_float", issue = "54361")] + #[inline] + pub const fn as_secs_f32(&self) -> f32 { + (self.secs as f32) + (self.nanos as f32) / (NANOS_PER_SEC as f32) + } + + /// Creates a new `Duration` from the specified number of seconds represented + /// as `f64`. /// /// # Panics /// This constructor will panic if `secs` is not finite, negative or overflows `Duration`. @@ -528,12 +548,12 @@ impl Duration { /// #![feature(duration_float)] /// use std::time::Duration; /// - /// let dur = Duration::from_float_secs(2.7); + /// let dur = Duration::from_secs_f64(2.7); /// assert_eq!(dur, Duration::new(2, 700_000_000)); /// ``` #[unstable(feature = "duration_float", issue = "54361")] #[inline] - pub fn from_float_secs(secs: f64) -> Duration { + pub fn from_secs_f64(secs: f64) -> Duration { let nanos = secs * (NANOS_PER_SEC as f64); if !nanos.is_finite() { panic!("got non-finite value when converting float to duration"); @@ -551,6 +571,40 @@ impl Duration { } } + /// Creates a new `Duration` from the specified number of seconds represented + /// as `f32`. + /// + /// # Panics + /// This constructor will panic if `secs` is not finite, negative or overflows `Duration`. + /// + /// # Examples + /// ``` + /// #![feature(duration_float)] + /// use std::time::Duration; + /// + /// let dur = Duration::from_secs_f32(2.7); + /// assert_eq!(dur, Duration::new(2, 700_000_000)); + /// ``` + #[unstable(feature = "duration_float", issue = "54361")] + #[inline] + pub fn from_secs_f32(secs: f32) -> Duration { + let nanos = secs * (NANOS_PER_SEC as f32); + if !nanos.is_finite() { + panic!("got non-finite value when converting float to duration"); + } + if nanos >= MAX_NANOS_F32 { + panic!("overflow when converting float to duration"); + } + if nanos < 0.0 { + panic!("underflow when converting float to duration"); + } + let nanos = nanos as u128; + Duration { + secs: (nanos / (NANOS_PER_SEC as u128)) as u64, + nanos: (nanos % (NANOS_PER_SEC as u128)) as u32, + } + } + /// Multiplies `Duration` by `f64`. /// /// # Panics @@ -568,7 +622,27 @@ impl Duration { #[unstable(feature = "duration_float", issue = "54361")] #[inline] pub fn mul_f64(self, rhs: f64) -> Duration { - Duration::from_float_secs(rhs * self.as_float_secs()) + Duration::from_secs_f64(rhs * self.as_secs_f64()) + } + + /// Multiplies `Duration` by `f32`. + /// + /// # Panics + /// This method will panic if result is not finite, negative or overflows `Duration`. + /// + /// # Examples + /// ``` + /// #![feature(duration_float)] + /// use std::time::Duration; + /// + /// let dur = Duration::new(2, 700_000_000); + /// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_000)); + /// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847_800, 0)); + /// ``` + #[unstable(feature = "duration_float", issue = "54361")] + #[inline] + pub fn mul_f32(self, rhs: f32) -> Duration { + Duration::from_secs_f32(rhs * self.as_secs_f32()) } /// Divide `Duration` by `f64`. @@ -589,7 +663,28 @@ impl Duration { #[unstable(feature = "duration_float", issue = "54361")] #[inline] pub fn div_f64(self, rhs: f64) -> Duration { - Duration::from_float_secs(self.as_float_secs() / rhs) + Duration::from_secs_f64(self.as_secs_f64() / rhs) + } + + /// Divide `Duration` by `f32`. + /// + /// # Panics + /// This method will panic if result is not finite, negative or overflows `Duration`. + /// + /// # Examples + /// ``` + /// #![feature(duration_float)] + /// use std::time::Duration; + /// + /// let dur = Duration::new(2, 700_000_000); + /// assert_eq!(dur.div_f32(3.14), Duration::new(0, 859_872_611)); + /// // note that truncation is used, not rounding + /// assert_eq!(dur.div_f32(3.14e5), Duration::new(0, 8_598)); + /// ``` + #[unstable(feature = "duration_float", issue = "54361")] + #[inline] + pub fn div_f32(self, rhs: f32) -> Duration { + Duration::from_secs_f32(self.as_secs_f32() / rhs) } /// Divide `Duration` by `Duration` and return `f64`. @@ -605,8 +700,25 @@ impl Duration { /// ``` #[unstable(feature = "duration_float", issue = "54361")] #[inline] - pub fn div_duration(self, rhs: Duration) -> f64 { - self.as_float_secs() / rhs.as_float_secs() + pub fn div_duration_f64(self, rhs: Duration) -> f64 { + self.as_secs_f64() / rhs.as_secs_f64() + } + + /// Divide `Duration` by `Duration` and return `f32`. + /// + /// # Examples + /// ``` + /// #![feature(duration_float)] + /// use std::time::Duration; + /// + /// let dur1 = Duration::new(2, 700_000_000); + /// let dur2 = Duration::new(5, 400_000_000); + /// assert_eq!(dur1.div_duration(dur2), 0.5); + /// ``` + #[unstable(feature = "duration_float", issue = "54361")] + #[inline] + pub fn div_duration_f32(self, rhs: Duration) -> f32 { + self.as_secs_f32() / rhs.as_secs_f32() } } From 35c19c5b3d1fe8675132ea96e014e37455653ce8 Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 11 Mar 2019 18:06:13 +0300 Subject: [PATCH 23/58] move MAX_NANOS_F64/32 to methods --- src/libcore/time.rs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libcore/time.rs b/src/libcore/time.rs index c8f23fd90bd7a..d3f80835c0175 100644 --- a/src/libcore/time.rs +++ b/src/libcore/time.rs @@ -21,8 +21,6 @@ const NANOS_PER_MILLI: u32 = 1_000_000; const NANOS_PER_MICRO: u32 = 1_000; const MILLIS_PER_SEC: u64 = 1_000; const MICROS_PER_SEC: u64 = 1_000_000; -const MAX_NANOS_F64: f64 = ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f64; -const MAX_NANOS_F32: f64 = ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f32; /// A `Duration` type to represent a span of time, typically used for system /// timeouts. @@ -554,6 +552,8 @@ impl Duration { #[unstable(feature = "duration_float", issue = "54361")] #[inline] pub fn from_secs_f64(secs: f64) -> Duration { + const MAX_NANOS_F64: f64 = + ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f64; let nanos = secs * (NANOS_PER_SEC as f64); if !nanos.is_finite() { panic!("got non-finite value when converting float to duration"); @@ -588,6 +588,8 @@ impl Duration { #[unstable(feature = "duration_float", issue = "54361")] #[inline] pub fn from_secs_f32(secs: f32) -> Duration { + const MAX_NANOS_F32: f32 = + ((u64::MAX as u128 + 1)*(NANOS_PER_SEC as u128)) as f32; let nanos = secs * (NANOS_PER_SEC as f32); if !nanos.is_finite() { panic!("got non-finite value when converting float to duration"); From d4b2071b1faeaa15ecbad7dc74a94def96200d87 Mon Sep 17 00:00:00 2001 From: Alexander Regueiro Date: Mon, 11 Mar 2019 15:54:57 +0000 Subject: [PATCH 24/58] Resolved nits raised in review. --- src/libstd/sync/condvar.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libstd/sync/condvar.rs b/src/libstd/sync/condvar.rs index 4ad383aa5b613..c383f21dcd752 100644 --- a/src/libstd/sync/condvar.rs +++ b/src/libstd/sync/condvar.rs @@ -190,7 +190,7 @@ impl Condvar { /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // As long as the value inside the `Mutex` is `false`, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// while !*started { /// started = cvar.wait(started).unwrap(); /// } @@ -254,7 +254,7 @@ impl Condvar { /// /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; - /// // As long as the value inside the `Mutex` is `false`, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// let _guard = cvar.wait_until(lock.lock().unwrap(), |started| { *started }).unwrap(); /// ``` #[unstable(feature = "wait_until", issue = "47960")] @@ -311,7 +311,7 @@ impl Condvar { /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // As long as the value inside the `Mutex` is `false`, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// loop { /// let result = cvar.wait_timeout_ms(started, 10).unwrap(); /// // 10 milliseconds have passed, or maybe the value changed! @@ -384,7 +384,7 @@ impl Condvar { /// // wait for the thread to start up /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // as long as the value inside the `Mutex` is `false`, we wait + /// // as long as the value inside the `Mutex` is `false`, we wait /// loop { /// let result = cvar.wait_timeout(started, Duration::from_millis(10)).unwrap(); /// // 10 milliseconds have passed, or maybe the value changed! @@ -518,7 +518,7 @@ impl Condvar { /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // As long as the value inside the `Mutex` is `false`, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// while !*started { /// started = cvar.wait(started).unwrap(); /// } @@ -558,7 +558,7 @@ impl Condvar { /// // Wait for the thread to start up. /// let &(ref lock, ref cvar) = &*pair; /// let mut started = lock.lock().unwrap(); - /// // As long as the value inside the `Mutex` is `false`, we wait. + /// // As long as the value inside the `Mutex` is `false`, we wait. /// while !*started { /// started = cvar.wait(started).unwrap(); /// } From 980871af270314d1e4dd42828d9a7c76d6e0c89a Mon Sep 17 00:00:00 2001 From: newpavlov Date: Mon, 11 Mar 2019 19:57:53 +0300 Subject: [PATCH 25/58] fix tests --- src/libcore/time.rs | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/src/libcore/time.rs b/src/libcore/time.rs index d3f80835c0175..c4d4c4622f3a4 100644 --- a/src/libcore/time.rs +++ b/src/libcore/time.rs @@ -638,8 +638,10 @@ impl Duration { /// use std::time::Duration; /// /// let dur = Duration::new(2, 700_000_000); - /// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_000)); - /// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847_800, 0)); + /// // note that due to rounding errors result is slightly different + /// // from 8.478 + /// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_640)); + /// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847_800, 64_000_000)); /// ``` #[unstable(feature = "duration_float", issue = "54361")] #[inline] @@ -679,7 +681,9 @@ impl Duration { /// use std::time::Duration; /// /// let dur = Duration::new(2, 700_000_000); - /// assert_eq!(dur.div_f32(3.14), Duration::new(0, 859_872_611)); + /// // note that due to rounding errors result is slightly + /// // different from 0.859_872_611 + /// assert_eq!(dur.div_f32(3.14), Duration::new(0, 859_872_576)); /// // note that truncation is used, not rounding /// assert_eq!(dur.div_f32(3.14e5), Duration::new(0, 8_598)); /// ``` @@ -698,7 +702,7 @@ impl Duration { /// /// let dur1 = Duration::new(2, 700_000_000); /// let dur2 = Duration::new(5, 400_000_000); - /// assert_eq!(dur1.div_duration(dur2), 0.5); + /// assert_eq!(dur1.div_duration_f64(dur2), 0.5); /// ``` #[unstable(feature = "duration_float", issue = "54361")] #[inline] @@ -715,7 +719,7 @@ impl Duration { /// /// let dur1 = Duration::new(2, 700_000_000); /// let dur2 = Duration::new(5, 400_000_000); - /// assert_eq!(dur1.div_duration(dur2), 0.5); + /// assert_eq!(dur1.div_duration_f32(dur2), 0.5); /// ``` #[unstable(feature = "duration_float", issue = "54361")] #[inline] From 197efb05243976a631107f1d6ad88bff65fd43e9 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Mon, 11 Mar 2019 18:59:41 +0000 Subject: [PATCH 26/58] fix test --- src/libcore/time.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libcore/time.rs b/src/libcore/time.rs index c4d4c4622f3a4..f106d06d2ffc1 100644 --- a/src/libcore/time.rs +++ b/src/libcore/time.rs @@ -639,9 +639,9 @@ impl Duration { /// /// let dur = Duration::new(2, 700_000_000); /// // note that due to rounding errors result is slightly different - /// // from 8.478 + /// // from 8.478 anf 847800.0 /// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_640)); - /// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847_800, 64_000_000)); + /// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847799, 969_120_256)); /// ``` #[unstable(feature = "duration_float", issue = "54361")] #[inline] From 78b248dc4c17581211aaed5c3a449e5b07ebdb52 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Tue, 12 Mar 2019 16:42:18 +0300 Subject: [PATCH 27/58] fix typo --- src/libcore/time.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libcore/time.rs b/src/libcore/time.rs index f106d06d2ffc1..ae6d8078fd236 100644 --- a/src/libcore/time.rs +++ b/src/libcore/time.rs @@ -639,7 +639,7 @@ impl Duration { /// /// let dur = Duration::new(2, 700_000_000); /// // note that due to rounding errors result is slightly different - /// // from 8.478 anf 847800.0 + /// // from 8.478 and 847800.0 /// assert_eq!(dur.mul_f32(3.14), Duration::new(8, 478_000_640)); /// assert_eq!(dur.mul_f32(3.14e5), Duration::new(847799, 969_120_256)); /// ``` From 507448945612f6b6f80a08a943e88d9a3a14b52f Mon Sep 17 00:00:00 2001 From: Oliver Scherer Date: Tue, 12 Mar 2019 17:37:22 +0100 Subject: [PATCH 28/58] Unregress using scalar unions in constants. --- src/librustc_mir/const_eval.rs | 26 +++++++++++++------------- src/test/ui/consts/union_constant.rs | 11 +++++++++++ 2 files changed, 24 insertions(+), 13 deletions(-) create mode 100644 src/test/ui/consts/union_constant.rs diff --git a/src/librustc_mir/const_eval.rs b/src/librustc_mir/const_eval.rs index 365cb508b0925..d97be0b28725c 100644 --- a/src/librustc_mir/const_eval.rs +++ b/src/librustc_mir/const_eval.rs @@ -65,12 +65,12 @@ pub(crate) fn eval_promoted<'a, 'mir, 'tcx>( fn mplace_to_const<'tcx>( ecx: &CompileTimeEvalContext<'_, '_, 'tcx>, mplace: MPlaceTy<'tcx>, -) -> EvalResult<'tcx, ty::Const<'tcx>> { +) -> ty::Const<'tcx> { let MemPlace { ptr, align, meta } = *mplace; // extract alloc-offset pair assert!(meta.is_none()); - let ptr = ptr.to_ptr()?; - let alloc = ecx.memory.get(ptr.alloc_id)?; + let ptr = ptr.to_ptr().unwrap(); + let alloc = ecx.memory.get(ptr.alloc_id).unwrap(); assert!(alloc.align >= align); assert!(alloc.bytes.len() as u64 - ptr.offset.bytes() >= mplace.layout.size.bytes()); let mut alloc = alloc.clone(); @@ -79,16 +79,16 @@ fn mplace_to_const<'tcx>( // interned this? I thought that is the entire point of that `FinishStatic` stuff? let alloc = ecx.tcx.intern_const_alloc(alloc); let val = ConstValue::ByRef(ptr, alloc); - Ok(ty::Const { val, ty: mplace.layout.ty }) + ty::Const { val, ty: mplace.layout.ty } } fn op_to_const<'tcx>( ecx: &CompileTimeEvalContext<'_, '_, 'tcx>, op: OpTy<'tcx>, -) -> EvalResult<'tcx, ty::Const<'tcx>> { - // We do not normalize just any data. Only scalar layout and slices. +) -> ty::Const<'tcx> { + // We do not normalize just any data. Only non-union scalars and slices. let normalize = match op.layout.abi { - layout::Abi::Scalar(..) => true, + layout::Abi::Scalar(..) => op.layout.ty.ty_adt_def().map_or(true, |adt| !adt.is_union()), layout::Abi::ScalarPair(..) => op.layout.ty.is_slice(), _ => false, }; @@ -100,11 +100,11 @@ fn op_to_const<'tcx>( let val = match normalized_op { Ok(mplace) => return mplace_to_const(ecx, mplace), Err(Immediate::Scalar(x)) => - ConstValue::Scalar(x.not_undef()?), + ConstValue::Scalar(x.not_undef().unwrap()), Err(Immediate::ScalarPair(a, b)) => - ConstValue::Slice(a.not_undef()?, b.to_usize(ecx)?), + ConstValue::Slice(a.not_undef().unwrap(), b.to_usize(ecx).unwrap()), }; - Ok(ty::Const { val, ty: op.layout.ty }) + ty::Const { val, ty: op.layout.ty } } fn eval_body_and_ecx<'a, 'mir, 'tcx>( @@ -488,7 +488,7 @@ pub fn const_field<'a, 'tcx>( let field = ecx.operand_field(down, field.index() as u64).unwrap(); // and finally move back to the const world, always normalizing because // this is not called for statics. - op_to_const(&ecx, field).unwrap() + op_to_const(&ecx, field) } // this function uses `unwrap` copiously, because an already validated constant must have valid @@ -534,9 +534,9 @@ fn validate_and_turn_into_const<'a, 'tcx>( // Now that we validated, turn this into a proper constant. let def_id = cid.instance.def.def_id(); if tcx.is_static(def_id).is_some() || cid.promoted.is_some() { - mplace_to_const(&ecx, mplace) + Ok(mplace_to_const(&ecx, mplace)) } else { - op_to_const(&ecx, mplace.into()) + Ok(op_to_const(&ecx, mplace.into())) } })(); diff --git a/src/test/ui/consts/union_constant.rs b/src/test/ui/consts/union_constant.rs new file mode 100644 index 0000000000000..074014908bad4 --- /dev/null +++ b/src/test/ui/consts/union_constant.rs @@ -0,0 +1,11 @@ +// compile-pass + +union Uninit { + _never_use: *const u8, + uninit: (), +} + +const UNINIT: Uninit = Uninit { uninit: () }; + +fn main() {} + From df05fbf006e90ed4827c385eb9192e4c46de70f4 Mon Sep 17 00:00:00 2001 From: Sean McArthur Date: Mon, 11 Mar 2019 16:39:40 -0700 Subject: [PATCH 29/58] rustc: fix ICE when trait alias has bare Self --- src/librustc/hir/map/mod.rs | 6 ++++-- src/test/ui/issues/issue-59029-1.rs | 8 ++++++++ src/test/ui/issues/issue-59029-1.stderr | 9 +++++++++ src/test/ui/issues/issue-59029-2.rs | 8 ++++++++ 4 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 src/test/ui/issues/issue-59029-1.rs create mode 100644 src/test/ui/issues/issue-59029-1.stderr create mode 100644 src/test/ui/issues/issue-59029-2.rs diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 86b6805cc9b4c..0e83ce009c943 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -541,7 +541,8 @@ impl<'hir> Map<'hir> { pub fn ty_param_owner(&self, id: HirId) -> HirId { match self.get_by_hir_id(id) { - Node::Item(&Item { node: ItemKind::Trait(..), .. }) => id, + Node::Item(&Item { node: ItemKind::Trait(..), .. }) | + Node::Item(&Item { node: ItemKind::TraitAlias(..), .. }) => id, Node::GenericParam(_) => self.get_parent_node_by_hir_id(id), _ => bug!("ty_param_owner: {} not a type parameter", self.hir_to_string(id)) } @@ -549,7 +550,8 @@ impl<'hir> Map<'hir> { pub fn ty_param_name(&self, id: HirId) -> Name { match self.get_by_hir_id(id) { - Node::Item(&Item { node: ItemKind::Trait(..), .. }) => keywords::SelfUpper.name(), + Node::Item(&Item { node: ItemKind::Trait(..), .. }) | + Node::Item(&Item { node: ItemKind::TraitAlias(..), .. }) => keywords::SelfUpper.name(), Node::GenericParam(param) => param.name.ident().name, _ => bug!("ty_param_name: {} not a type parameter", self.hir_to_string(id)), } diff --git a/src/test/ui/issues/issue-59029-1.rs b/src/test/ui/issues/issue-59029-1.rs new file mode 100644 index 0000000000000..e98a4d0e491a3 --- /dev/null +++ b/src/test/ui/issues/issue-59029-1.rs @@ -0,0 +1,8 @@ +#![feature(trait_alias)] + +trait Svc { type Res; } + +trait MkSvc = Svc where Self::Res: Svc; +//~^ ERROR associated type `Res` not found for `Self` + +fn main() {} diff --git a/src/test/ui/issues/issue-59029-1.stderr b/src/test/ui/issues/issue-59029-1.stderr new file mode 100644 index 0000000000000..ed1d98c40d18a --- /dev/null +++ b/src/test/ui/issues/issue-59029-1.stderr @@ -0,0 +1,9 @@ +error[E0220]: associated type `Res` not found for `Self` + --> $DIR/issue-59029-1.rs:5:46 + | +LL | trait MkSvc = Svc where Self::Res: Svc; + | ^^^^^^^^^ associated type `Res` not found + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0220`. diff --git a/src/test/ui/issues/issue-59029-2.rs b/src/test/ui/issues/issue-59029-2.rs new file mode 100644 index 0000000000000..2bdb128d8c4c8 --- /dev/null +++ b/src/test/ui/issues/issue-59029-2.rs @@ -0,0 +1,8 @@ +// run-pass +#![feature(trait_alias)] + +trait Svc { type Res; } + +trait MkSvc = Svc where >::Res: Svc; + +fn main() {} From 795d307f10ec0fd3851b18a3365755d76b7403e5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 12 Mar 2019 14:57:13 -0700 Subject: [PATCH 30/58] Suggest return lifetime when there's only one named lifetime --- src/librustc/middle/resolve_lifetime.rs | 37 +++++++++++++++++-- .../ui/suggestions/return-without-lifetime.rs | 8 ++++ .../return-without-lifetime.stderr | 19 ++++++++++ 3 files changed, 60 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/suggestions/return-without-lifetime.rs create mode 100644 src/test/ui/suggestions/return-without-lifetime.stderr diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index f862b690f8806..35bca04d1e623 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -2298,6 +2298,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { let span = lifetime_refs[0].span; let mut late_depth = 0; let mut scope = self.scope; + let mut lifetime_names = FxHashSet::default(); let error = loop { match *scope { // Do not assign any resolution, it will be inferred. @@ -2310,7 +2311,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { scope = s; } - Scope::Elision { ref elide, .. } => { + Scope::Elision { ref elide, ref s, .. } => { let lifetime = match *elide { Elide::FreshLateAnon(ref counter) => { for lifetime_ref in lifetime_refs { @@ -2320,7 +2321,16 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { return; } Elide::Exact(l) => l.shifted(late_depth), - Elide::Error(ref e) => break Some(e), + Elide::Error(ref e) => { + if let Scope::Binder { ref lifetimes, .. } = s { + for name in lifetimes.keys() { + if let hir::ParamName::Plain(name) = name { + lifetime_names.insert(*name); + } + } + } + break Some(e); + } }; for lifetime_ref in lifetime_refs { self.insert_lifetime(lifetime_ref, lifetime); @@ -2343,7 +2353,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { } } if add_label { - add_missing_lifetime_specifiers_label(&mut err, span, lifetime_refs.len()); + add_missing_lifetime_specifiers_label( + &mut err, + span, + lifetime_refs.len(), + &lifetime_names, + self.tcx.sess.source_map().span_to_snippet(span).ok().as_ref().map(|s| s.as_str()), + ); } err.emit(); @@ -2884,10 +2900,23 @@ fn add_missing_lifetime_specifiers_label( err: &mut DiagnosticBuilder<'_>, span: Span, count: usize, + lifetime_names: &FxHashSet, + snippet: Option<&str>, ) { if count > 1 { err.span_label(span, format!("expected {} lifetime parameters", count)); + } else if let (1, Some(name), Some("&")) = ( + lifetime_names.len(), + lifetime_names.iter().next(), + snippet, + ) { + err.span_suggestion( + span, + &format!("consider using the named lifetime `{}`", name), + format!("&{} ", name), + Applicability::MaybeIncorrect, + ); } else { err.span_label(span, "expected lifetime parameter"); - }; + } } diff --git a/src/test/ui/suggestions/return-without-lifetime.rs b/src/test/ui/suggestions/return-without-lifetime.rs new file mode 100644 index 0000000000000..5f19e93013acf --- /dev/null +++ b/src/test/ui/suggestions/return-without-lifetime.rs @@ -0,0 +1,8 @@ +struct Thing<'a>(&'a ()); + +fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() } +//~^ ERROR missing lifetime specifier +fn func2<'a>(_arg: &Thing<'a>) -> &() { unimplemented!() } +//~^ ERROR missing lifetime specifier + +fn main() {} diff --git a/src/test/ui/suggestions/return-without-lifetime.stderr b/src/test/ui/suggestions/return-without-lifetime.stderr new file mode 100644 index 0000000000000..72f1c142d028f --- /dev/null +++ b/src/test/ui/suggestions/return-without-lifetime.stderr @@ -0,0 +1,19 @@ +error[E0106]: missing lifetime specifier + --> $DIR/return-without-lifetime.rs:3:34 + | +LL | fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() } + | ^ help: consider using the named lifetime `'a`: `&'a` + | + = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from + +error[E0106]: missing lifetime specifier + --> $DIR/return-without-lifetime.rs:5:35 + | +LL | fn func2<'a>(_arg: &Thing<'a>) -> &() { unimplemented!() } + | ^ help: consider using the named lifetime `'a`: `&'a` + | + = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0106`. From f9234767e4ff9b682437464efc9a6ff59db4cff9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 12 Mar 2019 15:34:16 -0700 Subject: [PATCH 31/58] review comments --- src/librustc/middle/resolve_lifetime.rs | 2 +- src/test/ui/suggestions/return-without-lifetime.stderr | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 35bca04d1e623..d03268df5e148 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -2912,7 +2912,7 @@ fn add_missing_lifetime_specifiers_label( ) { err.span_suggestion( span, - &format!("consider using the named lifetime `{}`", name), + "consider using the named lifetime", format!("&{} ", name), Applicability::MaybeIncorrect, ); diff --git a/src/test/ui/suggestions/return-without-lifetime.stderr b/src/test/ui/suggestions/return-without-lifetime.stderr index 72f1c142d028f..1ffe91bce05a5 100644 --- a/src/test/ui/suggestions/return-without-lifetime.stderr +++ b/src/test/ui/suggestions/return-without-lifetime.stderr @@ -2,7 +2,7 @@ error[E0106]: missing lifetime specifier --> $DIR/return-without-lifetime.rs:3:34 | LL | fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() } - | ^ help: consider using the named lifetime `'a`: `&'a` + | ^ help: consider using the named lifetime: `&'a` | = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from @@ -10,7 +10,7 @@ error[E0106]: missing lifetime specifier --> $DIR/return-without-lifetime.rs:5:35 | LL | fn func2<'a>(_arg: &Thing<'a>) -> &() { unimplemented!() } - | ^ help: consider using the named lifetime `'a`: `&'a` + | ^ help: consider using the named lifetime: `&'a` | = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from From adbd0a66457159ffcdd02ee0b553581298968847 Mon Sep 17 00:00:00 2001 From: Jethro Beekman Date: Tue, 12 Mar 2019 16:09:20 -0700 Subject: [PATCH 32/58] Make std time tests more robust for platform differences --- src/libstd/time.rs | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/src/libstd/time.rs b/src/libstd/time.rs index 6d7093ac33ea7..4c86f70ad871d 100644 --- a/src/libstd/time.rs +++ b/src/libstd/time.rs @@ -712,13 +712,6 @@ mod tests { assert_almost_eq!(a - second + second, a); assert_almost_eq!(a.checked_sub(second).unwrap().checked_add(second).unwrap(), a); - // A difference of 80 and 800 years cannot fit inside a 32-bit time_t - if !(cfg!(unix) && crate::mem::size_of::() <= 4) { - let eighty_years = second * 60 * 60 * 24 * 365 * 80; - assert_almost_eq!(a - eighty_years + eighty_years, a); - assert_almost_eq!(a - (eighty_years * 10) + (eighty_years * 10), a); - } - let one_second_from_epoch = UNIX_EPOCH + Duration::new(1, 0); let one_second_from_epoch2 = UNIX_EPOCH + Duration::new(0, 500_000_000) + Duration::new(0, 500_000_000); @@ -747,8 +740,8 @@ mod tests { #[test] fn since_epoch() { let ts = SystemTime::now(); - let a = ts.duration_since(UNIX_EPOCH).unwrap(); - let b = ts.duration_since(UNIX_EPOCH - Duration::new(1, 0)).unwrap(); + let a = ts.duration_since(UNIX_EPOCH + Duration::new(1, 0)).unwrap(); + let b = ts.duration_since(UNIX_EPOCH).unwrap(); assert!(b > a); assert_eq!(b - a, Duration::new(1, 0)); From 0ea9b58029bc7c3da3f213eb9e39acdefcf12647 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 12 Mar 2019 18:18:24 -0700 Subject: [PATCH 33/58] Suggest adding lifetime to struct field --- src/librustc/middle/resolve_lifetime.rs | 9 ++++++++- src/test/ui/suggestions/return-without-lifetime.rs | 2 ++ .../ui/suggestions/return-without-lifetime.stderr | 12 +++++++++--- 3 files changed, 19 insertions(+), 4 deletions(-) diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index d03268df5e148..c9ff84ab2f08a 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -2306,7 +2306,13 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { Scope::Root => break None, - Scope::Binder { s, .. } => { + Scope::Binder { s, ref lifetimes, .. } => { + // collect named lifetimes for suggestions + for name in lifetimes.keys() { + if let hir::ParamName::Plain(name) = name { + lifetime_names.insert(*name); + } + } late_depth += 1; scope = s; } @@ -2323,6 +2329,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { Elide::Exact(l) => l.shifted(late_depth), Elide::Error(ref e) => { if let Scope::Binder { ref lifetimes, .. } = s { + // collect named lifetimes for suggestions for name in lifetimes.keys() { if let hir::ParamName::Plain(name) = name { lifetime_names.insert(*name); diff --git a/src/test/ui/suggestions/return-without-lifetime.rs b/src/test/ui/suggestions/return-without-lifetime.rs index 5f19e93013acf..9bfce11be9ea3 100644 --- a/src/test/ui/suggestions/return-without-lifetime.rs +++ b/src/test/ui/suggestions/return-without-lifetime.rs @@ -1,4 +1,6 @@ struct Thing<'a>(&'a ()); +struct Foo<'a>(&usize); +//~^ ERROR missing lifetime specifier fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() } //~^ ERROR missing lifetime specifier diff --git a/src/test/ui/suggestions/return-without-lifetime.stderr b/src/test/ui/suggestions/return-without-lifetime.stderr index 1ffe91bce05a5..7f5ff95938e30 100644 --- a/src/test/ui/suggestions/return-without-lifetime.stderr +++ b/src/test/ui/suggestions/return-without-lifetime.stderr @@ -1,5 +1,11 @@ error[E0106]: missing lifetime specifier - --> $DIR/return-without-lifetime.rs:3:34 + --> $DIR/return-without-lifetime.rs:2:16 + | +LL | struct Foo<'a>(&usize); + | ^ help: consider using the named lifetime: `&'a` + +error[E0106]: missing lifetime specifier + --> $DIR/return-without-lifetime.rs:5:34 | LL | fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() } | ^ help: consider using the named lifetime: `&'a` @@ -7,13 +13,13 @@ LL | fn func1<'a>(_arg: &'a Thing) -> &() { unimplemented!() } = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from error[E0106]: missing lifetime specifier - --> $DIR/return-without-lifetime.rs:5:35 + --> $DIR/return-without-lifetime.rs:7:35 | LL | fn func2<'a>(_arg: &Thing<'a>) -> &() { unimplemented!() } | ^ help: consider using the named lifetime: `&'a` | = help: this function's return type contains a borrowed value, but the signature does not say which one of `_arg`'s 2 lifetimes it is borrowed from -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0106`. From 266ca31f74ae343fc773b88f3bb77b601034babf Mon Sep 17 00:00:00 2001 From: Steven Malis Date: Tue, 12 Mar 2019 21:00:37 -0700 Subject: [PATCH 34/58] Stabilize Range*::contains. --- src/libcore/ops/range.rs | 49 +++++++++++++------------------- src/librustc_codegen_llvm/lib.rs | 1 - src/librustc_errors/lib.rs | 1 - src/librustc_mir/lib.rs | 1 - src/libstd/lib.rs | 2 +- 5 files changed, 20 insertions(+), 34 deletions(-) diff --git a/src/libcore/ops/range.rs b/src/libcore/ops/range.rs index 998b597d5e113..cb82ad38eb87d 100644 --- a/src/libcore/ops/range.rs +++ b/src/libcore/ops/range.rs @@ -67,7 +67,7 @@ impl fmt::Debug for RangeFull { /// assert_eq!(arr[1..3], [ 'b', 'c' ]); // Range /// ``` #[doc(alias = "..")] -#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 +#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[stable(feature = "rust1", since = "1.0.0")] pub struct Range { /// The lower bound of the range (inclusive). @@ -91,8 +91,6 @@ impl> Range { /// # Examples /// /// ``` - /// #![feature(range_contains)] - /// /// use std::f32; /// /// assert!(!(3..5).contains(&2)); @@ -108,7 +106,7 @@ impl> Range { /// assert!(!(0.0..f32::NAN).contains(&0.5)); /// assert!(!(f32::NAN..1.0).contains(&0.5)); /// ``` - #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] + #[stable(feature = "range_contains", since = "1.35.0")] pub fn contains(&self, item: &U) -> bool where Idx: PartialOrd, @@ -169,7 +167,7 @@ impl> Range { /// /// [`Iterator`]: ../iter/trait.IntoIterator.html #[doc(alias = "..")] -#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 +#[derive(Clone, PartialEq, Eq, Hash)] // not Copy -- see #27186 #[stable(feature = "rust1", since = "1.0.0")] pub struct RangeFrom { /// The lower bound of the range (inclusive). @@ -190,8 +188,6 @@ impl> RangeFrom { /// # Examples /// /// ``` - /// #![feature(range_contains)] - /// /// use std::f32; /// /// assert!(!(3..).contains(&2)); @@ -202,7 +198,7 @@ impl> RangeFrom { /// assert!(!(0.0..).contains(&f32::NAN)); /// assert!(!(f32::NAN..).contains(&0.5)); /// ``` - #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] + #[stable(feature = "range_contains", since = "1.35.0")] pub fn contains(&self, item: &U) -> bool where Idx: PartialOrd, @@ -272,8 +268,6 @@ impl> RangeTo { /// # Examples /// /// ``` - /// #![feature(range_contains)] - /// /// use std::f32; /// /// assert!( (..5).contains(&-1_000_000_000)); @@ -284,7 +278,7 @@ impl> RangeTo { /// assert!(!(..1.0).contains(&f32::NAN)); /// assert!(!(..f32::NAN).contains(&0.5)); /// ``` - #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] + #[stable(feature = "range_contains", since = "1.35.0")] pub fn contains(&self, item: &U) -> bool where Idx: PartialOrd, @@ -317,7 +311,7 @@ impl> RangeTo { /// assert_eq!(arr[1..=2], [ 1,2 ]); // RangeInclusive /// ``` #[doc(alias = "..=")] -#[derive(Clone)] // not Copy -- see #27186 +#[derive(Clone)] // not Copy -- see #27186 #[stable(feature = "inclusive_range", since = "1.26.0")] pub struct RangeInclusive { pub(crate) start: Idx, @@ -353,7 +347,8 @@ impl RangeInclusiveEquality for T { impl PartialEq for RangeInclusive { #[inline] fn eq(&self, other: &Self) -> bool { - self.start == other.start && self.end == other.end + self.start == other.start + && self.end == other.end && RangeInclusiveEquality::canonicalized_is_empty(self) == RangeInclusiveEquality::canonicalized_is_empty(other) } @@ -385,7 +380,11 @@ impl RangeInclusive { #[inline] #[rustc_promotable] pub const fn new(start: Idx, end: Idx) -> Self { - Self { start, end, is_empty: None } + Self { + start, + end, + is_empty: None, + } } /// Returns the lower bound of the range (inclusive). @@ -466,8 +465,6 @@ impl> RangeInclusive { /// # Examples /// /// ``` - /// #![feature(range_contains)] - /// /// use std::f32; /// /// assert!(!(3..=5).contains(&2)); @@ -484,7 +481,7 @@ impl> RangeInclusive { /// assert!(!(0.0..=f32::NAN).contains(&0.0)); /// assert!(!(f32::NAN..=1.0).contains(&1.0)); /// ``` - #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] + #[stable(feature = "range_contains", since = "1.35.0")] pub fn contains(&self, item: &U) -> bool where Idx: PartialOrd, @@ -593,15 +590,12 @@ impl fmt::Debug for RangeToInclusive { } } -#[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] impl> RangeToInclusive { /// Returns `true` if `item` is contained in the range. /// /// # Examples /// /// ``` - /// #![feature(range_contains)] - /// /// use std::f32; /// /// assert!( (..=5).contains(&-1_000_000_000)); @@ -612,7 +606,7 @@ impl> RangeToInclusive { /// assert!(!(..=1.0).contains(&f32::NAN)); /// assert!(!(..=f32::NAN).contains(&0.5)); /// ``` - #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] + #[stable(feature = "range_contains", since = "1.35.0")] pub fn contains(&self, item: &U) -> bool where Idx: PartialOrd, @@ -714,14 +708,11 @@ pub trait RangeBounds { #[stable(feature = "collections_range", since = "1.28.0")] fn end_bound(&self) -> Bound<&T>; - /// Returns `true` if `item` is contained in the range. /// /// # Examples /// /// ``` - /// #![feature(range_contains)] - /// /// use std::f32; /// /// assert!( (3..5).contains(&4)); @@ -731,7 +722,7 @@ pub trait RangeBounds { /// assert!(!(0.0..1.0).contains(&f32::NAN)); /// assert!(!(0.0..f32::NAN).contains(&0.5)); /// assert!(!(f32::NAN..1.0).contains(&0.5)); - #[unstable(feature = "range_contains", reason = "recently added as per RFC", issue = "32311")] + #[stable(feature = "range_contains", since = "1.35.0")] fn contains(&self, item: &U) -> bool where T: PartialOrd, @@ -741,9 +732,7 @@ pub trait RangeBounds { Included(ref start) => *start <= item, Excluded(ref start) => *start < item, Unbounded => true, - }) - && - (match self.end_bound() { + }) && (match self.end_bound() { Included(ref end) => item <= *end, Excluded(ref end) => item < *end, Unbounded => true, @@ -819,7 +808,7 @@ impl RangeBounds for (Bound, Bound) { match *self { (Included(ref start), _) => Included(start), (Excluded(ref start), _) => Excluded(start), - (Unbounded, _) => Unbounded, + (Unbounded, _) => Unbounded, } } @@ -827,7 +816,7 @@ impl RangeBounds for (Bound, Bound) { match *self { (_, Included(ref end)) => Included(end), (_, Excluded(ref end)) => Excluded(end), - (_, Unbounded) => Unbounded, + (_, Unbounded) => Unbounded, } } } diff --git a/src/librustc_codegen_llvm/lib.rs b/src/librustc_codegen_llvm/lib.rs index 7b2b9ec24ea0f..b396c6b54db3f 100644 --- a/src/librustc_codegen_llvm/lib.rs +++ b/src/librustc_codegen_llvm/lib.rs @@ -15,7 +15,6 @@ #![allow(unused_attributes)] #![feature(libc)] #![feature(nll)] -#![feature(range_contains)] #![feature(rustc_diagnostic_macros)] #![feature(optin_builtin_traits)] #![feature(concat_idents)] diff --git a/src/librustc_errors/lib.rs b/src/librustc_errors/lib.rs index 7c7698ddd3d73..6b4b437930d26 100644 --- a/src/librustc_errors/lib.rs +++ b/src/librustc_errors/lib.rs @@ -2,7 +2,6 @@ #![feature(custom_attribute)] #![allow(unused_attributes)] -#![feature(range_contains)] #![cfg_attr(unix, feature(libc))] #![feature(nll)] #![feature(optin_builtin_traits)] diff --git a/src/librustc_mir/lib.rs b/src/librustc_mir/lib.rs index 0b735b4b39cf5..c45e694ebf832 100644 --- a/src/librustc_mir/lib.rs +++ b/src/librustc_mir/lib.rs @@ -14,7 +14,6 @@ Rust MIR: a lowered representation of Rust. Also: an experiment! #![feature(const_fn)] #![feature(decl_macro)] #![feature(exhaustive_patterns)] -#![feature(range_contains)] #![feature(rustc_diagnostic_macros)] #![feature(rustc_attrs)] #![feature(never_type)] diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index e31680f23f1da..307e0c63f3415 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -221,7 +221,7 @@ #![cfg_attr(test, feature(print_internals, set_stdio, test, update_panic_count))] #![cfg_attr(all(target_vendor = "fortanix", target_env = "sgx"), - feature(global_asm, range_contains, slice_index_methods, + feature(global_asm, slice_index_methods, decl_macro, coerce_unsized, sgx_platform, ptr_wrapping_offset_from))] // std is implemented with unstable features, many of which are internal From 9d938f69362e9568c14955d7df801c21a2266e66 Mon Sep 17 00:00:00 2001 From: David Wood Date: Wed, 13 Mar 2019 12:38:10 +0100 Subject: [PATCH 35/58] Add test for #55809. This commit adds a regression test for #55809 which checks that a overflow does not occur when evaluating a requirement for async functions and `&mut` arguments in some specific circumstances. --- src/test/run-pass/issue-55809.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 src/test/run-pass/issue-55809.rs diff --git a/src/test/run-pass/issue-55809.rs b/src/test/run-pass/issue-55809.rs new file mode 100644 index 0000000000000..86b0977bebe1d --- /dev/null +++ b/src/test/run-pass/issue-55809.rs @@ -0,0 +1,30 @@ +// edition:2018 +// run-pass + +#![feature(async_await, await_macro, futures_api)] + +trait Foo { } + +impl Foo for () { } + +impl<'a, T> Foo for &'a mut T where T: Foo { } + +async fn foo_async(_v: T) -> u8 where T: Foo { + 0 +} + +async fn bad(v: T) -> u8 where T: Foo { + await!(foo_async(v)) +} + +async fn async_main() { + let mut v = (); + + let _ = await!(bad(&mut v)); + let _ = await!(foo_async(&mut v)); + let _ = await!(bad(v)); +} + +fn main() { + let _ = async_main(); +} From 311025e6a5aad80d028f0771970c43cb4ed025a8 Mon Sep 17 00:00:00 2001 From: Angelos Oikonomopoulos Date: Thu, 7 Mar 2019 18:30:26 +0100 Subject: [PATCH 36/58] Fix generic argument lookup for Self Rewrite the SelfCtor early and use the replacement Def when calculating the path_segs. Note that this also changes which def is seen by the code that computes user_self_ty and is_alias_variant_ctor; I don't see a immediate issue with that, but I'm not 100% clear on the implications. Fixes #57924 --- src/librustc_typeck/check/mod.rs | 119 ++++++++++++------------ src/test/run-pass/issues/issue-57924.rs | 9 ++ 2 files changed, 69 insertions(+), 59 deletions(-) create mode 100644 src/test/run-pass/issues/issue-57924.rs diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 301d7d3ac5623..7dfe9f40d318f 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -5302,6 +5302,53 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { Some(original_span.with_lo(original_span.hi() - BytePos(1))) } + // Rewrite `SelfCtor` to `StructCtor` + pub fn rewrite_self_ctor(&self, def: Def, span: Span) -> (Def, DefId, Ty<'tcx>) { + let tcx = self.tcx; + if let Def::SelfCtor(impl_def_id) = def { + let ty = self.impl_self_ty(span, impl_def_id).ty; + let adt_def = ty.ty_adt_def(); + + match adt_def { + Some(adt_def) if adt_def.has_ctor() => { + let variant = adt_def.non_enum_variant(); + let def = Def::StructCtor(variant.did, variant.ctor_kind); + (def, variant.did, tcx.type_of(variant.did)) + } + _ => { + let mut err = tcx.sess.struct_span_err(span, + "the `Self` constructor can only be used with tuple or unit structs"); + if let Some(adt_def) = adt_def { + match adt_def.adt_kind() { + AdtKind::Enum => { + err.help("did you mean to use one of the enum's variants?"); + }, + AdtKind::Struct | + AdtKind::Union => { + err.span_suggestion( + span, + "use curly brackets", + String::from("Self { /* fields */ }"), + Applicability::HasPlaceholders, + ); + } + } + } + err.emit(); + + (def, impl_def_id, tcx.types.err) + } + } + } else { + let def_id = def.def_id(); + + // The things we are substituting into the type should not contain + // escaping late-bound regions, and nor should the base type scheme. + let ty = tcx.type_of(def_id); + (def, def_id, ty) + } + } + // Instantiates the given path, which must refer to an item with the given // number of type parameters and type. pub fn instantiate_value_path(&self, @@ -5321,6 +5368,18 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let tcx = self.tcx; + match def { + Def::Local(nid) | Def::Upvar(nid, ..) => { + let hid = self.tcx.hir().node_to_hir_id(nid); + let ty = self.local_ty(span, hid).decl_ty; + let ty = self.normalize_associated_types_in(span, &ty); + self.write_ty(hir_id, ty); + return (ty, def); + } + _ => {} + } + + let (def, def_id, ty) = self.rewrite_self_ctor(def, span); let path_segs = AstConv::def_ids_for_path_segments(self, segments, self_ty, def); let mut user_self_ty = None; @@ -5382,17 +5441,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { user_self_ty = None; } - match def { - Def::Local(nid) | Def::Upvar(nid, ..) => { - let hid = self.tcx.hir().node_to_hir_id(nid); - let ty = self.local_ty(span, hid).decl_ty; - let ty = self.normalize_associated_types_in(span, &ty); - self.write_ty(hir_id, ty); - return (ty, def); - } - _ => {} - } - // Now we have to compare the types that the user *actually* // provided against the types that were *expected*. If the user // did not provide any types, then we want to substitute inference @@ -5425,53 +5473,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { tcx.generics_of(*def_id).has_self }).unwrap_or(false); - let mut new_def = def; - let (def_id, ty) = match def { - Def::SelfCtor(impl_def_id) => { - let ty = self.impl_self_ty(span, impl_def_id).ty; - let adt_def = ty.ty_adt_def(); - - match adt_def { - Some(adt_def) if adt_def.has_ctor() => { - let variant = adt_def.non_enum_variant(); - new_def = Def::StructCtor(variant.did, variant.ctor_kind); - (variant.did, tcx.type_of(variant.did)) - } - _ => { - let mut err = tcx.sess.struct_span_err(span, - "the `Self` constructor can only be used with tuple or unit structs"); - if let Some(adt_def) = adt_def { - match adt_def.adt_kind() { - AdtKind::Enum => { - err.help("did you mean to use one of the enum's variants?"); - }, - AdtKind::Struct | - AdtKind::Union => { - err.span_suggestion( - span, - "use curly brackets", - String::from("Self { /* fields */ }"), - Applicability::HasPlaceholders, - ); - } - } - } - err.emit(); - - (impl_def_id, tcx.types.err) - } - } - } - _ => { - let def_id = def.def_id(); - - // The things we are substituting into the type should not contain - // escaping late-bound regions, and nor should the base type scheme. - let ty = tcx.type_of(def_id); - (def_id, ty) - } - }; - let substs = AstConv::create_substs_for_generic_args( tcx, def_id, @@ -5587,7 +5588,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { ty_substituted); self.write_substs(hir_id, substs); - (ty_substituted, new_def) + (ty_substituted, def) } fn check_rustc_args_require_const(&self, diff --git a/src/test/run-pass/issues/issue-57924.rs b/src/test/run-pass/issues/issue-57924.rs new file mode 100644 index 0000000000000..232596334b0ed --- /dev/null +++ b/src/test/run-pass/issues/issue-57924.rs @@ -0,0 +1,9 @@ +pub struct Gcm(E); + +impl Gcm { + pub fn crash(e: E) -> Self { + Self::(e) + } +} + +fn main() {} From c37dab7df82e38788648044017ba6dc48c240776 Mon Sep 17 00:00:00 2001 From: Manish Goregaokar Date: Wed, 13 Mar 2019 07:39:07 -0700 Subject: [PATCH 37/58] Revert "Don't generate minification variable if minification disabled" Fixes #59157 This reverts commit b5ae4d58883151a977487de86856d9529df9d948. --- src/librustdoc/html/render.rs | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index d711e4514a049..5109e775ebf81 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -1117,11 +1117,7 @@ themePicker.onblur = handleThemeButtonsBlur; // with rustdoc running in parallel. all_indexes.sort(); let mut w = try_err!(File::create(&dst), &dst); - if options.enable_minification { - try_err!(writeln!(&mut w, "var N=null,E=\"\",T=\"t\",U=\"u\",searchIndex={{}};"), &dst); - } else { - try_err!(writeln!(&mut w, "var searchIndex={{}};"), &dst); - } + try_err!(writeln!(&mut w, "var N=null,E=\"\",T=\"t\",U=\"u\",searchIndex={{}};"), &dst); try_err!(write_minify_replacer(&mut w, &format!("{}\n{}", variables.join(""), all_indexes.join("\n")), options.enable_minification), From 5abd6d9492e8a5a4592bca4c18e1de6104b1ea51 Mon Sep 17 00:00:00 2001 From: Andy Russell Date: Sun, 10 Mar 2019 21:01:53 -0400 Subject: [PATCH 38/58] add suggestions to invalid macro item error --- src/libsyntax/parse/parser.rs | 45 ++++++++++--------- src/test/ui/issues/issue-10536.rs | 2 +- src/test/ui/issues/issue-10536.stderr | 10 ++++- .../ui/parser/macros-no-semicolon-items.rs | 11 +++++ .../parser/macros-no-semicolon-items.stderr | 41 ++++++++++++++++- 5 files changed, 85 insertions(+), 24 deletions(-) diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index fe31311094b89..22af7d47fd0a1 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -5116,12 +5116,8 @@ impl<'a> Parser<'a> { let ident = self.parse_ident()?; let (delim, tokens) = self.expect_delimited_token_tree()?; - if delim != MacDelimiter::Brace { - if !self.eat(&token::Semi) { - let msg = "macros that expand to items must either \ - be surrounded with braces or followed by a semicolon"; - self.span_err(self.prev_span, msg); - } + if delim != MacDelimiter::Brace && !self.eat(&token::Semi) { + self.report_invalid_macro_expansion_item(); } (ident, ast::MacroDef { tokens: tokens, legacy: true }) @@ -5264,13 +5260,8 @@ impl<'a> Parser<'a> { // if it has a special ident, it's definitely an item // // Require a semicolon or braces. - if style != MacStmtStyle::Braces { - if !self.eat(&token::Semi) { - self.span_err(self.prev_span, - "macros that expand to items must \ - either be surrounded with braces or \ - followed by a semicolon"); - } + if style != MacStmtStyle::Braces && !self.eat(&token::Semi) { + self.report_invalid_macro_expansion_item(); } let span = lo.to(hi); Stmt { @@ -8360,13 +8351,8 @@ impl<'a> Parser<'a> { }; // eat a matched-delimiter token tree: let (delim, tts) = self.expect_delimited_token_tree()?; - if delim != MacDelimiter::Brace { - if !self.eat(&token::Semi) { - self.span_err(self.prev_span, - "macros that expand to items must either \ - be surrounded with braces or followed by \ - a semicolon"); - } + if delim != MacDelimiter::Brace && !self.eat(&token::Semi) { + self.report_invalid_macro_expansion_item(); } let hi = self.prev_span; @@ -8597,6 +8583,25 @@ impl<'a> Parser<'a> { } } } + + fn report_invalid_macro_expansion_item(&self) { + self.struct_span_err( + self.prev_span, + "macros that expand to items must be delimited with braces or followed by a semicolon", + ).multipart_suggestion( + "change the delimiters to curly braces", + vec![ + (self.prev_span.with_hi(self.prev_span.lo() + BytePos(1)), String::from(" {")), + (self.prev_span.with_lo(self.prev_span.hi() - BytePos(1)), '}'.to_string()), + ], + Applicability::MaybeIncorrect, + ).span_suggestion( + self.sess.source_map.next_point(self.prev_span), + "add a semicolon", + ';'.to_string(), + Applicability::MaybeIncorrect, + ).emit(); + } } pub fn emit_unclosed_delims(unclosed_delims: &mut Vec, handler: &errors::Handler) { diff --git a/src/test/ui/issues/issue-10536.rs b/src/test/ui/issues/issue-10536.rs index 95c8c2b0585b6..ceb44ecf7f583 100644 --- a/src/test/ui/issues/issue-10536.rs +++ b/src/test/ui/issues/issue-10536.rs @@ -12,7 +12,7 @@ pub fn main() { foo!(); assert!({one! two()}); - //~^ ERROR macros that expand to items must either be surrounded with braces or followed by a + //~^ ERROR macros that expand to items //~| ERROR cannot find macro `one!` in this scope //~| ERROR mismatched types diff --git a/src/test/ui/issues/issue-10536.stderr b/src/test/ui/issues/issue-10536.stderr index d5caf777cd45e..584cdf43a8f4b 100644 --- a/src/test/ui/issues/issue-10536.stderr +++ b/src/test/ui/issues/issue-10536.stderr @@ -1,8 +1,16 @@ -error: macros that expand to items must either be surrounded with braces or followed by a semicolon +error: macros that expand to items must be delimited with braces or followed by a semicolon --> $DIR/issue-10536.rs:14:22 | LL | assert!({one! two()}); | ^^ +help: change the delimiters to curly braces + | +LL | assert!({one! two {}}); + | ^^ +help: add a semicolon + | +LL | assert!({one! two();}); + | ^ error: expected `(` or `{`, found `}` --> $DIR/issue-10536.rs:21:22 diff --git a/src/test/ui/parser/macros-no-semicolon-items.rs b/src/test/ui/parser/macros-no-semicolon-items.rs index a727cafcab023..3afc275d61a2b 100644 --- a/src/test/ui/parser/macros-no-semicolon-items.rs +++ b/src/test/ui/parser/macros-no-semicolon-items.rs @@ -1,4 +1,15 @@ macro_rules! foo() //~ ERROR semicolon + //~| ERROR unexpected end of macro + +macro_rules! bar { + ($($tokens:tt)*) => {} +} + +bar!( //~ ERROR semicolon + blah + blah + blah +) fn main() { } diff --git a/src/test/ui/parser/macros-no-semicolon-items.stderr b/src/test/ui/parser/macros-no-semicolon-items.stderr index a869a53c1eee2..5276aa6f5e9e9 100644 --- a/src/test/ui/parser/macros-no-semicolon-items.stderr +++ b/src/test/ui/parser/macros-no-semicolon-items.stderr @@ -1,8 +1,45 @@ -error: macros that expand to items must either be surrounded with braces or followed by a semicolon +error: macros that expand to items must be delimited with braces or followed by a semicolon --> $DIR/macros-no-semicolon-items.rs:1:17 | LL | macro_rules! foo() | ^^ +help: change the delimiters to curly braces + | +LL | macro_rules! foo {} + | ^^ +help: add a semicolon + | +LL | macro_rules! foo(); + | ^ + +error: macros that expand to items must be delimited with braces or followed by a semicolon + --> $DIR/macros-no-semicolon-items.rs:8:5 + | +LL | bar!( + | _____^ +LL | | blah +LL | | blah +LL | | blah +LL | | ) + | |_^ +help: change the delimiters to curly braces + | +LL | bar! { +LL | blah +LL | blah +LL | blah +LL | } + | +help: add a semicolon + | +LL | ); + | ^ + +error: unexpected end of macro invocation + --> $DIR/macros-no-semicolon-items.rs:1:1 + | +LL | macro_rules! foo() + | ^^^^^^^^^^^^^^^^^^ missing tokens in macro arguments -error: aborting due to previous error +error: aborting due to 3 previous errors From e7b7c417e639a2070ae91c2b84e0574beafb0bb7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Emilio=20Cobos=20=C3=81lvarez?= Date: Thu, 14 Mar 2019 02:23:08 +0100 Subject: [PATCH 39/58] bootstrap: Default to a sensible llvm-suffix. I used version-channel-sha, hopefully that should work. I checked that bootstrap builds, but I cannot check anything else since the llvm build process is started from cargo, and thus calls clang, and thus I hit the same bug I hope to fix with this change. Hopefully fixes #59034. --- src/bootstrap/lib.rs | 6 ++++++ src/bootstrap/native.rs | 22 +++++++++++++++++++++- 2 files changed, 27 insertions(+), 1 deletion(-) diff --git a/src/bootstrap/lib.rs b/src/bootstrap/lib.rs index 9317a40545eac..976b30a55c94b 100644 --- a/src/bootstrap/lib.rs +++ b/src/bootstrap/lib.rs @@ -241,6 +241,8 @@ pub struct Build { clippy_info: channel::GitInfo, miri_info: channel::GitInfo, rustfmt_info: channel::GitInfo, + in_tree_llvm_info: channel::GitInfo, + emscripten_llvm_info: channel::GitInfo, local_rebuild: bool, fail_fast: bool, doc_tests: DocTests, @@ -363,6 +365,8 @@ impl Build { let clippy_info = channel::GitInfo::new(&config, &src.join("src/tools/clippy")); let miri_info = channel::GitInfo::new(&config, &src.join("src/tools/miri")); let rustfmt_info = channel::GitInfo::new(&config, &src.join("src/tools/rustfmt")); + let in_tree_llvm_info = channel::GitInfo::new(&config, &src.join("src/llvm-project")); + let emscripten_llvm_info = channel::GitInfo::new(&config, &src.join("src/llvm-emscripten")); let mut build = Build { initial_rustc: config.initial_rustc.clone(), @@ -386,6 +390,8 @@ impl Build { clippy_info, miri_info, rustfmt_info, + in_tree_llvm_info, + emscripten_llvm_info, cc: HashMap::new(), cxx: HashMap::new(), ar: HashMap::new(), diff --git a/src/bootstrap/native.rs b/src/bootstrap/native.rs index d78670cfe515a..3babbc9e10231 100644 --- a/src/bootstrap/native.rs +++ b/src/bootstrap/native.rs @@ -18,6 +18,7 @@ use build_helper::output; use cmake; use cc; +use crate::channel; use crate::util::{self, exe}; use build_helper::up_to_date; use crate::builder::{Builder, RunConfig, ShouldRun, Step}; @@ -231,7 +232,26 @@ impl Step for Llvm { } if let Some(ref suffix) = builder.config.llvm_version_suffix { - cfg.define("LLVM_VERSION_SUFFIX", suffix); + // Allow version-suffix="" to not define a version suffix at all. + if !suffix.is_empty() { + cfg.define("LLVM_VERSION_SUFFIX", suffix); + } + } else { + let mut default_suffix = format!( + "-rust-{}-{}", + channel::CFG_RELEASE_NUM, + builder.config.channel, + ); + let llvm_info = if self.emscripten { + &builder.emscripten_llvm_info + } else { + &builder.in_tree_llvm_info + }; + if let Some(sha) = llvm_info.sha_short() { + default_suffix.push_str("-"); + default_suffix.push_str(sha); + } + cfg.define("LLVM_VERSION_SUFFIX", default_suffix); } if let Some(ref linker) = builder.config.llvm_use_linker { From 88d43a052a9230230bb263ff0b7b072134203510 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 14 Mar 2019 05:53:44 +0100 Subject: [PATCH 40/58] Don't run test launching `echo` since that doesn't exist on Windows --- src/libstd/process.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/process.rs b/src/libstd/process.rs index 568400093440c..ad86acbb47de4 100644 --- a/src/libstd/process.rs +++ b/src/libstd/process.rs @@ -8,7 +8,7 @@ //! //! The [`Command`] struct is used to configure and spawn processes: //! -//! ``` +//! ```no_run //! use std::process::Command; //! //! let output = Command::new("echo") From 41cdf07483ed39ccd85ce1c9ae7512ceb3bbb657 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?John=20K=C3=A5re=20Alsaker?= Date: Thu, 14 Mar 2019 06:35:48 +0100 Subject: [PATCH 41/58] Run RustdocUi earlier --- src/bootstrap/builder.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/bootstrap/builder.rs b/src/bootstrap/builder.rs index ffd23e72e80a6..daa6749f87f3e 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -408,11 +408,11 @@ impl<'a> Builder<'a> { test::RustdocJSStd, test::RustdocJSNotStd, test::RustdocTheme, + test::RustdocUi, // Run bootstrap close to the end as it's unlikely to fail test::Bootstrap, // Run run-make last, since these won't pass without make on Windows test::RunMake, - test::RustdocUi ), Kind::Bench => describe!(test::Crate, test::CrateLibrustc), Kind::Doc => describe!( From ab19e5870ea28584ecf3ff4885e29afbbcaf0854 Mon Sep 17 00:00:00 2001 From: Taiki Endo Date: Thu, 14 Mar 2019 23:12:56 +0900 Subject: [PATCH 42/58] Use try blocks in rustc_codegen_ssa --- src/librustc_codegen_ssa/back/linker.rs | 15 ++++++--------- src/librustc_codegen_ssa/lib.rs | 1 + 2 files changed, 7 insertions(+), 9 deletions(-) diff --git a/src/librustc_codegen_ssa/back/linker.rs b/src/librustc_codegen_ssa/back/linker.rs index 1f4c5543fa9aa..e6470dbb61ce1 100644 --- a/src/librustc_codegen_ssa/back/linker.rs +++ b/src/librustc_codegen_ssa/back/linker.rs @@ -382,20 +382,19 @@ impl<'a> Linker for GccLinker<'a> { if self.sess.target.target.options.is_like_osx { // Write a plain, newline-separated list of symbols - let res = (|| -> io::Result<()> { + let res: io::Result<()> = try { let mut f = BufWriter::new(File::create(&path)?); for sym in self.info.exports[&crate_type].iter() { debug!(" _{}", sym); writeln!(f, "_{}", sym)?; } - Ok(()) - })(); + }; if let Err(e) = res { self.sess.fatal(&format!("failed to write lib.def file: {}", e)); } } else { // Write an LD version script - let res = (|| -> io::Result<()> { + let res: io::Result<()> = try { let mut f = BufWriter::new(File::create(&path)?); writeln!(f, "{{\n global:")?; for sym in self.info.exports[&crate_type].iter() { @@ -403,8 +402,7 @@ impl<'a> Linker for GccLinker<'a> { writeln!(f, " {};", sym)?; } writeln!(f, "\n local:\n *;\n}};")?; - Ok(()) - })(); + }; if let Err(e) = res { self.sess.fatal(&format!("failed to write version script: {}", e)); } @@ -644,7 +642,7 @@ impl<'a> Linker for MsvcLinker<'a> { tmpdir: &Path, crate_type: CrateType) { let path = tmpdir.join("lib.def"); - let res = (|| -> io::Result<()> { + let res: io::Result<()> = try { let mut f = BufWriter::new(File::create(&path)?); // Start off with the standard module name header and then go @@ -655,8 +653,7 @@ impl<'a> Linker for MsvcLinker<'a> { debug!(" _{}", symbol); writeln!(f, " {}", symbol)?; } - Ok(()) - })(); + }; if let Err(e) = res { self.sess.fatal(&format!("failed to write lib.def file: {}", e)); } diff --git a/src/librustc_codegen_ssa/lib.rs b/src/librustc_codegen_ssa/lib.rs index fec41936a2384..fe9b88c85f009 100644 --- a/src/librustc_codegen_ssa/lib.rs +++ b/src/librustc_codegen_ssa/lib.rs @@ -7,6 +7,7 @@ #![feature(libc)] #![feature(rustc_diagnostic_macros)] #![feature(stmt_expr_attributes)] +#![feature(try_blocks)] #![feature(in_band_lifetimes)] #![feature(nll)] #![allow(unused_attributes)] From d1fcd867386f40af25cd66f5d4a2dfcd028d858d Mon Sep 17 00:00:00 2001 From: lukaslueg Date: Thu, 14 Mar 2019 17:06:46 +0100 Subject: [PATCH 43/58] Update sources.rs The current language may be amusing, yet is just imprecise and most especially difficult to understand for someone who speaks English as a foreign language. --- src/libcore/iter/sources.rs | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/src/libcore/iter/sources.rs b/src/libcore/iter/sources.rs index 74ff7f41d76fa..ffc24df3ed42e 100644 --- a/src/libcore/iter/sources.rs +++ b/src/libcore/iter/sources.rs @@ -39,8 +39,7 @@ unsafe impl TrustedLen for Repeat {} /// Creates a new iterator that endlessly repeats a single element. /// -/// The `repeat()` function repeats a single value over and over and over and -/// over and over and 🔁. +/// The `repeat()` function repeats a single value over and over again. /// /// Infinite iterators like `repeat()` are often used with adapters like /// [`take`], in order to make them finite. @@ -128,8 +127,7 @@ unsafe impl A> TrustedLen for RepeatWith {} /// Creates a new iterator that repeats elements of type `A` endlessly by /// applying the provided closure, the repeater, `F: FnMut() -> A`. /// -/// The `repeat_with()` function calls the repeater over and over and over and -/// over and over and 🔁. +/// The `repeat_with()` function calls the repeater over and over again. /// /// Infinite iterators like `repeat_with()` are often used with adapters like /// [`take`], in order to make them finite. From fa8fd3daa7efefd4036a377f48f755be0b6952ee Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Thu, 14 Mar 2019 15:05:49 -0700 Subject: [PATCH 44/58] Add support for comma-separated option lists --- src/librustc/session/config.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 55c4b0e54b822..d39057cbf92ed 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -800,6 +800,7 @@ macro_rules! options { pub const parse_opt_pathbuf: Option<&str> = Some("a path"); pub const parse_list: Option<&str> = Some("a space-separated list of strings"); pub const parse_opt_list: Option<&str> = Some("a space-separated list of strings"); + pub const parse_opt_comma_list: Option<&str> = Some("a comma-separated list of strings"); pub const parse_uint: Option<&str> = Some("a number"); pub const parse_passes: Option<&str> = Some("a space-separated list of passes, or `all`"); @@ -926,6 +927,18 @@ macro_rules! options { } } + fn parse_opt_comma_list(slot: &mut Option>, v: Option<&str>) + -> bool { + match v { + Some(s) => { + let v = s.split(',').map(|s| s.to_string()).collect(); + *slot = Some(v); + true + }, + None => false, + } + } + fn parse_uint(slot: &mut usize, v: Option<&str>) -> bool { match v.and_then(|s| s.parse().ok()) { Some(i) => { *slot = i; true }, From 7c59ce9f5db9cb7dbfbd07fab625e2b67aa042f5 Mon Sep 17 00:00:00 2001 From: Tyler Mandry Date: Wed, 13 Mar 2019 16:29:24 -0700 Subject: [PATCH 45/58] Add `-Z allow_features=...` flag --- src/librustc/session/config.rs | 6 ++++++ src/librustc_interface/passes.rs | 1 + src/libsyntax/config.rs | 6 +++--- src/libsyntax/diagnostic_list.rs | 15 +++++++++++++ src/libsyntax/feature_gate.rs | 11 +++++++++- .../ui/feature-gate/allow-features-empty.rs | 10 +++++++++ .../feature-gate/allow-features-empty.stderr | 21 +++++++++++++++++++ src/test/ui/feature-gate/allow-features.rs | 10 +++++++++ .../ui/feature-gate/allow-features.stderr | 9 ++++++++ 9 files changed, 85 insertions(+), 4 deletions(-) create mode 100644 src/test/ui/feature-gate/allow-features-empty.rs create mode 100644 src/test/ui/feature-gate/allow-features-empty.stderr create mode 100644 src/test/ui/feature-gate/allow-features.rs create mode 100644 src/test/ui/feature-gate/allow-features.stderr diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index d39057cbf92ed..ff18678f091b9 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -1440,6 +1440,8 @@ options! {DebuggingOptions, DebuggingSetter, basic_debugging_options, merge_functions: Option = (None, parse_merge_functions, [TRACKED], "control the operation of the MergeFunctions LLVM pass, taking the same values as the target option of the same name"), + allow_features: Option> = (None, parse_opt_comma_list, [TRACKED], + "only allow the listed language features to be enabled in code (space separated)"), } pub fn default_lib_output() -> CrateType { @@ -3286,6 +3288,10 @@ mod tests { opts = reference.clone(); opts.debugging_opts.merge_functions = Some(MergeFunctions::Disabled); assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); + + opts = reference.clone(); + opts.debugging_opts.allow_features = Some(vec![String::from("lang_items")]); + assert!(reference.dep_tracking_hash() != opts.dep_tracking_hash()); } #[test] diff --git a/src/librustc_interface/passes.rs b/src/librustc_interface/passes.rs index 5bb47bda17b33..0c710fd283be8 100644 --- a/src/librustc_interface/passes.rs +++ b/src/librustc_interface/passes.rs @@ -243,6 +243,7 @@ pub fn register_plugins<'a>( krate, &sess.parse_sess, sess.edition(), + &sess.opts.debugging_opts.allow_features, ); // these need to be set "early" so that expansion sees `quote` if enabled. sess.init_features(features); diff --git a/src/libsyntax/config.rs b/src/libsyntax/config.rs index 4e4432a3f334d..2abb7e407eb02 100644 --- a/src/libsyntax/config.rs +++ b/src/libsyntax/config.rs @@ -24,8 +24,8 @@ pub struct StripUnconfigured<'a> { } // `cfg_attr`-process the crate's attributes and compute the crate's features. -pub fn features(mut krate: ast::Crate, sess: &ParseSess, edition: Edition) - -> (ast::Crate, Features) { +pub fn features(mut krate: ast::Crate, sess: &ParseSess, edition: Edition, + allow_features: &Option>) -> (ast::Crate, Features) { let features; { let mut strip_unconfigured = StripUnconfigured { @@ -43,7 +43,7 @@ pub fn features(mut krate: ast::Crate, sess: &ParseSess, edition: Edition) return (krate, Features::new()); } - features = get_features(&sess.span_diagnostic, &krate.attrs, edition); + features = get_features(&sess.span_diagnostic, &krate.attrs, edition, allow_features); // Avoid reconfiguring malformed `cfg_attr`s if err_count == sess.span_diagnostic.err_count() { diff --git a/src/libsyntax/diagnostic_list.rs b/src/libsyntax/diagnostic_list.rs index 2c367f1f40242..ac24475cab89f 100644 --- a/src/libsyntax/diagnostic_list.rs +++ b/src/libsyntax/diagnostic_list.rs @@ -378,6 +378,21 @@ Erroneous code example: "##, +E0725: r##" +A feature attribute named a feature that was disallowed in the compiler +command line flags. + +Erroneous code example: + +```ignore (can't specify compiler flags from doctests) +#![feature(never_type)] // error: the feature `never_type` is not in + // the list of allowed features +``` + +Delete the offending feature attribute, or add it to the list of allowed +features in the `-Z allow_features` flag. +"##, + } register_diagnostics! { diff --git a/src/libsyntax/feature_gate.rs b/src/libsyntax/feature_gate.rs index 279e2089f5d71..77e8e75d8321b 100644 --- a/src/libsyntax/feature_gate.rs +++ b/src/libsyntax/feature_gate.rs @@ -2008,7 +2008,7 @@ impl<'a> Visitor<'a> for PostExpansionVisitor<'a> { } pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], - crate_edition: Edition) -> Features { + crate_edition: Edition, allow_features: &Option>) -> Features { fn feature_removed(span_handler: &Handler, span: Span, reason: Option<&str>) { let mut err = struct_span_err!(span_handler, span, E0557, "feature has been removed"); if let Some(reason) = reason { @@ -2127,6 +2127,15 @@ pub fn get_features(span_handler: &Handler, krate_attrs: &[ast::Attribute], } if let Some((.., set)) = ACTIVE_FEATURES.iter().find(|f| name == f.0) { + if let Some(allowed) = allow_features.as_ref() { + if allowed.iter().find(|f| *f == name.as_str()).is_none() { + span_err!(span_handler, mi.span, E0725, + "the feature `{}` is not in the list of allowed features", + name); + continue; + } + } + set(&mut features, mi.span); features.declared_lang_features.push((name, mi.span, None)); continue diff --git a/src/test/ui/feature-gate/allow-features-empty.rs b/src/test/ui/feature-gate/allow-features-empty.rs new file mode 100644 index 0000000000000..83250052cb506 --- /dev/null +++ b/src/test/ui/feature-gate/allow-features-empty.rs @@ -0,0 +1,10 @@ +// compile-flags: -Z allow_features= +// Note: This test uses rustc internal flags because they will never stabilize. + +#![feature(rustc_diagnostic_macros)] //~ ERROR + +#![feature(rustc_const_unstable)] //~ ERROR + +#![feature(lang_items)] //~ ERROR + +fn main() {} diff --git a/src/test/ui/feature-gate/allow-features-empty.stderr b/src/test/ui/feature-gate/allow-features-empty.stderr new file mode 100644 index 0000000000000..cce2c4078c242 --- /dev/null +++ b/src/test/ui/feature-gate/allow-features-empty.stderr @@ -0,0 +1,21 @@ +error[E0725]: the feature `rustc_diagnostic_macros` is not in the list of allowed features + --> $DIR/allow-features-empty.rs:4:12 + | +LL | #![feature(rustc_diagnostic_macros)] + | ^^^^^^^^^^^^^^^^^^^^^^^ + +error[E0725]: the feature `rustc_const_unstable` is not in the list of allowed features + --> $DIR/allow-features-empty.rs:6:12 + | +LL | #![feature(rustc_const_unstable)] + | ^^^^^^^^^^^^^^^^^^^^ + +error[E0725]: the feature `lang_items` is not in the list of allowed features + --> $DIR/allow-features-empty.rs:8:12 + | +LL | #![feature(lang_items)] + | ^^^^^^^^^^ + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0725`. diff --git a/src/test/ui/feature-gate/allow-features.rs b/src/test/ui/feature-gate/allow-features.rs new file mode 100644 index 0000000000000..1cebc8f34f26f --- /dev/null +++ b/src/test/ui/feature-gate/allow-features.rs @@ -0,0 +1,10 @@ +// compile-flags: -Z allow_features=rustc_diagnostic_macros,lang_items +// Note: This test uses rustc internal flags because they will never stabilize. + +#![feature(rustc_diagnostic_macros)] + +#![feature(rustc_const_unstable)] //~ ERROR + +#![feature(lang_items)] + +fn main() {} diff --git a/src/test/ui/feature-gate/allow-features.stderr b/src/test/ui/feature-gate/allow-features.stderr new file mode 100644 index 0000000000000..b13560fb81c6a --- /dev/null +++ b/src/test/ui/feature-gate/allow-features.stderr @@ -0,0 +1,9 @@ +error[E0725]: the feature `rustc_const_unstable` is not in the list of allowed features + --> $DIR/allow-features.rs:6:12 + | +LL | #![feature(rustc_const_unstable)] + | ^^^^^^^^^^^^^^^^^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0725`. From bcf1a179aed651fe27fef7578bfc25b063a33a8e Mon Sep 17 00:00:00 2001 From: O01eg Date: Fri, 15 Mar 2019 08:50:08 +0300 Subject: [PATCH 46/58] Output diagnostic information for rustdoc. Use the information same as rustc. --- src/bootstrap/bin/rustdoc.rs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/bootstrap/bin/rustdoc.rs b/src/bootstrap/bin/rustdoc.rs index 36beec3a944a0..085f243785cbe 100644 --- a/src/bootstrap/bin/rustdoc.rs +++ b/src/bootstrap/bin/rustdoc.rs @@ -35,7 +35,7 @@ fn main() { .arg("--cfg") .arg("dox") .arg("--sysroot") - .arg(sysroot) + .arg(&sysroot) .env(bootstrap::util::dylib_path_var(), env::join_paths(&dylib_path).unwrap()); @@ -72,7 +72,13 @@ fn main() { } if verbose > 1 { - eprintln!("rustdoc command: {:?}", cmd); + eprintln!( + "rustdoc command: {:?}={:?} {:?}", + bootstrap::util::dylib_path_var(), + env::join_paths(&dylib_path).unwrap(), + cmd, + ); + eprintln!("sysroot: {:?}", sysroot); eprintln!("libdir: {:?}", libdir); } From 9445f2bf719d4f6064d9d79349e21822c6293d3c Mon Sep 17 00:00:00 2001 From: sntdevco Date: Fri, 15 Mar 2019 16:37:53 +0530 Subject: [PATCH 47/58] Improved test output for liballoc/str --- src/liballoc/tests/str.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/liballoc/tests/str.rs b/src/liballoc/tests/str.rs index b33a564218888..f465d67dc9368 100644 --- a/src/liballoc/tests/str.rs +++ b/src/liballoc/tests/str.rs @@ -7,7 +7,7 @@ fn test_le() { assert!("" <= ""); assert!("" <= "foo"); assert!("foo" <= "foo"); - assert!("foo" != "bar"); + assert_ne!("foo", "bar"); } #[test] From 6d73a8f753fb68bb7da4b2c35908d0512a981db9 Mon Sep 17 00:00:00 2001 From: sntdevco Date: Fri, 15 Mar 2019 16:38:07 +0530 Subject: [PATCH 48/58] Improved test output for libcore/cell --- src/libcore/tests/cell.rs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/src/libcore/tests/cell.rs b/src/libcore/tests/cell.rs index b16416022c04e..085d81a36d185 100644 --- a/src/libcore/tests/cell.rs +++ b/src/libcore/tests/cell.rs @@ -5,15 +5,15 @@ use std::mem::drop; #[test] fn smoketest_cell() { let x = Cell::new(10); - assert!(x == Cell::new(10)); - assert!(x.get() == 10); + assert_eq!(x, Cell::new(10)); + assert_eq!(x.get(), 10); x.set(20); - assert!(x == Cell::new(20)); - assert!(x.get() == 20); + assert_eq!(x, Cell::new(20)); + assert_eq!(x.get(), 20); let y = Cell::new((30, 40)); - assert!(y == Cell::new((30, 40))); - assert!(y.get() == (30, 40)); + assert_eq!(y, Cell::new((30, 40))); + assert_eq!(y.get(), (30, 40)); } #[test] From 8ff2198bc7a8a0a986e0df930422d9aa63b1bcd3 Mon Sep 17 00:00:00 2001 From: sntdevco Date: Fri, 15 Mar 2019 16:38:23 +0530 Subject: [PATCH 49/58] Improved test output for libcore/ops --- src/libcore/tests/ops.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libcore/tests/ops.rs b/src/libcore/tests/ops.rs index 401644e120d16..78cf07119e729 100644 --- a/src/libcore/tests/ops.rs +++ b/src/libcore/tests/ops.rs @@ -7,11 +7,11 @@ fn test_range() { let r = Range { start: 2, end: 10 }; let mut count = 0; for (i, ri) in r.enumerate() { - assert!(ri == i + 2); + assert_eq!(ri, i + 2); assert!(ri >= 2 && ri < 10); count += 1; } - assert!(count == 8); + assert_eq!(count, 8); } #[test] @@ -19,11 +19,11 @@ fn test_range_from() { let r = RangeFrom { start: 2 }; let mut count = 0; for (i, ri) in r.take(10).enumerate() { - assert!(ri == i + 2); + assert_eq!(ri, i + 2); assert!(ri >= 2 && ri < 12); count += 1; } - assert!(count == 10); + assert_eq!(count, 10); } #[test] From 2f5238867186b7e30a3baff0086b25c9cf7407b7 Mon Sep 17 00:00:00 2001 From: sntdevco Date: Fri, 15 Mar 2019 16:38:37 +0530 Subject: [PATCH 50/58] Improved test output for libcore/num/int_macros --- src/libcore/tests/num/int_macros.rs | 48 ++++++++++++++--------------- 1 file changed, 24 insertions(+), 24 deletions(-) diff --git a/src/libcore/tests/num/int_macros.rs b/src/libcore/tests/num/int_macros.rs index 5c6ee8f8ba038..4881f79ec248a 100644 --- a/src/libcore/tests/num/int_macros.rs +++ b/src/libcore/tests/num/int_macros.rs @@ -12,7 +12,7 @@ mod tests { fn test_overflows() { assert!(MAX > 0); assert!(MIN <= 0); - assert!(MIN + MAX + 1 == 0); + assert_eq!(MIN + MAX + 1, 0); } #[test] @@ -22,22 +22,22 @@ mod tests { #[test] fn test_rem_euclid() { - assert!((-1 as $T).rem_euclid(MIN) == MAX); + assert_eq!((-1 as $T).rem_euclid(MIN), MAX); } #[test] pub fn test_abs() { - assert!((1 as $T).abs() == 1 as $T); - assert!((0 as $T).abs() == 0 as $T); - assert!((-1 as $T).abs() == 1 as $T); + assert_eq!((1 as $T).abs(), 1 as $T); + assert_eq!((0 as $T).abs(), 0 as $T); + assert_eq!((-1 as $T).abs(), 1 as $T); } #[test] fn test_signum() { - assert!((1 as $T).signum() == 1 as $T); - assert!((0 as $T).signum() == 0 as $T); - assert!((-0 as $T).signum() == 0 as $T); - assert!((-1 as $T).signum() == -1 as $T); + assert_eq!((1 as $T).signum(), 1 as $T); + assert_eq!((0 as $T).signum(), 0 as $T); + assert_eq!((-0 as $T).signum(), 0 as $T); + assert_eq!((-1 as $T).signum(), -1 as $T); } #[test] @@ -58,12 +58,12 @@ mod tests { #[test] fn test_bitwise_operators() { - assert!(0b1110 as $T == (0b1100 as $T).bitor(0b1010 as $T)); - assert!(0b1000 as $T == (0b1100 as $T).bitand(0b1010 as $T)); - assert!(0b0110 as $T == (0b1100 as $T).bitxor(0b1010 as $T)); - assert!(0b1110 as $T == (0b0111 as $T).shl(1)); - assert!(0b0111 as $T == (0b1110 as $T).shr(1)); - assert!(-(0b11 as $T) - (1 as $T) == (0b11 as $T).not()); + assert_eq!(0b1110 as $T, (0b1100 as $T).bitor(0b1010 as $T)); + assert_eq!(0b1000 as $T, (0b1100 as $T).bitand(0b1010 as $T)); + assert_eq!(0b0110 as $T, (0b1100 as $T).bitxor(0b1010 as $T)); + assert_eq!(0b1110 as $T, (0b0111 as $T).shl(1)); + assert_eq!(0b0111 as $T, (0b1110 as $T).shr(1)); + assert_eq!(-(0b11 as $T) - (1 as $T), (0b11 as $T).not()); } const A: $T = 0b0101100; @@ -75,17 +75,17 @@ mod tests { #[test] fn test_count_ones() { - assert!(A.count_ones() == 3); - assert!(B.count_ones() == 2); - assert!(C.count_ones() == 5); + assert_eq!(A.count_ones(), 3); + assert_eq!(B.count_ones(), 2); + assert_eq!(C.count_ones(), 5); } #[test] fn test_count_zeros() { let bits = mem::size_of::<$T>() * 8; - assert!(A.count_zeros() == bits as u32 - 3); - assert!(B.count_zeros() == bits as u32 - 2); - assert!(C.count_zeros() == bits as u32 - 5); + assert_eq!(A.count_zeros(), bits as u32 - 3); + assert_eq!(B.count_zeros(), bits as u32 - 2); + assert_eq!(C.count_zeros(), bits as u32 - 5); } #[test] @@ -148,9 +148,9 @@ mod tests { #[test] fn test_signed_checked_div() { - assert!((10 as $T).checked_div(2) == Some(5)); - assert!((5 as $T).checked_div(0) == None); - assert!(isize::MIN.checked_div(-1) == None); + assert_eq!((10 as $T).checked_div(2), Some(5)); + assert_eq!((5 as $T).checked_div(0), None); + assert_eq!(isize::MIN.checked_div(-1), None); } #[test] From e9e5a75fd2bc5f7908642129aa462ee15ce17a3b Mon Sep 17 00:00:00 2001 From: sntdevco Date: Fri, 15 Mar 2019 16:38:51 +0530 Subject: [PATCH 51/58] Improved test output for estr-slice --- src/test/run-pass/array-slice-vec/estr-slice.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/run-pass/array-slice-vec/estr-slice.rs b/src/test/run-pass/array-slice-vec/estr-slice.rs index 02b88f6a7abfc..cd2c17220655a 100644 --- a/src/test/run-pass/array-slice-vec/estr-slice.rs +++ b/src/test/run-pass/array-slice-vec/estr-slice.rs @@ -14,7 +14,7 @@ pub fn main() { let z : &str = "thing"; assert_eq!(v, x); - assert!(x != z); + assert_ne!(x, z); let a = "aaaa"; let b = "bbbb"; @@ -26,7 +26,7 @@ pub fn main() { assert!(a < b); assert!(a <= b); - assert!(a != b); + assert_ne!(a, b); assert!(b >= a); assert!(b > a); @@ -34,7 +34,7 @@ pub fn main() { assert!(a < c); assert!(a <= c); - assert!(a != c); + assert_ne!(a, c); assert!(c >= a); assert!(c > a); @@ -42,7 +42,7 @@ pub fn main() { assert!(c < cc); assert!(c <= cc); - assert!(c != cc); + assert_ne!(c, cc); assert!(cc >= c); assert!(cc > c); From 12e3e8412cd8eb1ec93034d52e4287dbae2027de Mon Sep 17 00:00:00 2001 From: kenta7777 Date: Fri, 15 Mar 2019 21:48:05 +0900 Subject: [PATCH 52/58] reduced a code repetition related to bit operation. --- src/librustc_mir/hair/pattern/_match.rs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index 586a3fdb907ee..76e04d349f15b 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -172,7 +172,7 @@ use rustc::ty::{self, subst::SubstsRef, Ty, TyCtxt, TypeFoldable, Const}; use rustc::ty::layout::{Integer, IntegerExt, VariantIdx, Size}; use rustc::mir::Field; -use rustc::mir::interpret::{ConstValue, Scalar}; +use rustc::mir::interpret::{ConstValue, Scalar, truncate}; use rustc::util::common::ErrorReported; use syntax::attr::{SignedInt, UnsignedInt}; @@ -685,9 +685,8 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>, vec![ConstantRange(min, max, pcx.ty, RangeEnd::Included)] } ty::Uint(uty) => { - // FIXME(49937): refactor these bit manipulations into interpret. - let bits = Integer::from_attr(&cx.tcx, UnsignedInt(uty)).size().bits() as u128; - let max = !0u128 >> (128 - bits); + let size = Integer::from_attr(&cx.tcx, UnsignedInt(uty)).size(); + let max = truncate(u128::max_value(), size); vec![ConstantRange(0, max, pcx.ty, RangeEnd::Included)] } _ => { From 5303c1b90b12c0edb3fbadf96f15edf93fb69155 Mon Sep 17 00:00:00 2001 From: Brian Campbell Date: Fri, 15 Mar 2019 01:51:26 -0400 Subject: [PATCH 53/58] Remove restriction on isize/usize in repr(simd) As discussed in #55078, there's no known reason for this restriction. It's unlikely that repr(simd) will be stabilized in its current form, but might as well remove some restrictions on it. This removes the branch in `is_machine` which returns false for these types. `is_machine` is only used for the repr(simd) type validation check. --- src/librustc/ty/sty.rs | 1 - src/test/run-pass/simd/simd-size-align.rs | 32 +++++++++++++++++++++++ src/test/ui/simd-type.rs | 3 --- src/test/ui/simd-type.stderr | 10 ++----- 4 files changed, 34 insertions(+), 12 deletions(-) diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index 39728cc8cd5cb..2db4caaff92bc 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -1910,7 +1910,6 @@ impl<'a, 'gcx, 'tcx> TyS<'tcx> { pub fn is_machine(&self) -> bool { match self.sty { - Int(ast::IntTy::Isize) | Uint(ast::UintTy::Usize) => false, Int(..) | Uint(..) | Float(..) => true, _ => false, } diff --git a/src/test/run-pass/simd/simd-size-align.rs b/src/test/run-pass/simd/simd-size-align.rs index 0a537071a3c63..556013788c335 100644 --- a/src/test/run-pass/simd/simd-size-align.rs +++ b/src/test/run-pass/simd/simd-size-align.rs @@ -37,6 +37,22 @@ fn main() { check::(); check::(); check::(); + + check::(); + check::(); + check::(); + check::(); + check::(); + check::(); + check::(); + + check::(); + check::(); + check::(); + check::(); + check::(); + check::(); + check::(); } #[repr(simd)] struct u8x2(u8, u8); @@ -62,3 +78,19 @@ fn main() { #[repr(simd)] struct f32x6(f32, f32, f32, f32, f32, f32); #[repr(simd)] struct f32x7(f32, f32, f32, f32, f32, f32, f32); #[repr(simd)] struct f32x8(f32, f32, f32, f32, f32, f32, f32, f32); + +#[repr(simd)] struct usizex2(usize, usize); +#[repr(simd)] struct usizex3(usize, usize, usize); +#[repr(simd)] struct usizex4(usize, usize, usize, usize); +#[repr(simd)] struct usizex5(usize, usize, usize, usize, usize); +#[repr(simd)] struct usizex6(usize, usize, usize, usize, usize, usize); +#[repr(simd)] struct usizex7(usize, usize, usize, usize, usize, usize, usize); +#[repr(simd)] struct usizex8(usize, usize, usize, usize, usize, usize, usize, usize); + +#[repr(simd)] struct isizex2(isize, isize); +#[repr(simd)] struct isizex3(isize, isize, isize); +#[repr(simd)] struct isizex4(isize, isize, isize, isize); +#[repr(simd)] struct isizex5(isize, isize, isize, isize, isize); +#[repr(simd)] struct isizex6(isize, isize, isize, isize, isize, isize); +#[repr(simd)] struct isizex7(isize, isize, isize, isize, isize, isize, isize); +#[repr(simd)] struct isizex8(isize, isize, isize, isize, isize, isize, isize, isize); diff --git a/src/test/ui/simd-type.rs b/src/test/ui/simd-type.rs index d1e2efa6a3331..9e4b7e7656055 100644 --- a/src/test/ui/simd-type.rs +++ b/src/test/ui/simd-type.rs @@ -7,7 +7,4 @@ struct empty; //~ ERROR SIMD vector cannot be empty #[repr(simd)] struct i64f64(i64, f64); //~ ERROR SIMD vector should be homogeneous -#[repr(simd)] -struct int4(isize, isize, isize, isize); //~ ERROR SIMD vector element type should be machine type - fn main() {} diff --git a/src/test/ui/simd-type.stderr b/src/test/ui/simd-type.stderr index 027afcb981a0d..48b9916e89d98 100644 --- a/src/test/ui/simd-type.stderr +++ b/src/test/ui/simd-type.stderr @@ -10,13 +10,7 @@ error[E0076]: SIMD vector should be homogeneous LL | struct i64f64(i64, f64); | ^^^^^^^^^^^^^^^^^^^^^^^^ SIMD elements must have the same type -error[E0077]: SIMD vector element type should be machine type - --> $DIR/simd-type.rs:11:1 - | -LL | struct int4(isize, isize, isize, isize); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -error: aborting due to 3 previous errors +error: aborting due to 2 previous errors -Some errors occurred: E0075, E0076, E0077. +Some errors occurred: E0075, E0076. For more information about an error, try `rustc --explain E0075`. From 9c7bf76c087d4d579d1af5dc9a3f4fa9d81a3a61 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= Date: Fri, 15 Mar 2019 15:43:56 +0100 Subject: [PATCH 54/58] Add x86_64 musl host to the manifest --- src/tools/build-manifest/src/main.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs index d44a51a9635e9..f0b8ab13dc567 100644 --- a/src/tools/build-manifest/src/main.rs +++ b/src/tools/build-manifest/src/main.rs @@ -32,6 +32,7 @@ static HOSTS: &'static [&'static str] = &[ "x86_64-pc-windows-msvc", "x86_64-unknown-freebsd", "x86_64-unknown-linux-gnu", + "x86_64-unknown-linux-musl", "x86_64-unknown-netbsd", ]; From 50af62dae912d2b0ea24aef649bce7be8b7040a8 Mon Sep 17 00:00:00 2001 From: kenta7777 Date: Sat, 16 Mar 2019 01:14:46 +0900 Subject: [PATCH 55/58] removed some unnecessary comments. --- src/librustc_mir/build/matches/simplify.rs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/librustc_mir/build/matches/simplify.rs b/src/librustc_mir/build/matches/simplify.rs index d60a0941b5979..77978d7d38ff7 100644 --- a/src/librustc_mir/build/matches/simplify.rs +++ b/src/librustc_mir/build/matches/simplify.rs @@ -114,14 +114,12 @@ impl<'a, 'gcx, 'tcx> Builder<'a, 'gcx, 'tcx> { (Some(('\u{0000}' as u128, '\u{10FFFF}' as u128, Size::from_bits(32))), 0) } ty::Int(ity) => { - // FIXME(49937): refactor these bit manipulations into interpret. let size = Integer::from_attr(&tcx, SignedInt(ity)).size(); let max = truncate(u128::max_value(), size); let bias = 1u128 << (size.bits() - 1); (Some((0, max, size)), bias) } ty::Uint(uty) => { - // FIXME(49937): refactor these bit manipulations into interpret. let size = Integer::from_attr(&tcx, UnsignedInt(uty)).size(); let max = truncate(u128::max_value(), size); (Some((0, max, size)), 0) From a8fa1a153d332d31d7d95ce303bf2b347b7a03c5 Mon Sep 17 00:00:00 2001 From: kenta7777 Date: Sat, 16 Mar 2019 01:58:48 +0900 Subject: [PATCH 56/58] a simple refactoring and removing comment. --- src/librustc_mir/hair/pattern/_match.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/librustc_mir/hair/pattern/_match.rs b/src/librustc_mir/hair/pattern/_match.rs index 76e04d349f15b..44bcb9de0e157 100644 --- a/src/librustc_mir/hair/pattern/_match.rs +++ b/src/librustc_mir/hair/pattern/_match.rs @@ -678,10 +678,9 @@ fn all_constructors<'a, 'tcx: 'a>(cx: &mut MatchCheckCtxt<'a, 'tcx>, ] } ty::Int(ity) => { - // FIXME(49937): refactor these bit manipulations into interpret. let bits = Integer::from_attr(&cx.tcx, SignedInt(ity)).size().bits() as u128; let min = 1u128 << (bits - 1); - let max = (1u128 << (bits - 1)) - 1; + let max = min - 1; vec![ConstantRange(min, max, pcx.ty, RangeEnd::Included)] } ty::Uint(uty) => { From 9a61580d40df576d6774028cbba6a49b3c9dc0fe Mon Sep 17 00:00:00 2001 From: Chris Gregory Date: Fri, 15 Mar 2019 16:42:10 -0400 Subject: [PATCH 57/58] Option and Result: Add references to documentation of as_ref and as_mut --- src/libcore/option.rs | 4 ++-- src/libcore/result.rs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 46dfe28da622c..75fa24aa4dc1d 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -210,7 +210,7 @@ impl Option { // Adapter for working with references ///////////////////////////////////////////////////////////////////////// - /// Converts from `Option` to `Option<&T>`. + /// Converts from `&Option` to `Option<&T>`. /// /// # Examples /// @@ -239,7 +239,7 @@ impl Option { } } - /// Converts from `Option` to `Option<&mut T>`. + /// Converts from `&mut Option` to `Option<&mut T>`. /// /// # Examples /// diff --git a/src/libcore/result.rs b/src/libcore/result.rs index 2bd6b536301e8..967f7e3e2fe72 100644 --- a/src/libcore/result.rs +++ b/src/libcore/result.rs @@ -369,7 +369,7 @@ impl Result { // Adapter for working with references ///////////////////////////////////////////////////////////////////////// - /// Converts from `Result` to `Result<&T, &E>`. + /// Converts from `&Result` to `Result<&T, &E>`. /// /// Produces a new `Result`, containing a reference /// into the original, leaving the original in place. @@ -394,7 +394,7 @@ impl Result { } } - /// Converts from `Result` to `Result<&mut T, &mut E>`. + /// Converts from `&mut Result` to `Result<&mut T, &mut E>`. /// /// # Examples /// From 08f264d5762fc8cf817288084c03ce0d53ecb85b Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Sat, 16 Mar 2019 14:11:23 +0300 Subject: [PATCH 58/58] Stabilize Option::copied closes https://github.com/rust-lang/rust/issues/57126 --- src/libcore/option.rs | 8 ++------ src/libcore/tests/lib.rs | 1 - 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/src/libcore/option.rs b/src/libcore/option.rs index 46dfe28da622c..f7f7e96fff32e 100644 --- a/src/libcore/option.rs +++ b/src/libcore/option.rs @@ -881,15 +881,13 @@ impl Option<&T> { /// # Examples /// /// ``` - /// #![feature(copied)] - /// /// let x = 12; /// let opt_x = Some(&x); /// assert_eq!(opt_x, Some(&12)); /// let copied = opt_x.copied(); /// assert_eq!(copied, Some(12)); /// ``` - #[unstable(feature = "copied", issue = "57126")] + #[stable(feature = "copied", since = "1.35.0")] pub fn copied(self) -> Option { self.map(|&t| t) } @@ -902,15 +900,13 @@ impl Option<&mut T> { /// # Examples /// /// ``` - /// #![feature(copied)] - /// /// let mut x = 12; /// let opt_x = Some(&mut x); /// assert_eq!(opt_x, Some(&mut 12)); /// let copied = opt_x.copied(); /// assert_eq!(copied, Some(12)); /// ``` - #[unstable(feature = "copied", issue = "57126")] + #[stable(feature = "copied", since = "1.35.0")] pub fn copied(self) -> Option { self.map(|&mut t| t) } diff --git a/src/libcore/tests/lib.rs b/src/libcore/tests/lib.rs index d002137638977..a50310e195f0d 100644 --- a/src/libcore/tests/lib.rs +++ b/src/libcore/tests/lib.rs @@ -1,6 +1,5 @@ #![feature(box_syntax)] #![feature(cell_update)] -#![feature(copied)] #![feature(core_private_bignum)] #![feature(core_private_diy_float)] #![feature(dec2flt)]