From 86424127c67e70b546ff18c210eab44827eab565 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Tue, 17 Jul 2018 20:15:58 +0200 Subject: [PATCH 01/28] Update libc and activate align feature --- src/liblibc | 2 +- src/libstd/Cargo.toml | 2 +- src/rustc/libc_shim/Cargo.toml | 1 + 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/src/liblibc b/src/liblibc index b6d23ed45d729..8565755356f23 160000 --- a/src/liblibc +++ b/src/liblibc @@ -1 +1 @@ -Subproject commit b6d23ed45d72918239c0bfac11dc547895e59b81 +Subproject commit 8565755356f23baf6b2df933ff734ce2f00c8d9b diff --git a/src/libstd/Cargo.toml b/src/libstd/Cargo.toml index 5a2dce5930a4b..9691c00bc26e5 100644 --- a/src/libstd/Cargo.toml +++ b/src/libstd/Cargo.toml @@ -19,7 +19,7 @@ alloc_system = { path = "../liballoc_system" } panic_unwind = { path = "../libpanic_unwind", optional = true } panic_abort = { path = "../libpanic_abort" } core = { path = "../libcore" } -libc = { path = "../rustc/libc_shim" } +libc = { path = "../rustc/libc_shim", features = ["align"] } compiler_builtins = { path = "../rustc/compiler_builtins_shim" } profiler_builtins = { path = "../libprofiler_builtins", optional = true } std_unicode = { path = "../libstd_unicode" } diff --git a/src/rustc/libc_shim/Cargo.toml b/src/rustc/libc_shim/Cargo.toml index e77897d643313..81ace038b2a9e 100644 --- a/src/rustc/libc_shim/Cargo.toml +++ b/src/rustc/libc_shim/Cargo.toml @@ -37,3 +37,4 @@ compiler_builtins = { path = "../compiler_builtins_shim" } # outside rustc. See https://github.com/rust-lang/libc/search?l=Rust&q=stdbuild&type=&utf8=%E2%9C%93. stdbuild = [] default = ["stdbuild"] +align = [] From 2b5fc66d831f5b8a2329426ee3051e93f1df6c71 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Fri, 20 Jul 2018 01:14:56 +0200 Subject: [PATCH 02/28] Make Ipv{4,6}Addr::new const fns --- src/libstd/lib.rs | 2 ++ src/libstd/net/ip.rs | 48 ++++++++++++++++++++++++++------------------ 2 files changed, 30 insertions(+), 20 deletions(-) diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 3c01de2e997c9..823c6fbf7f3a0 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -254,6 +254,7 @@ #![feature(collections_range)] #![feature(compiler_builtins_lib)] #![feature(const_fn)] +#![feature(const_int_ops)] #![feature(core_intrinsics)] #![feature(dropck_eyepatch)] #![feature(exact_size_is_empty)] @@ -292,6 +293,7 @@ #![feature(rand)] #![feature(raw)] #![feature(rustc_attrs)] +#![feature(rustc_const_unstable)] #![feature(std_internals)] #![feature(stdsimd)] #![feature(shrink_to)] diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index fcec8d06853f6..ac9b95f84e945 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -17,7 +17,6 @@ use cmp::Ordering; use fmt; use hash; use mem; -use net::{hton, ntoh}; use sys::net::netc as c; use sys_common::{AsInner, FromInner}; @@ -340,13 +339,16 @@ impl Ipv4Addr { /// let addr = Ipv4Addr::new(127, 0, 0, 1); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr { + #[rustc_const_unstable(feature = "const_ip")] + pub const fn new(a: u8, b: u8, c: u8, d: u8) -> Ipv4Addr { Ipv4Addr { inner: c::in_addr { - s_addr: hton(((a as u32) << 24) | - ((b as u32) << 16) | - ((c as u32) << 8) | - (d as u32)), + s_addr: u32::to_be( + ((a as u32) << 24) | + ((b as u32) << 16) | + ((c as u32) << 8) | + (d as u32) + ), } } } @@ -399,7 +401,7 @@ impl Ipv4Addr { /// ``` #[stable(feature = "rust1", since = "1.0.0")] pub fn octets(&self) -> [u8; 4] { - let bits = ntoh(self.inner.s_addr); + let bits = u32::from_be(self.inner.s_addr); [(bits >> 24) as u8, (bits >> 16) as u8, (bits >> 8) as u8, bits as u8] } @@ -763,7 +765,7 @@ impl PartialOrd for Ipv4Addr { #[stable(feature = "rust1", since = "1.0.0")] impl Ord for Ipv4Addr { fn cmp(&self, other: &Ipv4Addr) -> Ordering { - ntoh(self.inner.s_addr).cmp(&ntoh(other.inner.s_addr)) + u32::from_be(self.inner.s_addr).cmp(&u32::from_be(other.inner.s_addr)) } } @@ -856,18 +858,24 @@ impl Ipv6Addr { /// let addr = Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc00a, 0x2ff); /// ``` #[stable(feature = "rust1", since = "1.0.0")] - pub fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, g: u16, - h: u16) -> Ipv6Addr { - let mut addr: c::in6_addr = unsafe { mem::zeroed() }; - addr.s6_addr = [(a >> 8) as u8, a as u8, - (b >> 8) as u8, b as u8, - (c >> 8) as u8, c as u8, - (d >> 8) as u8, d as u8, - (e >> 8) as u8, e as u8, - (f >> 8) as u8, f as u8, - (g >> 8) as u8, g as u8, - (h >> 8) as u8, h as u8]; - Ipv6Addr { inner: addr } + #[rustc_const_unstable(feature = "const_ip")] + pub const fn new(a: u16, b: u16, c: u16, d: u16, e: u16, f: u16, + g: u16, h: u16) -> Ipv6Addr { + Ipv6Addr { + inner: c::in6_addr { + s6_addr: [ + (a >> 8) as u8, a as u8, + (b >> 8) as u8, b as u8, + (c >> 8) as u8, c as u8, + (d >> 8) as u8, d as u8, + (e >> 8) as u8, e as u8, + (f >> 8) as u8, f as u8, + (g >> 8) as u8, g as u8, + (h >> 8) as u8, h as u8 + ], + } + } + } /// Creates a new IPv6 address representing localhost: `::1`. From 0d2f96e9e4a9570e623a72b63ab1fccce7e4f6a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Fri, 20 Jul 2018 09:09:48 +0200 Subject: [PATCH 03/28] Move IPs to assoc consts --- src/libstd/lib.rs | 1 + src/libstd/net/ip.rs | 48 ++++++++++++++++++-------------------------- 2 files changed, 21 insertions(+), 28 deletions(-) diff --git a/src/libstd/lib.rs b/src/libstd/lib.rs index 823c6fbf7f3a0..aa0f6b318227f 100644 --- a/src/libstd/lib.rs +++ b/src/libstd/lib.rs @@ -255,6 +255,7 @@ #![feature(compiler_builtins_lib)] #![feature(const_fn)] #![feature(const_int_ops)] +#![feature(const_ip)] #![feature(core_intrinsics)] #![feature(dropck_eyepatch)] #![feature(exact_size_is_empty)] diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index ac9b95f84e945..c8d4dd733ad64 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -353,7 +353,7 @@ impl Ipv4Addr { } } - /// Creates a new IPv4 address with the address pointing to localhost: 127.0.0.1. + /// An IPv4 address with the address pointing to localhost: 127.0.0.1. /// /// # Examples /// @@ -361,17 +361,15 @@ impl Ipv4Addr { /// #![feature(ip_constructors)] /// use std::net::Ipv4Addr; /// - /// let addr = Ipv4Addr::localhost(); + /// let addr = Ipv4Addr::LOCALHOST; /// assert_eq!(addr, Ipv4Addr::new(127, 0, 0, 1)); /// ``` #[unstable(feature = "ip_constructors", reason = "requires greater scrutiny before stabilization", issue = "44582")] - pub fn localhost() -> Ipv4Addr { - Ipv4Addr::new(127, 0, 0, 1) - } + pub const LOCALHOST: Self = Ipv4Addr::new(127, 0, 0, 1); - /// Creates a new IPv4 address representing an unspecified address: 0.0.0.0 + /// An IPv4 address representing an unspecified address: 0.0.0.0 /// /// # Examples /// @@ -379,15 +377,13 @@ impl Ipv4Addr { /// #![feature(ip_constructors)] /// use std::net::Ipv4Addr; /// - /// let addr = Ipv4Addr::unspecified(); + /// let addr = Ipv4Addr::UNSPECIFIED; /// assert_eq!(addr, Ipv4Addr::new(0, 0, 0, 0)); /// ``` #[unstable(feature = "ip_constructors", reason = "requires greater scrutiny before stabilization", issue = "44582")] - pub fn unspecified() -> Ipv4Addr { - Ipv4Addr::new(0, 0, 0, 0) - } + pub const UNSPECIFIED: Self = Ipv4Addr::new(0, 0, 0, 0); /// Returns the four eight-bit integers that make up this address. /// @@ -878,7 +874,7 @@ impl Ipv6Addr { } - /// Creates a new IPv6 address representing localhost: `::1`. + /// An IPv6 address representing localhost: `::1`. /// /// # Examples /// @@ -886,17 +882,15 @@ impl Ipv6Addr { /// #![feature(ip_constructors)] /// use std::net::Ipv6Addr; /// - /// let addr = Ipv6Addr::localhost(); + /// let addr = Ipv6Addr::LOCALHOST; /// assert_eq!(addr, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)); /// ``` #[unstable(feature = "ip_constructors", reason = "requires greater scrutiny before stabilization", issue = "44582")] - pub fn localhost() -> Ipv6Addr { - Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1) - } + pub const LOCALHOST: Self = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1); - /// Creates a new IPv6 address representing the unspecified address: `::` + /// An IPv6 address representing the unspecified address: `::` /// /// # Examples /// @@ -904,15 +898,13 @@ impl Ipv6Addr { /// #![feature(ip_constructors)] /// use std::net::Ipv6Addr; /// - /// let addr = Ipv6Addr::unspecified(); + /// let addr = Ipv6Addr::UNSPECIFIED; /// assert_eq!(addr, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)); /// ``` #[unstable(feature = "ip_constructors", reason = "requires greater scrutiny before stabilization", issue = "44582")] - pub fn unspecified() -> Ipv6Addr { - Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0) - } + pub const UNSPECIFIED: Self = Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0); /// Returns the eight 16-bit segments that make up this address. /// @@ -1854,18 +1846,18 @@ mod tests { #[test] fn ipv4_from_constructors() { - assert_eq!(Ipv4Addr::localhost(), Ipv4Addr::new(127, 0, 0, 1)); - assert!(Ipv4Addr::localhost().is_loopback()); - assert_eq!(Ipv4Addr::unspecified(), Ipv4Addr::new(0, 0, 0, 0)); - assert!(Ipv4Addr::unspecified().is_unspecified()); + assert_eq!(Ipv4Addr::LOCALHOST, Ipv4Addr::new(127, 0, 0, 1)); + assert!(Ipv4Addr::LOCALHOST.is_loopback()); + assert_eq!(Ipv4Addr::UNSPECIFIED, Ipv4Addr::new(0, 0, 0, 0)); + assert!(Ipv4Addr::UNSPECIFIED.is_unspecified()); } #[test] fn ipv6_from_contructors() { - assert_eq!(Ipv6Addr::localhost(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)); - assert!(Ipv6Addr::localhost().is_loopback()); - assert_eq!(Ipv6Addr::unspecified(), Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)); - assert!(Ipv6Addr::unspecified().is_unspecified()); + assert_eq!(Ipv6Addr::LOCALHOST, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1)); + assert!(Ipv6Addr::LOCALHOST.is_loopback()); + assert_eq!(Ipv6Addr::UNSPECIFIED, Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 0)); + assert!(Ipv6Addr::UNSPECIFIED.is_unspecified()); } #[test] From 798680afba37929c625d20d5f0bdffb4ec0835f5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Sun, 29 Jul 2018 22:24:19 +0200 Subject: [PATCH 04/28] Add Ipv4Addr BROADCAST assoc const --- src/libstd/net/ip.rs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index c8d4dd733ad64..2f3994365e0bd 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -385,6 +385,22 @@ impl Ipv4Addr { issue = "44582")] pub const UNSPECIFIED: Self = Ipv4Addr::new(0, 0, 0, 0); + /// An IPv4 address representing the broadcast address: 255.255.255.255 + /// + /// # Examples + /// + /// ``` + /// #![feature(ip_constructors)] + /// use std::net::Ipv4Addr; + /// + /// let addr = Ipv4Addr::BROADCAST; + /// assert_eq!(addr, Ipv4Addr::new(255, 255, 255, 255)); + /// ``` + #[unstable(feature = "ip_constructors", + reason = "requires greater scrutiny before stabilization", + issue = "44582")] + pub const BROADCAST: Self = Ipv4Addr::new(255, 255, 255, 255); + /// Returns the four eight-bit integers that make up this address. /// /// # Examples @@ -1850,6 +1866,8 @@ mod tests { assert!(Ipv4Addr::LOCALHOST.is_loopback()); assert_eq!(Ipv4Addr::UNSPECIFIED, Ipv4Addr::new(0, 0, 0, 0)); assert!(Ipv4Addr::UNSPECIFIED.is_unspecified()); + assert_eq!(Ipv4Addr::BROADCAST, Ipv4Addr::new(255, 255, 255, 255)); + assert!(Ipv4Addr::BROADCAST.is_broadcast()); } #[test] From 312cdb4233511ef9c8af6e4803bc01e45dab2907 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Linus=20F=C3=A4rnstrand?= Date: Sun, 29 Jul 2018 22:35:31 +0200 Subject: [PATCH 05/28] Simplify is_broadcast --- src/libstd/net/ip.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/libstd/net/ip.rs b/src/libstd/net/ip.rs index 2f3994365e0bd..341757aeb75a5 100644 --- a/src/libstd/net/ip.rs +++ b/src/libstd/net/ip.rs @@ -587,8 +587,7 @@ impl Ipv4Addr { /// ``` #[stable(since = "1.7.0", feature = "ip_17")] pub fn is_broadcast(&self) -> bool { - self.octets()[0] == 255 && self.octets()[1] == 255 && - self.octets()[2] == 255 && self.octets()[3] == 255 + self == &Self::BROADCAST } /// Returns [`true`] if this address is in a range designated for documentation. From 0da7da8391cfb27a809b3fea7e0f50dd64d018c8 Mon Sep 17 00:00:00 2001 From: kennytm Date: Wed, 1 Aug 2018 18:03:19 +0800 Subject: [PATCH 06/28] Align 6-week cycle check with beta promotion instead of stable release. The regression check is to make beta promotion easier, so it makes more sense to use the Tuesday of the release week (T-2) as the end point of the regression prevention, instead of Thursday (T-0). But since the beta promotion PR is sent at Tuesday evening at UTC, the protection should include the whole Tuesday as well, meaning the 6-week cycle will start from Wednesdays. This will also move the start of the regression protection week one day earlier. --- src/ci/docker/x86_64-gnu-tools/checktools.sh | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/src/ci/docker/x86_64-gnu-tools/checktools.sh b/src/ci/docker/x86_64-gnu-tools/checktools.sh index 16055078ad5eb..d876cb7f37a41 100755 --- a/src/ci/docker/x86_64-gnu-tools/checktools.sh +++ b/src/ci/docker/x86_64-gnu-tools/checktools.sh @@ -17,9 +17,11 @@ TOOLSTATE_FILE="$(realpath $2)" OS="$3" COMMIT="$(git rev-parse HEAD)" CHANGED_FILES="$(git diff --name-status HEAD HEAD^)" -SIX_WEEK_CYCLE="$(( ($(date +%s) / 604800 - 3) % 6 ))" -# ^ 1970 Jan 1st is a Thursday, and our release dates are also on Thursdays, -# thus we could divide by 604800 (7 days in seconds) directly. +SIX_WEEK_CYCLE="$(( ($(date +%s) / 86400 - 20) % 42 ))" +# ^ Number of days after the last promotion of beta. +# Its value is 41 on the Tuesday where "Promote master to beta (T-2)" happens. +# The Wednesday after this has value 0. +# We track this value to prevent regressing tools in the last week of the 6-week cycle. touch "$TOOLSTATE_FILE" @@ -98,7 +100,7 @@ change_toolstate() { if python2.7 "$CHECK_NOT" "$OS" "$TOOLSTATE_FILE" "_data/latest.json" changed; then echo 'Toolstate is not changed. Not updating.' else - if [ $SIX_WEEK_CYCLE -eq 5 ]; then + if [ $SIX_WEEK_CYCLE -ge 35 ]; then python2.7 "$CHECK_NOT" "$OS" "$TOOLSTATE_FILE" "_data/latest.json" regressed fi sed -i "1 a\\ From 66a47182d10542b68773d8a1cb9230a4918a5068 Mon Sep 17 00:00:00 2001 From: Marc-Antoine Perennou Date: Thu, 2 Aug 2018 08:49:36 +0200 Subject: [PATCH 07/28] rustbuild: fix local_rebuild If we detect a local rebuild (e.g. bootstrap compiler is the same version as target compiler), we set stage to 1. When trying to build e.g. UnstableBook, we use Mode::ToolBootstrap and stage is 1. Just allow Mode::ToolBootstrap and stagge != 0 if we are in a local_rebuild Signed-off-by: Marc-Antoine Perennou --- 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 724d3b741903f..dc0b0aaf0bb3c 100644 --- a/src/bootstrap/builder.rs +++ b/src/bootstrap/builder.rs @@ -777,7 +777,7 @@ impl<'a> Builder<'a> { // compiler, but for tools we just use the precompiled libraries that // we've downloaded let use_snapshot = mode == Mode::ToolBootstrap; - assert!(!use_snapshot || stage == 0); + assert!(!use_snapshot || stage == 0 || self.local_rebuild); let maybe_sysroot = self.sysroot(compiler); let sysroot = if use_snapshot { From 0217459c7cb93247074461d6df22d12f6ce4f9ba Mon Sep 17 00:00:00 2001 From: Alex Crichton Date: Thu, 2 Aug 2018 07:09:13 -0700 Subject: [PATCH 08/28] Update LLVM submodule to 7.0 This commit updates the following submodules to LLVM's [recently branched][1] 7.0 release branch: * src/llvm * src/tools/lld * src/libcompiler_builtins/compiler-rt [1]: https://lists.llvm.org/pipermail/llvm-dev/2018-August/125004.html Closes #52970 --- src/libcompiler_builtins | 2 +- src/llvm | 2 +- src/rustllvm/llvm-rebuild-trigger | 2 +- src/tools/lld | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libcompiler_builtins b/src/libcompiler_builtins index 52a6a4d7087d1..43a66634d6d3c 160000 --- a/src/libcompiler_builtins +++ b/src/libcompiler_builtins @@ -1 +1 @@ -Subproject commit 52a6a4d7087d14a35d44a11c39c77fa79d71378d +Subproject commit 43a66634d6d3c99dcd0c814e5320bb93cfe59e05 diff --git a/src/llvm b/src/llvm index 03684905101f0..e19f07f5a6e55 160000 --- a/src/llvm +++ b/src/llvm @@ -1 +1 @@ -Subproject commit 03684905101f0b7e49dfe530e54dc1aeac6ef0fb +Subproject commit e19f07f5a6e5546ab4f6ea951e3c6b8627edeaa7 diff --git a/src/rustllvm/llvm-rebuild-trigger b/src/rustllvm/llvm-rebuild-trigger index 1722211c9e89f..7da830e1125ba 100644 --- a/src/rustllvm/llvm-rebuild-trigger +++ b/src/rustllvm/llvm-rebuild-trigger @@ -1,4 +1,4 @@ # If this file is modified, then llvm will be (optionally) cleaned and then rebuilt. # The actual contents of this file do not matter, but to trigger a change on the # build bots then the contents should be changed so git updates the mtime. -2018-07-12 \ No newline at end of file +2018-08-02 diff --git a/src/tools/lld b/src/tools/lld index 8214ccf861d53..f76ea3ca16ed2 160000 --- a/src/tools/lld +++ b/src/tools/lld @@ -1 +1 @@ -Subproject commit 8214ccf861d538671b0a1436dbf4538dc4a64d09 +Subproject commit f76ea3ca16ed22dde8ef929db74a4b4df6f2f899 From f3733a2f82b0c98f53ed85425c9b00cf8093337b Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Wed, 1 Aug 2018 21:12:19 -0500 Subject: [PATCH 09/28] make `everybody_loops` keep item declarations --- src/librustc_driver/lib.rs | 1 + src/librustc_driver/pretty.rs | 94 ++++++++++++++++++++++++++--------- 2 files changed, 71 insertions(+), 24 deletions(-) diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index df641b8fbc0fe..44fac8ae0a09a 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -20,6 +20,7 @@ #![feature(box_syntax)] #![cfg_attr(unix, feature(libc))] +#![feature(option_replace)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] #![feature(slice_sort_by_cached_key)] diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 6433a93a317a6..1e74ae10403a8 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -33,6 +33,7 @@ use syntax::fold::{self, Folder}; use syntax::print::{pprust}; use syntax::print::pprust::PrintState; use syntax::ptr::P; +use syntax::util::ThinVec; use syntax::util::small_vector::SmallVector; use syntax_pos::{self, FileName}; @@ -650,12 +651,17 @@ impl UserIdentifiedItem { // [#34511]: https://github.com/rust-lang/rust/issues/34511#issuecomment-322340401 pub struct ReplaceBodyWithLoop<'a> { within_static_or_const: bool, + nested_blocks: Option>, sess: &'a Session, } impl<'a> ReplaceBodyWithLoop<'a> { pub fn new(sess: &'a Session) -> ReplaceBodyWithLoop<'a> { - ReplaceBodyWithLoop { within_static_or_const: false, sess } + ReplaceBodyWithLoop { + within_static_or_const: false, + nested_blocks: None, + sess + } } fn run R>(&mut self, is_const: bool, action: F) -> R { @@ -740,41 +746,81 @@ impl<'a> fold::Folder for ReplaceBodyWithLoop<'a> { } fn fold_block(&mut self, b: P) -> P { - fn expr_to_block(rules: ast::BlockCheckMode, + fn stmt_to_block(rules: ast::BlockCheckMode, recovered: bool, - e: Option>, - sess: &Session) -> P { - P(ast::Block { - stmts: e.map(|e| { - ast::Stmt { - id: sess.next_node_id(), - span: e.span, - node: ast::StmtKind::Expr(e), - } - }) - .into_iter() - .collect(), + s: Option, + sess: &Session) -> ast::Block { + ast::Block { + stmts: s.into_iter().collect(), rules, id: sess.next_node_id(), span: syntax_pos::DUMMY_SP, recovered, - }) + } } - if !self.within_static_or_const { - - let empty_block = expr_to_block(BlockCheckMode::Default, false, None, self.sess); - let loop_expr = P(ast::Expr { - node: ast::ExprKind::Loop(empty_block, None), - id: self.sess.next_node_id(), + fn block_to_stmt(b: ast::Block, sess: &Session) -> ast::Stmt { + let expr = P(ast::Expr { + id: sess.next_node_id(), + node: ast::ExprKind::Block(P(b), None), span: syntax_pos::DUMMY_SP, - attrs: ast::ThinVec::new(), + attrs: ThinVec::new(), }); - expr_to_block(b.rules, b.recovered, Some(loop_expr), self.sess) + ast::Stmt { + id: sess.next_node_id(), + node: ast::StmtKind::Expr(expr), + span: syntax_pos::DUMMY_SP, + } + } + + let empty_block = stmt_to_block(BlockCheckMode::Default, false, None, self.sess); + let loop_expr = P(ast::Expr { + node: ast::ExprKind::Loop(P(empty_block), None), + id: self.sess.next_node_id(), + span: syntax_pos::DUMMY_SP, + attrs: ast::ThinVec::new(), + }); + + let loop_stmt = ast::Stmt { + id: self.sess.next_node_id(), + span: syntax_pos::DUMMY_SP, + node: ast::StmtKind::Expr(loop_expr), + }; - } else { + if self.within_static_or_const { fold::noop_fold_block(b, self) + } else { + b.map(|b| { + let old_blocks = self.nested_blocks.replace(vec![]); + + let mut stmts = b.stmts.into_iter() + .flat_map(|s| self.fold_stmt(s)) + .filter(|s| s.is_item()) + .collect::>(); + + // we put a Some in there earlier with that replace(), so this is valid + let new_blocks = self.nested_blocks.take().unwrap(); + self.nested_blocks = old_blocks; + stmts.extend(new_blocks.into_iter().map(|b| block_to_stmt(b, &self.sess))); + + let mut new_block = ast::Block { + stmts, + ..b + }; + + if let Some(old_blocks) = self.nested_blocks.as_mut() { + //push our fresh block onto the cache and yield an empty block with `loop {}` + old_blocks.push(new_block); + + stmt_to_block(b.rules, b.recovered, Some(loop_stmt), self.sess) + } else { + //push `loop {}` onto the end of our fresh block and yield that + new_block.stmts.push(loop_stmt); + + new_block + } + }) } } From 3a93e914ebe317a2b8267401e65e137961afc851 Mon Sep 17 00:00:00 2001 From: Taylor Cramer Date: Thu, 2 Aug 2018 13:07:55 -0700 Subject: [PATCH 10/28] Remove unnecessary local in await! macro --- src/libstd/future.rs | 4 ++-- src/libstd/macros.rs | 15 +++++++++------ 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/src/libstd/future.rs b/src/libstd/future.rs index c1cc36f3b419a..12ea1ea9f9d49 100644 --- a/src/libstd/future.rs +++ b/src/libstd/future.rs @@ -108,9 +108,9 @@ where #[unstable(feature = "gen_future", issue = "50547")] /// Polls a future in the current thread-local task context. -pub fn poll_in_task_cx(f: &mut PinMut) -> Poll +pub fn poll_in_task_cx(f: PinMut) -> Poll where F: Future { - get_task_cx(|cx| f.reborrow().poll(cx)) + get_task_cx(|cx| f.poll(cx)) } diff --git a/src/libstd/macros.rs b/src/libstd/macros.rs index a96e2ba21345b..f15494c5fd7f5 100644 --- a/src/libstd/macros.rs +++ b/src/libstd/macros.rs @@ -227,14 +227,17 @@ macro_rules! eprintln { macro_rules! await { ($e:expr) => { { let mut pinned = $e; - let mut pinned = unsafe { $crate::mem::PinMut::new_unchecked(&mut pinned) }; loop { - match $crate::future::poll_in_task_cx(&mut pinned) { - // FIXME(cramertj) prior to stabilizing await, we have to ensure that this - // can't be used to create a generator on stable via `|| await!()`. - $crate::task::Poll::Pending => yield, - $crate::task::Poll::Ready(x) => break x, + if let $crate::task::Poll::Ready(x) = + $crate::future::poll_in_task_cx(unsafe { + $crate::mem::PinMut::new_unchecked(&mut pinned) + }) + { + break x; } + // FIXME(cramertj) prior to stabilizing await, we have to ensure that this + // can't be used to create a generator on stable via `|| await!()`. + yield } } } } From 8df498be1c08bb4a5c6317ef0a5802c362ba26ac Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Thu, 2 Aug 2018 15:30:57 -0500 Subject: [PATCH 11/28] more fixes for everybody_loops --- src/librustc_driver/pretty.rs | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 1e74ae10403a8..2777593b6bd66 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -666,8 +666,10 @@ impl<'a> ReplaceBodyWithLoop<'a> { fn run R>(&mut self, is_const: bool, action: F) -> R { let old_const = mem::replace(&mut self.within_static_or_const, is_const); + let old_blocks = self.nested_blocks.take(); let ret = action(self); self.within_static_or_const = old_const; + self.nested_blocks = old_blocks; ret } @@ -745,6 +747,10 @@ impl<'a> fold::Folder for ReplaceBodyWithLoop<'a> { self.run(is_const, |s| fold::noop_fold_impl_item(i, s)) } + fn fold_anon_const(&mut self, c: ast::AnonConst) -> ast::AnonConst { + self.run(true, |s| fold::noop_fold_anon_const(c, s)) + } + fn fold_block(&mut self, b: P) -> P { fn stmt_to_block(rules: ast::BlockCheckMode, recovered: bool, @@ -811,7 +817,9 @@ impl<'a> fold::Folder for ReplaceBodyWithLoop<'a> { if let Some(old_blocks) = self.nested_blocks.as_mut() { //push our fresh block onto the cache and yield an empty block with `loop {}` - old_blocks.push(new_block); + if !new_block.stmts.is_empty() { + old_blocks.push(new_block); + } stmt_to_block(b.rules, b.recovered, Some(loop_stmt), self.sess) } else { From d6a7a3cab0b93b680802876ab490ce25b6b861f4 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Thu, 2 Aug 2018 15:42:02 -0500 Subject: [PATCH 12/28] add rustdoc test for `everybody_loops` fix --- src/test/rustdoc/traits-in-bodies.rs | 29 ++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 src/test/rustdoc/traits-in-bodies.rs diff --git a/src/test/rustdoc/traits-in-bodies.rs b/src/test/rustdoc/traits-in-bodies.rs new file mode 100644 index 0000000000000..3acf4af5fd247 --- /dev/null +++ b/src/test/rustdoc/traits-in-bodies.rs @@ -0,0 +1,29 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +//prior to fixing `everybody_loops` to preserve items, rustdoc would crash on this file, as it +//didn't see that `SomeStruct` implemented `Clone` + +//FIXME(misdreavus): whenever rustdoc shows traits impl'd inside bodies, make sure this test +//reflects that + +pub struct Bounded(T); + +pub struct SomeStruct; + +fn asdf() -> Bounded { + impl Clone for SomeStruct { + fn clone(&self) -> SomeStruct { + SomeStruct + } + } + + Bounded(SomeStruct) +} From dda85abf099fc6f9f42ee270102117326d4b5184 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Thu, 2 Aug 2018 22:54:09 +0200 Subject: [PATCH 13/28] Stabilize --color and --error-format options in rustdoc --- src/librustdoc/lib.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/lib.rs b/src/librustdoc/lib.rs index 00cad5e376a40..2b413ac25fac1 100644 --- a/src/librustdoc/lib.rs +++ b/src/librustdoc/lib.rs @@ -289,7 +289,7 @@ pub fn opts() -> Vec { "edition to use when compiling rust code (default: 2015)", "EDITION") }), - unstable("color", |o| { + stable("color", |o| { o.optopt("", "color", "Configure coloring of output: @@ -298,7 +298,7 @@ pub fn opts() -> Vec { never = never colorize output", "auto|always|never") }), - unstable("error-format", |o| { + stable("error-format", |o| { o.optopt("", "error-format", "How errors and other messages are produced", From 23bdc82068b679be69a5247cb8d0d44842dbd2c9 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Thu, 2 Aug 2018 13:54:21 -0700 Subject: [PATCH 14/28] RELEASES.md: fix the `hash_map::Entry::or_default` link --- RELEASES.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RELEASES.md b/RELEASES.md index e969b91b2b643..1f7ffb53d3cad 100644 --- a/RELEASES.md +++ b/RELEASES.md @@ -144,7 +144,7 @@ Compatibility Notes [`alloc::handle_alloc_error`]: https://doc.rust-lang.org/std/alloc/fn.handle_alloc_error.html [`btree_map::Entry::or_default`]: https://doc.rust-lang.org/std/collections/btree_map/enum.Entry.html#method.or_default [`fmt::Alignment`]: https://doc.rust-lang.org/std/fmt/enum.Alignment.html -[`hash_map::Entry::or_default`]: https://doc.rust-lang.org/std/collections/btree_map/enum.Entry.html#method.or_default +[`hash_map::Entry::or_default`]: https://doc.rust-lang.org/std/collections/hash_map/enum.Entry.html#method.or_default [`iter::repeat_with`]: https://doc.rust-lang.org/std/iter/fn.repeat_with.html [`num::NonZeroUsize`]: https://doc.rust-lang.org/std/num/struct.NonZeroUsize.html [`num::NonZeroU128`]: https://doc.rust-lang.org/std/num/struct.NonZeroU128.html From 4471537ea046da8d8465e2234fa501c29b201d0c Mon Sep 17 00:00:00 2001 From: Andre Bogus Date: Thu, 2 Aug 2018 22:58:53 +0200 Subject: [PATCH 15/28] make TinyList more readable and optimize remove(_) also add benchmarks Before: ``` test tiny_list::test::bench_insert_empty ... bench: 1 ns/iter (+/- 0) test tiny_list::test::bench_insert_one ... bench: 16 ns/iter (+/- 0) test tiny_list::test::bench_remove_empty ... bench: 2 ns/iter (+/- 0) test tiny_list::test::bench_remove_one ... bench: 6 ns/iter (+/- 0) test tiny_list::test::bench_remove_unknown ... bench: 4 ns/iter (+/- 0) ``` After: ``` test tiny_list::test::bench_insert_empty ... bench: 1 ns/iter (+/- 0) test tiny_list::test::bench_insert_one ... bench: 16 ns/iter (+/- 0) test tiny_list::test::bench_remove_empty ... bench: 0 ns/iter (+/- 0) test tiny_list::test::bench_remove_one ... bench: 3 ns/iter (+/- 0) test tiny_list::test::bench_remove_unknown ... bench: 2 ns/iter (+/- 0) ``` --- src/librustc_data_structures/tiny_list.rs | 81 ++++++++++++++--------- 1 file changed, 49 insertions(+), 32 deletions(-) diff --git a/src/librustc_data_structures/tiny_list.rs b/src/librustc_data_structures/tiny_list.rs index 5b1b2aadec563..c12fc22baf020 100644 --- a/src/librustc_data_structures/tiny_list.rs +++ b/src/librustc_data_structures/tiny_list.rs @@ -50,44 +50,22 @@ impl TinyList { #[inline] pub fn insert(&mut self, data: T) { - let current_head = mem::replace(&mut self.head, None); - - if let Some(current_head) = current_head { - let current_head = Box::new(current_head); - self.head = Some(Element { - data, - next: Some(current_head) - }); - } else { - self.head = Some(Element { - data, - next: None, - }) - } + self.head = Some(Element { + data, + next: mem::replace(&mut self.head, None).map(Box::new), + }); } #[inline] pub fn remove(&mut self, data: &T) -> bool { - let remove_head = if let Some(ref mut head) = self.head { - if head.data == *data { - Some(mem::replace(&mut head.next, None)) - } else { - None + self.head = match self.head { + Some(ref mut head) if head.data == *data => { + mem::replace(&mut head.next, None).map(|x| *x) } - } else { - return false + Some(ref mut head) => return head.remove_next(data), + None => return false, }; - - if let Some(remove_head) = remove_head { - if let Some(next) = remove_head { - self.head = Some(*next); - } else { - self.head = None; - } - return true - } - - self.head.as_mut().unwrap().remove_next(data) + true } #[inline] @@ -156,6 +134,8 @@ impl Element { #[cfg(test)] mod test { use super::*; + extern crate test; + use self::test::Bencher; #[test] fn test_contains_and_insert() { @@ -248,4 +228,41 @@ mod test { assert_eq!(list.len(), 0); } + + #[bench] + fn bench_insert_empty(b: &mut Bencher) { + b.iter(|| { + let mut list = TinyList::new(); + list.insert(1); + }) + } + + #[bench] + fn bench_insert_one(b: &mut Bencher) { + b.iter(|| { + let mut list = TinyList::new_single(0); + list.insert(1); + }) + } + + #[bench] + fn bench_remove_empty(b: &mut Bencher) { + b.iter(|| { + TinyList::new().remove(&1) + }); + } + + #[bench] + fn bench_remove_unknown(b: &mut Bencher) { + b.iter(|| { + TinyList::new_single(0).remove(&1) + }); + } + + #[bench] + fn bench_remove_one(b: &mut Bencher) { + b.iter(|| { + TinyList::new_single(1).remove(&1) + }); + } } From 7e77d19905ebfcc76c19301587baf2c53acf2fd9 Mon Sep 17 00:00:00 2001 From: QuietMisdreavus Date: Thu, 2 Aug 2018 16:24:20 -0500 Subject: [PATCH 16/28] preserve order if blocks are between items --- src/librustc_driver/pretty.rs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 2777593b6bd66..9135c9e179fca 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -798,17 +798,17 @@ impl<'a> fold::Folder for ReplaceBodyWithLoop<'a> { fold::noop_fold_block(b, self) } else { b.map(|b| { - let old_blocks = self.nested_blocks.replace(vec![]); + let mut stmts = vec![]; + for s in b.stmts { + let old_blocks = self.nested_blocks.replace(vec![]); - let mut stmts = b.stmts.into_iter() - .flat_map(|s| self.fold_stmt(s)) - .filter(|s| s.is_item()) - .collect::>(); + stmts.extend(self.fold_stmt(s).into_iter().filter(|s| s.is_item())); - // we put a Some in there earlier with that replace(), so this is valid - let new_blocks = self.nested_blocks.take().unwrap(); - self.nested_blocks = old_blocks; - stmts.extend(new_blocks.into_iter().map(|b| block_to_stmt(b, &self.sess))); + // we put a Some in there earlier with that replace(), so this is valid + let new_blocks = self.nested_blocks.take().unwrap(); + self.nested_blocks = old_blocks; + stmts.extend(new_blocks.into_iter().map(|b| block_to_stmt(b, &self.sess))); + } let mut new_block = ast::Block { stmts, From 71460d4d1144de2ddc4a088b81a30c6bc47dee59 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Fri, 3 Aug 2018 12:15:00 +0200 Subject: [PATCH 17/28] volatile operations docs: clarify that this does not help wrt. concurrency --- src/libcore/ptr.rs | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) diff --git a/src/libcore/ptr.rs b/src/libcore/ptr.rs index 479c10c4ffbae..c8670e5ec34d3 100644 --- a/src/libcore/ptr.rs +++ b/src/libcore/ptr.rs @@ -448,6 +448,12 @@ pub unsafe fn write_unaligned(dst: *mut T, src: T) { /// `write_bytes`, or `copy`). Note that `*src = foo` counts as a use /// because it will attempt to drop the value previously at `*src`. /// +/// Just like in C, whether an operation is volatile has no bearing whatsoever +/// on questions involving concurrent access from multiple threads. Volatile +/// accesses behave exactly like non-atomic accesses in that regard. In particular, +/// a race between a `read_volatile` and any write operation to the same location +/// is undefined behavior. +/// /// # Examples /// /// Basic usage: @@ -498,6 +504,12 @@ pub unsafe fn read_volatile(src: *const T) -> T { /// This is appropriate for initializing uninitialized memory, or overwriting /// memory that has previously been `read` from. /// +/// Just like in C, whether an operation is volatile has no bearing whatsoever +/// on questions involving concurrent access from multiple threads. Volatile +/// accesses behave exactly like non-atomic accesses in that regard. In particular, +/// a race between a `write_volatile` and any other operation (reading or writing) +/// on the same location is undefined behavior. +/// /// # Examples /// /// Basic usage: @@ -1057,6 +1069,12 @@ impl *const T { /// `write_bytes`, or `copy`). Note that `*self = foo` counts as a use /// because it will attempt to drop the value previously at `*self`. /// + /// Just like in C, whether an operation is volatile has no bearing whatsoever + /// on questions involving concurrent access from multiple threads. Volatile + /// accesses behave exactly like non-atomic accesses in that regard. In particular, + /// a race between a `read_volatile` and any write operation to the same location + /// is undefined behavior. + /// /// # Examples /// /// Basic usage: @@ -1790,6 +1808,12 @@ impl *mut T { /// `write_bytes`, or `copy`). Note that `*self = foo` counts as a use /// because it will attempt to drop the value previously at `*self`. /// + /// Just like in C, whether an operation is volatile has no bearing whatsoever + /// on questions involving concurrent access from multiple threads. Volatile + /// accesses behave exactly like non-atomic accesses in that regard. In particular, + /// a race between a `read_volatile` and any write operation to the same location + /// is undefined behavior. + /// /// # Examples /// /// Basic usage: @@ -2105,6 +2129,12 @@ impl *mut T { /// This is appropriate for initializing uninitialized memory, or overwriting /// memory that has previously been `read` from. /// + /// Just like in C, whether an operation is volatile has no bearing whatsoever + /// on questions involving concurrent access from multiple threads. Volatile + /// accesses behave exactly like non-atomic accesses in that regard. In particular, + /// a race between a `write_volatile` and any other operation (reading or writing) + /// on the same location is undefined behavior. + /// /// # Examples /// /// Basic usage: From 94de821002f3378a59c2bf812ce73756f3ed0512 Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 3 Aug 2018 14:18:06 +0300 Subject: [PATCH 18/28] Specify reentrancy gurantees of `Once::call_once` --- src/libstd/sync/once.rs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs index 10282ecb65883..113fbbf1f616a 100644 --- a/src/libstd/sync/once.rs +++ b/src/libstd/sync/once.rs @@ -178,6 +178,10 @@ impl Once { /// happens-before relation between the closure and code executing after the /// return). /// + /// If the given closure recusively invokes `call_once` on the same `Once` + /// instance the exact behavior is not specified, allowed outcomes are + /// a panic or a deadlock. + /// /// # Examples /// /// ``` From a2f9aaf7a35e673c3b8f0825a07505b0294aa24f Mon Sep 17 00:00:00 2001 From: Aleksey Kladov Date: Fri, 3 Aug 2018 16:50:30 +0300 Subject: [PATCH 19/28] Fix trailnig WS --- src/libstd/sync/once.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libstd/sync/once.rs b/src/libstd/sync/once.rs index 113fbbf1f616a..3abc260b45868 100644 --- a/src/libstd/sync/once.rs +++ b/src/libstd/sync/once.rs @@ -178,7 +178,7 @@ impl Once { /// happens-before relation between the closure and code executing after the /// return). /// - /// If the given closure recusively invokes `call_once` on the same `Once` + /// If the given closure recusively invokes `call_once` on the same `Once` /// instance the exact behavior is not specified, allowed outcomes are /// a panic or a deadlock. /// From d4beecaed36f6c8ba8f73f06d89fd20267887749 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 31 Jul 2018 12:07:37 -0600 Subject: [PATCH 20/28] Move validate_crate_name to rustc_metadata --- src/Cargo.lock | 10 ++++++ src/librustc/middle/cstore.rs | 27 ----------------- src/librustc_codegen_utils/Cargo.toml | 1 + src/librustc_codegen_utils/lib.rs | 1 + src/librustc_codegen_utils/link.rs | 5 +-- src/librustc_metadata/Cargo.toml | 1 + src/librustc_metadata/creader.rs | 4 ++- src/librustc_metadata/lib.rs | 1 + src/librustc_metadata_utils/Cargo.toml | 13 ++++++++ src/librustc_metadata_utils/lib.rs | 42 ++++++++++++++++++++++++++ 10 files changed, 75 insertions(+), 30 deletions(-) create mode 100644 src/librustc_metadata_utils/Cargo.toml create mode 100644 src/librustc_metadata_utils/lib.rs diff --git a/src/Cargo.lock b/src/Cargo.lock index 8a94faf2c5294..1455ea506e64a 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -2219,6 +2219,7 @@ dependencies = [ "rustc 0.0.0", "rustc_data_structures 0.0.0", "rustc_incremental 0.0.0", + "rustc_metadata_utils 0.0.0", "rustc_mir 0.0.0", "rustc_target 0.0.0", "syntax 0.0.0", @@ -2352,6 +2353,7 @@ dependencies = [ "rustc 0.0.0", "rustc_data_structures 0.0.0", "rustc_errors 0.0.0", + "rustc_metadata_utils 0.0.0", "rustc_target 0.0.0", "serialize 0.0.0", "syntax 0.0.0", @@ -2359,6 +2361,14 @@ dependencies = [ "syntax_pos 0.0.0", ] +[[package]] +name = "rustc_metadata_utils" +version = "0.0.0" +dependencies = [ + "rustc 0.0.0", + "syntax_pos 0.0.0", +] + [[package]] name = "rustc_mir" version = "0.0.0" diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 54169acac46ac..6132d8f2bf6a1 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -260,33 +260,6 @@ pub trait CrateStore { pub type CrateStoreDyn = dyn CrateStore + sync::Sync; -// FIXME: find a better place for this? -pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option) { - let mut err_count = 0; - { - let mut say = |s: &str| { - match (sp, sess) { - (_, None) => bug!("{}", s), - (Some(sp), Some(sess)) => sess.span_err(sp, s), - (None, Some(sess)) => sess.err(s), - } - err_count += 1; - }; - if s.is_empty() { - say("crate name must not be empty"); - } - for c in s.chars() { - if c.is_alphanumeric() { continue } - if c == '_' { continue } - say(&format!("invalid character `{}` in crate name: `{}`", c, s)); - } - } - - if err_count > 0 { - sess.unwrap().abort_if_errors(); - } -} - /// A dummy crate store that does not support any non-local crates, /// for test purposes. pub struct DummyCrateStore; diff --git a/src/librustc_codegen_utils/Cargo.toml b/src/librustc_codegen_utils/Cargo.toml index 30f533285ddfd..a1f4a323f849e 100644 --- a/src/librustc_codegen_utils/Cargo.toml +++ b/src/librustc_codegen_utils/Cargo.toml @@ -20,3 +20,4 @@ rustc_target = { path = "../librustc_target" } rustc_data_structures = { path = "../librustc_data_structures" } rustc_mir = { path = "../librustc_mir" } rustc_incremental = { path = "../librustc_incremental" } +rustc_metadata_utils = { path = "../librustc_metadata_utils" } diff --git a/src/librustc_codegen_utils/lib.rs b/src/librustc_codegen_utils/lib.rs index f59cf5832fcb4..3ff2388beea2a 100644 --- a/src/librustc_codegen_utils/lib.rs +++ b/src/librustc_codegen_utils/lib.rs @@ -37,6 +37,7 @@ extern crate rustc_incremental; extern crate syntax; extern crate syntax_pos; #[macro_use] extern crate rustc_data_structures; +extern crate rustc_metadata_utils; use rustc::ty::TyCtxt; diff --git a/src/librustc_codegen_utils/link.rs b/src/librustc_codegen_utils/link.rs index aabe931d79c57..b33482eb868ff 100644 --- a/src/librustc_codegen_utils/link.rs +++ b/src/librustc_codegen_utils/link.rs @@ -10,11 +10,12 @@ use rustc::session::config::{self, OutputFilenames, Input, OutputType}; use rustc::session::Session; -use rustc::middle::cstore::{self, LinkMeta}; +use rustc::middle::cstore::LinkMeta; use rustc::hir::svh::Svh; use std::path::{Path, PathBuf}; use syntax::{ast, attr}; use syntax_pos::Span; +use rustc_metadata_utils::validate_crate_name; pub fn out_filename(sess: &Session, crate_type: config::CrateType, @@ -61,7 +62,7 @@ pub fn find_crate_name(sess: Option<&Session>, attrs: &[ast::Attribute], input: &Input) -> String { let validate = |s: String, span: Option| { - cstore::validate_crate_name(sess, &s, span); + validate_crate_name(sess, &s, span); s }; diff --git a/src/librustc_metadata/Cargo.toml b/src/librustc_metadata/Cargo.toml index 338824d5efe4c..6142fe78149ce 100644 --- a/src/librustc_metadata/Cargo.toml +++ b/src/librustc_metadata/Cargo.toml @@ -20,3 +20,4 @@ serialize = { path = "../libserialize" } syntax = { path = "../libsyntax" } syntax_ext = { path = "../libsyntax_ext" } syntax_pos = { path = "../libsyntax_pos" } +rustc_metadata_utils = { path = "../librustc_metadata_utils" } diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 4f808dee61f21..1910540f00b11 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -25,11 +25,13 @@ use rustc::session::config::{Sanitizer, self}; use rustc_target::spec::{PanicStrategy, TargetTriple}; use rustc::session::search_paths::PathKind; use rustc::middle; -use rustc::middle::cstore::{validate_crate_name, ExternCrate, ExternCrateSource}; +use rustc::middle::cstore::{ExternCrate, ExternCrateSource}; use rustc::util::common::record_time; use rustc::util::nodemap::FxHashSet; use rustc::hir::map::Definitions; +use rustc_metadata_utils::validate_crate_name; + use std::ops::Deref; use std::path::PathBuf; use std::{cmp, fs}; diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index 5cba0387d17bb..798b631989bd5 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -37,6 +37,7 @@ extern crate serialize as rustc_serialize; // used by deriving extern crate rustc_errors as errors; extern crate syntax_ext; extern crate proc_macro; +extern crate rustc_metadata_utils; #[macro_use] extern crate rustc; diff --git a/src/librustc_metadata_utils/Cargo.toml b/src/librustc_metadata_utils/Cargo.toml new file mode 100644 index 0000000000000..ef2e73f8e3fc7 --- /dev/null +++ b/src/librustc_metadata_utils/Cargo.toml @@ -0,0 +1,13 @@ +[package] +authors = ["The Rust Project Developers"] +name = "rustc_metadata_utils" +version = "0.0.0" + +[lib] +name = "rustc_metadata_utils" +path = "lib.rs" +crate-type = ["dylib"] + +[dependencies] +rustc = { path = "../librustc" } +syntax_pos = { path = "../libsyntax_pos" } diff --git a/src/librustc_metadata_utils/lib.rs b/src/librustc_metadata_utils/lib.rs new file mode 100644 index 0000000000000..a1e5150390ac1 --- /dev/null +++ b/src/librustc_metadata_utils/lib.rs @@ -0,0 +1,42 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +#[macro_use] +extern crate rustc; +extern crate syntax_pos; + +use rustc::session::Session; +use syntax_pos::Span; + +pub fn validate_crate_name(sess: Option<&Session>, s: &str, sp: Option) { + let mut err_count = 0; + { + let mut say = |s: &str| { + match (sp, sess) { + (_, None) => bug!("{}", s), + (Some(sp), Some(sess)) => sess.span_err(sp, s), + (None, Some(sess)) => sess.err(s), + } + err_count += 1; + }; + if s.is_empty() { + say("crate name must not be empty"); + } + for c in s.chars() { + if c.is_alphanumeric() { continue } + if c == '_' { continue } + say(&format!("invalid character `{}` in crate name: `{}`", c, s)); + } + } + + if err_count > 0 { + sess.unwrap().abort_if_errors(); + } +} From cc1a6b99b0fd5440d528283116c4e94b6a8df4c6 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 31 Jul 2018 14:24:31 -0600 Subject: [PATCH 21/28] Delete dummy crate store --- src/librustc/middle/cstore.rs | 63 ----------------------------------- 1 file changed, 63 deletions(-) diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 6132d8f2bf6a1..793a3f2abc140 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -260,69 +260,6 @@ pub trait CrateStore { pub type CrateStoreDyn = dyn CrateStore + sync::Sync; -/// A dummy crate store that does not support any non-local crates, -/// for test purposes. -pub struct DummyCrateStore; - -#[allow(unused_variables)] -impl CrateStore for DummyCrateStore { - fn crate_data_as_rc_any(&self, krate: CrateNum) -> Lrc - { bug!("crate_data_as_rc_any") } - // item info - fn visibility_untracked(&self, def: DefId) -> ty::Visibility { bug!("visibility") } - fn item_generics_cloned_untracked(&self, def: DefId, sess: &Session) -> ty::Generics - { bug!("item_generics_cloned") } - - // trait/impl-item info - fn associated_item_cloned_untracked(&self, def: DefId) -> ty::AssociatedItem - { bug!("associated_item_cloned") } - - // crate metadata - fn dep_kind_untracked(&self, cnum: CrateNum) -> DepKind { bug!("is_explicitly_linked") } - fn export_macros_untracked(&self, cnum: CrateNum) { bug!("export_macros") } - fn crate_name_untracked(&self, cnum: CrateNum) -> Symbol { bug!("crate_name") } - fn crate_disambiguator_untracked(&self, cnum: CrateNum) -> CrateDisambiguator { - bug!("crate_disambiguator") - } - fn crate_hash_untracked(&self, cnum: CrateNum) -> Svh { bug!("crate_hash") } - fn crate_edition_untracked(&self, cnum: CrateNum) -> Edition { bug!("crate_edition_untracked") } - - // resolve - fn def_key(&self, def: DefId) -> DefKey { bug!("def_key") } - fn def_path(&self, def: DefId) -> hir_map::DefPath { - bug!("relative_def_path") - } - fn def_path_hash(&self, def: DefId) -> hir_map::DefPathHash { - bug!("def_path_hash") - } - fn def_path_table(&self, cnum: CrateNum) -> Lrc { - bug!("def_path_table") - } - fn struct_field_names_untracked(&self, def: DefId) -> Vec { - bug!("struct_field_names") - } - fn item_children_untracked(&self, did: DefId, sess: &Session) -> Vec { - bug!("item_children") - } - fn load_macro_untracked(&self, did: DefId, sess: &Session) -> LoadedMacro { bug!("load_macro") } - - fn crates_untracked(&self) -> Vec { vec![] } - - // utility functions - fn extern_mod_stmt_cnum_untracked(&self, emod_id: ast::NodeId) -> Option { None } - fn encode_metadata<'a, 'tcx>(&self, - tcx: TyCtxt<'a, 'tcx, 'tcx>, - link_meta: &LinkMeta) - -> EncodedMetadata { - bug!("encode_metadata") - } - fn metadata_encoding_version(&self) -> &[u8] { bug!("metadata_encoding_version") } - fn postorder_cnums_untracked(&self) -> Vec { bug!("postorder_cnums_untracked") } - - // access to the metadata loader - fn metadata_loader(&self) -> &dyn MetadataLoader { bug!("metadata_loader") } -} - pub trait CrateLoader { fn process_extern_crate(&mut self, item: &ast::Item, defs: &Definitions) -> CrateNum; From eb0bc642653519f5b8ab460e3d5bb4bff1e58753 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 31 Jul 2018 15:35:35 -0600 Subject: [PATCH 22/28] Visibility is now a query --- src/librustc/middle/cstore.rs | 1 - src/librustc_metadata/cstore_impl.rs | 4 ---- 2 files changed, 5 deletions(-) diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 793a3f2abc140..caa8ad7da995a 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -231,7 +231,6 @@ pub trait CrateStore { fn def_path_table(&self, cnum: CrateNum) -> Lrc; // "queries" used in resolve that aren't tracked for incremental compilation - fn visibility_untracked(&self, def: DefId) -> ty::Visibility; fn export_macros_untracked(&self, cnum: CrateNum); fn dep_kind_untracked(&self, cnum: CrateNum) -> DepKind; fn crate_name_untracked(&self, cnum: CrateNum) -> Symbol; diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index e3a7918f8c589..fc23494585a76 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -420,10 +420,6 @@ impl CrateStore for cstore::CStore { &*self.metadata_loader } - fn visibility_untracked(&self, def: DefId) -> ty::Visibility { - self.get_crate_data(def.krate).get_visibility(def.index) - } - fn item_generics_cloned_untracked(&self, def: DefId, sess: &Session) -> ty::Generics { self.get_crate_data(def.krate).get_generics(def.index, sess) } From 5aec365cb9d3df7b6da30393363ea571f2e60368 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 31 Jul 2018 15:23:31 -0600 Subject: [PATCH 23/28] Store concrete crate stores where possible --- src/Cargo.lock | 1 + src/librustc/middle/cstore.rs | 22 +------------- src/librustc_driver/driver.rs | 15 +++++----- src/librustc_driver/lib.rs | 6 ++-- src/librustc_driver/pretty.rs | 8 +++--- src/librustc_metadata/creader.rs | 13 +++++---- src/librustc_resolve/Cargo.toml | 1 + src/librustc_resolve/build_reduced_graph.rs | 11 +++---- src/librustc_resolve/check_unused.rs | 18 ++++++------ src/librustc_resolve/lib.rs | 30 +++++++++++--------- src/librustc_resolve/macros.rs | 11 ++++--- src/librustc_resolve/resolve_imports.rs | 23 ++++++++------- src/librustdoc/clean/auto_trait.rs | 9 +++--- src/librustdoc/clean/inline.rs | 2 +- src/librustdoc/clean/mod.rs | 2 +- src/librustdoc/core.rs | 9 +++--- src/librustdoc/visit_ast.rs | 10 ++++--- src/librustdoc/visit_lib.rs | 10 ++++--- src/test/run-pass-fulldeps/compiler-calls.rs | 5 ++-- 19 files changed, 101 insertions(+), 105 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 1455ea506e64a..54aeeed4fcd99 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -2451,6 +2451,7 @@ dependencies = [ "rustc 0.0.0", "rustc_data_structures 0.0.0", "rustc_errors 0.0.0", + "rustc_metadata 0.0.0", "syntax 0.0.0", "syntax_pos 0.0.0", ] diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index caa8ad7da995a..492be23fa1714 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -25,7 +25,7 @@ use hir::def; use hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use hir::map as hir_map; -use hir::map::definitions::{Definitions, DefKey, DefPathTable}; +use hir::map::definitions::{DefKey, DefPathTable}; use hir::svh::Svh; use ty::{self, TyCtxt}; use session::{Session, CrateDisambiguator}; @@ -259,26 +259,6 @@ pub trait CrateStore { pub type CrateStoreDyn = dyn CrateStore + sync::Sync; -pub trait CrateLoader { - fn process_extern_crate(&mut self, item: &ast::Item, defs: &Definitions) -> CrateNum; - - fn process_path_extern( - &mut self, - name: Symbol, - span: Span, - ) -> CrateNum; - - fn process_use_extern( - &mut self, - name: Symbol, - span: Span, - id: ast::NodeId, - defs: &Definitions, - ) -> CrateNum; - - fn postprocess(&mut self, krate: &ast::Crate); -} - // This method is used when generating the command line to pass through to // system linker. The linker expects undefined symbols on the left of the // command line to be defined in libraries on the right, not the other way diff --git a/src/librustc_driver/driver.rs b/src/librustc_driver/driver.rs index f178f847aa51e..2c877e27e2ea7 100644 --- a/src/librustc_driver/driver.rs +++ b/src/librustc_driver/driver.rs @@ -20,7 +20,6 @@ use rustc::session::config::{self, Input, OutputFilenames, OutputType}; use rustc::session::search_paths::PathKind; use rustc::lint; use rustc::middle::{self, reachable, resolve_lifetime, stability}; -use rustc::middle::cstore::CrateStoreDyn; use rustc::middle::privacy::AccessLevels; use rustc::ty::{self, AllArenas, Resolutions, TyCtxt}; use rustc::traits; @@ -484,7 +483,7 @@ impl<'a> ::CompilerCalls<'a> for CompileController<'a> { codegen_backend: &dyn (::CodegenBackend), matches: &::getopts::Matches, sess: &Session, - cstore: &dyn (::CrateStore), + cstore: &CStore, input: &Input, odir: &Option, ofile: &Option, @@ -728,9 +727,9 @@ pub struct ExpansionResult { pub hir_forest: hir_map::Forest, } -pub struct InnerExpansionResult<'a> { +pub struct InnerExpansionResult<'a, 'b: 'a> { pub expanded_crate: ast::Crate, - pub resolver: Resolver<'a>, + pub resolver: Resolver<'a, 'b>, pub hir_forest: hir_map::Forest, } @@ -806,7 +805,7 @@ where /// Same as phase_2_configure_and_expand, but doesn't let you keep the resolver /// around -pub fn phase_2_configure_and_expand_inner<'a, F>( +pub fn phase_2_configure_and_expand_inner<'a, 'b: 'a, F>( sess: &'a Session, cstore: &'a CStore, mut krate: ast::Crate, @@ -815,9 +814,9 @@ pub fn phase_2_configure_and_expand_inner<'a, F>( addl_plugins: Option>, make_glob_map: MakeGlobMap, resolver_arenas: &'a ResolverArenas<'a>, - crate_loader: &'a mut CrateLoader, + crate_loader: &'a mut CrateLoader<'b>, after_expand: F, -) -> Result, CompileIncomplete> +) -> Result, CompileIncomplete> where F: FnOnce(&ast::Crate) -> CompileResult, { @@ -1209,7 +1208,7 @@ pub fn phase_3_run_analysis_passes<'tcx, F, R>( codegen_backend: &dyn CodegenBackend, control: &CompileController, sess: &'tcx Session, - cstore: &'tcx CrateStoreDyn, + cstore: &'tcx CStore, hir_map: hir_map::Map<'tcx>, mut analysis: ty::CrateAnalysis, resolutions: Resolutions, diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index df641b8fbc0fe..ed3fda8e72300 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -676,7 +676,7 @@ pub trait CompilerCalls<'a> { _: &dyn CodegenBackend, _: &getopts::Matches, _: &Session, - _: &dyn CrateStore, + _: &CStore, _: &Input, _: &Option, _: &Option) @@ -884,7 +884,7 @@ impl<'a> CompilerCalls<'a> for RustcDefaultCalls { codegen_backend: &dyn CodegenBackend, matches: &getopts::Matches, sess: &Session, - cstore: &dyn CrateStore, + cstore: &CStore, input: &Input, odir: &Option, ofile: &Option) @@ -990,7 +990,7 @@ pub fn enable_save_analysis(control: &mut CompileController) { impl RustcDefaultCalls { pub fn list_metadata(sess: &Session, - cstore: &dyn CrateStore, + cstore: &CStore, matches: &getopts::Matches, input: &Input) -> Compilation { diff --git a/src/librustc_driver/pretty.rs b/src/librustc_driver/pretty.rs index 6433a93a317a6..5c1f3bfbe670b 100644 --- a/src/librustc_driver/pretty.rs +++ b/src/librustc_driver/pretty.rs @@ -20,11 +20,11 @@ use {abort_on_err, driver}; use rustc::ty::{self, TyCtxt, Resolutions, AllArenas}; use rustc::cfg; use rustc::cfg::graphviz::LabelledCFG; -use rustc::middle::cstore::CrateStoreDyn; use rustc::session::Session; use rustc::session::config::{Input, OutputFilenames}; use rustc_borrowck as borrowck; use rustc_borrowck::graphviz as borrowck_dot; +use rustc_metadata::cstore::CStore; use rustc_mir::util::{write_mir_pretty, write_mir_graphviz}; @@ -199,7 +199,7 @@ impl PpSourceMode { } fn call_with_pp_support_hir<'tcx, A, F>(&self, sess: &'tcx Session, - cstore: &'tcx CrateStoreDyn, + cstore: &'tcx CStore, hir_map: &hir_map::Map<'tcx>, analysis: &ty::CrateAnalysis, resolutions: &Resolutions, @@ -918,7 +918,7 @@ pub fn print_after_parsing(sess: &Session, } pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, - cstore: &'tcx CrateStoreDyn, + cstore: &'tcx CStore, hir_map: &hir_map::Map<'tcx>, analysis: &ty::CrateAnalysis, resolutions: &Resolutions, @@ -1074,7 +1074,7 @@ pub fn print_after_hir_lowering<'tcx, 'a: 'tcx>(sess: &'a Session, // with a different callback than the standard driver, so that isn't easy. // Instead, we call that function ourselves. fn print_with_analysis<'tcx, 'a: 'tcx>(sess: &'a Session, - cstore: &'a CrateStoreDyn, + cstore: &'a CStore, hir_map: &hir_map::Map<'tcx>, analysis: &ty::CrateAnalysis, resolutions: &Resolutions, diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 1910540f00b11..b5b47fb35dc21 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -24,7 +24,6 @@ use rustc::session::{Session, CrateDisambiguator}; use rustc::session::config::{Sanitizer, self}; use rustc_target::spec::{PanicStrategy, TargetTriple}; use rustc::session::search_paths::PathKind; -use rustc::middle; use rustc::middle::cstore::{ExternCrate, ExternCrateSource}; use rustc::util::common::record_time; use rustc::util::nodemap::FxHashSet; @@ -1058,8 +1057,8 @@ impl<'a> CrateLoader<'a> { } } -impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> { - fn postprocess(&mut self, krate: &ast::Crate) { +impl<'a> CrateLoader<'a> { + pub fn postprocess(&mut self, krate: &ast::Crate) { // inject the sanitizer runtime before the allocator runtime because all // sanitizers force the use of the `alloc_system` allocator self.inject_sanitizer_runtime(); @@ -1072,7 +1071,9 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> { } } - fn process_extern_crate(&mut self, item: &ast::Item, definitions: &Definitions) -> CrateNum { + pub fn process_extern_crate( + &mut self, item: &ast::Item, definitions: &Definitions, + ) -> CrateNum { match item.node { ast::ItemKind::ExternCrate(orig_name) => { debug!("resolving extern crate stmt. ident: {} orig_name: {:?}", @@ -1115,7 +1116,7 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> { } } - fn process_path_extern( + pub fn process_path_extern( &mut self, name: Symbol, span: Span, @@ -1139,7 +1140,7 @@ impl<'a> middle::cstore::CrateLoader for CrateLoader<'a> { cnum } - fn process_use_extern( + pub fn process_use_extern( &mut self, name: Symbol, span: Span, diff --git a/src/librustc_resolve/Cargo.toml b/src/librustc_resolve/Cargo.toml index 4c8d42cf02f98..837340f70fce7 100644 --- a/src/librustc_resolve/Cargo.toml +++ b/src/librustc_resolve/Cargo.toml @@ -17,3 +17,4 @@ arena = { path = "../libarena" } rustc_errors = { path = "../librustc_errors" } syntax_pos = { path = "../libsyntax_pos" } rustc_data_structures = { path = "../librustc_data_structures" } +rustc_metadata = { path = "../librustc_metadata" } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index ab4d15d0b9040..db905630ee711 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -25,6 +25,7 @@ use rustc::middle::cstore::LoadedMacro; use rustc::hir::def::*; use rustc::hir::def_id::{BUILTIN_MACROS_CRATE, CRATE_DEF_INDEX, LOCAL_CRATE, DefId}; use rustc::ty; +use rustc::middle::cstore::CrateStore; use std::cell::Cell; use rustc_data_structures::sync::Lrc; @@ -86,7 +87,7 @@ struct LegacyMacroImports { imports: Vec<(Name, Span)>, } -impl<'a> Resolver<'a> { +impl<'a, 'cl> Resolver<'a, 'cl> { /// Defines `name` in namespace `ns` of module `parent` to be `def` if it is not yet defined; /// otherwise, reports an error. pub fn define(&mut self, parent: Module<'a>, ident: Ident, ns: Namespace, def: T) @@ -776,13 +777,13 @@ impl<'a> Resolver<'a> { } } -pub struct BuildReducedGraphVisitor<'a, 'b: 'a> { - pub resolver: &'a mut Resolver<'b>, +pub struct BuildReducedGraphVisitor<'a, 'b: 'a, 'c: 'b> { + pub resolver: &'a mut Resolver<'b, 'c>, pub legacy_scope: LegacyScope<'b>, pub expansion: Mark, } -impl<'a, 'b> BuildReducedGraphVisitor<'a, 'b> { +impl<'a, 'b, 'cl> BuildReducedGraphVisitor<'a, 'b, 'cl> { fn visit_invoc(&mut self, id: ast::NodeId) -> &'b InvocationData<'b> { let mark = id.placeholder_to_mark(); self.resolver.current_module.unresolved_invocations.borrow_mut().insert(mark); @@ -806,7 +807,7 @@ macro_rules! method { } } -impl<'a, 'b> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b> { +impl<'a, 'b, 'cl> Visitor<'a> for BuildReducedGraphVisitor<'a, 'b, 'cl> { method!(visit_impl_item: ast::ImplItem, ast::ImplItemKind::Macro, walk_impl_item); method!(visit_expr: ast::Expr, ast::ExprKind::Mac, walk_expr); method!(visit_pat: ast::Pat, ast::PatKind::Mac, walk_pat); diff --git a/src/librustc_resolve/check_unused.rs b/src/librustc_resolve/check_unused.rs index 4c12591c83207..e1b059d2b733f 100644 --- a/src/librustc_resolve/check_unused.rs +++ b/src/librustc_resolve/check_unused.rs @@ -31,8 +31,8 @@ use syntax::visit::{self, Visitor}; use syntax_pos::{Span, MultiSpan, DUMMY_SP}; -struct UnusedImportCheckVisitor<'a, 'b: 'a> { - resolver: &'a mut Resolver<'b>, +struct UnusedImportCheckVisitor<'a, 'b: 'a, 'd: 'b> { + resolver: &'a mut Resolver<'b, 'd>, /// All the (so far) unused imports, grouped path list unused_imports: NodeMap>, base_id: ast::NodeId, @@ -40,21 +40,21 @@ struct UnusedImportCheckVisitor<'a, 'b: 'a> { } // Deref and DerefMut impls allow treating UnusedImportCheckVisitor as Resolver. -impl<'a, 'b> Deref for UnusedImportCheckVisitor<'a, 'b> { - type Target = Resolver<'b>; +impl<'a, 'b, 'd> Deref for UnusedImportCheckVisitor<'a, 'b, 'd> { + type Target = Resolver<'b, 'd>; - fn deref<'c>(&'c self) -> &'c Resolver<'b> { + fn deref<'c>(&'c self) -> &'c Resolver<'b, 'd> { &*self.resolver } } -impl<'a, 'b> DerefMut for UnusedImportCheckVisitor<'a, 'b> { - fn deref_mut<'c>(&'c mut self) -> &'c mut Resolver<'b> { +impl<'a, 'b, 'd> DerefMut for UnusedImportCheckVisitor<'a, 'b, 'd> { + fn deref_mut<'c>(&'c mut self) -> &'c mut Resolver<'b, 'd> { &mut *self.resolver } } -impl<'a, 'b> UnusedImportCheckVisitor<'a, 'b> { +impl<'a, 'b, 'd> UnusedImportCheckVisitor<'a, 'b, 'd> { // We have information about whether `use` (import) directives are actually // used now. If an import is not used at all, we signal a lint error. fn check_import(&mut self, item_id: ast::NodeId, id: ast::NodeId, span: Span) { @@ -77,7 +77,7 @@ impl<'a, 'b> UnusedImportCheckVisitor<'a, 'b> { } } -impl<'a, 'b> Visitor<'a> for UnusedImportCheckVisitor<'a, 'b> { +impl<'a, 'b, 'cl> Visitor<'a> for UnusedImportCheckVisitor<'a, 'b, 'cl> { fn visit_item(&mut self, item: &'a ast::Item) { self.item_span = item.span; diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 9c58d2c1f0b0c..a7fcc89f6b974 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -26,6 +26,7 @@ extern crate arena; #[macro_use] extern crate rustc; extern crate rustc_data_structures; +extern crate rustc_metadata; pub use rustc::hir::def::{Namespace, PerNS}; @@ -34,7 +35,7 @@ use self::RibKind::*; use rustc::hir::map::{Definitions, DefCollector}; use rustc::hir::{self, PrimTy, TyBool, TyChar, TyFloat, TyInt, TyUint, TyStr}; -use rustc::middle::cstore::{CrateStore, CrateLoader}; +use rustc::middle::cstore::CrateStore; use rustc::session::Session; use rustc::lint; use rustc::hir::def::*; @@ -44,6 +45,9 @@ use rustc::ty; use rustc::hir::{Freevar, FreevarMap, TraitCandidate, TraitMap, GlobMap}; use rustc::util::nodemap::{NodeMap, NodeSet, FxHashMap, FxHashSet, DefIdMap}; +use rustc_metadata::creader::CrateLoader; +use rustc_metadata::cstore::CStore; + use syntax::codemap::CodeMap; use syntax::ext::hygiene::{Mark, Transparency, SyntaxContext}; use syntax::ast::{self, Name, NodeId, Ident, FloatTy, IntTy, UintTy}; @@ -687,7 +691,7 @@ impl<'tcx> Visitor<'tcx> for UsePlacementFinder { } /// This thing walks the whole crate in DFS manner, visiting each item, resolving names as it goes. -impl<'a, 'tcx> Visitor<'tcx> for Resolver<'a> { +impl<'a, 'tcx, 'cl> Visitor<'tcx> for Resolver<'a, 'cl> { fn visit_item(&mut self, item: &'tcx Item) { self.resolve_item(item); } @@ -1176,7 +1180,7 @@ impl<'a> NameBinding<'a> { } } - fn get_macro(&self, resolver: &mut Resolver<'a>) -> Lrc { + fn get_macro<'b: 'a>(&self, resolver: &mut Resolver<'a, 'b>) -> Lrc { resolver.get_macro(self.def_ignoring_ambiguity()) } @@ -1291,9 +1295,9 @@ impl PrimitiveTypeTable { /// The main resolver class. /// /// This is the visitor that walks the whole crate. -pub struct Resolver<'a> { +pub struct Resolver<'a, 'b: 'a> { session: &'a Session, - cstore: &'a dyn CrateStore, + cstore: &'a CStore, pub definitions: Definitions, @@ -1389,7 +1393,7 @@ pub struct Resolver<'a> { /// true if `#![feature(use_extern_macros)]` use_extern_macros: bool, - crate_loader: &'a mut dyn CrateLoader, + crate_loader: &'a mut CrateLoader<'b>, macro_names: FxHashSet, macro_prelude: FxHashMap>, pub all_macros: FxHashMap, @@ -1473,7 +1477,7 @@ impl<'a> ResolverArenas<'a> { } } -impl<'a, 'b: 'a> ty::DefIdTree for &'a Resolver<'b> { +impl<'a, 'b: 'a, 'cl: 'b> ty::DefIdTree for &'a Resolver<'b, 'cl> { fn parent(self, id: DefId) -> Option { match id.krate { LOCAL_CRATE => self.definitions.def_key(id.index).parent, @@ -1484,7 +1488,7 @@ impl<'a, 'b: 'a> ty::DefIdTree for &'a Resolver<'b> { /// This interface is used through the AST→HIR step, to embed full paths into the HIR. After that /// the resolver is no longer needed as all the relevant information is inline. -impl<'a> hir::lowering::Resolver for Resolver<'a> { +impl<'a, 'cl> hir::lowering::Resolver for Resolver<'a, 'cl> { fn resolve_hir_path(&mut self, path: &mut hir::Path, is_value: bool) { self.resolve_hir_path_cb(path, is_value, |resolver, span, error| resolve_error(resolver, span, error)) @@ -1537,7 +1541,7 @@ impl<'a> hir::lowering::Resolver for Resolver<'a> { } } -impl<'a> Resolver<'a> { +impl<'a, 'crateloader> Resolver<'a, 'crateloader> { /// Rustdoc uses this to resolve things in a recoverable way. ResolutionError<'a> /// isn't something that can be returned because it can't be made to live that long, /// and also it's a private type. Fortunately rustdoc doesn't need to know the error, @@ -1603,15 +1607,15 @@ impl<'a> Resolver<'a> { } } -impl<'a> Resolver<'a> { +impl<'a, 'crateloader: 'a> Resolver<'a, 'crateloader> { pub fn new(session: &'a Session, - cstore: &'a dyn CrateStore, + cstore: &'a CStore, krate: &Crate, crate_name: &str, make_glob_map: MakeGlobMap, - crate_loader: &'a mut dyn CrateLoader, + crate_loader: &'a mut CrateLoader<'crateloader>, arenas: &'a ResolverArenas<'a>) - -> Resolver<'a> { + -> Resolver<'a, 'crateloader> { let root_def_id = DefId::local(CRATE_DEF_INDEX); let root_module_kind = ModuleKind::Def(Def::Mod(root_def_id), keywords::Invalid.name()); let graph_root = arenas.alloc_module(ModuleData { diff --git a/src/librustc_resolve/macros.rs b/src/librustc_resolve/macros.rs index 60a6bcf499db4..993874d7c0be8 100644 --- a/src/librustc_resolve/macros.rs +++ b/src/librustc_resolve/macros.rs @@ -18,6 +18,7 @@ use rustc::hir::def_id::{DefId, BUILTIN_MACROS_CRATE, CRATE_DEF_INDEX, DefIndex, use rustc::hir::def::{Def, Export}; use rustc::hir::map::{self, DefCollector}; use rustc::{ty, lint}; +use rustc::middle::cstore::CrateStore; use syntax::ast::{self, Name, Ident}; use syntax::attr::{self, HasAttrs}; use syntax::errors::DiagnosticBuilder; @@ -117,7 +118,7 @@ impl<'a> MacroBinding<'a> { } } -impl<'a> base::Resolver for Resolver<'a> { +impl<'a, 'crateloader: 'a> base::Resolver for Resolver<'a, 'crateloader> { fn next_node_id(&mut self) -> ast::NodeId { self.session.next_node_id() } @@ -135,9 +136,11 @@ impl<'a> base::Resolver for Resolver<'a> { } fn eliminate_crate_var(&mut self, item: P) -> P { - struct EliminateCrateVar<'b, 'a: 'b>(&'b mut Resolver<'a>, Span); + struct EliminateCrateVar<'b, 'a: 'b, 'crateloader: 'a>( + &'b mut Resolver<'a, 'crateloader>, Span + ); - impl<'a, 'b> Folder for EliminateCrateVar<'a, 'b> { + impl<'a, 'b, 'crateloader> Folder for EliminateCrateVar<'a, 'b, 'crateloader> { fn fold_path(&mut self, path: ast::Path) -> ast::Path { match self.fold_qpath(None, path) { (None, path) => path, @@ -387,7 +390,7 @@ impl<'a> base::Resolver for Resolver<'a> { } } -impl<'a> Resolver<'a> { +impl<'a, 'cl> Resolver<'a, 'cl> { fn report_proc_macro_stub(&self, span: Span) { self.session.span_err(span, "can't use a procedural macro from the same crate that defines it"); diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index b6ad2f316a0a2..9f748761f7380 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -25,6 +25,7 @@ use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId}; use rustc::hir::def::*; use rustc::session::DiagnosticMessageId; use rustc::util::nodemap::{FxHashMap, FxHashSet}; +use rustc::middle::cstore::CrateStore; use syntax::ast::{Ident, Name, NodeId, CRATE_NODE_ID}; use syntax::ext::base::Determinacy::{self, Determined, Undetermined}; @@ -123,7 +124,7 @@ impl<'a> NameResolution<'a> { } } -impl<'a> Resolver<'a> { +impl<'a, 'crateloader> Resolver<'a, 'crateloader> { fn resolution(&self, module: Module<'a>, ident: Ident, ns: Namespace) -> &'a RefCell> { *module.resolutions.borrow_mut().entry((ident.modern(), ns)) @@ -402,7 +403,7 @@ impl<'a> Resolver<'a> { // If the resolution becomes a success, define it in the module's glob importers. fn update_resolution(&mut self, module: Module<'a>, ident: Ident, ns: Namespace, f: F) -> T - where F: FnOnce(&mut Resolver<'a>, &mut NameResolution<'a>) -> T + where F: FnOnce(&mut Resolver<'a, 'crateloader>, &mut NameResolution<'a>) -> T { // Ensure that `resolution` isn't borrowed when defining in the module's glob importers, // during which the resolution might end up getting re-defined via a glob cycle. @@ -453,30 +454,30 @@ impl<'a> Resolver<'a> { } } -pub struct ImportResolver<'a, 'b: 'a> { - pub resolver: &'a mut Resolver<'b>, +pub struct ImportResolver<'a, 'b: 'a, 'c: 'a + 'b> { + pub resolver: &'a mut Resolver<'b, 'c>, } -impl<'a, 'b: 'a> ::std::ops::Deref for ImportResolver<'a, 'b> { - type Target = Resolver<'b>; - fn deref(&self) -> &Resolver<'b> { +impl<'a, 'b: 'a, 'c: 'a + 'b> ::std::ops::Deref for ImportResolver<'a, 'b, 'c> { + type Target = Resolver<'b, 'c>; + fn deref(&self) -> &Resolver<'b, 'c> { self.resolver } } -impl<'a, 'b: 'a> ::std::ops::DerefMut for ImportResolver<'a, 'b> { - fn deref_mut(&mut self) -> &mut Resolver<'b> { +impl<'a, 'b: 'a, 'c: 'a + 'b> ::std::ops::DerefMut for ImportResolver<'a, 'b, 'c> { + fn deref_mut(&mut self) -> &mut Resolver<'b, 'c> { self.resolver } } -impl<'a, 'b: 'a> ty::DefIdTree for &'a ImportResolver<'a, 'b> { +impl<'a, 'b: 'a, 'c: 'a + 'b> ty::DefIdTree for &'a ImportResolver<'a, 'b, 'c> { fn parent(self, id: DefId) -> Option { self.resolver.parent(id) } } -impl<'a, 'b:'a> ImportResolver<'a, 'b> { +impl<'a, 'b:'a, 'c: 'b> ImportResolver<'a, 'b, 'c> { // Import resolution // // This is a fixed-point algorithm. We resolve imports until our efforts diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index c30d6817b4664..23056218269b6 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -13,6 +13,7 @@ use rustc::traits::{self, auto_trait as auto}; use rustc::ty::{self, ToPredicate, TypeFoldable}; use rustc::ty::subst::Subst; use rustc::infer::InferOk; +use rustc::middle::cstore::CrateStore; use std::fmt::Debug; use syntax_pos::DUMMY_SP; @@ -20,13 +21,13 @@ use core::DocAccessLevels; use super::*; -pub struct AutoTraitFinder<'a, 'tcx: 'a, 'rcx: 'a> { - pub cx: &'a core::DocContext<'a, 'tcx, 'rcx>, +pub struct AutoTraitFinder<'a, 'tcx: 'a, 'rcx: 'a, 'cstore: 'rcx> { + pub cx: &'a core::DocContext<'a, 'tcx, 'rcx, 'cstore>, pub f: auto::AutoTraitFinder<'a, 'tcx>, } -impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { - pub fn new(cx: &'a core::DocContext<'a, 'tcx, 'rcx>) -> Self { +impl<'a, 'tcx, 'rcx, 'cstore> AutoTraitFinder<'a, 'tcx, 'rcx, 'cstore> { + pub fn new(cx: &'a core::DocContext<'a, 'tcx, 'rcx, 'cstore>) -> Self { let f = auto::AutoTraitFinder::new(&cx.tcx); AutoTraitFinder { cx, f } diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 9245ef3cf507b..6ce6144147ea1 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -19,7 +19,7 @@ use syntax_pos::Span; use rustc::hir; use rustc::hir::def::{Def, CtorKind}; use rustc::hir::def_id::DefId; -use rustc::middle::cstore::LoadedMacro; +use rustc::middle::cstore::{CrateStore, LoadedMacro}; use rustc::ty; use rustc::util::nodemap::FxHashSet; diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 45566230fdaae..4512a33ec4a21 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -145,7 +145,7 @@ pub struct Crate { pub masked_crates: FxHashSet, } -impl<'a, 'tcx, 'rcx> Clean for visit_ast::RustdocVisitor<'a, 'tcx, 'rcx> { +impl<'a, 'tcx, 'rcx, 'cstore> Clean for visit_ast::RustdocVisitor<'a, 'tcx, 'rcx, 'cstore> { fn clean(&self, cx: &DocContext) -> Crate { use ::visit_lib::LibEmbargoVisitor; diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 769c9804a355a..84741f12ad183 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -13,7 +13,6 @@ use rustc_driver::{self, driver, target_features, abort_on_err}; use rustc::session::{self, config}; use rustc::hir::def_id::{DefId, CrateNum, LOCAL_CRATE}; use rustc::hir::def::Def; -use rustc::middle::cstore::CrateStore; use rustc::middle::privacy::AccessLevels; use rustc::ty::{self, TyCtxt, AllArenas}; use rustc::hir::map as hir_map; @@ -49,13 +48,13 @@ pub use rustc::session::search_paths::SearchPaths; pub type ExternalPaths = FxHashMap, clean::TypeKind)>; -pub struct DocContext<'a, 'tcx: 'a, 'rcx: 'a> { +pub struct DocContext<'a, 'tcx: 'a, 'rcx: 'a, 'cstore: 'rcx> { pub tcx: TyCtxt<'a, 'tcx, 'tcx>, - pub resolver: &'a RefCell>, + pub resolver: &'a RefCell>, /// The stack of module NodeIds up till this point pub mod_ids: RefCell>, pub crate_name: Option, - pub cstore: Rc, + pub cstore: Rc, pub populated_all_crate_impls: Cell, // Note that external items for which `doc(hidden)` applies to are shown as // non-reachable while local items aren't. This is because we're reusing @@ -87,7 +86,7 @@ pub struct DocContext<'a, 'tcx: 'a, 'rcx: 'a> { pub all_traits: Vec, } -impl<'a, 'tcx, 'rcx> DocContext<'a, 'tcx, 'rcx> { +impl<'a, 'tcx, 'rcx, 'cstore> DocContext<'a, 'tcx, 'rcx, 'cstore> { pub fn sess(&self) -> &session::Session { &self.tcx.sess } diff --git a/src/librustdoc/visit_ast.rs b/src/librustdoc/visit_ast.rs index 287913d2cc9b8..e2c935e2f6921 100644 --- a/src/librustdoc/visit_ast.rs +++ b/src/librustdoc/visit_ast.rs @@ -38,10 +38,10 @@ use doctree::*; // also, is there some reason that this doesn't use the 'visit' // framework from syntax? -pub struct RustdocVisitor<'a, 'tcx: 'a, 'rcx: 'a> { +pub struct RustdocVisitor<'a, 'tcx: 'a, 'rcx: 'a, 'cstore: 'rcx> { pub module: Module, pub attrs: hir::HirVec, - pub cx: &'a core::DocContext<'a, 'tcx, 'rcx>, + pub cx: &'a core::DocContext<'a, 'tcx, 'rcx, 'cstore>, view_item_stack: FxHashSet, inlining: bool, /// Is the current module and all of its parents public? @@ -49,8 +49,10 @@ pub struct RustdocVisitor<'a, 'tcx: 'a, 'rcx: 'a> { exact_paths: Option>>, } -impl<'a, 'tcx, 'rcx> RustdocVisitor<'a, 'tcx, 'rcx> { - pub fn new(cx: &'a core::DocContext<'a, 'tcx, 'rcx>) -> RustdocVisitor<'a, 'tcx, 'rcx> { +impl<'a, 'tcx, 'rcx, 'cstore> RustdocVisitor<'a, 'tcx, 'rcx, 'cstore> { + pub fn new( + cx: &'a core::DocContext<'a, 'tcx, 'rcx, 'cstore> + ) -> RustdocVisitor<'a, 'tcx, 'rcx, 'cstore> { // If the root is re-exported, terminate all recursion. let mut stack = FxHashSet(); stack.insert(ast::CRATE_NODE_ID); diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs index 4c773fc1dd78b..10a4e69dcc6cd 100644 --- a/src/librustdoc/visit_lib.rs +++ b/src/librustdoc/visit_lib.rs @@ -22,8 +22,8 @@ use clean::{AttributesExt, NestedAttributesExt}; /// Similar to `librustc_privacy::EmbargoVisitor`, but also takes /// specific rustdoc annotations into account (i.e. `doc(hidden)`) -pub struct LibEmbargoVisitor<'a, 'tcx: 'a, 'rcx: 'a> { - cx: &'a ::core::DocContext<'a, 'tcx, 'rcx>, +pub struct LibEmbargoVisitor<'a, 'tcx: 'a, 'rcx: 'a, 'cstore: 'rcx> { + cx: &'a ::core::DocContext<'a, 'tcx, 'rcx, 'cstore>, // Accessibility levels for reachable nodes access_levels: RefMut<'a, AccessLevels>, // Previous accessibility level, None means unreachable @@ -32,8 +32,10 @@ pub struct LibEmbargoVisitor<'a, 'tcx: 'a, 'rcx: 'a> { visited_mods: FxHashSet, } -impl<'a, 'tcx, 'rcx> LibEmbargoVisitor<'a, 'tcx, 'rcx> { - pub fn new(cx: &'a ::core::DocContext<'a, 'tcx, 'rcx>) -> LibEmbargoVisitor<'a, 'tcx, 'rcx> { +impl<'a, 'tcx, 'rcx, 'cstore> LibEmbargoVisitor<'a, 'tcx, 'rcx, 'cstore> { + pub fn new( + cx: &'a ::core::DocContext<'a, 'tcx, 'rcx, 'cstore> + ) -> LibEmbargoVisitor<'a, 'tcx, 'rcx, 'cstore> { LibEmbargoVisitor { cx, access_levels: cx.access_levels.borrow_mut(), diff --git a/src/test/run-pass-fulldeps/compiler-calls.rs b/src/test/run-pass-fulldeps/compiler-calls.rs index b3a6fb4d590ae..cc2b6c641e90c 100644 --- a/src/test/run-pass-fulldeps/compiler-calls.rs +++ b/src/test/run-pass-fulldeps/compiler-calls.rs @@ -21,12 +21,13 @@ extern crate rustc_driver; extern crate rustc_codegen_utils; extern crate syntax; extern crate rustc_errors as errors; +extern crate rustc_metadata; -use rustc::middle::cstore::CrateStore; use rustc::session::Session; use rustc::session::config::{self, Input}; use rustc_driver::{driver, CompilerCalls, Compilation}; use rustc_codegen_utils::codegen_backend::CodegenBackend; +use rustc_metadata::cstore::CStore; use syntax::ast; use std::path::PathBuf; @@ -51,7 +52,7 @@ impl<'a> CompilerCalls<'a> for TestCalls<'a> { _: &CodegenBackend, _: &getopts::Matches, _: &Session, - _: &CrateStore, + _: &CStore, _: &Input, _: &Option, _: &Option) From 6fdd6f65cae1dffec4010cbedd05247f6dace3b2 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Tue, 31 Jul 2018 17:23:29 -0600 Subject: [PATCH 24/28] Move unused trait functions to inherent functions --- src/Cargo.lock | 1 + src/librustc/middle/cstore.rs | 18 --- src/librustc_driver/lib.rs | 3 +- src/librustc_metadata/cstore.rs | 5 + src/librustc_metadata/cstore_impl.rs | 149 ++++++++++---------- src/librustc_metadata_utils/Cargo.toml | 1 + src/librustc_resolve/build_reduced_graph.rs | 2 +- src/librustc_resolve/resolve_imports.rs | 1 - src/librustdoc/clean/inline.rs | 2 +- 9 files changed, 81 insertions(+), 101 deletions(-) diff --git a/src/Cargo.lock b/src/Cargo.lock index 54aeeed4fcd99..5f0d96c9c052c 100644 --- a/src/Cargo.lock +++ b/src/Cargo.lock @@ -2366,6 +2366,7 @@ name = "rustc_metadata_utils" version = "0.0.0" dependencies = [ "rustc 0.0.0", + "syntax 0.0.0", "syntax_pos 0.0.0", ] diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 492be23fa1714..0e84104245dcb 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -22,7 +22,6 @@ //! are *mostly* used as a part of that interface, but these should //! probably get a better home if someone can find one. -use hir::def; use hir::def_id::{CrateNum, DefId, LOCAL_CRATE}; use hir::map as hir_map; use hir::map::definitions::{DefKey, DefPathTable}; @@ -34,8 +33,6 @@ use session::search_paths::PathKind; use std::any::Any; use std::path::{Path, PathBuf}; use syntax::ast; -use syntax::edition::Edition; -use syntax::ext::base::SyntaxExtension; use syntax::symbol::Symbol; use syntax_pos::Span; use rustc_target::spec::Target; @@ -140,11 +137,6 @@ pub struct ForeignModule { pub def_id: DefId, } -pub enum LoadedMacro { - MacroDef(ast::Item), - ProcMacro(Lrc), -} - #[derive(Copy, Clone, Debug)] pub struct ExternCrate { pub src: ExternCrateSource, @@ -221,9 +213,6 @@ pub trait MetadataLoader { pub trait CrateStore { fn crate_data_as_rc_any(&self, krate: CrateNum) -> Lrc; - // access to the metadata loader - fn metadata_loader(&self) -> &dyn MetadataLoader; - // resolve fn def_key(&self, def: DefId) -> DefKey; fn def_path(&self, def: DefId) -> hir_map::DefPath; @@ -231,18 +220,11 @@ pub trait CrateStore { fn def_path_table(&self, cnum: CrateNum) -> Lrc; // "queries" used in resolve that aren't tracked for incremental compilation - fn export_macros_untracked(&self, cnum: CrateNum); - fn dep_kind_untracked(&self, cnum: CrateNum) -> DepKind; fn crate_name_untracked(&self, cnum: CrateNum) -> Symbol; fn crate_disambiguator_untracked(&self, cnum: CrateNum) -> CrateDisambiguator; fn crate_hash_untracked(&self, cnum: CrateNum) -> Svh; - fn crate_edition_untracked(&self, cnum: CrateNum) -> Edition; - fn struct_field_names_untracked(&self, def: DefId) -> Vec; - fn item_children_untracked(&self, did: DefId, sess: &Session) -> Vec; - fn load_macro_untracked(&self, did: DefId, sess: &Session) -> LoadedMacro; fn extern_mod_stmt_cnum_untracked(&self, emod_id: ast::NodeId) -> Option; fn item_generics_cloned_untracked(&self, def: DefId, sess: &Session) -> ty::Generics; - fn associated_item_cloned_untracked(&self, def: DefId) -> ty::AssociatedItem; fn postorder_cnums_untracked(&self) -> Vec; // This is basically a 1-based range of ints, which is a little diff --git a/src/librustc_driver/lib.rs b/src/librustc_driver/lib.rs index ed3fda8e72300..74e7d328891e0 100644 --- a/src/librustc_driver/lib.rs +++ b/src/librustc_driver/lib.rs @@ -78,7 +78,6 @@ use rustc::session::filesearch; use rustc::session::{early_error, early_warn}; use rustc::lint::Lint; use rustc::lint; -use rustc::middle::cstore::CrateStore; use rustc_metadata::locator; use rustc_metadata::cstore::CStore; use rustc_metadata::dynamic_lib::DynamicLibrary; @@ -1002,7 +1001,7 @@ impl RustcDefaultCalls { let mut v = Vec::new(); locator::list_file_metadata(&sess.target.target, path, - cstore.metadata_loader(), + &*cstore.metadata_loader, &mut v) .unwrap(); println!("{}", String::from_utf8(v).unwrap()); diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index d93a7f9526e1a..2d3e3080c89e3 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -93,6 +93,11 @@ pub struct CStore { pub metadata_loader: Box, } +pub enum LoadedMacro { + MacroDef(ast::Item), + ProcMacro(Lrc), +} + impl CStore { pub fn new(metadata_loader: Box) -> CStore { CStore { diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs index fc23494585a76..916c0920e0b4b 100644 --- a/src/librustc_metadata/cstore_impl.rs +++ b/src/librustc_metadata/cstore_impl.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use cstore; +use cstore::{self, LoadedMacro}; use encoder; use link_args; use native_libs; @@ -17,8 +17,8 @@ use schema; use rustc::ty::query::QueryConfig; use rustc::middle::cstore::{CrateStore, DepKind, - MetadataLoader, LinkMeta, - LoadedMacro, EncodedMetadata, NativeLibraryKind}; + LinkMeta, + EncodedMetadata, NativeLibraryKind}; use rustc::middle::exported_symbols::ExportedSymbol; use rustc::middle::stability::DeprecationEntry; use rustc::hir::def; @@ -411,32 +411,8 @@ pub fn provide<'tcx>(providers: &mut Providers<'tcx>) { }; } -impl CrateStore for cstore::CStore { - fn crate_data_as_rc_any(&self, krate: CrateNum) -> Lrc { - self.get_crate_data(krate) - } - - fn metadata_loader(&self) -> &dyn MetadataLoader { - &*self.metadata_loader - } - - fn item_generics_cloned_untracked(&self, def: DefId, sess: &Session) -> ty::Generics { - self.get_crate_data(def.krate).get_generics(def.index, sess) - } - - fn associated_item_cloned_untracked(&self, def: DefId) -> ty::AssociatedItem - { - self.get_crate_data(def.krate).get_associated_item(def.index) - } - - fn dep_kind_untracked(&self, cnum: CrateNum) -> DepKind - { - let data = self.get_crate_data(cnum); - let r = *data.dep_kind.lock(); - r - } - - fn export_macros_untracked(&self, cnum: CrateNum) { +impl cstore::CStore { + pub fn export_macros_untracked(&self, cnum: CrateNum) { let data = self.get_crate_data(cnum); let mut dep_kind = data.dep_kind.lock(); if *dep_kind == DepKind::UnexportedMacrosOnly { @@ -444,69 +420,28 @@ impl CrateStore for cstore::CStore { } } - fn crate_name_untracked(&self, cnum: CrateNum) -> Symbol - { - self.get_crate_data(cnum).name - } - - fn crate_disambiguator_untracked(&self, cnum: CrateNum) -> CrateDisambiguator - { - self.get_crate_data(cnum).root.disambiguator - } - - fn crate_hash_untracked(&self, cnum: CrateNum) -> hir::svh::Svh - { - self.get_crate_data(cnum).root.hash + pub fn dep_kind_untracked(&self, cnum: CrateNum) -> DepKind { + let data = self.get_crate_data(cnum); + let r = *data.dep_kind.lock(); + r } - fn crate_edition_untracked(&self, cnum: CrateNum) -> Edition - { + pub fn crate_edition_untracked(&self, cnum: CrateNum) -> Edition { self.get_crate_data(cnum).root.edition } - /// Returns the `DefKey` for a given `DefId`. This indicates the - /// parent `DefId` as well as some idea of what kind of data the - /// `DefId` refers to. - fn def_key(&self, def: DefId) -> DefKey { - // Note: loading the def-key (or def-path) for a def-id is not - // a *read* of its metadata. This is because the def-id is - // really just an interned shorthand for a def-path, which is the - // canonical name for an item. - // - // self.dep_graph.read(DepNode::MetaData(def)); - self.get_crate_data(def.krate).def_key(def.index) - } - - fn def_path(&self, def: DefId) -> DefPath { - // See `Note` above in `def_key()` for why this read is - // commented out: - // - // self.dep_graph.read(DepNode::MetaData(def)); - self.get_crate_data(def.krate).def_path(def.index) - } - - fn def_path_hash(&self, def: DefId) -> DefPathHash { - self.get_crate_data(def.krate).def_path_hash(def.index) - } - - fn def_path_table(&self, cnum: CrateNum) -> Lrc { - self.get_crate_data(cnum).def_path_table.clone() - } - - fn struct_field_names_untracked(&self, def: DefId) -> Vec - { + pub fn struct_field_names_untracked(&self, def: DefId) -> Vec { self.get_crate_data(def.krate).get_struct_field_names(def.index) } - fn item_children_untracked(&self, def_id: DefId, sess: &Session) -> Vec - { + pub fn item_children_untracked(&self, def_id: DefId, sess: &Session) -> Vec { let mut result = vec![]; self.get_crate_data(def_id.krate) .each_child_of_item(def_id.index, |child| result.push(child), sess); result } - fn load_macro_untracked(&self, id: DefId, sess: &Session) -> LoadedMacro { + pub fn load_macro_untracked(&self, id: DefId, sess: &Session) -> LoadedMacro { let data = self.get_crate_data(id.krate); if let Some(ref proc_macros) = data.proc_macros { return LoadedMacro::ProcMacro(proc_macros[id.index.to_proc_macro_index()].1.clone()); @@ -555,6 +490,64 @@ impl CrateStore for cstore::CStore { }) } + pub fn associated_item_cloned_untracked(&self, def: DefId) -> ty::AssociatedItem { + self.get_crate_data(def.krate).get_associated_item(def.index) + } +} + +impl CrateStore for cstore::CStore { + fn crate_data_as_rc_any(&self, krate: CrateNum) -> Lrc { + self.get_crate_data(krate) + } + + fn item_generics_cloned_untracked(&self, def: DefId, sess: &Session) -> ty::Generics { + self.get_crate_data(def.krate).get_generics(def.index, sess) + } + + fn crate_name_untracked(&self, cnum: CrateNum) -> Symbol + { + self.get_crate_data(cnum).name + } + + fn crate_disambiguator_untracked(&self, cnum: CrateNum) -> CrateDisambiguator + { + self.get_crate_data(cnum).root.disambiguator + } + + fn crate_hash_untracked(&self, cnum: CrateNum) -> hir::svh::Svh + { + self.get_crate_data(cnum).root.hash + } + + /// Returns the `DefKey` for a given `DefId`. This indicates the + /// parent `DefId` as well as some idea of what kind of data the + /// `DefId` refers to. + fn def_key(&self, def: DefId) -> DefKey { + // Note: loading the def-key (or def-path) for a def-id is not + // a *read* of its metadata. This is because the def-id is + // really just an interned shorthand for a def-path, which is the + // canonical name for an item. + // + // self.dep_graph.read(DepNode::MetaData(def)); + self.get_crate_data(def.krate).def_key(def.index) + } + + fn def_path(&self, def: DefId) -> DefPath { + // See `Note` above in `def_key()` for why this read is + // commented out: + // + // self.dep_graph.read(DepNode::MetaData(def)); + self.get_crate_data(def.krate).def_path(def.index) + } + + fn def_path_hash(&self, def: DefId) -> DefPathHash { + self.get_crate_data(def.krate).def_path_hash(def.index) + } + + fn def_path_table(&self, cnum: CrateNum) -> Lrc { + self.get_crate_data(cnum).def_path_table.clone() + } + fn crates_untracked(&self) -> Vec { let mut result = vec![]; diff --git a/src/librustc_metadata_utils/Cargo.toml b/src/librustc_metadata_utils/Cargo.toml index ef2e73f8e3fc7..4a5e20376bfb5 100644 --- a/src/librustc_metadata_utils/Cargo.toml +++ b/src/librustc_metadata_utils/Cargo.toml @@ -10,4 +10,5 @@ crate-type = ["dylib"] [dependencies] rustc = { path = "../librustc" } +syntax = { path = "../libsyntax" } syntax_pos = { path = "../libsyntax_pos" } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index db905630ee711..c782f2072b9aa 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -21,11 +21,11 @@ use {PerNS, Resolver, ResolverArenas}; use Namespace::{self, TypeNS, ValueNS, MacroNS}; use {resolve_error, resolve_struct_error, ResolutionError}; -use rustc::middle::cstore::LoadedMacro; use rustc::hir::def::*; use rustc::hir::def_id::{BUILTIN_MACROS_CRATE, CRATE_DEF_INDEX, LOCAL_CRATE, DefId}; use rustc::ty; use rustc::middle::cstore::CrateStore; +use rustc_metadata::cstore::LoadedMacro; use std::cell::Cell; use rustc_data_structures::sync::Lrc; diff --git a/src/librustc_resolve/resolve_imports.rs b/src/librustc_resolve/resolve_imports.rs index 9f748761f7380..a3a9b938bbd6f 100644 --- a/src/librustc_resolve/resolve_imports.rs +++ b/src/librustc_resolve/resolve_imports.rs @@ -25,7 +25,6 @@ use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId}; use rustc::hir::def::*; use rustc::session::DiagnosticMessageId; use rustc::util::nodemap::{FxHashMap, FxHashSet}; -use rustc::middle::cstore::CrateStore; use syntax::ast::{Ident, Name, NodeId, CRATE_NODE_ID}; use syntax::ext::base::Determinacy::{self, Determined, Undetermined}; diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 6ce6144147ea1..8b4df1b7b7d21 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -19,7 +19,7 @@ use syntax_pos::Span; use rustc::hir; use rustc::hir::def::{Def, CtorKind}; use rustc::hir::def_id::DefId; -use rustc::middle::cstore::{CrateStore, LoadedMacro}; +use rustc_metadata::cstore::LoadedMacro; use rustc::ty; use rustc::util::nodemap::FxHashSet; From e2cda7dd821ea7fa7e08a4ffe260c58eb832a025 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Fri, 3 Aug 2018 23:30:16 +0200 Subject: [PATCH 25/28] Fix invalid code css rule --- src/librustdoc/html/static/themes/dark.css | 2 +- src/librustdoc/html/static/themes/light.css | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/librustdoc/html/static/themes/dark.css b/src/librustdoc/html/static/themes/dark.css index b4342f4749185..faca264ea1006 100644 --- a/src/librustdoc/html/static/themes/dark.css +++ b/src/librustdoc/html/static/themes/dark.css @@ -33,7 +33,7 @@ h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.t background: rgba(0, 0, 0, 0); } -.docblock p > code, .docblock-short p > code { +.docblock code, .docblock-short code { background-color: #2A2A2A; } pre { diff --git a/src/librustdoc/html/static/themes/light.css b/src/librustdoc/html/static/themes/light.css index e84e3cb56636e..5725a41d939d5 100644 --- a/src/librustdoc/html/static/themes/light.css +++ b/src/librustdoc/html/static/themes/light.css @@ -35,7 +35,7 @@ h2, h3:not(.impl):not(.method):not(.type):not(.tymethod), h4:not(.method):not(.t background: rgba(0, 0, 0, 0); } -.docblock p > code, .docblock-short p > code { +.docblock code, .docblock-short code { background-color: #F5F5F5; } pre { From 903851f785aaa01b5ae2e9648a2fd1256eea2ba5 Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Wed, 1 Aug 2018 20:38:02 +0100 Subject: [PATCH 26/28] Highlight closure spans for borrow and initialization errors --- .../borrow_check/error_reporting.rs | 519 ++++++++++++------ src/librustc_mir/borrow_check/mod.rs | 2 +- .../borrow_check/mutability_errors.rs | 43 +- .../borrow_check/nll/explain_borrow/mod.rs | 28 +- src/librustc_mir/util/borrowck_errors.rs | 11 +- 5 files changed, 403 insertions(+), 200 deletions(-) diff --git a/src/librustc_mir/borrow_check/error_reporting.rs b/src/librustc_mir/borrow_check/error_reporting.rs index e2ac7dde55854..aabed6686858f 100644 --- a/src/librustc_mir/borrow_check/error_reporting.rs +++ b/src/librustc_mir/borrow_check/error_reporting.rs @@ -10,13 +10,14 @@ use borrow_check::WriteKind; use rustc::middle::region::ScopeTree; +use rustc::mir::VarBindingForm; use rustc::mir::{BindingForm, BorrowKind, ClearCrossCrate, Field, Local}; use rustc::mir::{LocalDecl, LocalKind, Location, Operand, Place}; use rustc::mir::{ProjectionElem, Rvalue, Statement, StatementKind}; -use rustc::mir::VarBindingForm; use rustc::ty; use rustc_data_structures::indexed_vec::Idx; use rustc_data_structures::sync::Lrc; +use rustc_errors::DiagnosticBuilder; use syntax_pos::Span; use super::borrow_set::BorrowData; @@ -30,12 +31,17 @@ use util::borrowck_errors::{BorrowckErrors, Origin}; impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { pub(super) fn report_use_of_moved_or_uninitialized( &mut self, - _context: Context, + context: Context, desired_action: InitializationRequiringAction, (place, span): (&Place<'tcx>, Span), mpi: MovePathIndex, curr_move_out: &FlowAtLocation>, ) { + let use_spans = self + .move_spans(place, context.loc) + .or_else(|| self.borrow_spans(span, context.loc)); + let span = use_spans.args_or_use(); + let mois = self.move_data.path_map[mpi] .iter() .filter(|moi| curr_move_out.contains(moi)) @@ -58,16 +64,21 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { Some(name) => format!("`{}`", name), None => "value".to_owned(), }; - let mut err = self.tcx - .cannot_act_on_uninitialized_variable( - span, - desired_action.as_noun(), - &self - .describe_place_with_options(place, IncludingDowncast(true)) - .unwrap_or("_".to_owned()), - Origin::Mir, - ); + let mut err = self.tcx.cannot_act_on_uninitialized_variable( + span, + desired_action.as_noun(), + &self + .describe_place_with_options(place, IncludingDowncast(true)) + .unwrap_or("_".to_owned()), + Origin::Mir, + ); err.span_label(span, format!("use of possibly uninitialized {}", item_msg)); + + use_spans.var_span_label( + &mut err, + format!("{} occurs due to use in closure", desired_action.as_noun()), + ); + err.buffer(&mut self.errors_buffer); } else { let msg = ""; //FIXME: add "partially " or "collaterally " @@ -82,11 +93,18 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { let mut is_loop_move = false; for moi in &mois { - let move_msg = ""; //FIXME: add " (into closure)" - let move_span = self - .mir - .source_info(self.move_data.moves[**moi].source) - .span; + let move_out = self.move_data.moves[**moi]; + let moved_place = &self.move_data.move_paths[move_out.path].place; + + let move_spans = self.move_spans(moved_place, move_out.source); + let move_span = move_spans.args_or_use(); + + let move_msg = if move_spans.for_closure() { + " into closure" + } else { + "" + }; + if span == move_span { err.span_label( span, @@ -95,8 +113,15 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { is_loop_move = true; } else { err.span_label(move_span, format!("value moved{} here", move_msg)); + move_spans.var_span_label(&mut err, "variable moved due to use in closure"); }; } + + use_spans.var_span_label( + &mut err, + format!("{} occurs due to use in closure", desired_action.as_noun()), + ); + if !is_loop_move { err.span_label( span, @@ -150,7 +175,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { pub(super) fn report_move_out_while_borrowed( &mut self, context: Context, - (place, span): (&Place<'tcx>, Span), + (place, _span): (&Place<'tcx>, Span), borrow: &BorrowData<'tcx>, ) { let tcx = self.tcx; @@ -162,16 +187,25 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { Some(name) => format!("`{}`", name), None => "value".to_owned(), }; + + let borrow_spans = self.retrieve_borrow_spans(borrow); + let borrow_span = borrow_spans.args_or_use(); + + let move_spans = self.move_spans(place, context.loc); + let span = move_spans.args_or_use(); + let mut err = tcx.cannot_move_when_borrowed( span, &self.describe_place(place).unwrap_or("_".to_owned()), Origin::Mir, ); - err.span_label( - self.retrieve_borrow_span(borrow), - format!("borrow of {} occurs here", borrow_msg), - ); + err.span_label(borrow_span, format!("borrow of {} occurs here", borrow_msg)); err.span_label(span, format!("move out of {} occurs here", value_msg)); + + borrow_spans.var_span_label(&mut err, "borrow occurs due to use in closure"); + + move_spans.var_span_label(&mut err, "move occurs due to use in closure"); + self.explain_why_borrow_contains_point(context, borrow, None, &mut err); err.buffer(&mut self.errors_buffer); } @@ -179,92 +213,38 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { pub(super) fn report_use_while_mutably_borrowed( &mut self, context: Context, - (place, span): (&Place<'tcx>, Span), + (place, _span): (&Place<'tcx>, Span), borrow: &BorrowData<'tcx>, ) { let tcx = self.tcx; + + let borrow_spans = self.retrieve_borrow_spans(borrow); + let borrow_span = borrow_spans.args_or_use(); + + // Conflicting borrows are reported separately, so only check for move + // captures. + let use_spans = self.move_spans(place, context.loc); + let span = use_spans.var_or_use(); + let mut err = tcx.cannot_use_when_mutably_borrowed( span, &self.describe_place(place).unwrap_or("_".to_owned()), - self.retrieve_borrow_span(borrow), + borrow_span, &self .describe_place(&borrow.borrowed_place) .unwrap_or("_".to_owned()), Origin::Mir, ); - self.explain_why_borrow_contains_point(context, borrow, None, &mut err); - err.buffer(&mut self.errors_buffer); - } - - /// Finds the span of arguments of a closure (within `maybe_closure_span`) and its usage of - /// the local assigned at `location`. - /// This is done by searching in statements succeeding `location` - /// and originating from `maybe_closure_span`. - pub(super) fn find_closure_span( - &self, - maybe_closure_span: Span, - location: Location, - ) -> Option<(Span, Span)> { - use rustc::hir::ExprKind::Closure; - use rustc::mir::AggregateKind; - - let local = match self.mir[location.block] - .statements - .get(location.statement_index) - { - Some(&Statement { - kind: StatementKind::Assign(Place::Local(local), _), - .. - }) => local, - _ => return None, - }; - - for stmt in &self.mir[location.block].statements[location.statement_index + 1..] { - if maybe_closure_span != stmt.source_info.span { - break; - } + borrow_spans.var_span_label(&mut err, { + let place = &borrow.borrowed_place; + let desc_place = self.describe_place(place).unwrap_or("_".to_owned()); - if let StatementKind::Assign(_, Rvalue::Aggregate(ref kind, ref places)) = stmt.kind { - if let AggregateKind::Closure(def_id, _) = **kind { - debug!("find_closure_span: found closure {:?}", places); + format!("borrow occurs due to use of `{}` in closure", desc_place) + }); - return if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) { - let args_span = if let Closure(_, _, _, span, _) = - self.tcx.hir.expect_expr(node_id).node - { - span - } else { - return None; - }; - - self.tcx - .with_freevars(node_id, |freevars| { - for (v, place) in freevars.iter().zip(places) { - match *place { - Operand::Copy(Place::Local(l)) - | Operand::Move(Place::Local(l)) if local == l => - { - debug!( - "find_closure_span: found captured local {:?}", - l - ); - return Some(v.span); - } - _ => {} - } - } - None - }) - .map(|var_span| (args_span, var_span)) - } else { - None - }; - } - } - } - - None + self.explain_why_borrow_contains_point(context, borrow, None, &mut err); + err.buffer(&mut self.errors_buffer); } pub(super) fn report_conflicting_borrow( @@ -274,14 +254,11 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { gen_borrow_kind: BorrowKind, issued_borrow: &BorrowData<'tcx>, ) { - let issued_span = self.retrieve_borrow_span(issued_borrow); + let issued_spans = self.retrieve_borrow_spans(issued_borrow); + let issued_span = issued_spans.args_or_use(); - let new_closure_span = self.find_closure_span(span, context.loc); - let span = new_closure_span.map(|(args, _)| args).unwrap_or(span); - let old_closure_span = self.find_closure_span(issued_span, issued_borrow.reserve_location); - let issued_span = old_closure_span - .map(|(args, _)| args) - .unwrap_or(issued_span); + let borrow_spans = self.borrow_spans(span, context.loc); + let span = borrow_spans.args_or_use(); let desc_place = self.describe_place(place).unwrap_or("_".to_owned()); let tcx = self.tcx; @@ -368,23 +345,28 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { (BorrowKind::Shared, _, _, BorrowKind::Shared, _, _) => unreachable!(), }; - if let Some((_, var_span)) = old_closure_span { - let place = &issued_borrow.borrowed_place; - let desc_place = self.describe_place(place).unwrap_or("_".to_owned()); - - err.span_label( - var_span, + if issued_spans == borrow_spans { + borrow_spans.var_span_label( + &mut err, format!( - "previous borrow occurs due to use of `{}` in closure", + "borrows occur due to use of `{}` in closure", desc_place ), ); - } + } else { + let borrow_place = &issued_borrow.borrowed_place; + let borrow_place_desc = self.describe_place(borrow_place).unwrap_or("_".to_owned()); + issued_spans.var_span_label( + &mut err, + format!( + "first borrow occurs due to use of `{}` in closure", + borrow_place_desc + ), + ); - if let Some((_, var_span)) = new_closure_span { - err.span_label( - var_span, - format!("borrow occurs due to use of `{}` in closure", desc_place), + borrow_spans.var_span_label( + &mut err, + format!("second borrow occurs due to use of `{}` in closure", desc_place), ); } @@ -407,7 +389,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { .last() .unwrap(); - let borrow_span = self.mir.source_info(borrow.reserve_location).span; + let borrow_spans = self.retrieve_borrow_spans(borrow); + let borrow_span = borrow_spans.var_or_use(); + let proper_span = match *root_place { Place::Local(local) => self.mir.local_decls[local].source_info.span, _ => drop_span, @@ -427,30 +411,30 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { self.access_place_error_reported .insert((root_place.clone(), borrow_span)); - match &self.describe_place(&borrow.borrowed_place) { - Some(name) => { - self.report_local_value_does_not_live_long_enough( - context, - name, - &scope_tree, - &borrow, - drop_span, - borrow_span, - proper_span, - kind.map(|k| (k, place_span.0)), - ); - } - None => { - self.report_temporary_value_does_not_live_long_enough( - context, - &scope_tree, - &borrow, - drop_span, - borrow_span, - proper_span, - ); - } - } + let mut err = match &self.describe_place(&borrow.borrowed_place) { + Some(name) => self.report_local_value_does_not_live_long_enough( + context, + name, + &scope_tree, + &borrow, + drop_span, + borrow_span, + proper_span, + kind.map(|k| (k, place_span.0)), + ), + None => self.report_temporary_value_does_not_live_long_enough( + context, + &scope_tree, + &borrow, + drop_span, + borrow_span, + proper_span, + ), + }; + + borrow_spans.args_span_label(&mut err, "value captured here"); + + err.buffer(&mut self.errors_buffer); } fn report_local_value_does_not_live_long_enough( @@ -463,7 +447,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { borrow_span: Span, _proper_span: Span, kind_place: Option<(WriteKind, &Place<'tcx>)>, - ) { + ) -> DiagnosticBuilder<'cx> { debug!( "report_local_value_does_not_live_long_enough(\ {:?}, {:?}, {:?}, {:?}, {:?}, {:?}\ @@ -481,7 +465,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { ); self.explain_why_borrow_contains_point(context, borrow, kind_place, &mut err); - err.buffer(&mut self.errors_buffer); + err } fn report_temporary_value_does_not_live_long_enough( @@ -492,7 +476,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { drop_span: Span, _borrow_span: Span, proper_span: Span, - ) { + ) -> DiagnosticBuilder<'cx> { debug!( "report_temporary_value_does_not_live_long_enough(\ {:?}, {:?}, {:?}, {:?}, {:?}\ @@ -507,7 +491,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { err.span_label(drop_span, "temporary value only lives until here"); self.explain_why_borrow_contains_point(context, borrow, None, &mut err); - err.buffer(&mut self.errors_buffer); + err } pub(super) fn report_illegal_mutation_of_borrowed( @@ -516,14 +500,19 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { (place, span): (&Place<'tcx>, Span), loan: &BorrowData<'tcx>, ) { + let loan_spans = self.retrieve_borrow_spans(loan); + let loan_span = loan_spans.args_or_use(); + let tcx = self.tcx; let mut err = tcx.cannot_assign_to_borrowed( span, - self.retrieve_borrow_span(loan), + loan_span, &self.describe_place(place).unwrap_or("_".to_owned()), Origin::Mir, ); + loan_spans.var_span_label(&mut err, "borrow occurs due to use in closure"); + self.explain_why_borrow_contains_point(context, loan, None, &mut err); err.buffer(&mut self.errors_buffer); @@ -556,12 +545,22 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { // PATTERN;) then make the error refer to that local, rather than the // place being assigned later. let (place_description, assigned_span) = match local_decl { - Some(LocalDecl { is_user_variable: Some(ClearCrossCrate::Clear), .. }) - | Some(LocalDecl { is_user_variable: Some(ClearCrossCrate::Set( - BindingForm::Var(VarBindingForm { - opt_match_place: None, .. - }))), ..}) - | Some(LocalDecl { is_user_variable: None, .. }) + Some(LocalDecl { + is_user_variable: Some(ClearCrossCrate::Clear), + .. + }) + | Some(LocalDecl { + is_user_variable: + Some(ClearCrossCrate::Set(BindingForm::Var(VarBindingForm { + opt_match_place: None, + .. + }))), + .. + }) + | Some(LocalDecl { + is_user_variable: None, + .. + }) | None => (self.describe_place(place), assigned_span), Some(decl) => (self.describe_place(err_place), decl.source_info.span), }; @@ -647,8 +646,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { Place::Projection(ref proj) => { match proj.elem { ProjectionElem::Deref => { - let upvar_field_projection = place.is_upvar_field_projection( - self.mir, &self.tcx); + let upvar_field_projection = + place.is_upvar_field_projection(self.mir, &self.tcx); if let Some(field) = upvar_field_projection { let var_index = field.index(); let name = self.mir.upvar_decls[var_index].debug_name.to_string(); @@ -666,8 +665,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { &including_downcast, )?; } else if let Place::Local(local) = proj.base { - if let Some(ClearCrossCrate::Set(BindingForm::RefForGuard)) - = self.mir.local_decls[local].is_user_variable { + if let Some(ClearCrossCrate::Set(BindingForm::RefForGuard)) = + self.mir.local_decls[local].is_user_variable + { self.append_place_to_string( &proj.base, buf, @@ -708,8 +708,8 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { ProjectionElem::Field(field, _ty) => { autoderef = true; - let upvar_field_projection = place.is_upvar_field_projection( - self.mir, &self.tcx); + let upvar_field_projection = + place.is_upvar_field_projection(self.mir, &self.tcx); if let Some(field) = upvar_field_projection { let var_index = field.index(); let name = self.mir.upvar_decls[var_index].debug_name.to_string(); @@ -810,7 +810,9 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { ty::TyAdt(def, _) => if def.is_enum() { field.index().to_string() } else { - def.non_enum_variant().fields[field.index()].ident.to_string() + def.non_enum_variant().fields[field.index()] + .ident + .to_string() }, ty::TyTuple(_) => field.index().to_string(), ty::TyRef(_, ty, _) | ty::TyRawPtr(ty::TypeAndMut { ty, .. }) => { @@ -839,11 +841,6 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { } } - // Retrieve span of given borrow from the current MIR representation - crate fn retrieve_borrow_span(&self, borrow: &BorrowData) -> Span { - self.mir.source_info(borrow.reserve_location).span - } - // Retrieve type of a place for the current MIR representation fn retrieve_type_for_place(&self, place: &Place<'tcx>) -> Option { match place { @@ -860,3 +857,205 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { } } } + +// The span(s) associated to a use of a place. +#[derive(Copy, Clone, PartialEq, Eq, Debug)] +pub(super) enum UseSpans { + // The access is caused by capturing a variable for a closure. + ClosureUse { + // The span of the args of the closure, including the `move` keyword if + // it's present. + args_span: Span, + // The span of the first use of the captured variable inside the closure. + var_span: Span + }, + // This access has a single span associated to it: common case. + OtherUse(Span), +} + +impl UseSpans { + pub(super) fn args_or_use(self) -> Span { + match self { + UseSpans::ClosureUse { + args_span: span, .. + } + | UseSpans::OtherUse(span) => span, + } + } + + pub(super) fn var_or_use(self) -> Span { + match self { + UseSpans::ClosureUse { var_span: span, .. } | UseSpans::OtherUse(span) => span, + } + } + + // Add a span label to the arguments of the closure, if it exists. + pub(super) fn args_span_label(self, err: &mut DiagnosticBuilder, message: impl Into) { + if let UseSpans::ClosureUse { args_span, .. } = self { + err.span_label(args_span, message); + } + } + + // Add a span label to the use of the captured variable, if it exists. + pub(super) fn var_span_label(self, err: &mut DiagnosticBuilder, message: impl Into) { + if let UseSpans::ClosureUse { var_span, .. } = self { + err.span_label(var_span, message); + } + } + + pub(super) fn for_closure(self) -> bool { + match self { + UseSpans::ClosureUse { .. } => true, + UseSpans::OtherUse(_) => false, + } + } + + pub(super) fn or_else(self, if_other: F) -> Self + where + F: FnOnce() -> Self, + { + match self { + closure @ UseSpans::ClosureUse { .. } => closure, + UseSpans::OtherUse(_) => if_other(), + } + } +} + +impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { + /// Finds the spans associated to a move or copy of move_place at location. + pub(super) fn move_spans( + &self, + moved_place: &Place<'tcx>, // Could also be an upvar. + location: Location, + ) -> UseSpans { + use self::UseSpans::*; + use rustc::hir::ExprKind::Closure; + use rustc::mir::AggregateKind; + + let stmt = match self.mir[location.block] + .statements + .get(location.statement_index) + { + Some(stmt) => stmt, + None => return OtherUse(self.mir.source_info(location).span), + }; + + if let StatementKind::Assign(_, Rvalue::Aggregate(ref kind, ref places)) = stmt.kind { + if let AggregateKind::Closure(def_id, _) = **kind { + debug!("find_closure_move_span: found closure {:?}", places); + + if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) { + if let Closure(_, _, _, args_span, _) = self.tcx.hir.expect_expr(node_id).node { + if let Some(var_span) = self.tcx.with_freevars(node_id, |freevars| { + for (v, place) in freevars.iter().zip(places) { + match place { + Operand::Copy(place) | Operand::Move(place) + if moved_place == place => + { + debug!( + "find_closure_move_span: found captured local {:?}", + place + ); + return Some(v.span); + } + _ => {} + } + } + None + }) { + return ClosureUse { + args_span, + var_span, + }; + } + } + } + } + } + + return OtherUse(stmt.source_info.span); + } + + /// Finds the span of arguments of a closure (within `maybe_closure_span`) + /// and its usage of the local assigned at `location`. + /// This is done by searching in statements succeeding `location` + /// and originating from `maybe_closure_span`. + pub(super) fn borrow_spans(&self, use_span: Span, location: Location) -> UseSpans { + use self::UseSpans::*; + use rustc::hir::ExprKind::Closure; + use rustc::mir::AggregateKind; + + let local = match self.mir[location.block] + .statements + .get(location.statement_index) + { + Some(&Statement { + kind: StatementKind::Assign(Place::Local(local), _), + .. + }) => local, + _ => return OtherUse(use_span), + }; + + if self.mir.local_kind(local) != LocalKind::Temp { + // operands are always temporaries. + return OtherUse(use_span); + } + + for stmt in &self.mir[location.block].statements[location.statement_index + 1..] { + if let StatementKind::Assign(_, Rvalue::Aggregate(ref kind, ref places)) = stmt.kind { + if let AggregateKind::Closure(def_id, _) = **kind { + debug!("find_closure_borrow_span: found closure {:?}", places); + + return if let Some(node_id) = self.tcx.hir.as_local_node_id(def_id) { + let args_span = if let Closure(_, _, _, span, _) = + self.tcx.hir.expect_expr(node_id).node + { + span + } else { + return OtherUse(use_span); + }; + + self.tcx + .with_freevars(node_id, |freevars| { + for (v, place) in freevars.iter().zip(places) { + match *place { + Operand::Copy(Place::Local(l)) + | Operand::Move(Place::Local(l)) + if local == l => + { + debug!( + "find_closure_borrow_span: found captured local \ + {:?}", + l + ); + return Some(v.span); + } + _ => {} + } + } + None + }).map(|var_span| ClosureUse { + args_span, + var_span, + }).unwrap_or(OtherUse(use_span)) + } else { + OtherUse(use_span) + }; + } + } + + if use_span != stmt.source_info.span { + break; + } + } + + OtherUse(use_span) + } + + /// Helper to retrieve span(s) of given borrow from the current MIR + /// representation + pub(super) fn retrieve_borrow_spans(&self, borrow: &BorrowData) -> UseSpans { + let span = self.mir.source_info(borrow.reserve_location).span; + self.borrow_spans(span, borrow.reserve_location) + } +} diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 4596c7be1c557..320d3a4720321 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -1542,7 +1542,7 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { if borrow_of_local_data(&borrow.borrowed_place) { let err = self.tcx .cannot_borrow_across_generator_yield( - self.retrieve_borrow_span(borrow), + self.retrieve_borrow_spans(borrow).var_or_use(), yield_span, Origin::Mir, ); diff --git a/src/librustc_mir/borrow_check/mutability_errors.rs b/src/librustc_mir/borrow_check/mutability_errors.rs index cd2de3247cfba..e8862320ddf3f 100644 --- a/src/librustc_mir/borrow_check/mutability_errors.rs +++ b/src/librustc_mir/borrow_check/mutability_errors.rs @@ -160,7 +160,6 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> { let act; let acted_on; - let span = match error_access { AccessKind::Move => { err = self.tcx @@ -180,31 +179,23 @@ impl<'a, 'gcx, 'tcx> MirBorrowckCtxt<'a, 'gcx, 'tcx> { act = "borrow as mutable"; acted_on = "borrowed as mutable"; - let closure_span = self.find_closure_span(span, location); - if let Some((args, var)) = closure_span { - err = self.tcx.cannot_borrow_path_as_mutable_because( - args, - &item_msg, - &reason, - Origin::Mir, - ); - err.span_label( - var, - format!( - "mutable borrow occurs due to use of `{}` in closure", - self.describe_place(access_place).unwrap(), - ), - ); - args - } else { - err = self.tcx.cannot_borrow_path_as_mutable_because( - span, - &item_msg, - &reason, - Origin::Mir, - ); - span - } + let borrow_spans = self.borrow_spans(span, location); + let borrow_span = borrow_spans.args_or_use(); + err = self.tcx.cannot_borrow_path_as_mutable_because( + borrow_span, + &item_msg, + &reason, + Origin::Mir, + ); + borrow_spans.var_span_label( + &mut err, + format!( + "mutable borrow occurs due to use of `{}` in closure", + // always Some() if the message is printed. + self.describe_place(access_place).unwrap_or(String::new()), + ) + ); + borrow_span } }; diff --git a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs index d98bba72f7a33..5098b24adc367 100644 --- a/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs +++ b/src/librustc_mir/borrow_check/nll/explain_borrow/mod.rs @@ -62,18 +62,24 @@ impl<'cx, 'gcx, 'tcx> MirBorrowckCtxt<'cx, 'gcx, 'tcx> { ); match find_use::find(mir, regioncx, tcx, region_sub, context.loc) { - Some(Cause::LiveVar(_local, location)) => { - if self.is_borrow_location_in_loop(context.loc) { - err.span_label( - mir.source_info(location).span, - "borrow used here in later iteration of loop".to_string(), - ); + Some(Cause::LiveVar(local, location)) => { + let span = mir.source_info(location).span; + let spans = self.move_spans(&Place::Local(local), location) + .or_else(|| self.borrow_spans(span, location)); + let message = if self.is_borrow_location_in_loop(context.loc) { + if spans.for_closure() { + "borrow captured here by closure in later iteration of loop" + } else { + "borrow used here in later iteration of loop" + } } else { - err.span_label( - mir.source_info(location).span, - "borrow later used here".to_string(), - ); - } + if spans.for_closure() { + "borrow later captured here by closure" + } else { + "borrow later used here" + } + }; + err.span_label(spans.var_or_use(), message); } Some(Cause::DropVar(local, location)) => match &mir.local_decls[local].name { diff --git a/src/librustc_mir/util/borrowck_errors.rs b/src/librustc_mir/util/borrowck_errors.rs index 2d6b6cea03019..0a53361df6e95 100644 --- a/src/librustc_mir/util/borrowck_errors.rs +++ b/src/librustc_mir/util/borrowck_errors.rs @@ -203,8 +203,15 @@ pub trait BorrowckErrors<'cx>: Sized + Copy { desc, OGN = o ); - err.span_label(old_loan_span, "first closure is constructed here"); - err.span_label(new_loan_span, "second closure is constructed here"); + if old_loan_span == new_loan_span { + err.span_label( + old_loan_span, + "closures are constructed here in different iterations of loop" + ); + } else { + err.span_label(old_loan_span, "first closure is constructed here"); + err.span_label(new_loan_span, "second closure is constructed here"); + } if let Some(old_load_end_span) = old_load_end_span { err.span_label(old_load_end_span, "borrow from first closure ends here"); } From 5639e2173b2506ed540ca4a563f0e63731e56bcb Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Wed, 1 Aug 2018 20:40:06 +0100 Subject: [PATCH 27/28] Tests for closure spans --- src/test/ui/nll/closure-access-spans.rs | 68 ++++++++ src/test/ui/nll/closure-access-spans.stderr | 110 +++++++++++++ src/test/ui/nll/closure-borrow-spans.rs | 112 +++++++++++++ src/test/ui/nll/closure-borrow-spans.stderr | 172 ++++++++++++++++++++ src/test/ui/nll/closure-move-spans.rs | 33 ++++ src/test/ui/nll/closure-move-spans.stderr | 39 +++++ src/test/ui/nll/closure-use-spans.rs | 33 ++++ src/test/ui/nll/closure-use-spans.stderr | 33 ++++ src/test/ui/nll/closures-in-loops.rs | 36 ++++ src/test/ui/nll/closures-in-loops.stderr | 30 ++++ 10 files changed, 666 insertions(+) create mode 100644 src/test/ui/nll/closure-access-spans.rs create mode 100644 src/test/ui/nll/closure-access-spans.stderr create mode 100644 src/test/ui/nll/closure-borrow-spans.rs create mode 100644 src/test/ui/nll/closure-borrow-spans.stderr create mode 100644 src/test/ui/nll/closure-move-spans.rs create mode 100644 src/test/ui/nll/closure-move-spans.stderr create mode 100644 src/test/ui/nll/closure-use-spans.rs create mode 100644 src/test/ui/nll/closure-use-spans.stderr create mode 100644 src/test/ui/nll/closures-in-loops.rs create mode 100644 src/test/ui/nll/closures-in-loops.stderr diff --git a/src/test/ui/nll/closure-access-spans.rs b/src/test/ui/nll/closure-access-spans.rs new file mode 100644 index 0000000000000..b49436fabcf74 --- /dev/null +++ b/src/test/ui/nll/closure-access-spans.rs @@ -0,0 +1,68 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// check that accesses due to a closure capture give a special note + +#![feature(nll)] + +fn closure_imm_capture_conflict(mut x: i32) { + let r = &mut x; + || x; //~ ERROR + r.use_mut(); +} + +fn closure_mut_capture_conflict(mut x: i32) { + let r = &mut x; + || x = 2; //~ ERROR + r.use_mut(); +} + +fn closure_unique_capture_conflict(mut x: &mut i32) { + let r = &mut x; + || *x = 2; //~ ERROR + r.use_mut(); +} + +fn closure_copy_capture_conflict(mut x: i32) { + let r = &mut x; + move || x; //~ ERROR + r.use_ref(); +} + +fn closure_move_capture_conflict(mut x: String) { + let r = &x; + || x; //~ ERROR + r.use_ref(); +} + +fn closure_imm_capture_moved(mut x: String) { + let r = x; + || x.len(); //~ ERROR +} + +fn closure_mut_capture_moved(mut x: String) { + let r = x; + || x = String::new(); //~ ERROR +} + +fn closure_unique_capture_moved(x: &mut String) { + let r = x; + || *x = String::new(); //~ ERROR +} + +fn closure_move_capture_moved(x: &mut String) { + let r = x; + || x; //~ ERROR +} + +fn main() {} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } diff --git a/src/test/ui/nll/closure-access-spans.stderr b/src/test/ui/nll/closure-access-spans.stderr new file mode 100644 index 0000000000000..0042b5d7d529b --- /dev/null +++ b/src/test/ui/nll/closure-access-spans.stderr @@ -0,0 +1,110 @@ +error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable + --> $DIR/closure-access-spans.rs:17:5 + | +LL | let r = &mut x; + | ------ mutable borrow occurs here +LL | || x; //~ ERROR + | ^^ - second borrow occurs due to use of `x` in closure + | | + | immutable borrow occurs here +LL | r.use_mut(); + | - borrow later used here + +error[E0499]: cannot borrow `x` as mutable more than once at a time + --> $DIR/closure-access-spans.rs:23:5 + | +LL | let r = &mut x; + | ------ first mutable borrow occurs here +LL | || x = 2; //~ ERROR + | ^^ - second borrow occurs due to use of `x` in closure + | | + | second mutable borrow occurs here +LL | r.use_mut(); + | - borrow later used here + +error[E0500]: closure requires unique access to `x` but it is already borrowed + --> $DIR/closure-access-spans.rs:29:5 + | +LL | let r = &mut x; + | ------ borrow occurs here +LL | || *x = 2; //~ ERROR + | ^^ - second borrow occurs due to use of `x` in closure + | | + | closure construction occurs here +LL | r.use_mut(); + | - borrow later used here + +error[E0503]: cannot use `x` because it was mutably borrowed + --> $DIR/closure-access-spans.rs:35:13 + | +LL | let r = &mut x; + | ------ borrow of `x` occurs here +LL | move || x; //~ ERROR + | ^ use of borrowed `x` +LL | r.use_ref(); + | - borrow later used here + +error[E0505]: cannot move out of `x` because it is borrowed + --> $DIR/closure-access-spans.rs:41:5 + | +LL | let r = &x; + | -- borrow of `x` occurs here +LL | || x; //~ ERROR + | ^^ - move occurs due to use in closure + | | + | move out of `x` occurs here +LL | r.use_ref(); + | - borrow later used here + +error[E0382]: borrow of moved value: `x` + --> $DIR/closure-access-spans.rs:47:5 + | +LL | let r = x; + | - value moved here +LL | || x.len(); //~ ERROR + | ^^ - borrow occurs due to use in closure + | | + | value borrowed here after move + | + = note: move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait + +error[E0382]: borrow of moved value: `x` + --> $DIR/closure-access-spans.rs:52:5 + | +LL | let r = x; + | - value moved here +LL | || x = String::new(); //~ ERROR + | ^^ - borrow occurs due to use in closure + | | + | value borrowed here after move + | + = note: move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait + +error[E0382]: borrow of moved value: `x` + --> $DIR/closure-access-spans.rs:57:5 + | +LL | let r = x; + | - value moved here +LL | || *x = String::new(); //~ ERROR + | ^^ - borrow occurs due to use in closure + | | + | value borrowed here after move + | + = note: move occurs because `x` has type `&mut std::string::String`, which does not implement the `Copy` trait + +error[E0382]: use of moved value: `x` + --> $DIR/closure-access-spans.rs:62:5 + | +LL | let r = x; + | - value moved here +LL | || x; //~ ERROR + | ^^ - use occurs due to use in closure + | | + | value used here after move + | + = note: move occurs because `x` has type `&mut std::string::String`, which does not implement the `Copy` trait + +error: aborting due to 9 previous errors + +Some errors occurred: E0382, E0499, E0500, E0502, E0503, E0505. +For more information about an error, try `rustc --explain E0382`. diff --git a/src/test/ui/nll/closure-borrow-spans.rs b/src/test/ui/nll/closure-borrow-spans.rs new file mode 100644 index 0000000000000..d62dc27dade8f --- /dev/null +++ b/src/test/ui/nll/closure-borrow-spans.rs @@ -0,0 +1,112 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// check that existing borrows due to a closure capture give a special note + +#![feature(nll)] + +fn move_while_borrowed(x: String) { + let f = || x.len(); + let y = x; //~ ERROR + f.use_ref(); +} + +fn borrow_mut_while_borrowed(mut x: i32) { + let f = || x; + let y = &mut x; //~ ERROR + f.use_ref(); +} + +fn drop_while_borrowed() { + let f; + { + let x = 1; + f = || x; //~ ERROR + } + f.use_ref(); +} + +fn assign_while_borrowed(mut x: i32) { + let f = || x; + x = 1; //~ ERROR + f.use_ref(); +} + +fn copy_while_borrowed_mut(mut x: i32) { + let f = || x = 0; + let y = x; //~ ERROR + f.use_ref(); +} + +fn borrow_while_borrowed_mut(mut x: i32) { + let f = || x = 0; + let y = &x; //~ ERROR + f.use_ref(); +} + +fn borrow_mut_while_borrowed_mut(mut x: i32) { + let f = || x = 0; + let y = &mut x; //~ ERROR + f.use_ref(); +} + +fn drop_while_borrowed_mut() { + let f; + { + let mut x = 1; + f = || x = 0; //~ ERROR + } + f.use_ref(); +} + +fn assign_while_borrowed_mut(mut x: i32) { + let f = || x = 0; + x = 1; //~ ERROR + f.use_ref(); +} + +fn copy_while_borrowed_unique(x: &mut i32) { + let f = || *x = 0; + let y = x; //~ ERROR + f.use_ref(); +} + +fn borrow_while_borrowed_unique(x: &mut i32) { + let f = || *x = 0; + let y = &x; //~ ERROR + f.use_ref(); +} + +fn borrow_mut_while_borrowed_unique(mut x: &mut i32) { + let f = || *x = 0; + let y = &mut x; //~ ERROR + f.use_ref(); +} + +fn drop_while_borrowed_unique() { + let mut z = 1; + let f; + { + let x = &mut z; + f = || *x = 0; //~ ERROR + } + f.use_ref(); +} + +fn assign_while_borrowed_unique(x: &mut i32) { + let f = || *x = 0; + *x = 1; //~ ERROR + f.use_ref(); +} + +fn main() {} + +trait Fake { fn use_mut(&mut self) { } fn use_ref(&self) { } } +impl Fake for T { } diff --git a/src/test/ui/nll/closure-borrow-spans.stderr b/src/test/ui/nll/closure-borrow-spans.stderr new file mode 100644 index 0000000000000..1b9420b3c0bf3 --- /dev/null +++ b/src/test/ui/nll/closure-borrow-spans.stderr @@ -0,0 +1,172 @@ +error[E0505]: cannot move out of `x` because it is borrowed + --> $DIR/closure-borrow-spans.rs:17:13 + | +LL | let f = || x.len(); + | -- - borrow occurs due to use in closure + | | + | borrow of `x` occurs here +LL | let y = x; //~ ERROR + | ^ move out of `x` occurs here +LL | f.use_ref(); + | - borrow later used here + +error[E0502]: cannot borrow `x` as mutable because it is also borrowed as immutable + --> $DIR/closure-borrow-spans.rs:23:13 + | +LL | let f = || x; + | -- - first borrow occurs due to use of `x` in closure + | | + | immutable borrow occurs here +LL | let y = &mut x; //~ ERROR + | ^^^^^^ mutable borrow occurs here +LL | f.use_ref(); + | - borrow later used here + +error[E0597]: `x` does not live long enough + --> $DIR/closure-borrow-spans.rs:31:16 + | +LL | f = || x; //~ ERROR + | -- ^ borrowed value does not live long enough + | | + | value captured here +LL | } + | - `x` dropped here while still borrowed +LL | f.use_ref(); + | - borrow later used here + +error[E0506]: cannot assign to `x` because it is borrowed + --> $DIR/closure-borrow-spans.rs:38:5 + | +LL | let f = || x; + | -- - borrow occurs due to use in closure + | | + | borrow of `x` occurs here +LL | x = 1; //~ ERROR + | ^^^^^ assignment to borrowed `x` occurs here +LL | f.use_ref(); + | - borrow later used here + +error[E0503]: cannot use `x` because it was mutably borrowed + --> $DIR/closure-borrow-spans.rs:44:13 + | +LL | let f = || x = 0; + | -- - borrow occurs due to use of `x` in closure + | | + | borrow of `x` occurs here +LL | let y = x; //~ ERROR + | ^ use of borrowed `x` +LL | f.use_ref(); + | - borrow later used here + +error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable + --> $DIR/closure-borrow-spans.rs:50:13 + | +LL | let f = || x = 0; + | -- - first borrow occurs due to use of `x` in closure + | | + | mutable borrow occurs here +LL | let y = &x; //~ ERROR + | ^^ immutable borrow occurs here +LL | f.use_ref(); + | - borrow later used here + +error[E0499]: cannot borrow `x` as mutable more than once at a time + --> $DIR/closure-borrow-spans.rs:56:13 + | +LL | let f = || x = 0; + | -- - first borrow occurs due to use of `x` in closure + | | + | first mutable borrow occurs here +LL | let y = &mut x; //~ ERROR + | ^^^^^^ second mutable borrow occurs here +LL | f.use_ref(); + | - borrow later used here + +error[E0597]: `x` does not live long enough + --> $DIR/closure-borrow-spans.rs:64:16 + | +LL | f = || x = 0; //~ ERROR + | -- ^ borrowed value does not live long enough + | | + | value captured here +LL | } + | - `x` dropped here while still borrowed +LL | f.use_ref(); + | - borrow later used here + +error[E0506]: cannot assign to `x` because it is borrowed + --> $DIR/closure-borrow-spans.rs:71:5 + | +LL | let f = || x = 0; + | -- - borrow occurs due to use in closure + | | + | borrow of `x` occurs here +LL | x = 1; //~ ERROR + | ^^^^^ assignment to borrowed `x` occurs here +LL | f.use_ref(); + | - borrow later used here + +error[E0505]: cannot move out of `x` because it is borrowed + --> $DIR/closure-borrow-spans.rs:77:13 + | +LL | let f = || *x = 0; + | -- - borrow occurs due to use in closure + | | + | borrow of `x` occurs here +LL | let y = x; //~ ERROR + | ^ move out of `x` occurs here +LL | f.use_ref(); + | - borrow later used here + +error[E0501]: cannot borrow `x` as immutable because previous closure requires unique access + --> $DIR/closure-borrow-spans.rs:83:13 + | +LL | let f = || *x = 0; + | -- - first borrow occurs due to use of `x` in closure + | | + | closure construction occurs here +LL | let y = &x; //~ ERROR + | ^^ borrow occurs here +LL | f.use_ref(); + | - borrow later used here + +error[E0501]: cannot borrow `x` as mutable because previous closure requires unique access + --> $DIR/closure-borrow-spans.rs:89:13 + | +LL | let f = || *x = 0; + | -- - first borrow occurs due to use of `x` in closure + | | + | closure construction occurs here +LL | let y = &mut x; //~ ERROR + | ^^^^^^ borrow occurs here +LL | f.use_ref(); + | - borrow later used here + +error[E0597]: `x` does not live long enough + --> $DIR/closure-borrow-spans.rs:98:17 + | +LL | f = || *x = 0; //~ ERROR + | -- ^ borrowed value does not live long enough + | | + | value captured here +LL | } + | - `x` dropped here while still borrowed +LL | f.use_ref(); + | - borrow later used here + +error[E0506]: cannot assign to `*x` because it is borrowed + --> $DIR/closure-borrow-spans.rs:105:5 + | +LL | let f = || *x = 0; + | -- - borrow occurs due to use in closure + | | + | borrow of `*x` occurs here +LL | *x = 1; //~ ERROR + | ^^^^^^ assignment to borrowed `*x` occurs here +LL | f.use_ref(); + | - borrow later used here + +error: aborting due to 14 previous errors + +Some errors occurred: E0499, E0501, E0502, E0503, E0505, E0506, E0597. +For more information about an error, try `rustc --explain E0499`. diff --git a/src/test/ui/nll/closure-move-spans.rs b/src/test/ui/nll/closure-move-spans.rs new file mode 100644 index 0000000000000..7e836275c8bff --- /dev/null +++ b/src/test/ui/nll/closure-move-spans.rs @@ -0,0 +1,33 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// check that moves due to a closure capture give a special note + +#![feature(nll)] + +fn move_after_move(x: String) { + || x; + let y = x; //~ ERROR +} + +fn borrow_after_move(x: String) { + || x; + let y = &x; //~ ERROR +} + +fn borrow_mut_after_move(mut x: String) { + || x; + let y = &mut x; //~ ERROR +} + +fn fn_ref(f: F) -> F { f } +fn fn_mut(f: F) -> F { f } + +fn main() {} diff --git a/src/test/ui/nll/closure-move-spans.stderr b/src/test/ui/nll/closure-move-spans.stderr new file mode 100644 index 0000000000000..80b7b4246a747 --- /dev/null +++ b/src/test/ui/nll/closure-move-spans.stderr @@ -0,0 +1,39 @@ +error[E0382]: use of moved value: `x` + --> $DIR/closure-move-spans.rs:17:13 + | +LL | || x; + | -- - variable moved due to use in closure + | | + | value moved into closure here +LL | let y = x; //~ ERROR + | ^ value used here after move + | + = note: move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait + +error[E0382]: borrow of moved value: `x` + --> $DIR/closure-move-spans.rs:22:13 + | +LL | || x; + | -- - variable moved due to use in closure + | | + | value moved into closure here +LL | let y = &x; //~ ERROR + | ^^ value borrowed here after move + | + = note: move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait + +error[E0382]: borrow of moved value: `x` + --> $DIR/closure-move-spans.rs:27:13 + | +LL | || x; + | -- - variable moved due to use in closure + | | + | value moved into closure here +LL | let y = &mut x; //~ ERROR + | ^^^^^^ value borrowed here after move + | + = note: move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0382`. diff --git a/src/test/ui/nll/closure-use-spans.rs b/src/test/ui/nll/closure-use-spans.rs new file mode 100644 index 0000000000000..7ab382a96bbb4 --- /dev/null +++ b/src/test/ui/nll/closure-use-spans.rs @@ -0,0 +1,33 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// check that liveness due to a closure capture gives a special note + +#![feature(nll)] + +fn use_as_borrow_capture(mut x: i32) { + let y = &x; + x = 0; //~ ERROR + || *y; +} + +fn use_as_borrow_mut_capture(mut x: i32) { + let y = &mut x; + x = 0; //~ ERROR + || *y = 1; +} + +fn use_as_move_capture(mut x: i32) { + let y = &x; + x = 0; //~ ERROR + move || *y; +} + +fn main() {} diff --git a/src/test/ui/nll/closure-use-spans.stderr b/src/test/ui/nll/closure-use-spans.stderr new file mode 100644 index 0000000000000..7e5f9621d0955 --- /dev/null +++ b/src/test/ui/nll/closure-use-spans.stderr @@ -0,0 +1,33 @@ +error[E0506]: cannot assign to `x` because it is borrowed + --> $DIR/closure-use-spans.rs:17:5 + | +LL | let y = &x; + | -- borrow of `x` occurs here +LL | x = 0; //~ ERROR + | ^^^^^ assignment to borrowed `x` occurs here +LL | || *y; + | - borrow later captured here by closure + +error[E0506]: cannot assign to `x` because it is borrowed + --> $DIR/closure-use-spans.rs:23:5 + | +LL | let y = &mut x; + | ------ borrow of `x` occurs here +LL | x = 0; //~ ERROR + | ^^^^^ assignment to borrowed `x` occurs here +LL | || *y = 1; + | - borrow later captured here by closure + +error[E0506]: cannot assign to `x` because it is borrowed + --> $DIR/closure-use-spans.rs:29:5 + | +LL | let y = &x; + | -- borrow of `x` occurs here +LL | x = 0; //~ ERROR + | ^^^^^ assignment to borrowed `x` occurs here +LL | move || *y; + | - borrow later captured here by closure + +error: aborting due to 3 previous errors + +For more information about this error, try `rustc --explain E0506`. diff --git a/src/test/ui/nll/closures-in-loops.rs b/src/test/ui/nll/closures-in-loops.rs new file mode 100644 index 0000000000000..c6113f3a9c50a --- /dev/null +++ b/src/test/ui/nll/closures-in-loops.rs @@ -0,0 +1,36 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +// Test messages where a closure capture conflicts with itself because it's in +// a loop. + +#![feature(nll)] + +fn repreated_move(x: String) { + for i in 0..10 { + || x; //~ ERROR + } +} + +fn repreated_mut_borrow(mut x: String) { + let mut v = Vec::new(); + for i in 0..10 { + v.push(|| x = String::new()); //~ ERROR + } +} + +fn repreated_unique_borrow(x: &mut String) { + let mut v = Vec::new(); + for i in 0..10 { + v.push(|| *x = String::new()); //~ ERROR + } +} + +fn main() {} diff --git a/src/test/ui/nll/closures-in-loops.stderr b/src/test/ui/nll/closures-in-loops.stderr new file mode 100644 index 0000000000000..9758a80362000 --- /dev/null +++ b/src/test/ui/nll/closures-in-loops.stderr @@ -0,0 +1,30 @@ +error[E0382]: use of moved value: `x` + --> $DIR/closures-in-loops.rs:18:9 + | +LL | || x; //~ ERROR + | ^^ - use occurs due to use in closure + | | + | value moved into closure here in previous iteration of loop + | + = note: move occurs because `x` has type `std::string::String`, which does not implement the `Copy` trait + +error[E0499]: cannot borrow `x` as mutable more than once at a time + --> $DIR/closures-in-loops.rs:25:16 + | +LL | v.push(|| x = String::new()); //~ ERROR + | ^^ - borrows occur due to use of `x` in closure + | | + | mutable borrow starts here in previous iteration of loop + +error[E0524]: two closures require unique access to `x` at the same time + --> $DIR/closures-in-loops.rs:32:16 + | +LL | v.push(|| *x = String::new()); //~ ERROR + | ^^ - borrows occur due to use of `x` in closure + | | + | closures are constructed here in different iterations of loop + +error: aborting due to 3 previous errors + +Some errors occurred: E0382, E0499, E0524. +For more information about an error, try `rustc --explain E0382`. From 12af36a5c4638755be622c220efadffb1864f2ab Mon Sep 17 00:00:00 2001 From: Matthew Jasper Date: Wed, 1 Aug 2018 21:02:10 +0100 Subject: [PATCH 28/28] Update tests for new spans for nll errors involving closures --- .../borrowck/borrowck-closures-two-mut.stderr | 20 +-- ...rrowck-escaping-closure-error-1.nll.stderr | 6 +- ...rrowck-escaping-closure-error-2.nll.stderr | 6 +- src/test/ui/error-codes/E0504.nll.stderr | 17 ++- src/test/ui/issue-11192.nll.stderr | 2 +- src/test/ui/issue-11873.nll.stderr | 4 +- src/test/ui/issue-18783.nll.stderr | 8 +- src/test/ui/issue-24357.nll.stderr | 4 +- ...e-27282-move-match-input-into-guard.stderr | 10 +- ...27282-mutate-before-diverging-arm-1.stderr | 2 +- ...27282-mutate-before-diverging-arm-2.stderr | 2 +- src/test/ui/issue-4335.nll.stderr | 6 +- src/test/ui/issue-6801.nll.stderr | 4 +- src/test/ui/nll/closure-captures.rs | 2 +- .../escape-upvar-nested.rs | 4 +- .../escape-upvar-nested.stderr | 26 ++-- .../escape-upvar-ref.stderr | 6 +- src/test/ui/nll/issue-51268.stderr | 2 +- ...borrow-params-issue-29793-small.nll.stderr | 120 ++++++++++++------ src/test/ui/regions-nested-fns-2.nll.stderr | 17 +-- ...owck-call-is-borrow-issue-12224.nll.stderr | 25 ++-- ...d-is-not-static-ensures-scoping.nll.stderr | 21 ++- 22 files changed, 184 insertions(+), 130 deletions(-) diff --git a/src/test/ui/borrowck/borrowck-closures-two-mut.stderr b/src/test/ui/borrowck/borrowck-closures-two-mut.stderr index a4f8e8b408ba5..6186c3839193d 100644 --- a/src/test/ui/borrowck/borrowck-closures-two-mut.stderr +++ b/src/test/ui/borrowck/borrowck-closures-two-mut.stderr @@ -77,11 +77,11 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir) --> $DIR/borrowck-closures-two-mut.rs:24:24 | LL | let c1 = to_fn_mut(|| x = 4); - | -- - previous borrow occurs due to use of `x` in closure + | -- - first borrow occurs due to use of `x` in closure | | | first mutable borrow occurs here LL | let c2 = to_fn_mut(|| x = 5); //~ ERROR cannot borrow `x` as mutable more than once - | ^^ - borrow occurs due to use of `x` in closure + | ^^ - second borrow occurs due to use of `x` in closure | | | second mutable borrow occurs here LL | //~| ERROR cannot borrow `x` as mutable more than once @@ -92,11 +92,11 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir) --> $DIR/borrowck-closures-two-mut.rs:36:24 | LL | let c1 = to_fn_mut(|| set(&mut x)); - | -- - previous borrow occurs due to use of `x` in closure + | -- - first borrow occurs due to use of `x` in closure | | | first mutable borrow occurs here LL | let c2 = to_fn_mut(|| set(&mut x)); //~ ERROR cannot borrow `x` as mutable more than once - | ^^ - borrow occurs due to use of `x` in closure + | ^^ - second borrow occurs due to use of `x` in closure | | | second mutable borrow occurs here LL | //~| ERROR cannot borrow `x` as mutable more than once @@ -107,11 +107,11 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir) --> $DIR/borrowck-closures-two-mut.rs:44:24 | LL | let c1 = to_fn_mut(|| x = 5); - | -- - previous borrow occurs due to use of `x` in closure + | -- - first borrow occurs due to use of `x` in closure | | | first mutable borrow occurs here LL | let c2 = to_fn_mut(|| set(&mut x)); //~ ERROR cannot borrow `x` as mutable more than once - | ^^ - borrow occurs due to use of `x` in closure + | ^^ - second borrow occurs due to use of `x` in closure | | | second mutable borrow occurs here LL | //~| ERROR cannot borrow `x` as mutable more than once @@ -122,11 +122,11 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir) --> $DIR/borrowck-closures-two-mut.rs:52:24 | LL | let c1 = to_fn_mut(|| x = 5); - | -- - previous borrow occurs due to use of `x` in closure + | -- - first borrow occurs due to use of `x` in closure | | | first mutable borrow occurs here LL | let c2 = to_fn_mut(|| { let _y = to_fn_mut(|| set(&mut x)); }); // (nested closure) - | ^^ - borrow occurs due to use of `x` in closure + | ^^ - second borrow occurs due to use of `x` in closure | | | second mutable borrow occurs here ... @@ -137,11 +137,11 @@ error[E0499]: cannot borrow `x` as mutable more than once at a time (Mir) --> $DIR/borrowck-closures-two-mut.rs:65:24 | LL | let c1 = to_fn_mut(|| set(&mut *x.f)); - | -- - previous borrow occurs due to use of `x` in closure + | -- - first borrow occurs due to use of `x` in closure | | | first mutable borrow occurs here LL | let c2 = to_fn_mut(|| set(&mut *x.f)); - | ^^ - borrow occurs due to use of `x` in closure + | ^^ - second borrow occurs due to use of `x` in closure | | | second mutable borrow occurs here ... diff --git a/src/test/ui/borrowck/borrowck-escaping-closure-error-1.nll.stderr b/src/test/ui/borrowck/borrowck-escaping-closure-error-1.nll.stderr index b15f156b7c201..426419a7b3b7f 100644 --- a/src/test/ui/borrowck/borrowck-escaping-closure-error-1.nll.stderr +++ b/src/test/ui/borrowck/borrowck-escaping-closure-error-1.nll.stderr @@ -1,8 +1,10 @@ error[E0597]: `books` does not live long enough - --> $DIR/borrowck-escaping-closure-error-1.rs:23:11 + --> $DIR/borrowck-escaping-closure-error-1.rs:23:14 | LL | spawn(|| books.push(4)); - | ^^^^^^^^^^^^^^^^ borrowed value does not live long enough + | -- ^^^^^ borrowed value does not live long enough + | | + | value captured here LL | //~^ ERROR E0373 LL | } | - `books` dropped here while still borrowed diff --git a/src/test/ui/borrowck/borrowck-escaping-closure-error-2.nll.stderr b/src/test/ui/borrowck/borrowck-escaping-closure-error-2.nll.stderr index 8c643973af67b..d5f3a0ed6d82e 100644 --- a/src/test/ui/borrowck/borrowck-escaping-closure-error-2.nll.stderr +++ b/src/test/ui/borrowck/borrowck-escaping-closure-error-2.nll.stderr @@ -1,8 +1,10 @@ error[E0597]: `books` does not live long enough - --> $DIR/borrowck-escaping-closure-error-2.rs:21:14 + --> $DIR/borrowck-escaping-closure-error-2.rs:21:17 | LL | Box::new(|| books.push(4)) - | ^^^^^^^^^^^^^^^^ borrowed value does not live long enough + | -- ^^^^^ borrowed value does not live long enough + | | + | value captured here LL | //~^ ERROR E0373 LL | } | - `books` dropped here while still borrowed diff --git a/src/test/ui/error-codes/E0504.nll.stderr b/src/test/ui/error-codes/E0504.nll.stderr index ec30bb306fc3f..6f4823326ffa6 100644 --- a/src/test/ui/error-codes/E0504.nll.stderr +++ b/src/test/ui/error-codes/E0504.nll.stderr @@ -1,17 +1,16 @@ error[E0505]: cannot move out of `fancy_num` because it is borrowed --> $DIR/E0504.rs:19:13 | -LL | let fancy_ref = &fancy_num; - | ---------- borrow of `fancy_num` occurs here +LL | let fancy_ref = &fancy_num; + | ---------- borrow of `fancy_num` occurs here LL | -LL | let x = move || { - | _____________^ -LL | | println!("child function: {}", fancy_num.num); //~ ERROR E0504 -LL | | }; - | |_____^ move out of `fancy_num` occurs here +LL | let x = move || { + | ^^^^^^^ move out of `fancy_num` occurs here +LL | println!("child function: {}", fancy_num.num); //~ ERROR E0504 + | --------- move occurs due to use in closure ... -LL | println!("main function: {}", fancy_ref.num); - | ------------- borrow later used here +LL | println!("main function: {}", fancy_ref.num); + | ------------- borrow later used here error: aborting due to previous error diff --git a/src/test/ui/issue-11192.nll.stderr b/src/test/ui/issue-11192.nll.stderr index d5a67083a23b8..a7e6c9f2b3371 100644 --- a/src/test/ui/issue-11192.nll.stderr +++ b/src/test/ui/issue-11192.nll.stderr @@ -5,7 +5,7 @@ LL | let mut test = |foo: &Foo| { | ----------- mutable borrow occurs here LL | println!("access {}", foo.x); LL | ptr = box Foo { x: ptr.x + 1 }; - | --- previous borrow occurs due to use of `ptr` in closure + | --- first borrow occurs due to use of `ptr` in closure ... LL | test(&*ptr); | -----^^^^^- diff --git a/src/test/ui/issue-11873.nll.stderr b/src/test/ui/issue-11873.nll.stderr index c12cbbfdd53a1..bf4fed06dee21 100644 --- a/src/test/ui/issue-11873.nll.stderr +++ b/src/test/ui/issue-11873.nll.stderr @@ -2,7 +2,9 @@ error[E0505]: cannot move out of `v` because it is borrowed --> $DIR/issue-11873.rs:14:14 | LL | let mut f = || v.push(2); - | ------------ borrow of `v` occurs here + | -- - borrow occurs due to use in closure + | | + | borrow of `v` occurs here LL | let _w = v; //~ ERROR: cannot move out of `v` | ^ move out of `v` occurs here LL | diff --git a/src/test/ui/issue-18783.nll.stderr b/src/test/ui/issue-18783.nll.stderr index 6bb7b4229d747..8acdc73bf0e68 100644 --- a/src/test/ui/issue-18783.nll.stderr +++ b/src/test/ui/issue-18783.nll.stderr @@ -2,11 +2,11 @@ error[E0499]: cannot borrow `y` as mutable more than once at a time --> $DIR/issue-18783.rs:17:21 | LL | c.push(Box::new(|| y = 0)); - | -- - previous borrow occurs due to use of `y` in closure + | -- - first borrow occurs due to use of `y` in closure | | | first mutable borrow occurs here LL | c.push(Box::new(|| y = 0)); - | ^^ - borrow occurs due to use of `y` in closure + | ^^ - second borrow occurs due to use of `y` in closure | | | second mutable borrow occurs here LL | //~^ ERROR cannot borrow `y` as mutable more than once at a time @@ -17,11 +17,11 @@ error[E0499]: cannot borrow `y` as mutable more than once at a time --> $DIR/issue-18783.rs:26:29 | LL | Push::push(&c, Box::new(|| y = 0)); - | -- - previous borrow occurs due to use of `y` in closure + | -- - first borrow occurs due to use of `y` in closure | | | first mutable borrow occurs here LL | Push::push(&c, Box::new(|| y = 0)); - | ^^ - borrow occurs due to use of `y` in closure + | ^^ - second borrow occurs due to use of `y` in closure | | | second mutable borrow occurs here LL | //~^ ERROR cannot borrow `y` as mutable more than once at a time diff --git a/src/test/ui/issue-24357.nll.stderr b/src/test/ui/issue-24357.nll.stderr index f601a6fbc8850..e35f443548d90 100644 --- a/src/test/ui/issue-24357.nll.stderr +++ b/src/test/ui/issue-24357.nll.stderr @@ -2,7 +2,9 @@ error[E0382]: use of moved value: `x` --> $DIR/issue-24357.rs:16:12 | LL | let f = move || { let y = x; }; - | ---------------------- value moved here + | ------- - variable moved due to use in closure + | | + | value moved into closure here LL | //~^ NOTE value moved (into closure) here LL | let z = x; | ^ value used here after move diff --git a/src/test/ui/issue-27282-move-match-input-into-guard.stderr b/src/test/ui/issue-27282-move-match-input-into-guard.stderr index d264bf8d2734d..91c51bcd05825 100644 --- a/src/test/ui/issue-27282-move-match-input-into-guard.stderr +++ b/src/test/ui/issue-27282-move-match-input-into-guard.stderr @@ -1,11 +1,13 @@ error[E0505]: cannot move out of `b` because it is borrowed - --> $DIR/issue-27282-move-match-input-into-guard.rs:26:16 + --> $DIR/issue-27282-move-match-input-into-guard.rs:26:17 | LL | match b { | - borrow of `b` occurs here LL | &mut false => {}, LL | _ if { (|| { let bar = b; *bar = false; })(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ move out of `b` occurs here + | ^^ - move occurs due to use in closure + | | + | move out of `b` occurs here ... LL | &mut true => { println!("You might think we should get here"); }, | --------- borrow later used here @@ -14,7 +16,9 @@ error[E0382]: use of moved value: `*b` --> $DIR/issue-27282-move-match-input-into-guard.rs:29:14 | LL | _ if { (|| { let bar = b; *bar = false; })(); - | ----------------------------------- value moved here + | -- - variable moved due to use in closure + | | + | value moved into closure here ... LL | &mut true => { println!("You might think we should get here"); }, | ^^^^ value used here after move diff --git a/src/test/ui/issue-27282-mutate-before-diverging-arm-1.stderr b/src/test/ui/issue-27282-mutate-before-diverging-arm-1.stderr index fb11090c222d0..a9d9651fb2a35 100644 --- a/src/test/ui/issue-27282-mutate-before-diverging-arm-1.stderr +++ b/src/test/ui/issue-27282-mutate-before-diverging-arm-1.stderr @@ -5,7 +5,7 @@ LL | match x { | - borrow occurs here ... LL | (|| { *x = None; drop(force_fn_once); })(); - | ^^ - borrow occurs due to use of `x` in closure + | ^^ - second borrow occurs due to use of `x` in closure | | | closure construction occurs here ... diff --git a/src/test/ui/issue-27282-mutate-before-diverging-arm-2.stderr b/src/test/ui/issue-27282-mutate-before-diverging-arm-2.stderr index 6e643d30185f9..582d0fd678c07 100644 --- a/src/test/ui/issue-27282-mutate-before-diverging-arm-2.stderr +++ b/src/test/ui/issue-27282-mutate-before-diverging-arm-2.stderr @@ -5,7 +5,7 @@ LL | match x { | - borrow occurs here ... LL | (|| { *x = None; drop(force_fn_once); })(); - | ^^ - borrow occurs due to use of `x` in closure + | ^^ - second borrow occurs due to use of `x` in closure | | | closure construction occurs here ... diff --git a/src/test/ui/issue-4335.nll.stderr b/src/test/ui/issue-4335.nll.stderr index 40d7838a80325..4ccd24fa45921 100644 --- a/src/test/ui/issue-4335.nll.stderr +++ b/src/test/ui/issue-4335.nll.stderr @@ -5,10 +5,12 @@ LL | id(Box::new(|| *v)) | ^^ cannot move out of captured variable in an `FnMut` closure error[E0597]: `v` does not live long enough - --> $DIR/issue-4335.rs:16:17 + --> $DIR/issue-4335.rs:16:21 | LL | id(Box::new(|| *v)) - | ^^^^^ borrowed value does not live long enough + | -- ^ borrowed value does not live long enough + | | + | value captured here ... LL | } | - `v` dropped here while still borrowed diff --git a/src/test/ui/issue-6801.nll.stderr b/src/test/ui/issue-6801.nll.stderr index 5436397c68ead..3ca2f39470da7 100644 --- a/src/test/ui/issue-6801.nll.stderr +++ b/src/test/ui/issue-6801.nll.stderr @@ -2,7 +2,9 @@ error[E0505]: cannot move out of `x` because it is borrowed --> $DIR/issue-6801.rs:29:13 | LL | let sq = || { *x * *x }; - | -------------- borrow of `x` occurs here + | -- - borrow occurs due to use in closure + | | + | borrow of `x` occurs here LL | LL | twice(x); //~ ERROR: cannot move out of | ^ move out of `x` occurs here diff --git a/src/test/ui/nll/closure-captures.rs b/src/test/ui/nll/closure-captures.rs index 03a22bb79a86b..16385ca2499cc 100644 --- a/src/test/ui/nll/closure-captures.rs +++ b/src/test/ui/nll/closure-captures.rs @@ -13,7 +13,7 @@ #![allow(unused)] #![feature(nll)] -// Should have one error per assigment +// Should have one error per assignment fn one_closure(x: i32) { || diff --git a/src/test/ui/nll/closure-requirements/escape-upvar-nested.rs b/src/test/ui/nll/closure-requirements/escape-upvar-nested.rs index 598839f872e01..ce44903e6e6a8 100644 --- a/src/test/ui/nll/closure-requirements/escape-upvar-nested.rs +++ b/src/test/ui/nll/closure-requirements/escape-upvar-nested.rs @@ -27,8 +27,8 @@ fn test() { { let y = 22; - let mut closure = || { //~ ERROR `y` does not live long enough [E0597] - let mut closure1 = || p = &y; + let mut closure = || { + let mut closure1 = || p = &y; //~ ERROR `y` does not live long enough [E0597] closure1(); }; diff --git a/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr b/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr index bf12800e58d71..ed2ae2f27b57b 100644 --- a/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr +++ b/src/test/ui/nll/closure-requirements/escape-upvar-nested.stderr @@ -1,7 +1,7 @@ note: External requirements --> $DIR/escape-upvar-nested.rs:31:32 | -LL | let mut closure1 = || p = &y; +LL | let mut closure1 = || p = &y; //~ ERROR `y` does not live long enough [E0597] | ^^^^^^^^^ | = note: defining type: DefId(0/1:10 ~ escape_upvar_nested[317d]::test[0]::{{closure}}[0]::{{closure}}[0]) with closure substs [ @@ -16,9 +16,9 @@ LL | let mut closure1 = || p = &y; note: External requirements --> $DIR/escape-upvar-nested.rs:30:27 | -LL | let mut closure = || { //~ ERROR `y` does not live long enough [E0597] +LL | let mut closure = || { | ___________________________^ -LL | | let mut closure1 = || p = &y; +LL | | let mut closure1 = || p = &y; //~ ERROR `y` does not live long enough [E0597] LL | | closure1(); LL | | }; | |_________^ @@ -47,20 +47,18 @@ LL | | } = note: defining type: DefId(0/0:3 ~ escape_upvar_nested[317d]::test[0]) with substs [] error[E0597]: `y` does not live long enough - --> $DIR/escape-upvar-nested.rs:30:27 + --> $DIR/escape-upvar-nested.rs:31:40 | -LL | let mut closure = || { //~ ERROR `y` does not live long enough [E0597] - | ___________________________^ -LL | | let mut closure1 = || p = &y; -LL | | closure1(); -LL | | }; - | |_________^ borrowed value does not live long enough +LL | let mut closure = || { + | -- value captured here +LL | let mut closure1 = || p = &y; //~ ERROR `y` does not live long enough [E0597] + | ^ borrowed value does not live long enough ... -LL | } - | - `y` dropped here while still borrowed +LL | } + | - `y` dropped here while still borrowed LL | -LL | deref(p); - | - borrow later used here +LL | deref(p); + | - borrow later used here error: aborting due to previous error diff --git a/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr b/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr index 4b0dad3bda022..8db56deeb1f7a 100644 --- a/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr +++ b/src/test/ui/nll/closure-requirements/escape-upvar-ref.stderr @@ -28,10 +28,12 @@ LL | | } = note: defining type: DefId(0/0:3 ~ escape_upvar_ref[317d]::test[0]) with substs [] error[E0597]: `y` does not live long enough - --> $DIR/escape-upvar-ref.rs:33:27 + --> $DIR/escape-upvar-ref.rs:33:35 | LL | let mut closure = || p = &y; - | ^^^^^^^^^ borrowed value does not live long enough + | -- ^ borrowed value does not live long enough + | | + | value captured here ... LL | } | - `y` dropped here while still borrowed diff --git a/src/test/ui/nll/issue-51268.stderr b/src/test/ui/nll/issue-51268.stderr index 269bc368305cb..2ecfe03e7de62 100644 --- a/src/test/ui/nll/issue-51268.stderr +++ b/src/test/ui/nll/issue-51268.stderr @@ -8,7 +8,7 @@ LL | self.thing.bar(|| { | || LL | || //~^ ERROR cannot borrow `self.thing` as mutable because it is also borrowed as immutable [E0502] LL | || &self.number; - | || ---- previous borrow occurs due to use of `self` in closure + | || ---- first borrow occurs due to use of `self` in closure LL | || }); | || ^ | ||__________| diff --git a/src/test/ui/region-borrow-params-issue-29793-small.nll.stderr b/src/test/ui/region-borrow-params-issue-29793-small.nll.stderr index ae7193ef4fa79..d0d6bd4c78570 100644 --- a/src/test/ui/region-borrow-params-issue-29793-small.nll.stderr +++ b/src/test/ui/region-borrow-params-issue-29793-small.nll.stderr @@ -1,44 +1,54 @@ error[E0597]: `x` does not live long enough - --> $DIR/region-borrow-params-issue-29793-small.rs:19:17 + --> $DIR/region-borrow-params-issue-29793-small.rs:19:34 | LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough + | --------- ^ borrowed value does not live long enough + | | + | value captured here ... LL | }; | - `x` dropped here while still borrowed error[E0597]: `y` does not live long enough - --> $DIR/region-borrow-params-issue-29793-small.rs:19:17 + --> $DIR/region-borrow-params-issue-29793-small.rs:19:45 | LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough + | --------- ^ borrowed value does not live long enough + | | + | value captured here ... LL | }; | - `y` dropped here while still borrowed error[E0597]: `x` does not live long enough - --> $DIR/region-borrow-params-issue-29793-small.rs:34:17 + --> $DIR/region-borrow-params-issue-29793-small.rs:34:34 | LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough + | --------- ^ borrowed value does not live long enough + | | + | value captured here ... LL | }; | - `x` dropped here while still borrowed error[E0597]: `y` does not live long enough - --> $DIR/region-borrow-params-issue-29793-small.rs:34:17 + --> $DIR/region-borrow-params-issue-29793-small.rs:34:45 | LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough + | --------- ^ borrowed value does not live long enough + | | + | value captured here ... LL | }; | - `y` dropped here while still borrowed error[E0597]: `x` does not live long enough - --> $DIR/region-borrow-params-issue-29793-small.rs:65:17 + --> $DIR/region-borrow-params-issue-29793-small.rs:65:34 | LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough + | --------- ^ borrowed value does not live long enough + | | + | value captured here ... LL | }; | - `x` dropped here while still borrowed @@ -50,10 +60,12 @@ LL | fn g<'a>(x: usize, y:usize) -> Box usize + 'a> { | ^^ error[E0597]: `y` does not live long enough - --> $DIR/region-borrow-params-issue-29793-small.rs:65:17 + --> $DIR/region-borrow-params-issue-29793-small.rs:65:45 | LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough + | --------- ^ borrowed value does not live long enough + | | + | value captured here ... LL | }; | - `y` dropped here while still borrowed @@ -65,10 +77,12 @@ LL | fn g<'a>(x: usize, y:usize) -> Box usize + 'a> { | ^^ error[E0597]: `x` does not live long enough - --> $DIR/region-borrow-params-issue-29793-small.rs:76:17 + --> $DIR/region-borrow-params-issue-29793-small.rs:76:34 | LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough + | --------- ^ borrowed value does not live long enough + | | + | value captured here ... LL | }; | - `x` dropped here while still borrowed @@ -80,10 +94,12 @@ LL | fn g<'a>(x: usize, y:usize) -> Box usize + 'a> { | ^^ error[E0597]: `y` does not live long enough - --> $DIR/region-borrow-params-issue-29793-small.rs:76:17 + --> $DIR/region-borrow-params-issue-29793-small.rs:76:45 | LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough + | --------- ^ borrowed value does not live long enough + | | + | value captured here ... LL | }; | - `y` dropped here while still borrowed @@ -95,10 +111,12 @@ LL | fn g<'a>(x: usize, y:usize) -> Box usize + 'a> { | ^^ error[E0597]: `x` does not live long enough - --> $DIR/region-borrow-params-issue-29793-small.rs:100:21 + --> $DIR/region-borrow-params-issue-29793-small.rs:100:38 | LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough + | --------- ^ borrowed value does not live long enough + | | + | value captured here ... LL | } | - `x` dropped here while still borrowed @@ -110,10 +128,12 @@ LL | fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { | ^^ error[E0597]: `y` does not live long enough - --> $DIR/region-borrow-params-issue-29793-small.rs:100:21 + --> $DIR/region-borrow-params-issue-29793-small.rs:100:49 | LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough + | --------- ^ borrowed value does not live long enough + | | + | value captured here ... LL | } | - `y` dropped here while still borrowed @@ -125,10 +145,12 @@ LL | fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { | ^^ error[E0597]: `x` does not live long enough - --> $DIR/region-borrow-params-issue-29793-small.rs:114:21 + --> $DIR/region-borrow-params-issue-29793-small.rs:114:38 | LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough + | --------- ^ borrowed value does not live long enough + | | + | value captured here ... LL | } | - `x` dropped here while still borrowed @@ -140,10 +162,12 @@ LL | fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { | ^^ error[E0597]: `y` does not live long enough - --> $DIR/region-borrow-params-issue-29793-small.rs:114:21 + --> $DIR/region-borrow-params-issue-29793-small.rs:114:49 | LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough + | --------- ^ borrowed value does not live long enough + | | + | value captured here ... LL | } | - `y` dropped here while still borrowed @@ -155,10 +179,12 @@ LL | fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { | ^^ error[E0597]: `x` does not live long enough - --> $DIR/region-borrow-params-issue-29793-small.rs:142:21 + --> $DIR/region-borrow-params-issue-29793-small.rs:142:38 | LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough + | --------- ^ borrowed value does not live long enough + | | + | value captured here ... LL | } | - `x` dropped here while still borrowed @@ -170,10 +196,12 @@ LL | fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { | ^^ error[E0597]: `y` does not live long enough - --> $DIR/region-borrow-params-issue-29793-small.rs:142:21 + --> $DIR/region-borrow-params-issue-29793-small.rs:142:49 | LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough + | --------- ^ borrowed value does not live long enough + | | + | value captured here ... LL | } | - `y` dropped here while still borrowed @@ -185,10 +213,12 @@ LL | fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { | ^^ error[E0597]: `x` does not live long enough - --> $DIR/region-borrow-params-issue-29793-small.rs:157:21 + --> $DIR/region-borrow-params-issue-29793-small.rs:157:38 | LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough + | --------- ^ borrowed value does not live long enough + | | + | value captured here ... LL | } | - `x` dropped here while still borrowed @@ -200,10 +230,12 @@ LL | fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { | ^^ error[E0597]: `y` does not live long enough - --> $DIR/region-borrow-params-issue-29793-small.rs:157:21 + --> $DIR/region-borrow-params-issue-29793-small.rs:157:49 | LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough + | --------- ^ borrowed value does not live long enough + | | + | value captured here ... LL | } | - `y` dropped here while still borrowed @@ -215,10 +247,12 @@ LL | fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { | ^^ error[E0597]: `x` does not live long enough - --> $DIR/region-borrow-params-issue-29793-small.rs:185:21 + --> $DIR/region-borrow-params-issue-29793-small.rs:185:38 | LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough + | --------- ^ borrowed value does not live long enough + | | + | value captured here ... LL | } | - `x` dropped here while still borrowed @@ -230,10 +264,12 @@ LL | fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { | ^^ error[E0597]: `y` does not live long enough - --> $DIR/region-borrow-params-issue-29793-small.rs:185:21 + --> $DIR/region-borrow-params-issue-29793-small.rs:185:49 | LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough + | --------- ^ borrowed value does not live long enough + | | + | value captured here ... LL | } | - `y` dropped here while still borrowed @@ -245,10 +281,12 @@ LL | fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { | ^^ error[E0597]: `x` does not live long enough - --> $DIR/region-borrow-params-issue-29793-small.rs:199:21 + --> $DIR/region-borrow-params-issue-29793-small.rs:199:38 | LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough + | --------- ^ borrowed value does not live long enough + | | + | value captured here ... LL | } | - `x` dropped here while still borrowed @@ -260,10 +298,12 @@ LL | fn g<'a>(&self, x: usize, y:usize) -> Box usize + 'a> { | ^^ error[E0597]: `y` does not live long enough - --> $DIR/region-borrow-params-issue-29793-small.rs:199:21 + --> $DIR/region-borrow-params-issue-29793-small.rs:199:49 | LL | let f = |t: bool| if t { x } else { y }; // (separate errors for `x` vs `y`) - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ borrowed value does not live long enough + | --------- ^ borrowed value does not live long enough + | | + | value captured here ... LL | } | - `y` dropped here while still borrowed diff --git a/src/test/ui/regions-nested-fns-2.nll.stderr b/src/test/ui/regions-nested-fns-2.nll.stderr index 13e34d85210a7..1b5bb7d500779 100644 --- a/src/test/ui/regions-nested-fns-2.nll.stderr +++ b/src/test/ui/regions-nested-fns-2.nll.stderr @@ -1,13 +1,14 @@ error[E0597]: `y` does not live long enough - --> $DIR/regions-nested-fns-2.rs:16:9 + --> $DIR/regions-nested-fns-2.rs:18:25 | -LL | / |z| { -LL | | //~^ ERROR E0373 -LL | | if false { &y } else { z } -LL | | }); - | |_________^ borrowed value does not live long enough -LL | } - | - `y` dropped here while still borrowed +LL | |z| { + | --- value captured here +LL | //~^ ERROR E0373 +LL | if false { &y } else { z } + | ^ borrowed value does not live long enough +LL | }); +LL | } + | - `y` dropped here while still borrowed | = note: borrowed value must be valid for the static lifetime... diff --git a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.nll.stderr b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.nll.stderr index b3563f1b6203c..c7dbc043cdaee 100644 --- a/src/test/ui/span/borrowck-call-is-borrow-issue-12224.nll.stderr +++ b/src/test/ui/span/borrowck-call-is-borrow-issue-12224.nll.stderr @@ -8,7 +8,7 @@ LL | f(Box::new(|| { | | LL | | //~^ ERROR: cannot borrow `f` as mutable more than once LL | | f((Box::new(|| {}))) - | | - borrow occurs due to use of `f` in closure + | | - second borrow occurs due to use of `f` in closure LL | | })); | |_______- borrow later used here @@ -37,18 +37,17 @@ LL | foo(f); error[E0505]: cannot move out of `f` because it is borrowed --> $DIR/borrowck-call-is-borrow-issue-12224.rs:65:16 | -LL | f(Box::new(|a| { - | _____-__________^ - | | | - | |_____borrow of `f` occurs here - | || -LL | || foo(f); -LL | || //~^ ERROR cannot move `f` into closure because it is borrowed -LL | || //~| ERROR cannot move out of captured outer variable in an `FnMut` closure -LL | || }), 3); - | ||_____^____- borrow later used here - | |_____| - | move out of `f` occurs here +LL | f(Box::new(|a| { + | - ^^^ move out of `f` occurs here + | | + | _____borrow of `f` occurs here + | | +LL | | foo(f); + | | - move occurs due to use in closure +LL | | //~^ ERROR cannot move `f` into closure because it is borrowed +LL | | //~| ERROR cannot move out of captured outer variable in an `FnMut` closure +LL | | }), 3); + | |__________- borrow later used here error: aborting due to 5 previous errors diff --git a/src/test/ui/span/send-is-not-static-ensures-scoping.nll.stderr b/src/test/ui/span/send-is-not-static-ensures-scoping.nll.stderr index 1753f710b8842..c14cb7098933f 100644 --- a/src/test/ui/span/send-is-not-static-ensures-scoping.nll.stderr +++ b/src/test/ui/span/send-is-not-static-ensures-scoping.nll.stderr @@ -11,19 +11,18 @@ LL | bad.join(); | --- borrow later used here error[E0597]: `y` does not live long enough - --> $DIR/send-is-not-static-ensures-scoping.rs:29:16 + --> $DIR/send-is-not-static-ensures-scoping.rs:30:22 | -LL | scoped(|| { - | ________________^ -LL | | let _z = y; -LL | | //~^ ERROR `y` does not live long enough -LL | | }) - | |_________^ borrowed value does not live long enough -LL | }; - | - `y` dropped here while still borrowed +LL | scoped(|| { + | -- value captured here +LL | let _z = y; + | ^ borrowed value does not live long enough +... +LL | }; + | - `y` dropped here while still borrowed LL | -LL | bad.join(); - | --- borrow later used here +LL | bad.join(); + | --- borrow later used here error: aborting due to 2 previous errors