From fd76552a4b41d132701dc0857a9fee9a3850088e Mon Sep 17 00:00:00 2001 From: joboet Date: Wed, 18 May 2022 12:18:51 +0200 Subject: [PATCH 01/20] std: use an event flag based thread parker on SOLID --- library/std/src/sys/itron/abi.rs | 48 +++++++++- library/std/src/sys/itron/wait_flag.rs | 67 +++++++++++++ library/std/src/sys/solid/mod.rs | 2 + .../std/src/sys_common/thread_parker/mod.rs | 7 +- .../src/sys_common/thread_parker/wait_flag.rs | 96 +++++++++++++++++++ 5 files changed, 214 insertions(+), 6 deletions(-) create mode 100644 library/std/src/sys/itron/wait_flag.rs create mode 100644 library/std/src/sys_common/thread_parker/wait_flag.rs diff --git a/library/std/src/sys/itron/abi.rs b/library/std/src/sys/itron/abi.rs index f99ee4fa897ea..5eb14bb7e534b 100644 --- a/library/std/src/sys/itron/abi.rs +++ b/library/std/src/sys/itron/abi.rs @@ -30,15 +30,32 @@ pub type ER = int_t; /// Error code type, `ID` on success pub type ER_ID = int_t; +/// Service call operational mode +pub type MODE = uint_t; + +/// OR waiting condition for an eventflag +pub const TWF_ORW: MODE = 0x01; + +/// Object attributes +pub type ATR = uint_t; + +/// FIFO wait order +pub const TA_FIFO: ATR = 0; +/// Only one task is allowed to be in the waiting state for the eventflag +pub const TA_WSGL: ATR = 0; +/// The eventflag’s bit pattern is cleared when a task is released from the +/// waiting state for that eventflag. +pub const TA_CLR: ATR = 0x04; + +/// Bit pattern of an eventflag +pub type FLGPTN = uint_t; + /// Task or interrupt priority pub type PRI = int_t; /// The special value of `PRI` representing the current task's priority. pub const TPRI_SELF: PRI = 0; -/// Object attributes -pub type ATR = uint_t; - /// Use the priority inheritance protocol #[cfg(target_os = "solid_asp3")] pub const TA_INHERIT: ATR = 0x02; @@ -90,6 +107,13 @@ pub struct T_CSEM { pub maxsem: uint_t, } +#[derive(Clone, Copy)] +#[repr(C)] +pub struct T_CFLG { + pub flgatr: ATR, + pub iflgptn: FLGPTN, +} + #[derive(Clone, Copy)] #[repr(C)] pub struct T_CMTX { @@ -139,6 +163,24 @@ extern "C" { pub fn sns_dsp() -> bool_t; #[link_name = "__asp3_get_tim"] pub fn get_tim(p_systim: *mut SYSTIM) -> ER; + #[link_name = "__asp3_acre_flg"] + pub fn acre_flg(pk_cflg: *const T_CFLG) -> ER_ID; + #[link_name = "__asp3_del_flg"] + pub fn del_flg(flgid: ID) -> ER; + #[link_name = "__asp3_set_flg"] + pub fn set_flg(flgid: ID, setptn: FLGPTN) -> ER; + #[link_name = "__asp3_clr_flg"] + pub fn clr_flg(flgid: ID, clrptn: FLGPTN) -> ER; + #[link_name = "__asp3_wai_flg"] + pub fn wai_flg(flgid: ID, waiptn: FLGPTN, wfmode: MODE, p_flgptn: *mut FLGPTN) -> ER; + #[link_name = "__asp3_twai_flg"] + pub fn twai_flg( + flgid: ID, + waiptn: FLGPTN, + wfmode: MODE, + p_flgptn: *mut FLGPTN, + tmout: TMO, + ) -> ER; #[link_name = "__asp3_acre_mtx"] pub fn acre_mtx(pk_cmtx: *const T_CMTX) -> ER_ID; #[link_name = "__asp3_del_mtx"] diff --git a/library/std/src/sys/itron/wait_flag.rs b/library/std/src/sys/itron/wait_flag.rs new file mode 100644 index 0000000000000..805f85a69b6c7 --- /dev/null +++ b/library/std/src/sys/itron/wait_flag.rs @@ -0,0 +1,67 @@ +use crate::mem::MaybeUninit; +use crate::time::Duration; + +use super::{ + abi, + error::{expect_success, fail}, + time::with_tmos, +}; + +const CLEAR: abi::FLGPTN = 0; +const RAISED: abi::FLGPTN = 1; + +/// A thread parking primitive that is not susceptible to race conditions, +/// but provides no atomic ordering guarantees and allows only one `raise` per wait. +pub struct WaitFlag { + flag: abi::ID, +} + +impl WaitFlag { + /// Creates a new wait flag. + pub fn new() -> WaitFlag { + let flag = expect_success( + unsafe { + abi::acre_flg(&abi::T_CFLG { + flgatr: abi::TA_FIFO | abi::TA_WSGL | abi::TA_CLR, + iflgptn: CLEAR, + }) + }, + &"acre_flg", + ); + + WaitFlag { flag } + } + + /// Wait for the wait flag to be raised. + pub fn wait(&self) { + let mut token = MaybeUninit::uninit(); + expect_success( + unsafe { abi::wai_flg(self.flag, RAISED, abi::TWF_ORW, token.as_mut_ptr()) }, + &"wai_flg", + ); + } + + /// Wait for the wait flag to be raised or the timeout to occur. + pub fn wait_timeout(&self, dur: Duration) { + let mut token = MaybeUninit::uninit(); + let er = with_tmos(dur, |tmout| unsafe { + abi::twai_flg(self.flag, RAISED, abi::TWF_ORW, token.as_mut_ptr(), tmout) + }); + if er != abi::E_OK && er != abi::E_TMOUT { + fail(er, &"twai_flg"); + } + } + + /// Raise the wait flag. + /// + /// Calls to this function should be balanced with the number of successful waits. + pub fn raise(&self) { + expect_success(unsafe { abi::set_flg(self.flag, RAISED) }, &"set_flg"); + } +} + +impl Drop for WaitFlag { + fn drop(&mut self) { + expect_success(unsafe { abi::del_flg(self.flag) }, &"del_flg"); + } +} diff --git a/library/std/src/sys/solid/mod.rs b/library/std/src/sys/solid/mod.rs index 5ffa381f2e50f..2d21e4764fc21 100644 --- a/library/std/src/sys/solid/mod.rs +++ b/library/std/src/sys/solid/mod.rs @@ -15,6 +15,7 @@ mod itron { pub mod thread; pub(super) mod time; use super::unsupported; + pub mod wait_flag; } pub mod alloc; @@ -43,6 +44,7 @@ pub mod memchr; pub mod thread_local_dtor; pub mod thread_local_key; pub mod time; +pub use self::itron::wait_flag; mod rwlock; diff --git a/library/std/src/sys_common/thread_parker/mod.rs b/library/std/src/sys_common/thread_parker/mod.rs index c789a388e05ad..79d5a498e054f 100644 --- a/library/std/src/sys_common/thread_parker/mod.rs +++ b/library/std/src/sys_common/thread_parker/mod.rs @@ -9,9 +9,10 @@ cfg_if::cfg_if! { ))] { mod futex; pub use futex::Parker; - } else if #[cfg(windows)] { - pub use crate::sys::thread_parker::Parker; - } else if #[cfg(target_family = "unix")] { + } else if #[cfg(target_os = "solid_asp3")] { + mod wait_flag; + pub use wait_flag::Parker; + } else if #[cfg(any(windows, target_family = "unix"))] { pub use crate::sys::thread_parker::Parker; } else { mod generic; diff --git a/library/std/src/sys_common/thread_parker/wait_flag.rs b/library/std/src/sys_common/thread_parker/wait_flag.rs new file mode 100644 index 0000000000000..39a0df1cd3de4 --- /dev/null +++ b/library/std/src/sys_common/thread_parker/wait_flag.rs @@ -0,0 +1,96 @@ +//! A wait-flag-based thread parker. +//! +//! Some operating systems provide low-level parking primitives like wait counts, +//! event flags or semaphores which are not susceptible to race conditions (meaning +//! the wakeup can occure before the wait operation). To implement the `std` thread +//! parker on top of these primitives, we only have to ensure that parking is fast +//! when the thread token is available, the atomic ordering guarantees are maintained +//! and spurious wakeups are minimized. +//! +//! To achieve this, this parker uses an atomic variable with three states: `EMPTY`, +//! `PARKED` and `NOTIFIED`: +//! * `EMPTY` means the token has not been made available, but the thread is not +//! currently waiting on it. +//! * `PARKED` means the token is not available and the thread is parked. +//! * `NOTIFIED` means the token is available. +//! +//! `park` and `park_timeout` change the state from `EMPTY` to `PARKED` and from +//! `NOTIFIED` to `EMPTY`. If the state was `NOTIFIED`, the thread was unparked and +//! execution can continue without calling into the OS. If the state was `EMPTY`, +//! the token is not available and the thread waits on the primitive (here called +//! "wait flag"). +//! +//! `unpark` changes the state to `NOTIFIED`. If the state was `PARKED`, the thread +//! is or will be sleeping on the wait flag, so we raise it. Only the first thread +//! to call `unpark` will raise the wait flag, so spurious wakeups are avoided +//! (this is especially important for semaphores). + +use crate::pin::Pin; +use crate::sync::atomic::AtomicI8; +use crate::sync::atomic::Ordering::SeqCst; +use crate::sys::wait_flag::WaitFlag; +use crate::time::Duration; + +const EMPTY: i8 = 0; +const PARKED: i8 = -1; +const NOTIFIED: i8 = 1; + +pub struct Parker { + state: AtomicI8, + wait_flag: WaitFlag, +} + +impl Parker { + /// Construct a parker for the current thread. The UNIX parker + /// implementation requires this to happen in-place. + pub unsafe fn new(parker: *mut Parker) { + parker.write(Parker { state: AtomicI8::new(EMPTY), wait_flag: WaitFlag::new() }) + } + + // This implementation doesn't require `unsafe` and `Pin`, but other implementations do. + pub unsafe fn park(self: Pin<&Self>) { + // The state values are chosen so that this subtraction changes + // `NOTIFIED` to `EMPTY` and `EMPTY` to `PARKED`. + let state = self.state.fetch_sub(1, SeqCst); + match state { + EMPTY => (), + NOTIFIED => return, + _ => panic!("inconsistent park state"), + } + + self.wait_flag.wait(); + + // We need to do a load here to use `Acquire` ordering. + self.state.swap(EMPTY, SeqCst); + } + + // This implementation doesn't require `unsafe` and `Pin`, but other implementations do. + pub unsafe fn park_timeout(self: Pin<&Self>, dur: Duration) { + let state = self.state.fetch_sub(1, SeqCst); + match state { + EMPTY => (), + NOTIFIED => return, + _ => panic!("inconsistent park state"), + } + + self.wait_flag.wait_timeout(dur); + let state = self.state.swap(EMPTY, SeqCst); + if state == NOTIFIED { + // The token was made available after the timeout occurred, but before + // we reset the state, so we need to reset the wait flag to avoid + // spurious wakeups. This wait has no timeout, but we know it will + // return quickly, as the unparking thread will definitely raise the + // flag if it has not already done so. + self.wait_flag.wait(); + } + } + + // This implementation doesn't require `Pin`, but other implementations do. + pub fn unpark(self: Pin<&Self>) { + let state = self.state.swap(NOTIFIED, SeqCst); + + if state == PARKED { + self.wait_flag.raise(); + } + } +} From 3b6ae15058dbb68710f92697265580c7e957629f Mon Sep 17 00:00:00 2001 From: joboet Date: Thu, 19 May 2022 14:37:29 +0200 Subject: [PATCH 02/20] std: fix deadlock in `Parker` --- library/std/src/sys/itron/wait_flag.rs | 13 +++++++++---- .../std/src/sys_common/thread_parker/wait_flag.rs | 8 ++++---- 2 files changed, 13 insertions(+), 8 deletions(-) diff --git a/library/std/src/sys/itron/wait_flag.rs b/library/std/src/sys/itron/wait_flag.rs index 805f85a69b6c7..e432edd207754 100644 --- a/library/std/src/sys/itron/wait_flag.rs +++ b/library/std/src/sys/itron/wait_flag.rs @@ -42,13 +42,18 @@ impl WaitFlag { } /// Wait for the wait flag to be raised or the timeout to occur. - pub fn wait_timeout(&self, dur: Duration) { + /// + /// Returns whether the flag was raised (`true`) or the operation timed out (`false`). + pub fn wait_timeout(&self, dur: Duration) -> bool { let mut token = MaybeUninit::uninit(); - let er = with_tmos(dur, |tmout| unsafe { + let res = with_tmos(dur, |tmout| unsafe { abi::twai_flg(self.flag, RAISED, abi::TWF_ORW, token.as_mut_ptr(), tmout) }); - if er != abi::E_OK && er != abi::E_TMOUT { - fail(er, &"twai_flg"); + + match res { + abi::E_OK => true, + abi::E_TMOUT => false, + error => fail(error, &"twai_flg"), } } diff --git a/library/std/src/sys_common/thread_parker/wait_flag.rs b/library/std/src/sys_common/thread_parker/wait_flag.rs index 39a0df1cd3de4..f9581ff5d5774 100644 --- a/library/std/src/sys_common/thread_parker/wait_flag.rs +++ b/library/std/src/sys_common/thread_parker/wait_flag.rs @@ -2,7 +2,7 @@ //! //! Some operating systems provide low-level parking primitives like wait counts, //! event flags or semaphores which are not susceptible to race conditions (meaning -//! the wakeup can occure before the wait operation). To implement the `std` thread +//! the wakeup can occur before the wait operation). To implement the `std` thread //! parker on top of these primitives, we only have to ensure that parking is fast //! when the thread token is available, the atomic ordering guarantees are maintained //! and spurious wakeups are minimized. @@ -73,10 +73,10 @@ impl Parker { _ => panic!("inconsistent park state"), } - self.wait_flag.wait_timeout(dur); + let wakeup = self.wait_flag.wait_timeout(dur); let state = self.state.swap(EMPTY, SeqCst); - if state == NOTIFIED { - // The token was made available after the timeout occurred, but before + if state == NOTIFIED && !wakeup { + // The token was made available after the wait timed out, but before // we reset the state, so we need to reset the wait flag to avoid // spurious wakeups. This wait has no timeout, but we know it will // return quickly, as the unparking thread will definitely raise the From b9660de664cc491b3f22a5c1dadee5a03e506b2a Mon Sep 17 00:00:00 2001 From: joboet Date: Sat, 4 Jun 2022 20:57:25 +0200 Subject: [PATCH 03/20] std: solve priority issue for Parker --- .../src/sys_common/thread_parker/wait_flag.rs | 55 +++++++++++-------- 1 file changed, 31 insertions(+), 24 deletions(-) diff --git a/library/std/src/sys_common/thread_parker/wait_flag.rs b/library/std/src/sys_common/thread_parker/wait_flag.rs index f9581ff5d5774..8db12693ef734 100644 --- a/library/std/src/sys_common/thread_parker/wait_flag.rs +++ b/library/std/src/sys_common/thread_parker/wait_flag.rs @@ -21,13 +21,11 @@ //! "wait flag"). //! //! `unpark` changes the state to `NOTIFIED`. If the state was `PARKED`, the thread -//! is or will be sleeping on the wait flag, so we raise it. Only the first thread -//! to call `unpark` will raise the wait flag, so spurious wakeups are avoided -//! (this is especially important for semaphores). +//! is or will be sleeping on the wait flag, so we raise it. use crate::pin::Pin; use crate::sync::atomic::AtomicI8; -use crate::sync::atomic::Ordering::SeqCst; +use crate::sync::atomic::Ordering::{Relaxed, SeqCst}; use crate::sys::wait_flag::WaitFlag; use crate::time::Duration; @@ -49,39 +47,48 @@ impl Parker { // This implementation doesn't require `unsafe` and `Pin`, but other implementations do. pub unsafe fn park(self: Pin<&Self>) { - // The state values are chosen so that this subtraction changes - // `NOTIFIED` to `EMPTY` and `EMPTY` to `PARKED`. - let state = self.state.fetch_sub(1, SeqCst); - match state { - EMPTY => (), + match self.state.fetch_sub(1, SeqCst) { + // NOTIFIED => EMPTY NOTIFIED => return, + // EMPTY => PARKED + EMPTY => (), _ => panic!("inconsistent park state"), } - self.wait_flag.wait(); + // Avoid waking up from spurious wakeups (these are quite likely, see below). + loop { + self.wait_flag.wait(); - // We need to do a load here to use `Acquire` ordering. - self.state.swap(EMPTY, SeqCst); + match self.state.compare_exchange(NOTIFIED, EMPTY, SeqCst, Relaxed) { + Ok(_) => return, + Err(PARKED) => (), + Err(_) => panic!("inconsistent park state"), + } + } } // This implementation doesn't require `unsafe` and `Pin`, but other implementations do. pub unsafe fn park_timeout(self: Pin<&Self>, dur: Duration) { - let state = self.state.fetch_sub(1, SeqCst); - match state { - EMPTY => (), + match self.state.fetch_sub(1, SeqCst) { NOTIFIED => return, + EMPTY => (), _ => panic!("inconsistent park state"), } - let wakeup = self.wait_flag.wait_timeout(dur); - let state = self.state.swap(EMPTY, SeqCst); - if state == NOTIFIED && !wakeup { - // The token was made available after the wait timed out, but before - // we reset the state, so we need to reset the wait flag to avoid - // spurious wakeups. This wait has no timeout, but we know it will - // return quickly, as the unparking thread will definitely raise the - // flag if it has not already done so. - self.wait_flag.wait(); + self.wait_flag.wait_timeout(dur); + + // Either a wakeup or a timeout occurred. Wakeups may be spurious, as there can be + // a race condition when `unpark` is performed between receiving the timeout and + // resetting the state, resulting in the eventflag being set unnecessarily. `park` + // is protected against this by looping until the token is actually given, but + // here we cannot easily tell. + + // Use `swap` to provide acquire ordering (not strictly necessary, but all other + // implementations do). + match self.state.swap(EMPTY, SeqCst) { + NOTIFIED => (), + PARKED => (), + _ => panic!("inconsistent park state"), } } From caff72361f9a3d9938032be703295ef7a0c0dd5d Mon Sep 17 00:00:00 2001 From: joboet Date: Tue, 7 Jun 2022 11:06:19 +0200 Subject: [PATCH 04/20] std: relax memory orderings in `Parker` Co-authored-by: Tomoaki Kawada --- .../std/src/sys_common/thread_parker/wait_flag.rs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/library/std/src/sys_common/thread_parker/wait_flag.rs b/library/std/src/sys_common/thread_parker/wait_flag.rs index 8db12693ef734..6561c186655a5 100644 --- a/library/std/src/sys_common/thread_parker/wait_flag.rs +++ b/library/std/src/sys_common/thread_parker/wait_flag.rs @@ -25,7 +25,7 @@ use crate::pin::Pin; use crate::sync::atomic::AtomicI8; -use crate::sync::atomic::Ordering::{Relaxed, SeqCst}; +use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release}; use crate::sys::wait_flag::WaitFlag; use crate::time::Duration; @@ -47,7 +47,7 @@ impl Parker { // This implementation doesn't require `unsafe` and `Pin`, but other implementations do. pub unsafe fn park(self: Pin<&Self>) { - match self.state.fetch_sub(1, SeqCst) { + match self.state.fetch_sub(1, Acquire) { // NOTIFIED => EMPTY NOTIFIED => return, // EMPTY => PARKED @@ -59,7 +59,7 @@ impl Parker { loop { self.wait_flag.wait(); - match self.state.compare_exchange(NOTIFIED, EMPTY, SeqCst, Relaxed) { + match self.state.compare_exchange(NOTIFIED, EMPTY, Acquire, Relaxed) { Ok(_) => return, Err(PARKED) => (), Err(_) => panic!("inconsistent park state"), @@ -69,7 +69,7 @@ impl Parker { // This implementation doesn't require `unsafe` and `Pin`, but other implementations do. pub unsafe fn park_timeout(self: Pin<&Self>, dur: Duration) { - match self.state.fetch_sub(1, SeqCst) { + match self.state.fetch_sub(1, Acquire) { NOTIFIED => return, EMPTY => (), _ => panic!("inconsistent park state"), @@ -83,9 +83,8 @@ impl Parker { // is protected against this by looping until the token is actually given, but // here we cannot easily tell. - // Use `swap` to provide acquire ordering (not strictly necessary, but all other - // implementations do). - match self.state.swap(EMPTY, SeqCst) { + // Use `swap` to provide acquire ordering. + match self.state.swap(EMPTY, Acquire) { NOTIFIED => (), PARKED => (), _ => panic!("inconsistent park state"), @@ -94,7 +93,7 @@ impl Parker { // This implementation doesn't require `Pin`, but other implementations do. pub fn unpark(self: Pin<&Self>) { - let state = self.state.swap(NOTIFIED, SeqCst); + let state = self.state.swap(NOTIFIED, Release); if state == PARKED { self.wait_flag.raise(); From c2385825f1b5aeb94a186b00cb0f0ede03bb7ce3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 21 Jun 2022 11:57:45 -0700 Subject: [PATCH 05/20] On partial uninit error point at where we need init When a binding is declared without a value, borrowck verifies that all codepaths have *one* assignment to them to initialize them fully. If there are any cases where a condition can be met that leaves the binding uninitialized or we attempt to initialize a field of an unitialized binding, we emit E0381. We now look at all the statements that initialize the binding, and use them to explore branching code paths that *don't* and point at them. If we find *no* potential places where an assignment to the binding might be missing, we display the spans of all the existing initializers to provide some context. --- .../rustc_borrowck/src/borrowck_errors.rs | 26 +- .../src/diagnostics/conflict_errors.rs | 222 ++++++++++++++++-- src/test/ui/asm/x86_64/type-check-5.rs | 4 +- src/test/ui/asm/x86_64/type-check-5.stderr | 12 +- .../no-non-guaranteed-initialization.rs | 3 +- .../no-non-guaranteed-initialization.stderr | 9 +- .../partial-initialization-across-await.rs | 9 +- ...partial-initialization-across-await.stderr | 28 ++- .../ui/borrowck/assign_mutable_fields.stderr | 16 +- src/test/ui/borrowck/borrowck-and-init.rs | 2 +- src/test/ui/borrowck/borrowck-and-init.stderr | 9 +- src/test/ui/borrowck/borrowck-block-unint.rs | 2 +- .../ui/borrowck/borrowck-block-unint.stderr | 6 +- .../ui/borrowck/borrowck-break-uninit-2.rs | 2 +- .../borrowck/borrowck-break-uninit-2.stderr | 7 +- src/test/ui/borrowck/borrowck-break-uninit.rs | 2 +- .../ui/borrowck/borrowck-break-uninit.stderr | 7 +- .../ui/borrowck/borrowck-field-sensitivity.rs | 6 +- .../borrowck-field-sensitivity.stderr | 24 +- src/test/ui/borrowck/borrowck-if-no-else.rs | 2 +- .../ui/borrowck/borrowck-if-no-else.stderr | 8 +- src/test/ui/borrowck/borrowck-if-with-else.rs | 2 +- .../ui/borrowck/borrowck-if-with-else.stderr | 9 +- .../borrowck-init-in-called-fn-expr.rs | 2 +- .../borrowck-init-in-called-fn-expr.stderr | 6 +- .../ui/borrowck/borrowck-init-in-fn-expr.rs | 2 +- .../borrowck/borrowck-init-in-fn-expr.stderr | 6 +- src/test/ui/borrowck/borrowck-init-in-fru.rs | 2 +- .../ui/borrowck/borrowck-init-in-fru.stderr | 6 +- .../ui/borrowck/borrowck-init-op-equal.rs | 2 +- .../ui/borrowck/borrowck-init-op-equal.stderr | 6 +- .../ui/borrowck/borrowck-init-plus-equal.rs | 2 +- .../borrowck/borrowck-init-plus-equal.stderr | 6 +- src/test/ui/borrowck/borrowck-or-init.rs | 2 +- src/test/ui/borrowck/borrowck-or-init.stderr | 9 +- .../ui/borrowck/borrowck-partial-reinit-4.rs | 3 +- .../borrowck/borrowck-partial-reinit-4.stderr | 6 +- src/test/ui/borrowck/borrowck-return.rs | 2 +- src/test/ui/borrowck/borrowck-return.stderr | 6 +- .../ui/borrowck/borrowck-storage-dead.stderr | 6 +- .../ui/borrowck/borrowck-uninit-after-item.rs | 2 +- .../borrowck-uninit-after-item.stderr | 7 +- .../borrowck-uninit-field-access.stderr | 6 +- .../borrowck/borrowck-uninit-in-assignop.rs | 20 +- .../borrowck-uninit-in-assignop.stderr | 60 +++-- .../ui/borrowck/borrowck-uninit-ref-chain.rs | 14 +- .../borrowck/borrowck-uninit-ref-chain.stderr | 50 ++-- src/test/ui/borrowck/borrowck-uninit.rs | 2 +- src/test/ui/borrowck/borrowck-uninit.stderr | 6 +- .../borrowck/borrowck-union-uninitialized.rs | 4 +- .../borrowck-union-uninitialized.stderr | 18 +- .../borrowck-use-in-index-lvalue.stderr | 12 +- ...wck-use-uninitialized-in-cast-trait.stderr | 6 +- .../borrowck-use-uninitialized-in-cast.stderr | 6 +- src/test/ui/borrowck/borrowck-while-break.rs | 2 +- .../ui/borrowck/borrowck-while-break.stderr | 9 +- src/test/ui/borrowck/borrowck-while-cond.rs | 2 +- .../ui/borrowck/borrowck-while-cond.stderr | 6 +- src/test/ui/borrowck/borrowck-while.rs | 2 +- src/test/ui/borrowck/borrowck-while.stderr | 8 +- .../disallow-possibly-uninitialized.rs | 8 +- .../disallow-possibly-uninitialized.stderr | 32 ++- src/test/ui/borrowck/issue-24267-flow-exit.rs | 4 +- .../ui/borrowck/issue-24267-flow-exit.stderr | 14 +- ...-54499-field-mutation-marks-mut-as-used.rs | 6 +- ...99-field-mutation-marks-mut-as-used.stderr | 24 +- ...ssue-54499-field-mutation-of-never-init.rs | 6 +- ...-54499-field-mutation-of-never-init.stderr | 24 +- .../borrowck/issue-62107-match-arm-scopes.rs | 2 +- .../issue-62107-match-arm-scopes.stderr | 6 +- .../reassignment_immutable_fields.stderr | 16 +- ...gnment_immutable_fields_overlapping.stderr | 8 +- ...reassignment_immutable_fields_twice.stderr | 8 +- .../match/pattern-matching-should-fail.rs | 17 +- .../match/pattern-matching-should-fail.stderr | 53 +++-- .../const-generic-default-wont-borrowck.rs | 3 +- ...const-generic-default-wont-borrowck.stderr | 6 +- src/test/ui/consts/issue-78655.rs | 2 +- src/test/ui/consts/issue-78655.stderr | 6 +- src/test/ui/drop/repeat-drop-2.rs | 2 +- src/test/ui/drop/repeat-drop-2.stderr | 6 +- .../partial-initialization-across-yield.rs | 9 +- ...partial-initialization-across-yield.stderr | 28 ++- src/test/ui/loops/loop-proper-liveness.rs | 2 +- src/test/ui/loops/loop-proper-liveness.stderr | 7 +- .../drop-elaboration-after-borrowck-error.rs | 2 +- ...op-elaboration-after-borrowck-error.stderr | 7 +- .../ui/moves/issue-72649-uninit-in-loop.rs | 12 +- .../moves/issue-72649-uninit-in-loop.stderr | 13 +- src/test/ui/moves/move-into-dead-array-1.rs | 2 +- .../ui/moves/move-into-dead-array-1.stderr | 6 +- src/test/ui/moves/move-of-addr-of-mut.rs | 2 +- src/test/ui/moves/move-of-addr-of-mut.stderr | 6 +- ...ue-21232-partial-init-and-erroneous-use.rs | 12 +- ...1232-partial-init-and-erroneous-use.stderr | 38 ++- .../nll/issue-21232-partial-init-and-use.rs | 36 +-- .../issue-21232-partial-init-and-use.stderr | 140 +++++++---- src/test/ui/nll/match-cfg-fake-edges.rs | 2 +- src/test/ui/nll/match-cfg-fake-edges.stderr | 9 +- src/test/ui/nll/match-on-borrowed.stderr | 6 +- .../chains-without-let.rs | 6 +- .../chains-without-let.stderr | 24 +- src/test/ui/try-block/try-block-opt-init.rs | 2 +- .../ui/try-block/try-block-opt-init.stderr | 10 +- .../privately-uninhabited-mir-call.rs | 2 +- .../privately-uninhabited-mir-call.stderr | 7 +- 106 files changed, 935 insertions(+), 441 deletions(-) diff --git a/compiler/rustc_borrowck/src/borrowck_errors.rs b/compiler/rustc_borrowck/src/borrowck_errors.rs index a1233d62cb02e..b6cf5275394fb 100644 --- a/compiler/rustc_borrowck/src/borrowck_errors.rs +++ b/compiler/rustc_borrowck/src/borrowck_errors.rs @@ -31,22 +31,6 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { err } - pub(crate) fn cannot_act_on_uninitialized_variable( - &self, - span: Span, - verb: &str, - desc: &str, - ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { - struct_span_err!( - self, - span, - E0381, - "{} of possibly-uninitialized variable: `{}`", - verb, - desc, - ) - } - pub(crate) fn cannot_mutably_borrow_multiply( &self, new_loan_span: Span, @@ -173,8 +157,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { self, new_loan_span, E0501, - "cannot borrow {}{} as {} because previous closure \ - requires unique access", + "cannot borrow {}{} as {} because previous closure requires unique access", desc_new, opt_via, kind_new, @@ -451,9 +434,8 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { self, closure_span, E0373, - "{} may outlive the current function, \ - but it borrows {}, \ - which is owned by the current function", + "{} may outlive the current function, but it borrows {}, which is owned by the current \ + function", closure_kind, borrowed_path, ); @@ -476,7 +458,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> { struct_span_err!(self, span, E0716, "temporary value dropped while borrowed",) } - fn struct_span_err_with_code>( + pub(crate) fn struct_span_err_with_code>( &self, sp: S, msg: &str, diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 73c0bf16a1f99..1f7cb972fcec8 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -2,9 +2,12 @@ use either::Either; use rustc_const_eval::util::CallKind; use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashSet; -use rustc_errors::{Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan}; +use rustc_errors::{ + struct_span_err, Applicability, Diagnostic, DiagnosticBuilder, ErrorGuaranteed, MultiSpan, +}; use rustc_hir as hir; use rustc_hir::def_id::DefId; +use rustc_hir::intravisit::{walk_expr, Visitor}; use rustc_hir::{AsyncGeneratorKind, GeneratorKind}; use rustc_infer::infer::TyCtxtInferExt; use rustc_infer::traits::ObligationCause; @@ -94,32 +97,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { return; } - let item_msg = - match self.describe_place_with_options(used_place, IncludingDowncast(true)) { - Some(name) => format!("`{}`", name), - None => "value".to_owned(), - }; - let mut err = self.cannot_act_on_uninitialized_variable( - span, - desired_action.as_noun(), - &self - .describe_place_with_options(moved_place, IncludingDowncast(true)) - .unwrap_or_else(|| "_".to_owned()), - ); - err.span_label(span, format!("use of possibly-uninitialized {}", item_msg)); - - use_spans.var_span_label_path_only( - &mut err, - format!("{} occurs due to use{}", desired_action.as_noun(), use_spans.describe()), - ); - + let err = + self.report_use_of_uninitialized(mpi, used_place, desired_action, span, use_spans); self.buffer_error(err); } else { if let Some((reported_place, _)) = self.has_move_error(&move_out_indices) { if self.prefixes(*reported_place, PrefixSet::All).any(|p| p == used_place) { debug!( - "report_use_of_moved_or_uninitialized place: error suppressed \ - mois={:?}", + "report_use_of_moved_or_uninitialized place: error suppressed mois={:?}", move_out_indices ); return; @@ -326,6 +311,99 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } + fn report_use_of_uninitialized( + &self, + mpi: MovePathIndex, + used_place: PlaceRef<'tcx>, + desired_action: InitializationRequiringAction, + span: Span, + use_spans: UseSpans<'tcx>, + ) -> DiagnosticBuilder<'cx, ErrorGuaranteed> { + // We need all statements in the body where the binding was assigned to to later find all + // the branching code paths where the binding *wasn't* assigned to. + let inits = &self.move_data.init_path_map[mpi]; + let move_path = &self.move_data.move_paths[mpi]; + let decl_span = self.body.local_decls[move_path.place.local].source_info.span; + let mut spans = vec![]; + for init_idx in inits { + let init = &self.move_data.inits[*init_idx]; + let span = init.span(&self.body); + spans.push(span); + } + + let (item_msg, name, desc) = + match self.describe_place_with_options(used_place, IncludingDowncast(true)) { + Some(name) => (format!("`{name}`"), format!("`{name}`"), format!("`{name}` ")), + None => ("value".to_string(), "the variable".to_string(), String::new()), + }; + let initialized = if let InitializationRequiringAction::PartialAssignment = desired_action { + // The same error is emitted for bindings that are *sometimes* initialized and the ones + // that are *partially* initialized by assigning to a field of an uninitialized + // binding. We differentiate between them for more accurate wording here. + "fully initialized" + } else if spans.iter().filter(|i| !i.contains(span)).count() == 0 { + // We filter above to avoid misleading wording in cases like: + // ``` + // let x; + // x += 1; + // ``` + "initialized" + } else { + "initialized in all conditions" + }; + let mut err = struct_span_err!(self, span, E0381, "binding {desc}isn't {initialized}"); + use_spans.var_span_label_path_only( + &mut err, + format!("{} occurs due to use{}", desired_action.as_noun(), use_spans.describe()), + ); + + if let InitializationRequiringAction::PartialAssignment = desired_action { + err.help( + "partial initialization isn't supported, fully initialize the binding with \ + a default value and mutate, or use `std::mem::MaybeUninit`", + ); + } + let verb = desired_action.as_verb_in_past_tense(); + err.span_label(span, format!("{item_msg} {verb} here but it isn't {initialized}",)); + + // We use the statements were the binding was initialized, and inspect the HIR to look + // for the branching codepaths that aren't covered, to point at them. + let hir_id = self.mir_hir_id(); + let map = self.infcx.tcx.hir(); + let body_id = map.body_owned_by(hir_id); + let body = map.body(body_id); + + let mut visitor = ConditionVisitor { spans: &spans, name: &name, errors: vec![] }; + visitor.visit_body(&body); + if visitor.errors.is_empty() { + for sp in &spans { + if *sp < span && !sp.overlaps(span) { + err.span_label(*sp, "binding initialized here in some conditions"); + } + } + } + for (sp, label) in visitor.errors { + if sp < span && !sp.overlaps(span) { + // When we have a case like `match-cfg-fake-edges.rs`, we don't want to mention + // match arms coming after the primary span because they aren't relevant: + // ``` + // let x; + // match y { + // _ if { x = 2; true } => {} + // _ if { + // x; //~ ERROR + // false + // } => {} + // _ => {} // We don't want to point to this. + // }; + // ``` + err.span_label(sp, &label); + } + } + err.span_label(decl_span, "variable declared here"); + err + } + fn suggest_borrow_fn_like( &self, err: &mut DiagnosticBuilder<'tcx, ErrorGuaranteed>, @@ -2448,3 +2526,103 @@ impl<'tcx> AnnotatedBorrowFnSignature<'tcx> { } } } + +/// Detect whether one of the provided spans is a statement nested within the top-most visited expr +struct ReferencedStatementsVisitor<'a>(&'a [Span], bool); + +impl<'a, 'v> Visitor<'v> for ReferencedStatementsVisitor<'a> { + fn visit_stmt(&mut self, s: &'v hir::Stmt<'v>) { + match s.kind { + hir::StmtKind::Semi(expr) if self.0.contains(&expr.span) => { + self.1 = true; + } + _ => {} + } + } +} + +/// Given a set of spans representing statements initializing the relevant binding, visit all the +/// function expressions looking for branching code paths that *do not* initialize the binding. +struct ConditionVisitor<'b> { + spans: &'b [Span], + name: &'b str, + errors: Vec<(Span, String)>, +} + +impl<'b, 'v> Visitor<'v> for ConditionVisitor<'b> { + fn visit_expr(&mut self, ex: &'v hir::Expr<'v>) { + match ex.kind { + hir::ExprKind::If(cond, body, None) => { + // `if` expressions with no `else` that initialize the binding might be missing an + // `else` arm. + let mut v = ReferencedStatementsVisitor(self.spans, false); + v.visit_expr(body); + if v.1 { + self.errors.push(( + cond.span, + format!( + "this `if` expression might be missing an `else` arm where {} is \ + initialized", + self.name, + ), + )); + } + } + hir::ExprKind::If(cond, body, Some(other)) => { + // `if` expressions where the binding is only initialized in one of the two arms + // might be missing a binding initialization. + let mut a = ReferencedStatementsVisitor(self.spans, false); + a.visit_expr(body); + let mut b = ReferencedStatementsVisitor(self.spans, false); + b.visit_expr(other); + match (a.1, b.1) { + (true, true) | (false, false) => {} + (true, false) => { + self.errors.push(( + cond.span, + format!("{} is uninitialized if this condition isn't met", self.name,), + )); + } + (false, true) => { + self.errors.push(( + cond.span, + format!("{} is uninitialized if this condition is met", self.name), + )); + } + } + } + hir::ExprKind::Match(_, arms, _) => { + // If the binding is initialized in one of the match arms, then the other match + // arms might be missing an initialization. + let results: Vec = arms + .iter() + .map(|arm| { + let mut v = ReferencedStatementsVisitor(self.spans, false); + v.visit_arm(arm); + v.1 + }) + .collect(); + if results.iter().any(|x| *x) && !results.iter().all(|x| *x) { + for (arm, seen) in arms.iter().zip(results) { + if !seen { + self.errors.push(( + arm.pat.span, + format!( + "{} is uninitialized if this pattern is matched", + self.name + ), + )); + } + } + } + } + // FIXME: should we also account for binops, particularly `&&` and `||`? `try` should + // also be accounted for. For now it is fine, as if we don't find *any* relevant + // branching code paths, we point at the places where the binding *is* initialized for + // *some* context. We should also specialize the output for `while` and `for` loops, + // but for now we can rely on their desugaring to provide appropriate output. + _ => {} + } + walk_expr(self, ex); + } +} diff --git a/src/test/ui/asm/x86_64/type-check-5.rs b/src/test/ui/asm/x86_64/type-check-5.rs index 474478f6a88e1..6190e0b52f4e9 100644 --- a/src/test/ui/asm/x86_64/type-check-5.rs +++ b/src/test/ui/asm/x86_64/type-check-5.rs @@ -13,10 +13,10 @@ fn main() { let x: u64; asm!("{}", in(reg) x); - //~^ ERROR use of possibly-uninitialized variable: `x` + //~^ ERROR E0381 let mut y: u64; asm!("{}", inout(reg) y); - //~^ ERROR use of possibly-uninitialized variable: `y` + //~^ ERROR E0381 let _ = y; // Outputs require mutable places diff --git a/src/test/ui/asm/x86_64/type-check-5.stderr b/src/test/ui/asm/x86_64/type-check-5.stderr index 181ecaf585585..26aac4ed2c1e0 100644 --- a/src/test/ui/asm/x86_64/type-check-5.stderr +++ b/src/test/ui/asm/x86_64/type-check-5.stderr @@ -1,14 +1,18 @@ -error[E0381]: use of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't initialized --> $DIR/type-check-5.rs:15:28 | +LL | let x: u64; + | - variable declared here LL | asm!("{}", in(reg) x); - | ^ use of possibly-uninitialized `x` + | ^ `x` used here but it isn't initialized -error[E0381]: use of possibly-uninitialized variable: `y` +error[E0381]: binding `y` isn't initialized --> $DIR/type-check-5.rs:18:9 | +LL | let mut y: u64; + | ----- variable declared here LL | asm!("{}", inout(reg) y); - | ^^^^^^^^^^^^^^^^^^^^^^^^ use of possibly-uninitialized `y` + | ^^^^^^^^^^^^^^^^^^^^^^^^ `y` used here but it isn't initialized error[E0596]: cannot borrow `v` as mutable, as it is not declared as mutable --> $DIR/type-check-5.rs:26:29 diff --git a/src/test/ui/async-await/no-non-guaranteed-initialization.rs b/src/test/ui/async-await/no-non-guaranteed-initialization.rs index 24070fe33083c..c4d81bf83a3c4 100644 --- a/src/test/ui/async-await/no-non-guaranteed-initialization.rs +++ b/src/test/ui/async-await/no-non-guaranteed-initialization.rs @@ -6,8 +6,7 @@ async fn no_non_guaranteed_initialization(x: usize) -> usize { if x > 5 { y = echo(10).await; } - y - //~^ use of possibly-uninitialized variable: `y` + y //~ ERROR E0381 } async fn echo(x: usize) -> usize { x + 1 } diff --git a/src/test/ui/async-await/no-non-guaranteed-initialization.stderr b/src/test/ui/async-await/no-non-guaranteed-initialization.stderr index f5991f4bccac9..c6490c7bf4dbf 100644 --- a/src/test/ui/async-await/no-non-guaranteed-initialization.stderr +++ b/src/test/ui/async-await/no-non-guaranteed-initialization.stderr @@ -1,8 +1,13 @@ -error[E0381]: use of possibly-uninitialized variable: `y` +error[E0381]: binding `y` isn't initialized in all conditions --> $DIR/no-non-guaranteed-initialization.rs:9:5 | +LL | let y; + | - variable declared here +LL | if x > 5 { + | ----- this `if` expression might be missing an `else` arm where `y` is initialized +... LL | y - | ^ use of possibly-uninitialized `y` + | ^ `y` used here but it isn't initialized in all conditions error: aborting due to previous error diff --git a/src/test/ui/async-await/partial-initialization-across-await.rs b/src/test/ui/async-await/partial-initialization-across-await.rs index 8a98a4b0f6bb4..7577aee3fb7d6 100644 --- a/src/test/ui/async-await/partial-initialization-across-await.rs +++ b/src/test/ui/async-await/partial-initialization-across-await.rs @@ -10,8 +10,7 @@ async fn noop() {} async fn test_tuple() { let mut t: (i32, i32); - t.0 = 42; - //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381] + t.0 = 42; //~ ERROR E0381 noop().await; t.1 = 88; let _ = t; @@ -19,8 +18,7 @@ async fn test_tuple() { async fn test_tuple_struct() { let mut t: T; - t.0 = 42; - //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381] + t.0 = 42; //~ ERROR E0381 noop().await; t.1 = 88; let _ = t; @@ -28,8 +26,7 @@ async fn test_tuple_struct() { async fn test_struct() { let mut t: S; - t.x = 42; - //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381] + t.x = 42; //~ ERROR E0381 noop().await; t.y = 88; let _ = t; diff --git a/src/test/ui/async-await/partial-initialization-across-await.stderr b/src/test/ui/async-await/partial-initialization-across-await.stderr index 9a510c22c4b1e..981e32cadd9de 100644 --- a/src/test/ui/async-await/partial-initialization-across-await.stderr +++ b/src/test/ui/async-await/partial-initialization-across-await.stderr @@ -1,20 +1,32 @@ -error[E0381]: assign to part of possibly-uninitialized variable: `t` +error[E0381]: binding `t` isn't fully initialized --> $DIR/partial-initialization-across-await.rs:13:5 | +LL | let mut t: (i32, i32); + | ----- variable declared here LL | t.0 = 42; - | ^^^^^^^^ use of possibly-uninitialized `t` + | ^^^^^^^^ `t` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` -error[E0381]: assign to part of possibly-uninitialized variable: `t` - --> $DIR/partial-initialization-across-await.rs:22:5 +error[E0381]: binding `t` isn't fully initialized + --> $DIR/partial-initialization-across-await.rs:21:5 | +LL | let mut t: T; + | ----- variable declared here LL | t.0 = 42; - | ^^^^^^^^ use of possibly-uninitialized `t` + | ^^^^^^^^ `t` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` -error[E0381]: assign to part of possibly-uninitialized variable: `t` - --> $DIR/partial-initialization-across-await.rs:31:5 +error[E0381]: binding `t` isn't fully initialized + --> $DIR/partial-initialization-across-await.rs:29:5 | +LL | let mut t: S; + | ----- variable declared here LL | t.x = 42; - | ^^^^^^^^ use of possibly-uninitialized `t` + | ^^^^^^^^ `t` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` error: aborting due to 3 previous errors diff --git a/src/test/ui/borrowck/assign_mutable_fields.stderr b/src/test/ui/borrowck/assign_mutable_fields.stderr index 40f1aae092dc6..57787b8924998 100644 --- a/src/test/ui/borrowck/assign_mutable_fields.stderr +++ b/src/test/ui/borrowck/assign_mutable_fields.stderr @@ -1,14 +1,22 @@ -error[E0381]: assign to part of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't fully initialized --> $DIR/assign_mutable_fields.rs:9:5 | +LL | let mut x: (u32, u32); + | ----- variable declared here LL | x.0 = 1; - | ^^^^^^^ use of possibly-uninitialized `x` + | ^^^^^^^ `x` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` -error[E0381]: assign to part of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't fully initialized --> $DIR/assign_mutable_fields.rs:17:5 | +LL | let mut x: (u32, u32); + | ----- variable declared here LL | x.0 = 1; - | ^^^^^^^ use of possibly-uninitialized `x` + | ^^^^^^^ `x` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` error: aborting due to 2 previous errors diff --git a/src/test/ui/borrowck/borrowck-and-init.rs b/src/test/ui/borrowck/borrowck-and-init.rs index f11d44e2217ba..eeb4f05d60c96 100644 --- a/src/test/ui/borrowck/borrowck-and-init.rs +++ b/src/test/ui/borrowck/borrowck-and-init.rs @@ -2,5 +2,5 @@ fn main() { let i: isize; println!("{}", false && { i = 5; true }); - println!("{}", i); //~ ERROR borrow of possibly-uninitialized variable: `i` + println!("{}", i); //~ ERROR E0381 } diff --git a/src/test/ui/borrowck/borrowck-and-init.stderr b/src/test/ui/borrowck/borrowck-and-init.stderr index d2c7473c036b8..de57243a5dbf7 100644 --- a/src/test/ui/borrowck/borrowck-and-init.stderr +++ b/src/test/ui/borrowck/borrowck-and-init.stderr @@ -1,8 +1,13 @@ -error[E0381]: borrow of possibly-uninitialized variable: `i` +error[E0381]: binding `i` isn't initialized in all conditions --> $DIR/borrowck-and-init.rs:5:20 | +LL | let i: isize; + | - variable declared here +LL | +LL | println!("{}", false && { i = 5; true }); + | ----- binding initialized here in some conditions LL | println!("{}", i); - | ^ use of possibly-uninitialized `i` + | ^ `i` borrowed here but it isn't initialized in all conditions | = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/borrowck/borrowck-block-unint.rs b/src/test/ui/borrowck/borrowck-block-unint.rs index 1e7306acaee98..8d13b25a35756 100644 --- a/src/test/ui/borrowck/borrowck-block-unint.rs +++ b/src/test/ui/borrowck/borrowck-block-unint.rs @@ -1,7 +1,7 @@ fn force(f: F) where F: FnOnce() { f(); } fn main() { let x: isize; - force(|| { //~ ERROR borrow of possibly-uninitialized variable: `x` + force(|| { //~ ERROR E0381 println!("{}", x); }); } diff --git a/src/test/ui/borrowck/borrowck-block-unint.stderr b/src/test/ui/borrowck/borrowck-block-unint.stderr index 578f89df46ce1..0f0fbedaf17e7 100644 --- a/src/test/ui/borrowck/borrowck-block-unint.stderr +++ b/src/test/ui/borrowck/borrowck-block-unint.stderr @@ -1,8 +1,10 @@ -error[E0381]: borrow of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't initialized --> $DIR/borrowck-block-unint.rs:4:11 | +LL | let x: isize; + | - variable declared here LL | force(|| { - | ^^ use of possibly-uninitialized `x` + | ^^ `x` borrowed here but it isn't initialized LL | println!("{}", x); | - borrow occurs due to use in closure diff --git a/src/test/ui/borrowck/borrowck-break-uninit-2.rs b/src/test/ui/borrowck/borrowck-break-uninit-2.rs index 126d991a51c6e..3abca33a84add 100644 --- a/src/test/ui/borrowck/borrowck-break-uninit-2.rs +++ b/src/test/ui/borrowck/borrowck-break-uninit-2.rs @@ -6,7 +6,7 @@ fn foo() -> isize { x = 0; } - println!("{}", x); //~ ERROR borrow of possibly-uninitialized variable: `x` + println!("{}", x); //~ ERROR E0381 return 17; } diff --git a/src/test/ui/borrowck/borrowck-break-uninit-2.stderr b/src/test/ui/borrowck/borrowck-break-uninit-2.stderr index b134f5cc2d8e3..2b5547dbf9556 100644 --- a/src/test/ui/borrowck/borrowck-break-uninit-2.stderr +++ b/src/test/ui/borrowck/borrowck-break-uninit-2.stderr @@ -1,8 +1,11 @@ -error[E0381]: borrow of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't initialized --> $DIR/borrowck-break-uninit-2.rs:9:20 | +LL | let x: isize; + | - variable declared here +... LL | println!("{}", x); - | ^ use of possibly-uninitialized `x` + | ^ `x` borrowed here but it isn't initialized | = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/borrowck/borrowck-break-uninit.rs b/src/test/ui/borrowck/borrowck-break-uninit.rs index 8ccb21ae8eebf..824f91dbc62c2 100644 --- a/src/test/ui/borrowck/borrowck-break-uninit.rs +++ b/src/test/ui/borrowck/borrowck-break-uninit.rs @@ -6,7 +6,7 @@ fn foo() -> isize { x = 0; } - println!("{}", x); //~ ERROR borrow of possibly-uninitialized variable: `x` + println!("{}", x); //~ ERROR E0381 return 17; } diff --git a/src/test/ui/borrowck/borrowck-break-uninit.stderr b/src/test/ui/borrowck/borrowck-break-uninit.stderr index 652d7d3076fbd..9d0fd5dac933f 100644 --- a/src/test/ui/borrowck/borrowck-break-uninit.stderr +++ b/src/test/ui/borrowck/borrowck-break-uninit.stderr @@ -1,8 +1,11 @@ -error[E0381]: borrow of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't initialized --> $DIR/borrowck-break-uninit.rs:9:20 | +LL | let x: isize; + | - variable declared here +... LL | println!("{}", x); - | ^ use of possibly-uninitialized `x` + | ^ `x` borrowed here but it isn't initialized | = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/borrowck/borrowck-field-sensitivity.rs b/src/test/ui/borrowck/borrowck-field-sensitivity.rs index 50edfb6ba2db1..03edf445ee97b 100644 --- a/src/test/ui/borrowck/borrowck-field-sensitivity.rs +++ b/src/test/ui/borrowck/borrowck-field-sensitivity.rs @@ -78,20 +78,20 @@ fn fu_move_after_fu_move() { fn copy_after_field_assign_after_uninit() { let mut x: A; - x.a = 1; //~ ERROR assign to part of possibly-uninitialized variable: `x` + x.a = 1; //~ ERROR E0381 drop(x.a); } fn borrow_after_field_assign_after_uninit() { let mut x: A; - x.a = 1; //~ ERROR assign to part of possibly-uninitialized variable: `x` + x.a = 1; //~ ERROR E0381 let p = &x.a; drop(*p); } fn move_after_field_assign_after_uninit() { let mut x: A; - x.b = Box::new(1); //~ ERROR assign to part of possibly-uninitialized variable: `x` + x.b = Box::new(1); //~ ERROR E0381 drop(x.b); } diff --git a/src/test/ui/borrowck/borrowck-field-sensitivity.stderr b/src/test/ui/borrowck/borrowck-field-sensitivity.stderr index bb4d2f06016b9..492bbfa9eb2d4 100644 --- a/src/test/ui/borrowck/borrowck-field-sensitivity.stderr +++ b/src/test/ui/borrowck/borrowck-field-sensitivity.stderr @@ -108,23 +108,35 @@ LL | let _z = A { a: 4, .. x }; | = note: move occurs because `x.b` has type `Box`, which does not implement the `Copy` trait -error[E0381]: assign to part of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't fully initialized --> $DIR/borrowck-field-sensitivity.rs:81:5 | +LL | let mut x: A; + | ----- variable declared here LL | x.a = 1; - | ^^^^^^^ use of possibly-uninitialized `x` + | ^^^^^^^ `x` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` -error[E0381]: assign to part of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't fully initialized --> $DIR/borrowck-field-sensitivity.rs:87:5 | +LL | let mut x: A; + | ----- variable declared here LL | x.a = 1; - | ^^^^^^^ use of possibly-uninitialized `x` + | ^^^^^^^ `x` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` -error[E0381]: assign to part of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't fully initialized --> $DIR/borrowck-field-sensitivity.rs:94:5 | +LL | let mut x: A; + | ----- variable declared here LL | x.b = Box::new(1); - | ^^^ use of possibly-uninitialized `x` + | ^^^ `x` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` error: aborting due to 14 previous errors diff --git a/src/test/ui/borrowck/borrowck-if-no-else.rs b/src/test/ui/borrowck/borrowck-if-no-else.rs index f59bcad6f61d7..534d771be1dfa 100644 --- a/src/test/ui/borrowck/borrowck-if-no-else.rs +++ b/src/test/ui/borrowck/borrowck-if-no-else.rs @@ -2,5 +2,5 @@ fn foo(x: isize) { println!("{}", x); } fn main() { let x: isize; if 1 > 2 { x = 10; } - foo(x); //~ ERROR use of possibly-uninitialized variable: `x` + foo(x); //~ ERROR E0381 } diff --git a/src/test/ui/borrowck/borrowck-if-no-else.stderr b/src/test/ui/borrowck/borrowck-if-no-else.stderr index 3e9d3d4f6d513..178381e847786 100644 --- a/src/test/ui/borrowck/borrowck-if-no-else.stderr +++ b/src/test/ui/borrowck/borrowck-if-no-else.stderr @@ -1,8 +1,12 @@ -error[E0381]: use of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't initialized in all conditions --> $DIR/borrowck-if-no-else.rs:5:9 | +LL | let x: isize; if 1 > 2 { x = 10; } + | - ----- this `if` expression might be missing an `else` arm where `x` is initialized + | | + | variable declared here LL | foo(x); - | ^ use of possibly-uninitialized `x` + | ^ `x` used here but it isn't initialized in all conditions error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-if-with-else.rs b/src/test/ui/borrowck/borrowck-if-with-else.rs index c13318b16c2fa..69d450c59891a 100644 --- a/src/test/ui/borrowck/borrowck-if-with-else.rs +++ b/src/test/ui/borrowck/borrowck-if-with-else.rs @@ -7,5 +7,5 @@ fn main() { } else { x = 10; } - foo(x); //~ ERROR use of possibly-uninitialized variable: `x` + foo(x); //~ ERROR E0381 } diff --git a/src/test/ui/borrowck/borrowck-if-with-else.stderr b/src/test/ui/borrowck/borrowck-if-with-else.stderr index 53b8a6bba2c76..f1af7b67b1c1b 100644 --- a/src/test/ui/borrowck/borrowck-if-with-else.stderr +++ b/src/test/ui/borrowck/borrowck-if-with-else.stderr @@ -1,8 +1,13 @@ -error[E0381]: use of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't initialized in all conditions --> $DIR/borrowck-if-with-else.rs:10:9 | +LL | let x: isize; + | - variable declared here +LL | if 1 > 2 { + | ----- `x` is uninitialized if this condition is met +... LL | foo(x); - | ^ use of possibly-uninitialized `x` + | ^ `x` used here but it isn't initialized in all conditions error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-init-in-called-fn-expr.rs b/src/test/ui/borrowck/borrowck-init-in-called-fn-expr.rs index 9905e420f948d..e6476b9c1bef7 100644 --- a/src/test/ui/borrowck/borrowck-init-in-called-fn-expr.rs +++ b/src/test/ui/borrowck/borrowck-init-in-called-fn-expr.rs @@ -1,7 +1,7 @@ fn main() { let j = || -> isize { let i: isize; - i //~ ERROR use of possibly-uninitialized variable: `i` + i //~ ERROR E0381 }; j(); } diff --git a/src/test/ui/borrowck/borrowck-init-in-called-fn-expr.stderr b/src/test/ui/borrowck/borrowck-init-in-called-fn-expr.stderr index 2d1d9bc8fa41d..8bdccd0dad6d2 100644 --- a/src/test/ui/borrowck/borrowck-init-in-called-fn-expr.stderr +++ b/src/test/ui/borrowck/borrowck-init-in-called-fn-expr.stderr @@ -1,8 +1,10 @@ -error[E0381]: use of possibly-uninitialized variable: `i` +error[E0381]: binding `i` isn't initialized --> $DIR/borrowck-init-in-called-fn-expr.rs:4:9 | +LL | let i: isize; + | - variable declared here LL | i - | ^ use of possibly-uninitialized `i` + | ^ `i` used here but it isn't initialized error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-init-in-fn-expr.rs b/src/test/ui/borrowck/borrowck-init-in-fn-expr.rs index 7dd3396c8c2cb..7eb204a0d1672 100644 --- a/src/test/ui/borrowck/borrowck-init-in-fn-expr.rs +++ b/src/test/ui/borrowck/borrowck-init-in-fn-expr.rs @@ -1,7 +1,7 @@ fn main() { let f = || -> isize { let i: isize; - i //~ ERROR use of possibly-uninitialized variable: `i` + i //~ ERROR E0381 }; println!("{}", f()); } diff --git a/src/test/ui/borrowck/borrowck-init-in-fn-expr.stderr b/src/test/ui/borrowck/borrowck-init-in-fn-expr.stderr index fd8b90eda6032..84ec5598abb89 100644 --- a/src/test/ui/borrowck/borrowck-init-in-fn-expr.stderr +++ b/src/test/ui/borrowck/borrowck-init-in-fn-expr.stderr @@ -1,8 +1,10 @@ -error[E0381]: use of possibly-uninitialized variable: `i` +error[E0381]: binding `i` isn't initialized --> $DIR/borrowck-init-in-fn-expr.rs:4:9 | +LL | let i: isize; + | - variable declared here LL | i - | ^ use of possibly-uninitialized `i` + | ^ `i` used here but it isn't initialized error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-init-in-fru.rs b/src/test/ui/borrowck/borrowck-init-in-fru.rs index d7ec2ed75c85c..c07957ab13973 100644 --- a/src/test/ui/borrowck/borrowck-init-in-fru.rs +++ b/src/test/ui/borrowck/borrowck-init-in-fru.rs @@ -7,6 +7,6 @@ struct Point { fn main() { let mut origin: Point; origin = Point { x: 10, ..origin }; - //~^ ERROR use of possibly-uninitialized variable: `origin` [E0381] + //~^ ERROR E0381 origin.clone(); } diff --git a/src/test/ui/borrowck/borrowck-init-in-fru.stderr b/src/test/ui/borrowck/borrowck-init-in-fru.stderr index f01afe1466aef..ddb2473d1ebee 100644 --- a/src/test/ui/borrowck/borrowck-init-in-fru.stderr +++ b/src/test/ui/borrowck/borrowck-init-in-fru.stderr @@ -1,8 +1,10 @@ -error[E0381]: use of possibly-uninitialized variable: `origin` +error[E0381]: binding `origin.y` isn't initialized --> $DIR/borrowck-init-in-fru.rs:9:14 | +LL | let mut origin: Point; + | ---------- variable declared here LL | origin = Point { x: 10, ..origin }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^ use of possibly-uninitialized `origin.y` + | ^^^^^^^^^^^^^^^^^^^^^^^^^ `origin.y` used here but it isn't initialized error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-init-op-equal.rs b/src/test/ui/borrowck/borrowck-init-op-equal.rs index 784eb8cf85b8a..3d08c1b81a79b 100644 --- a/src/test/ui/borrowck/borrowck-init-op-equal.rs +++ b/src/test/ui/borrowck/borrowck-init-op-equal.rs @@ -1,6 +1,6 @@ fn test() { let v: isize; - v += 1; //~ ERROR use of possibly-uninitialized variable: `v` + v += 1; //~ ERROR E0381 v.clone(); } diff --git a/src/test/ui/borrowck/borrowck-init-op-equal.stderr b/src/test/ui/borrowck/borrowck-init-op-equal.stderr index 6c88778ae0e5a..f1d7ec6a446d4 100644 --- a/src/test/ui/borrowck/borrowck-init-op-equal.stderr +++ b/src/test/ui/borrowck/borrowck-init-op-equal.stderr @@ -1,8 +1,10 @@ -error[E0381]: use of possibly-uninitialized variable: `v` +error[E0381]: binding `v` isn't initialized --> $DIR/borrowck-init-op-equal.rs:3:5 | +LL | let v: isize; + | - variable declared here LL | v += 1; - | ^^^^^^ use of possibly-uninitialized `v` + | ^^^^^^ `v` used here but it isn't initialized error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-init-plus-equal.rs b/src/test/ui/borrowck/borrowck-init-plus-equal.rs index d9d20a2a9c148..2a52a3f4e5eb1 100644 --- a/src/test/ui/borrowck/borrowck-init-plus-equal.rs +++ b/src/test/ui/borrowck/borrowck-init-plus-equal.rs @@ -1,6 +1,6 @@ fn test() { let mut v: isize; - v = v + 1; //~ ERROR use of possibly-uninitialized variable: `v` + v = v + 1; //~ ERROR E0381 v.clone(); } diff --git a/src/test/ui/borrowck/borrowck-init-plus-equal.stderr b/src/test/ui/borrowck/borrowck-init-plus-equal.stderr index fe09c8581df0e..26422af9c639a 100644 --- a/src/test/ui/borrowck/borrowck-init-plus-equal.stderr +++ b/src/test/ui/borrowck/borrowck-init-plus-equal.stderr @@ -1,8 +1,10 @@ -error[E0381]: use of possibly-uninitialized variable: `v` +error[E0381]: binding `v` isn't initialized --> $DIR/borrowck-init-plus-equal.rs:3:9 | +LL | let mut v: isize; + | ----- variable declared here LL | v = v + 1; - | ^ use of possibly-uninitialized `v` + | ^ `v` used here but it isn't initialized error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-or-init.rs b/src/test/ui/borrowck/borrowck-or-init.rs index 81b0b80bf11b5..079cf899e6dbf 100644 --- a/src/test/ui/borrowck/borrowck-or-init.rs +++ b/src/test/ui/borrowck/borrowck-or-init.rs @@ -2,5 +2,5 @@ fn main() { let i: isize; println!("{}", false || { i = 5; true }); - println!("{}", i); //~ ERROR borrow of possibly-uninitialized variable: `i` + println!("{}", i); //~ ERROR E0381 } diff --git a/src/test/ui/borrowck/borrowck-or-init.stderr b/src/test/ui/borrowck/borrowck-or-init.stderr index 6c757759f7134..7fcec3046474d 100644 --- a/src/test/ui/borrowck/borrowck-or-init.stderr +++ b/src/test/ui/borrowck/borrowck-or-init.stderr @@ -1,8 +1,13 @@ -error[E0381]: borrow of possibly-uninitialized variable: `i` +error[E0381]: binding `i` isn't initialized in all conditions --> $DIR/borrowck-or-init.rs:5:20 | +LL | let i: isize; + | - variable declared here +LL | +LL | println!("{}", false || { i = 5; true }); + | ----- binding initialized here in some conditions LL | println!("{}", i); - | ^ use of possibly-uninitialized `i` + | ^ `i` borrowed here but it isn't initialized in all conditions | = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/borrowck/borrowck-partial-reinit-4.rs b/src/test/ui/borrowck/borrowck-partial-reinit-4.rs index 5e5a8cdf4232b..a43a1936678ff 100644 --- a/src/test/ui/borrowck/borrowck-partial-reinit-4.rs +++ b/src/test/ui/borrowck/borrowck-partial-reinit-4.rs @@ -14,8 +14,7 @@ impl Drop for Test2 { fn stuff() { let mut x : (Test2, Test2); - (x.0).0 = Some(Test); - //~^ ERROR assign of possibly-uninitialized variable: `x.0` + (x.0).0 = Some(Test); //~ ERROR E0381 } fn main() { diff --git a/src/test/ui/borrowck/borrowck-partial-reinit-4.stderr b/src/test/ui/borrowck/borrowck-partial-reinit-4.stderr index 218c4f2de5bc7..be5de8a0a5a61 100644 --- a/src/test/ui/borrowck/borrowck-partial-reinit-4.stderr +++ b/src/test/ui/borrowck/borrowck-partial-reinit-4.stderr @@ -1,8 +1,10 @@ -error[E0381]: assign of possibly-uninitialized variable: `x.0` +error[E0381]: binding `x.0` isn't initialized --> $DIR/borrowck-partial-reinit-4.rs:17:5 | +LL | let mut x : (Test2, Test2); + | ----- variable declared here LL | (x.0).0 = Some(Test); - | ^^^^^^^ use of possibly-uninitialized `x.0` + | ^^^^^^^ `x.0` assigned here but it isn't initialized error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-return.rs b/src/test/ui/borrowck/borrowck-return.rs index 8c623356f6c6b..a63ffcff732ee 100644 --- a/src/test/ui/borrowck/borrowck-return.rs +++ b/src/test/ui/borrowck/borrowck-return.rs @@ -1,6 +1,6 @@ fn f() -> isize { let x: isize; - return x; //~ ERROR use of possibly-uninitialized variable: `x` + return x; //~ ERROR E0381 } fn main() { f(); } diff --git a/src/test/ui/borrowck/borrowck-return.stderr b/src/test/ui/borrowck/borrowck-return.stderr index bc74e8e343848..f42ac9fc54159 100644 --- a/src/test/ui/borrowck/borrowck-return.stderr +++ b/src/test/ui/borrowck/borrowck-return.stderr @@ -1,8 +1,10 @@ -error[E0381]: use of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't initialized --> $DIR/borrowck-return.rs:3:12 | +LL | let x: isize; + | - variable declared here LL | return x; - | ^ use of possibly-uninitialized `x` + | ^ `x` used here but it isn't initialized error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-storage-dead.stderr b/src/test/ui/borrowck/borrowck-storage-dead.stderr index 8e4932142f0db..6168961bd16db 100644 --- a/src/test/ui/borrowck/borrowck-storage-dead.stderr +++ b/src/test/ui/borrowck/borrowck-storage-dead.stderr @@ -1,8 +1,10 @@ -error[E0381]: use of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't initialized --> $DIR/borrowck-storage-dead.rs:16:17 | +LL | let x: i32; + | - variable declared here LL | let _ = x + 1; - | ^ use of possibly-uninitialized `x` + | ^ `x` used here but it isn't initialized error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-uninit-after-item.rs b/src/test/ui/borrowck/borrowck-uninit-after-item.rs index e9a389657c8fd..e97ce6aa407ed 100644 --- a/src/test/ui/borrowck/borrowck-uninit-after-item.rs +++ b/src/test/ui/borrowck/borrowck-uninit-after-item.rs @@ -1,5 +1,5 @@ fn main() { let bar; fn baz(_x: isize) { } - baz(bar); //~ ERROR use of possibly-uninitialized variable: `bar` + baz(bar); //~ ERROR E0381 } diff --git a/src/test/ui/borrowck/borrowck-uninit-after-item.stderr b/src/test/ui/borrowck/borrowck-uninit-after-item.stderr index f7f069b81be02..64bccecf68a94 100644 --- a/src/test/ui/borrowck/borrowck-uninit-after-item.stderr +++ b/src/test/ui/borrowck/borrowck-uninit-after-item.stderr @@ -1,8 +1,11 @@ -error[E0381]: use of possibly-uninitialized variable: `bar` +error[E0381]: binding `bar` isn't initialized --> $DIR/borrowck-uninit-after-item.rs:4:9 | +LL | let bar; + | --- variable declared here +LL | fn baz(_x: isize) { } LL | baz(bar); - | ^^^ use of possibly-uninitialized `bar` + | ^^^ `bar` used here but it isn't initialized error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-uninit-field-access.stderr b/src/test/ui/borrowck/borrowck-uninit-field-access.stderr index 7951a5b1b5d70..0ffa5cee5f167 100644 --- a/src/test/ui/borrowck/borrowck-uninit-field-access.stderr +++ b/src/test/ui/borrowck/borrowck-uninit-field-access.stderr @@ -1,8 +1,10 @@ -error[E0381]: use of possibly-uninitialized variable: `a` +error[E0381]: binding `a.x` isn't initialized --> $DIR/borrowck-uninit-field-access.rs:21:13 | +LL | let mut a: Point; + | ----- variable declared here LL | let _ = a.x + 1; - | ^^^ use of possibly-uninitialized `a.x` + | ^^^ `a.x` used here but it isn't initialized error[E0382]: use of moved value: `line1.origin` --> $DIR/borrowck-uninit-field-access.rs:25:13 diff --git a/src/test/ui/borrowck/borrowck-uninit-in-assignop.rs b/src/test/ui/borrowck/borrowck-uninit-in-assignop.rs index 20350d61d5bb6..92c3692bd2f69 100644 --- a/src/test/ui/borrowck/borrowck-uninit-in-assignop.rs +++ b/src/test/ui/borrowck/borrowck-uninit-in-assignop.rs @@ -3,32 +3,32 @@ pub fn main() { let x: isize; - x += 1; //~ ERROR use of possibly-uninitialized variable: `x` + x += 1; //~ ERROR E0381 let x: isize; - x -= 1; //~ ERROR use of possibly-uninitialized variable: `x` + x -= 1; //~ ERROR E0381 let x: isize; - x *= 1; //~ ERROR use of possibly-uninitialized variable: `x` + x *= 1; //~ ERROR E0381 let x: isize; - x /= 1; //~ ERROR use of possibly-uninitialized variable: `x` + x /= 1; //~ ERROR E0381 let x: isize; - x %= 1; //~ ERROR use of possibly-uninitialized variable: `x` + x %= 1; //~ ERROR E0381 let x: isize; - x ^= 1; //~ ERROR use of possibly-uninitialized variable: `x` + x ^= 1; //~ ERROR E0381 let x: isize; - x &= 1; //~ ERROR use of possibly-uninitialized variable: `x` + x &= 1; //~ ERROR E0381 let x: isize; - x |= 1; //~ ERROR use of possibly-uninitialized variable: `x` + x |= 1; //~ ERROR E0381 let x: isize; - x <<= 1; //~ ERROR use of possibly-uninitialized variable: `x` + x <<= 1; //~ ERROR E0381 let x: isize; - x >>= 1; //~ ERROR use of possibly-uninitialized variable: `x` + x >>= 1; //~ ERROR E0381 } diff --git a/src/test/ui/borrowck/borrowck-uninit-in-assignop.stderr b/src/test/ui/borrowck/borrowck-uninit-in-assignop.stderr index f2036df3ce92a..273370a4eef3a 100644 --- a/src/test/ui/borrowck/borrowck-uninit-in-assignop.stderr +++ b/src/test/ui/borrowck/borrowck-uninit-in-assignop.stderr @@ -1,62 +1,82 @@ -error[E0381]: use of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't initialized --> $DIR/borrowck-uninit-in-assignop.rs:6:5 | +LL | let x: isize; + | - variable declared here LL | x += 1; - | ^^^^^^ use of possibly-uninitialized `x` + | ^^^^^^ `x` used here but it isn't initialized -error[E0381]: use of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't initialized --> $DIR/borrowck-uninit-in-assignop.rs:9:5 | +LL | let x: isize; + | - variable declared here LL | x -= 1; - | ^^^^^^ use of possibly-uninitialized `x` + | ^^^^^^ `x` used here but it isn't initialized -error[E0381]: use of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't initialized --> $DIR/borrowck-uninit-in-assignop.rs:12:5 | +LL | let x: isize; + | - variable declared here LL | x *= 1; - | ^^^^^^ use of possibly-uninitialized `x` + | ^^^^^^ `x` used here but it isn't initialized -error[E0381]: use of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't initialized --> $DIR/borrowck-uninit-in-assignop.rs:15:5 | +LL | let x: isize; + | - variable declared here LL | x /= 1; - | ^^^^^^ use of possibly-uninitialized `x` + | ^^^^^^ `x` used here but it isn't initialized -error[E0381]: use of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't initialized --> $DIR/borrowck-uninit-in-assignop.rs:18:5 | +LL | let x: isize; + | - variable declared here LL | x %= 1; - | ^^^^^^ use of possibly-uninitialized `x` + | ^^^^^^ `x` used here but it isn't initialized -error[E0381]: use of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't initialized --> $DIR/borrowck-uninit-in-assignop.rs:21:5 | +LL | let x: isize; + | - variable declared here LL | x ^= 1; - | ^^^^^^ use of possibly-uninitialized `x` + | ^^^^^^ `x` used here but it isn't initialized -error[E0381]: use of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't initialized --> $DIR/borrowck-uninit-in-assignop.rs:24:5 | +LL | let x: isize; + | - variable declared here LL | x &= 1; - | ^^^^^^ use of possibly-uninitialized `x` + | ^^^^^^ `x` used here but it isn't initialized -error[E0381]: use of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't initialized --> $DIR/borrowck-uninit-in-assignop.rs:27:5 | +LL | let x: isize; + | - variable declared here LL | x |= 1; - | ^^^^^^ use of possibly-uninitialized `x` + | ^^^^^^ `x` used here but it isn't initialized -error[E0381]: use of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't initialized --> $DIR/borrowck-uninit-in-assignop.rs:30:5 | +LL | let x: isize; + | - variable declared here LL | x <<= 1; - | ^^^^^^^ use of possibly-uninitialized `x` + | ^^^^^^^ `x` used here but it isn't initialized -error[E0381]: use of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't initialized --> $DIR/borrowck-uninit-in-assignop.rs:33:5 | +LL | let x: isize; + | - variable declared here LL | x >>= 1; - | ^^^^^^^ use of possibly-uninitialized `x` + | ^^^^^^^ `x` used here but it isn't initialized error: aborting due to 10 previous errors diff --git a/src/test/ui/borrowck/borrowck-uninit-ref-chain.rs b/src/test/ui/borrowck/borrowck-uninit-ref-chain.rs index 0ccea49f329bb..c36b9707d2287 100644 --- a/src/test/ui/borrowck/borrowck-uninit-ref-chain.rs +++ b/src/test/ui/borrowck/borrowck-uninit-ref-chain.rs @@ -5,29 +5,29 @@ struct S { fn main() { let x: &&Box; - let _y = &**x; //~ [E0381] + let _y = &**x; //~ ERROR [E0381] let x: &&S; - let _y = &**x; //~ [E0381] + let _y = &**x; //~ ERROR [E0381] let x: &&i32; - let _y = &**x; //~ [E0381] + let _y = &**x; //~ ERROR [E0381] let mut a: S; - a.x = 0; //~ ERROR assign to part of possibly-uninitialized variable: `a` [E0381] + a.x = 0; //~ ERROR [E0381] let _b = &a.x; let mut a: S<&&i32, &&i32>; - a.x = &&0; //~ ERROR assign to part of possibly-uninitialized variable: `a` [E0381] + a.x = &&0; //~ ERROR [E0381] let _b = &**a.x; let mut a: S; - a.x = 0; //~ ERROR assign to part of possibly-uninitialized variable: `a` [E0381] + a.x = 0; //~ ERROR [E0381] let _b = &a.y; let mut a: S<&&i32, &&i32>; - a.x = &&0; //~ assign to part of possibly-uninitialized variable: `a` [E0381] + a.x = &&0; //~ ERROR [E0381] let _b = &**a.y; } diff --git a/src/test/ui/borrowck/borrowck-uninit-ref-chain.stderr b/src/test/ui/borrowck/borrowck-uninit-ref-chain.stderr index d99a50df75b8c..e78f5888df62d 100644 --- a/src/test/ui/borrowck/borrowck-uninit-ref-chain.stderr +++ b/src/test/ui/borrowck/borrowck-uninit-ref-chain.stderr @@ -1,44 +1,66 @@ -error[E0381]: borrow of possibly-uninitialized variable: `x` +error[E0381]: binding `**x` isn't initialized --> $DIR/borrowck-uninit-ref-chain.rs:8:14 | +LL | let x: &&Box; + | - variable declared here LL | let _y = &**x; - | ^^^^ use of possibly-uninitialized `**x` + | ^^^^ `**x` borrowed here but it isn't initialized -error[E0381]: borrow of possibly-uninitialized variable: `x` +error[E0381]: binding `**x` isn't initialized --> $DIR/borrowck-uninit-ref-chain.rs:11:14 | +LL | let x: &&S; + | - variable declared here LL | let _y = &**x; - | ^^^^ use of possibly-uninitialized `**x` + | ^^^^ `**x` borrowed here but it isn't initialized -error[E0381]: borrow of possibly-uninitialized variable: `x` +error[E0381]: binding `**x` isn't initialized --> $DIR/borrowck-uninit-ref-chain.rs:14:14 | +LL | let x: &&i32; + | - variable declared here LL | let _y = &**x; - | ^^^^ use of possibly-uninitialized `**x` + | ^^^^ `**x` borrowed here but it isn't initialized -error[E0381]: assign to part of possibly-uninitialized variable: `a` +error[E0381]: binding `a` isn't fully initialized --> $DIR/borrowck-uninit-ref-chain.rs:18:5 | +LL | let mut a: S; + | ----- variable declared here LL | a.x = 0; - | ^^^^^^^ use of possibly-uninitialized `a` + | ^^^^^^^ `a` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` -error[E0381]: assign to part of possibly-uninitialized variable: `a` +error[E0381]: binding `a` isn't fully initialized --> $DIR/borrowck-uninit-ref-chain.rs:22:5 | +LL | let mut a: S<&&i32, &&i32>; + | ----- variable declared here LL | a.x = &&0; - | ^^^^^^^^^ use of possibly-uninitialized `a` + | ^^^^^^^^^ `a` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` -error[E0381]: assign to part of possibly-uninitialized variable: `a` +error[E0381]: binding `a` isn't fully initialized --> $DIR/borrowck-uninit-ref-chain.rs:27:5 | +LL | let mut a: S; + | ----- variable declared here LL | a.x = 0; - | ^^^^^^^ use of possibly-uninitialized `a` + | ^^^^^^^ `a` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` -error[E0381]: assign to part of possibly-uninitialized variable: `a` +error[E0381]: binding `a` isn't fully initialized --> $DIR/borrowck-uninit-ref-chain.rs:31:5 | +LL | let mut a: S<&&i32, &&i32>; + | ----- variable declared here LL | a.x = &&0; - | ^^^^^^^^^ use of possibly-uninitialized `a` + | ^^^^^^^^^ `a` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` error: aborting due to 7 previous errors diff --git a/src/test/ui/borrowck/borrowck-uninit.rs b/src/test/ui/borrowck/borrowck-uninit.rs index 017b955a39535..5d0ebabb00872 100644 --- a/src/test/ui/borrowck/borrowck-uninit.rs +++ b/src/test/ui/borrowck/borrowck-uninit.rs @@ -2,5 +2,5 @@ fn foo(x: isize) { println!("{}", x); } fn main() { let x: isize; - foo(x); //~ ERROR use of possibly-uninitialized variable: `x` + foo(x); //~ ERROR E0381 } diff --git a/src/test/ui/borrowck/borrowck-uninit.stderr b/src/test/ui/borrowck/borrowck-uninit.stderr index effc209e81659..c5ee9cfd29747 100644 --- a/src/test/ui/borrowck/borrowck-uninit.stderr +++ b/src/test/ui/borrowck/borrowck-uninit.stderr @@ -1,8 +1,10 @@ -error[E0381]: use of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't initialized --> $DIR/borrowck-uninit.rs:5:9 | +LL | let x: isize; + | - variable declared here LL | foo(x); - | ^ use of possibly-uninitialized `x` + | ^ `x` used here but it isn't initialized error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-union-uninitialized.rs b/src/test/ui/borrowck/borrowck-union-uninitialized.rs index 3cc71e7cece0e..bbe9f22aac307 100644 --- a/src/test/ui/borrowck/borrowck-union-uninitialized.rs +++ b/src/test/ui/borrowck/borrowck-union-uninitialized.rs @@ -10,8 +10,8 @@ fn main() { unsafe { let mut s: S; let mut u: U; - s.a = 0; //~ ERROR assign to part of possibly-uninitialized variable: `s` - u.a = 0; //~ ERROR assign to part of possibly-uninitialized variable: `u` + s.a = 0; //~ ERROR E0381 + u.a = 0; //~ ERROR E0381 let sa = s.a; let ua = u.a; } diff --git a/src/test/ui/borrowck/borrowck-union-uninitialized.stderr b/src/test/ui/borrowck/borrowck-union-uninitialized.stderr index bd9ec5e579ca9..eee04f790337e 100644 --- a/src/test/ui/borrowck/borrowck-union-uninitialized.stderr +++ b/src/test/ui/borrowck/borrowck-union-uninitialized.stderr @@ -1,14 +1,24 @@ -error[E0381]: assign to part of possibly-uninitialized variable: `s` +error[E0381]: binding `s` isn't fully initialized --> $DIR/borrowck-union-uninitialized.rs:13:9 | +LL | let mut s: S; + | ----- variable declared here +LL | let mut u: U; LL | s.a = 0; - | ^^^^^^^ use of possibly-uninitialized `s` + | ^^^^^^^ `s` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` -error[E0381]: assign to part of possibly-uninitialized variable: `u` +error[E0381]: binding `u` isn't fully initialized --> $DIR/borrowck-union-uninitialized.rs:14:9 | +LL | let mut u: U; + | ----- variable declared here +LL | s.a = 0; LL | u.a = 0; - | ^^^^^^^ use of possibly-uninitialized `u` + | ^^^^^^^ `u` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` error: aborting due to 2 previous errors diff --git a/src/test/ui/borrowck/borrowck-use-in-index-lvalue.stderr b/src/test/ui/borrowck/borrowck-use-in-index-lvalue.stderr index d1b396aba8257..f7975c8ac920f 100644 --- a/src/test/ui/borrowck/borrowck-use-in-index-lvalue.stderr +++ b/src/test/ui/borrowck/borrowck-use-in-index-lvalue.stderr @@ -1,14 +1,18 @@ -error[E0381]: use of possibly-uninitialized variable: `w` +error[E0381]: binding `*w` isn't initialized --> $DIR/borrowck-use-in-index-lvalue.rs:3:5 | +LL | let w: &mut [isize]; + | - variable declared here LL | w[5] = 0; - | ^^^^ use of possibly-uninitialized `*w` + | ^^^^ `*w` used here but it isn't initialized -error[E0381]: use of possibly-uninitialized variable: `w` +error[E0381]: binding `*w` isn't initialized --> $DIR/borrowck-use-in-index-lvalue.rs:6:5 | +LL | let mut w: &mut [isize]; + | ----- variable declared here LL | w[5] = 0; - | ^^^^ use of possibly-uninitialized `*w` + | ^^^^ `*w` used here but it isn't initialized error: aborting due to 2 previous errors diff --git a/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.stderr b/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.stderr index ca5227c98c862..3d024b531ef7c 100644 --- a/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.stderr +++ b/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.stderr @@ -1,8 +1,10 @@ -error[E0381]: borrow of possibly-uninitialized variable: `x` +error[E0381]: binding `*x` isn't initialized --> $DIR/borrowck-use-uninitialized-in-cast-trait.rs:9:13 | +LL | let x: &i32; + | - variable declared here LL | let y = x as *const dyn Foo; - | ^ use of possibly-uninitialized `*x` + | ^ `*x` borrowed here but it isn't initialized error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.stderr b/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.stderr index 24897a0f2dc9c..20a5dcaade7e2 100644 --- a/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.stderr +++ b/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.stderr @@ -1,8 +1,10 @@ -error[E0381]: borrow of possibly-uninitialized variable: `x` +error[E0381]: binding `*x` isn't initialized --> $DIR/borrowck-use-uninitialized-in-cast.rs:7:13 | +LL | let x: &i32; + | - variable declared here LL | let y = x as *const i32; - | ^ use of possibly-uninitialized `*x` + | ^ `*x` borrowed here but it isn't initialized error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-while-break.rs b/src/test/ui/borrowck/borrowck-while-break.rs index 48e4221470221..7100b713031d2 100644 --- a/src/test/ui/borrowck/borrowck-while-break.rs +++ b/src/test/ui/borrowck/borrowck-while-break.rs @@ -4,7 +4,7 @@ fn test(cond: bool) { v = 3; break; } - println!("{}", v); //~ ERROR borrow of possibly-uninitialized variable: `v` + println!("{}", v); //~ ERROR E0381 } fn main() { diff --git a/src/test/ui/borrowck/borrowck-while-break.stderr b/src/test/ui/borrowck/borrowck-while-break.stderr index fc144a066bb27..501f0c6515177 100644 --- a/src/test/ui/borrowck/borrowck-while-break.stderr +++ b/src/test/ui/borrowck/borrowck-while-break.stderr @@ -1,8 +1,13 @@ -error[E0381]: borrow of possibly-uninitialized variable: `v` +error[E0381]: binding `v` isn't initialized in all conditions --> $DIR/borrowck-while-break.rs:7:20 | +LL | let v; + | - variable declared here +LL | while cond { + | ---- `v` is uninitialized if this condition isn't met +... LL | println!("{}", v); - | ^ use of possibly-uninitialized `v` + | ^ `v` borrowed here but it isn't initialized in all conditions | = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/borrowck/borrowck-while-cond.rs b/src/test/ui/borrowck/borrowck-while-cond.rs index b3ec20711c12b..62a9bdd202055 100644 --- a/src/test/ui/borrowck/borrowck-while-cond.rs +++ b/src/test/ui/borrowck/borrowck-while-cond.rs @@ -1,4 +1,4 @@ fn main() { let x: bool; - while x { } //~ ERROR use of possibly-uninitialized variable: `x` + while x { } //~ ERROR E0381 } diff --git a/src/test/ui/borrowck/borrowck-while-cond.stderr b/src/test/ui/borrowck/borrowck-while-cond.stderr index 92937a9c5730e..87d505b5fbbcd 100644 --- a/src/test/ui/borrowck/borrowck-while-cond.stderr +++ b/src/test/ui/borrowck/borrowck-while-cond.stderr @@ -1,8 +1,10 @@ -error[E0381]: use of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't initialized --> $DIR/borrowck-while-cond.rs:3:11 | +LL | let x: bool; + | - variable declared here LL | while x { } - | ^ use of possibly-uninitialized `x` + | ^ `x` used here but it isn't initialized error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-while.rs b/src/test/ui/borrowck/borrowck-while.rs index 6b3220c7d8591..f49a778eb6bbe 100644 --- a/src/test/ui/borrowck/borrowck-while.rs +++ b/src/test/ui/borrowck/borrowck-while.rs @@ -1,7 +1,7 @@ fn f() -> isize { let mut x: isize; while 1 == 1 { x = 10; } - return x; //~ ERROR use of possibly-uninitialized variable: `x` + return x; //~ ERROR E0381 } fn main() { f(); } diff --git a/src/test/ui/borrowck/borrowck-while.stderr b/src/test/ui/borrowck/borrowck-while.stderr index a1f8f64725dcd..36dda8ee13f77 100644 --- a/src/test/ui/borrowck/borrowck-while.stderr +++ b/src/test/ui/borrowck/borrowck-while.stderr @@ -1,8 +1,12 @@ -error[E0381]: use of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't initialized in all conditions --> $DIR/borrowck-while.rs:4:12 | +LL | let mut x: isize; + | ----- variable declared here +LL | while 1 == 1 { x = 10; } + | ------ `x` is uninitialized if this condition isn't met LL | return x; - | ^ use of possibly-uninitialized `x` + | ^ `x` used here but it isn't initialized in all conditions error: aborting due to previous error diff --git a/src/test/ui/borrowck/disallow-possibly-uninitialized.rs b/src/test/ui/borrowck/disallow-possibly-uninitialized.rs index 7043cb3a164e7..17de40d5ba967 100644 --- a/src/test/ui/borrowck/disallow-possibly-uninitialized.rs +++ b/src/test/ui/borrowck/disallow-possibly-uninitialized.rs @@ -4,19 +4,19 @@ fn main() { let mut t: (u64, u64); t.0 = 1; - //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381] + //~^ ERROR E0381 t.1 = 1; let mut t: (u64, u64); t.1 = 1; - //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381] + //~^ ERROR E0381 t.0 = 1; let mut t: (u64, u64); t.0 = 1; - //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381] + //~^ ERROR E0381 let mut t: (u64,); t.0 = 1; - //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381] + //~^ ERROR E0381 } diff --git a/src/test/ui/borrowck/disallow-possibly-uninitialized.stderr b/src/test/ui/borrowck/disallow-possibly-uninitialized.stderr index 8d5b39341c109..f6a0e3dbae053 100644 --- a/src/test/ui/borrowck/disallow-possibly-uninitialized.stderr +++ b/src/test/ui/borrowck/disallow-possibly-uninitialized.stderr @@ -1,26 +1,42 @@ -error[E0381]: assign to part of possibly-uninitialized variable: `t` +error[E0381]: binding `t` isn't fully initialized --> $DIR/disallow-possibly-uninitialized.rs:6:5 | +LL | let mut t: (u64, u64); + | ----- variable declared here LL | t.0 = 1; - | ^^^^^^^ use of possibly-uninitialized `t` + | ^^^^^^^ `t` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` -error[E0381]: assign to part of possibly-uninitialized variable: `t` +error[E0381]: binding `t` isn't fully initialized --> $DIR/disallow-possibly-uninitialized.rs:11:5 | +LL | let mut t: (u64, u64); + | ----- variable declared here LL | t.1 = 1; - | ^^^^^^^ use of possibly-uninitialized `t` + | ^^^^^^^ `t` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` -error[E0381]: assign to part of possibly-uninitialized variable: `t` +error[E0381]: binding `t` isn't fully initialized --> $DIR/disallow-possibly-uninitialized.rs:16:5 | +LL | let mut t: (u64, u64); + | ----- variable declared here LL | t.0 = 1; - | ^^^^^^^ use of possibly-uninitialized `t` + | ^^^^^^^ `t` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` -error[E0381]: assign to part of possibly-uninitialized variable: `t` +error[E0381]: binding `t` isn't fully initialized --> $DIR/disallow-possibly-uninitialized.rs:20:5 | +LL | let mut t: (u64,); + | ----- variable declared here LL | t.0 = 1; - | ^^^^^^^ use of possibly-uninitialized `t` + | ^^^^^^^ `t` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` error: aborting due to 4 previous errors diff --git a/src/test/ui/borrowck/issue-24267-flow-exit.rs b/src/test/ui/borrowck/issue-24267-flow-exit.rs index d6809ee4143b0..c419c5840d9a8 100644 --- a/src/test/ui/borrowck/issue-24267-flow-exit.rs +++ b/src/test/ui/borrowck/issue-24267-flow-exit.rs @@ -9,11 +9,11 @@ pub fn main() { pub fn foo1() { let x: i32; loop { x = break; } - println!("{}", x); //~ ERROR borrow of possibly-uninitialized variable: `x` + println!("{}", x); //~ ERROR E0381 } pub fn foo2() { let x: i32; for _ in 0..10 { x = continue; } - println!("{}", x); //~ ERROR borrow of possibly-uninitialized variable: `x` + println!("{}", x); //~ ERROR E0381 } diff --git a/src/test/ui/borrowck/issue-24267-flow-exit.stderr b/src/test/ui/borrowck/issue-24267-flow-exit.stderr index e29cf7a1a7519..25f7df4f58243 100644 --- a/src/test/ui/borrowck/issue-24267-flow-exit.stderr +++ b/src/test/ui/borrowck/issue-24267-flow-exit.stderr @@ -1,16 +1,22 @@ -error[E0381]: borrow of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't initialized --> $DIR/issue-24267-flow-exit.rs:12:20 | +LL | let x: i32; + | - variable declared here +LL | loop { x = break; } LL | println!("{}", x); - | ^ use of possibly-uninitialized `x` + | ^ `x` borrowed here but it isn't initialized | = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0381]: borrow of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't initialized --> $DIR/issue-24267-flow-exit.rs:18:20 | +LL | let x: i32; + | - variable declared here +LL | for _ in 0..10 { x = continue; } LL | println!("{}", x); - | ^ use of possibly-uninitialized `x` + | ^ `x` borrowed here but it isn't initialized | = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.rs b/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.rs index f031a144443b3..205ea10c90bf0 100644 --- a/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.rs +++ b/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.rs @@ -10,7 +10,7 @@ fn main() { { let mut t: Tuple; t.0 = S(1); - //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381] + //~^ ERROR E0381 t.1 = 2; println!("{:?} {:?}", t.0, t.1); } @@ -18,7 +18,7 @@ fn main() { { let mut u: Tpair; u.0 = S(1); - //~^ ERROR assign to part of possibly-uninitialized variable: `u` [E0381] + //~^ ERROR E0381 u.1 = 2; println!("{:?} {:?}", u.0, u.1); } @@ -26,7 +26,7 @@ fn main() { { let mut v: Spair; v.x = S(1); - //~^ ERROR assign to part of possibly-uninitialized variable: `v` [E0381] + //~^ ERROR E0381 v.y = 2; println!("{:?} {:?}", v.x, v.y); } diff --git a/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.stderr b/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.stderr index 22c6c3964edc1..99c25ad5446a2 100644 --- a/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.stderr +++ b/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.stderr @@ -1,20 +1,32 @@ -error[E0381]: assign to part of possibly-uninitialized variable: `t` +error[E0381]: binding `t` isn't fully initialized --> $DIR/issue-54499-field-mutation-marks-mut-as-used.rs:12:9 | +LL | let mut t: Tuple; + | ----- variable declared here LL | t.0 = S(1); - | ^^^^^^^^^^ use of possibly-uninitialized `t` + | ^^^^^^^^^^ `t` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` -error[E0381]: assign to part of possibly-uninitialized variable: `u` +error[E0381]: binding `u` isn't fully initialized --> $DIR/issue-54499-field-mutation-marks-mut-as-used.rs:20:9 | +LL | let mut u: Tpair; + | ----- variable declared here LL | u.0 = S(1); - | ^^^^^^^^^^ use of possibly-uninitialized `u` + | ^^^^^^^^^^ `u` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` -error[E0381]: assign to part of possibly-uninitialized variable: `v` +error[E0381]: binding `v` isn't fully initialized --> $DIR/issue-54499-field-mutation-marks-mut-as-used.rs:28:9 | +LL | let mut v: Spair; + | ----- variable declared here LL | v.x = S(1); - | ^^^^^^^^^^ use of possibly-uninitialized `v` + | ^^^^^^^^^^ `v` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` error: aborting due to 3 previous errors diff --git a/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.rs b/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.rs index 660d9e85ef54e..50d0c40fdf6f5 100644 --- a/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.rs +++ b/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.rs @@ -10,7 +10,7 @@ fn main() { { let t: Tuple; t.0 = S(1); - //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381] + //~^ ERROR E0381 t.1 = 2; println!("{:?} {:?}", t.0, t.1); } @@ -18,7 +18,7 @@ fn main() { { let u: Tpair; u.0 = S(1); - //~^ ERROR assign to part of possibly-uninitialized variable: `u` [E0381] + //~^ ERROR E0381 u.1 = 2; println!("{:?} {:?}", u.0, u.1); } @@ -26,7 +26,7 @@ fn main() { { let v: Spair; v.x = S(1); - //~^ ERROR assign to part of possibly-uninitialized variable: `v` [E0381] + //~^ ERROR E0381 v.y = 2; println!("{:?} {:?}", v.x, v.y); } diff --git a/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.stderr b/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.stderr index 5f9c978c342f6..1c78524a1b1a8 100644 --- a/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.stderr +++ b/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.stderr @@ -1,20 +1,32 @@ -error[E0381]: assign to part of possibly-uninitialized variable: `t` +error[E0381]: binding `t` isn't fully initialized --> $DIR/issue-54499-field-mutation-of-never-init.rs:12:9 | +LL | let t: Tuple; + | - variable declared here LL | t.0 = S(1); - | ^^^^^^^^^^ use of possibly-uninitialized `t` + | ^^^^^^^^^^ `t` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` -error[E0381]: assign to part of possibly-uninitialized variable: `u` +error[E0381]: binding `u` isn't fully initialized --> $DIR/issue-54499-field-mutation-of-never-init.rs:20:9 | +LL | let u: Tpair; + | - variable declared here LL | u.0 = S(1); - | ^^^^^^^^^^ use of possibly-uninitialized `u` + | ^^^^^^^^^^ `u` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` -error[E0381]: assign to part of possibly-uninitialized variable: `v` +error[E0381]: binding `v` isn't fully initialized --> $DIR/issue-54499-field-mutation-of-never-init.rs:28:9 | +LL | let v: Spair; + | - variable declared here LL | v.x = S(1); - | ^^^^^^^^^^ use of possibly-uninitialized `v` + | ^^^^^^^^^^ `v` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` error: aborting due to 3 previous errors diff --git a/src/test/ui/borrowck/issue-62107-match-arm-scopes.rs b/src/test/ui/borrowck/issue-62107-match-arm-scopes.rs index f8efa8c891eb3..93ce34d2fe535 100644 --- a/src/test/ui/borrowck/issue-62107-match-arm-scopes.rs +++ b/src/test/ui/borrowck/issue-62107-match-arm-scopes.rs @@ -1,7 +1,7 @@ fn main() { let e: i32; match e { - //~^ ERROR use of possibly-uninitialized variable + //~^ ERROR E0381 ref u if true => {} ref v if true => { let tx = 0; diff --git a/src/test/ui/borrowck/issue-62107-match-arm-scopes.stderr b/src/test/ui/borrowck/issue-62107-match-arm-scopes.stderr index 0eca447b55159..f809b7d4c3b0c 100644 --- a/src/test/ui/borrowck/issue-62107-match-arm-scopes.stderr +++ b/src/test/ui/borrowck/issue-62107-match-arm-scopes.stderr @@ -1,8 +1,10 @@ -error[E0381]: use of possibly-uninitialized variable: `e` +error[E0381]: binding `e` isn't initialized --> $DIR/issue-62107-match-arm-scopes.rs:3:11 | +LL | let e: i32; + | - variable declared here LL | match e { - | ^ use of possibly-uninitialized `e` + | ^ `e` used here but it isn't initialized error: aborting due to previous error diff --git a/src/test/ui/borrowck/reassignment_immutable_fields.stderr b/src/test/ui/borrowck/reassignment_immutable_fields.stderr index f09db378a75b4..045f95632d83e 100644 --- a/src/test/ui/borrowck/reassignment_immutable_fields.stderr +++ b/src/test/ui/borrowck/reassignment_immutable_fields.stderr @@ -1,14 +1,22 @@ -error[E0381]: assign to part of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't fully initialized --> $DIR/reassignment_immutable_fields.rs:7:5 | +LL | let x: (u32, u32); + | - variable declared here LL | x.0 = 1; - | ^^^^^^^ use of possibly-uninitialized `x` + | ^^^^^^^ `x` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` -error[E0381]: assign to part of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't fully initialized --> $DIR/reassignment_immutable_fields.rs:15:5 | +LL | let x: (u32, u32); + | - variable declared here LL | x.0 = 1; - | ^^^^^^^ use of possibly-uninitialized `x` + | ^^^^^^^ `x` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` error: aborting due to 2 previous errors diff --git a/src/test/ui/borrowck/reassignment_immutable_fields_overlapping.stderr b/src/test/ui/borrowck/reassignment_immutable_fields_overlapping.stderr index 0eae2c71e4a19..d848679272375 100644 --- a/src/test/ui/borrowck/reassignment_immutable_fields_overlapping.stderr +++ b/src/test/ui/borrowck/reassignment_immutable_fields_overlapping.stderr @@ -1,8 +1,12 @@ -error[E0381]: assign to part of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't fully initialized --> $DIR/reassignment_immutable_fields_overlapping.rs:12:5 | +LL | let x: Foo; + | - variable declared here LL | x.a = 1; - | ^^^^^^^ use of possibly-uninitialized `x` + | ^^^^^^^ `x` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` error[E0594]: cannot assign to `x.b`, as `x` is not declared as mutable --> $DIR/reassignment_immutable_fields_overlapping.rs:13:5 diff --git a/src/test/ui/borrowck/reassignment_immutable_fields_twice.stderr b/src/test/ui/borrowck/reassignment_immutable_fields_twice.stderr index f55e1a27f475e..db69f0b0db704 100644 --- a/src/test/ui/borrowck/reassignment_immutable_fields_twice.stderr +++ b/src/test/ui/borrowck/reassignment_immutable_fields_twice.stderr @@ -7,11 +7,15 @@ LL | x = (22, 44); LL | x.0 = 1; | ^^^^^^^ cannot assign -error[E0381]: assign to part of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't fully initialized --> $DIR/reassignment_immutable_fields_twice.rs:12:5 | +LL | let x: (u32, u32); + | - variable declared here LL | x.0 = 1; - | ^^^^^^^ use of possibly-uninitialized `x` + | ^^^^^^^ `x` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` error: aborting due to 2 previous errors diff --git a/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.rs b/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.rs index 0f288ffa95a87..69cf920de9478 100644 --- a/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.rs +++ b/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.rs @@ -6,14 +6,14 @@ fn test1() { let x: !; let c1 = || match x { }; - //~^ ERROR: use of possibly-uninitialized variable: `x` + //~^ ERROR E0381 } // Should fake read the discriminant and throw an error fn test2() { let x: !; let c2 = || match x { _ => () }; - //~^ ERROR: borrow of possibly-uninitialized variable: `x` + //~^ ERROR E0381 } // Testing single variant patterns @@ -25,7 +25,7 @@ enum SingleVariant { fn test3() { let variant: !; let c = || { - //~^ ERROR: borrow of possibly-uninitialized variable: `variant` + //~^ ERROR E0381 match variant { SingleVariant::Points(_) => {} } @@ -36,8 +36,7 @@ fn test3() { // Should fake read the discriminant and throw an error fn test4() { let variant: !; - let c = || { - //~^ ERROR: borrow of possibly-uninitialized variable: `variant` + let c = || { //~ ERROR E0381 match variant { SingleVariant::Points(a) => { println!("{:?}", a); @@ -52,11 +51,9 @@ fn test5() { let g: !; let a = || { - match g { }; - //~^ ERROR: use of possibly-uninitialized variable: `g` + match g { }; //~ ERROR E0381 let c = || { - match t { }; - //~^ ERROR: use of possibly-uninitialized variable: `t` + match t { }; //~ ERROR E0381 }; c(); @@ -68,7 +65,7 @@ fn test5() { fn test6() { let x: u8; let c1 = || match x { }; - //~^ ERROR: use of possibly-uninitialized variable: `x` + //~^ ERROR E0381 //~| ERROR: non-exhaustive patterns: type `u8` is non-empty } diff --git a/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr b/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr index e55fb7ce4bbe9..c891fff228a27 100644 --- a/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr +++ b/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr @@ -1,5 +1,5 @@ error[E0004]: non-exhaustive patterns: type `u8` is non-empty - --> $DIR/pattern-matching-should-fail.rs:70:23 + --> $DIR/pattern-matching-should-fail.rs:67:23 | LL | let c1 = || match x { }; | ^ @@ -12,55 +12,70 @@ LL + _ => todo!(), LL ~ }; | -error[E0381]: use of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't initialized --> $DIR/pattern-matching-should-fail.rs:8:23 | +LL | let x: !; + | - variable declared here LL | let c1 = || match x { }; - | ^ use of possibly-uninitialized `x` + | ^ `x` used here but it isn't initialized -error[E0381]: borrow of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't initialized --> $DIR/pattern-matching-should-fail.rs:15:14 | +LL | let x: !; + | - variable declared here LL | let c2 = || match x { _ => () }; | ^^ - borrow occurs due to use in closure | | - | use of possibly-uninitialized `x` + | `x` borrowed here but it isn't initialized -error[E0381]: borrow of possibly-uninitialized variable: `variant` +error[E0381]: binding `variant` isn't initialized --> $DIR/pattern-matching-should-fail.rs:27:13 | +LL | let variant: !; + | ------- variable declared here LL | let c = || { - | ^^ use of possibly-uninitialized `variant` + | ^^ `variant` borrowed here but it isn't initialized LL | LL | match variant { | ------- borrow occurs due to use in closure -error[E0381]: borrow of possibly-uninitialized variable: `variant` +error[E0381]: binding `variant` isn't initialized --> $DIR/pattern-matching-should-fail.rs:39:13 | +LL | let variant: !; + | ------- variable declared here LL | let c = || { - | ^^ use of possibly-uninitialized `variant` -LL | + | ^^ `variant` borrowed here but it isn't initialized LL | match variant { | ------- borrow occurs due to use in closure -error[E0381]: use of possibly-uninitialized variable: `g` - --> $DIR/pattern-matching-should-fail.rs:55:15 +error[E0381]: binding `g` isn't initialized + --> $DIR/pattern-matching-should-fail.rs:54:15 | +LL | let g: !; + | - variable declared here +... LL | match g { }; - | ^ use of possibly-uninitialized `g` + | ^ `g` used here but it isn't initialized -error[E0381]: use of possibly-uninitialized variable: `t` - --> $DIR/pattern-matching-should-fail.rs:58:19 +error[E0381]: binding `t` isn't initialized + --> $DIR/pattern-matching-should-fail.rs:56:19 | +LL | let t: !; + | - variable declared here +... LL | match t { }; - | ^ use of possibly-uninitialized `t` + | ^ `t` used here but it isn't initialized -error[E0381]: use of possibly-uninitialized variable: `x` - --> $DIR/pattern-matching-should-fail.rs:70:23 +error[E0381]: binding `x` isn't initialized + --> $DIR/pattern-matching-should-fail.rs:67:23 | +LL | let x: u8; + | - variable declared here LL | let c1 = || match x { }; - | ^ use of possibly-uninitialized `x` + | ^ `x` used here but it isn't initialized error: aborting due to 8 previous errors diff --git a/src/test/ui/const-generics/const-generic-default-wont-borrowck.rs b/src/test/ui/const-generics/const-generic-default-wont-borrowck.rs index bb5a2f1766f1b..e64adacac9fd2 100644 --- a/src/test/ui/const-generics/const-generic-default-wont-borrowck.rs +++ b/src/test/ui/const-generics/const-generic-default-wont-borrowck.rs @@ -1,6 +1,5 @@ struct X; fn main() {} diff --git a/src/test/ui/const-generics/const-generic-default-wont-borrowck.stderr b/src/test/ui/const-generics/const-generic-default-wont-borrowck.stderr index 6c25019b0ceb3..0638a9c61c17e 100644 --- a/src/test/ui/const-generics/const-generic-default-wont-borrowck.stderr +++ b/src/test/ui/const-generics/const-generic-default-wont-borrowck.stderr @@ -1,8 +1,10 @@ -error[E0381]: borrow of possibly-uninitialized variable: `s` +error[E0381]: binding `*s` isn't initialized --> $DIR/const-generic-default-wont-borrowck.rs:2:26 | LL | let s: &'static str; s.len() - | ^^^^^^^ use of possibly-uninitialized `*s` + | - ^^^^^^^ `*s` borrowed here but it isn't initialized + | | + | variable declared here error: aborting due to previous error diff --git a/src/test/ui/consts/issue-78655.rs b/src/test/ui/consts/issue-78655.rs index b85e612992549..82d2d7c21d859 100644 --- a/src/test/ui/consts/issue-78655.rs +++ b/src/test/ui/consts/issue-78655.rs @@ -1,6 +1,6 @@ const FOO: *const u32 = { let x; - &x //~ ERROR borrow of possibly-uninitialized variable: `x` + &x //~ ERROR E0381 }; fn main() { diff --git a/src/test/ui/consts/issue-78655.stderr b/src/test/ui/consts/issue-78655.stderr index 734266a3453b5..1c1a30d405d70 100644 --- a/src/test/ui/consts/issue-78655.stderr +++ b/src/test/ui/consts/issue-78655.stderr @@ -1,8 +1,10 @@ -error[E0381]: borrow of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't initialized --> $DIR/issue-78655.rs:3:5 | +LL | let x; + | - variable declared here LL | &x - | ^^ use of possibly-uninitialized `x` + | ^^ `x` borrowed here but it isn't initialized error: could not evaluate constant pattern --> $DIR/issue-78655.rs:7:9 diff --git a/src/test/ui/drop/repeat-drop-2.rs b/src/test/ui/drop/repeat-drop-2.rs index 2e7855328ecbf..59d5ef202051a 100644 --- a/src/test/ui/drop/repeat-drop-2.rs +++ b/src/test/ui/drop/repeat-drop-2.rs @@ -9,7 +9,7 @@ const _: [String; 0] = [String::new(); 0]; fn must_be_init() { let x: u8; - let _ = [x; 0]; //~ ERROR: use of possibly-uninitialized variable: `x` + let _ = [x; 0]; //~ ERROR E0381 } fn main() {} diff --git a/src/test/ui/drop/repeat-drop-2.stderr b/src/test/ui/drop/repeat-drop-2.stderr index cdc58180c37b4..845b6de798fa7 100644 --- a/src/test/ui/drop/repeat-drop-2.stderr +++ b/src/test/ui/drop/repeat-drop-2.stderr @@ -17,11 +17,13 @@ LL | const _: [String; 0] = [String::new(); 0]; | |constants cannot evaluate destructors | value is dropped here -error[E0381]: use of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't initialized --> $DIR/repeat-drop-2.rs:12:14 | +LL | let x: u8; + | - variable declared here LL | let _ = [x; 0]; - | ^ use of possibly-uninitialized `x` + | ^ `x` used here but it isn't initialized error: aborting due to 3 previous errors diff --git a/src/test/ui/generator/partial-initialization-across-yield.rs b/src/test/ui/generator/partial-initialization-across-yield.rs index 8b75721420351..65d9e6d39ca5a 100644 --- a/src/test/ui/generator/partial-initialization-across-yield.rs +++ b/src/test/ui/generator/partial-initialization-across-yield.rs @@ -9,8 +9,7 @@ struct T(i32, i32); fn test_tuple() { let _ = || { let mut t: (i32, i32); - t.0 = 42; - //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381] + t.0 = 42; //~ ERROR E0381 yield; t.1 = 88; let _ = t; @@ -20,8 +19,7 @@ fn test_tuple() { fn test_tuple_struct() { let _ = || { let mut t: T; - t.0 = 42; - //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381] + t.0 = 42; //~ ERROR E0381 yield; t.1 = 88; let _ = t; @@ -31,8 +29,7 @@ fn test_tuple_struct() { fn test_struct() { let _ = || { let mut t: S; - t.x = 42; - //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381] + t.x = 42; //~ ERROR E0381 yield; t.y = 88; let _ = t; diff --git a/src/test/ui/generator/partial-initialization-across-yield.stderr b/src/test/ui/generator/partial-initialization-across-yield.stderr index 66b86488eaec7..26f45538023bb 100644 --- a/src/test/ui/generator/partial-initialization-across-yield.stderr +++ b/src/test/ui/generator/partial-initialization-across-yield.stderr @@ -1,20 +1,32 @@ -error[E0381]: assign to part of possibly-uninitialized variable: `t` +error[E0381]: binding `t` isn't fully initialized --> $DIR/partial-initialization-across-yield.rs:12:9 | +LL | let mut t: (i32, i32); + | ----- variable declared here LL | t.0 = 42; - | ^^^^^^^^ use of possibly-uninitialized `t` + | ^^^^^^^^ `t` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` -error[E0381]: assign to part of possibly-uninitialized variable: `t` - --> $DIR/partial-initialization-across-yield.rs:23:9 +error[E0381]: binding `t` isn't fully initialized + --> $DIR/partial-initialization-across-yield.rs:22:9 | +LL | let mut t: T; + | ----- variable declared here LL | t.0 = 42; - | ^^^^^^^^ use of possibly-uninitialized `t` + | ^^^^^^^^ `t` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` -error[E0381]: assign to part of possibly-uninitialized variable: `t` - --> $DIR/partial-initialization-across-yield.rs:34:9 +error[E0381]: binding `t` isn't fully initialized + --> $DIR/partial-initialization-across-yield.rs:32:9 | +LL | let mut t: S; + | ----- variable declared here LL | t.x = 42; - | ^^^^^^^^ use of possibly-uninitialized `t` + | ^^^^^^^^ `t` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` error: aborting due to 3 previous errors diff --git a/src/test/ui/loops/loop-proper-liveness.rs b/src/test/ui/loops/loop-proper-liveness.rs index b242ec4296d66..6546e397785ca 100644 --- a/src/test/ui/loops/loop-proper-liveness.rs +++ b/src/test/ui/loops/loop-proper-liveness.rs @@ -6,7 +6,7 @@ fn test1() { 'a: loop { x = loop { break 'a }; } - println!("{:?}", x); //~ ERROR borrow of possibly-uninitialized variable + println!("{:?}", x); //~ ERROR E0381 } // test2 and test3 should not fail. diff --git a/src/test/ui/loops/loop-proper-liveness.stderr b/src/test/ui/loops/loop-proper-liveness.stderr index 20d5c66a3f205..dd6949b19f624 100644 --- a/src/test/ui/loops/loop-proper-liveness.stderr +++ b/src/test/ui/loops/loop-proper-liveness.stderr @@ -1,8 +1,11 @@ -error[E0381]: borrow of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't initialized --> $DIR/loop-proper-liveness.rs:9:22 | +LL | let x: i32; + | - variable declared here +... LL | println!("{:?}", x); - | ^ use of possibly-uninitialized `x` + | ^ `x` borrowed here but it isn't initialized | = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/mir/drop-elaboration-after-borrowck-error.rs b/src/test/ui/mir/drop-elaboration-after-borrowck-error.rs index c44dd51a5ec86..fc7341a563bb2 100644 --- a/src/test/ui/mir/drop-elaboration-after-borrowck-error.rs +++ b/src/test/ui/mir/drop-elaboration-after-borrowck-error.rs @@ -6,7 +6,7 @@ static A: () = { //~^ ERROR destructors cannot be evaluated at compile-time a[0] = String::new(); //~^ ERROR destructors cannot be evaluated at compile-time - //~| ERROR use of possibly-uninitialized variable + //~| ERROR binding `a` isn't initialized }; struct B([T; 1]); diff --git a/src/test/ui/mir/drop-elaboration-after-borrowck-error.stderr b/src/test/ui/mir/drop-elaboration-after-borrowck-error.stderr index 80d5fc7ec672c..ad2e5c9f64373 100644 --- a/src/test/ui/mir/drop-elaboration-after-borrowck-error.stderr +++ b/src/test/ui/mir/drop-elaboration-after-borrowck-error.stderr @@ -16,11 +16,14 @@ LL | let a: [String; 1]; LL | }; | - value is dropped here -error[E0381]: use of possibly-uninitialized variable: `a` +error[E0381]: binding `a` isn't initialized --> $DIR/drop-elaboration-after-borrowck-error.rs:7:5 | +LL | let a: [String; 1]; + | - variable declared here +LL | LL | a[0] = String::new(); - | ^^^^ use of possibly-uninitialized `a` + | ^^^^ `a` used here but it isn't initialized error[E0493]: destructors cannot be evaluated at compile-time --> $DIR/drop-elaboration-after-borrowck-error.rs:18:9 diff --git a/src/test/ui/moves/issue-72649-uninit-in-loop.rs b/src/test/ui/moves/issue-72649-uninit-in-loop.rs index e6bc4e22ec22c..e796466397b1e 100644 --- a/src/test/ui/moves/issue-72649-uninit-in-loop.rs +++ b/src/test/ui/moves/issue-72649-uninit-in-loop.rs @@ -57,17 +57,17 @@ fn moved_loop_2() { fn uninit_1() { loop { - let value: NonCopy; - let _used = value; //~ ERROR use of possibly-uninitialized variable: `value` - //~^ NOTE use of possibly-uninitialized `value` + let value: NonCopy; //~ NOTE variable declared here + let _used = value; //~ ERROR binding `value` isn't initialized + //~^ NOTE `value` used here but it isn't initialized } } fn uninit_2() { - let mut value: NonCopy; + let mut value: NonCopy; //~ NOTE variable declared here loop { - let _used = value; //~ ERROR use of possibly-uninitialized variable: `value` - //~^ NOTE use of possibly-uninitialized `value` + let _used = value; //~ ERROR binding `value` isn't initialized + //~^ NOTE `value` used here but it isn't initialized } } diff --git a/src/test/ui/moves/issue-72649-uninit-in-loop.stderr b/src/test/ui/moves/issue-72649-uninit-in-loop.stderr index 076d3dff14086..52dab5cabf817 100644 --- a/src/test/ui/moves/issue-72649-uninit-in-loop.stderr +++ b/src/test/ui/moves/issue-72649-uninit-in-loop.stderr @@ -40,17 +40,22 @@ LL | let mut value = NonCopy{}; LL | let _used2 = value; | ^^^^^ value moved here, in previous iteration of loop -error[E0381]: use of possibly-uninitialized variable: `value` +error[E0381]: binding `value` isn't initialized --> $DIR/issue-72649-uninit-in-loop.rs:61:21 | +LL | let value: NonCopy; + | ----- variable declared here LL | let _used = value; - | ^^^^^ use of possibly-uninitialized `value` + | ^^^^^ `value` used here but it isn't initialized -error[E0381]: use of possibly-uninitialized variable: `value` +error[E0381]: binding `value` isn't initialized --> $DIR/issue-72649-uninit-in-loop.rs:69:21 | +LL | let mut value: NonCopy; + | --------- variable declared here +LL | loop { LL | let _used = value; - | ^^^^^ use of possibly-uninitialized `value` + | ^^^^^ `value` used here but it isn't initialized error: aborting due to 6 previous errors diff --git a/src/test/ui/moves/move-into-dead-array-1.rs b/src/test/ui/moves/move-into-dead-array-1.rs index 2d0ff58526393..0b8d76def872c 100644 --- a/src/test/ui/moves/move-into-dead-array-1.rs +++ b/src/test/ui/moves/move-into-dead-array-1.rs @@ -11,5 +11,5 @@ fn main() { fn foo(i: usize) { let mut a: [D; 4]; - a[i] = d(); //~ ERROR use of possibly-uninitialized variable: `a` + a[i] = d(); //~ ERROR E0381 } diff --git a/src/test/ui/moves/move-into-dead-array-1.stderr b/src/test/ui/moves/move-into-dead-array-1.stderr index 5f20ccfeddf48..b5478196ef668 100644 --- a/src/test/ui/moves/move-into-dead-array-1.stderr +++ b/src/test/ui/moves/move-into-dead-array-1.stderr @@ -1,8 +1,10 @@ -error[E0381]: use of possibly-uninitialized variable: `a` +error[E0381]: binding `a` isn't initialized --> $DIR/move-into-dead-array-1.rs:14:5 | +LL | let mut a: [D; 4]; + | ----- variable declared here LL | a[i] = d(); - | ^^^^ use of possibly-uninitialized `a` + | ^^^^ `a` used here but it isn't initialized error: aborting due to previous error diff --git a/src/test/ui/moves/move-of-addr-of-mut.rs b/src/test/ui/moves/move-of-addr-of-mut.rs index f2f64e43cd2de..19fd7028692d4 100644 --- a/src/test/ui/moves/move-of-addr-of-mut.rs +++ b/src/test/ui/moves/move-of-addr-of-mut.rs @@ -5,7 +5,7 @@ struct S; fn main() { let mut x: S; - std::ptr::addr_of_mut!(x); //~ borrow of + std::ptr::addr_of_mut!(x); //~ ERROR E0381 let y = x; // Should error here if `addr_of_mut` is ever allowed on uninitialized variables drop(y); diff --git a/src/test/ui/moves/move-of-addr-of-mut.stderr b/src/test/ui/moves/move-of-addr-of-mut.stderr index ce8fb0283165c..a145b6223c187 100644 --- a/src/test/ui/moves/move-of-addr-of-mut.stderr +++ b/src/test/ui/moves/move-of-addr-of-mut.stderr @@ -1,8 +1,10 @@ -error[E0381]: borrow of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't initialized --> $DIR/move-of-addr-of-mut.rs:8:5 | +LL | let mut x: S; + | ----- variable declared here LL | std::ptr::addr_of_mut!(x); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ use of possibly-uninitialized `x` + | ^^^^^^^^^^^^^^^^^^^^^^^^^ `x` borrowed here but it isn't initialized | = note: this error originates in the macro `std::ptr::addr_of_mut` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.rs b/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.rs index ebea6d3d9d1ea..46a156d2af9ee 100644 --- a/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.rs +++ b/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.rs @@ -25,14 +25,12 @@ impl Drop for D { fn cannot_partially_init_adt_with_drop() { let d: D; - d.x = 10; - //~^ ERROR assign of possibly-uninitialized variable: `d` [E0381] + d.x = 10; //~ ERROR E0381 } fn cannot_partially_init_mutable_adt_with_drop() { let mut d: D; - d.x = 10; - //~^ ERROR assign of possibly-uninitialized variable: `d` [E0381] + d.x = 10; //~ ERROR E0381 } fn cannot_partially_reinit_adt_with_drop() { @@ -44,14 +42,12 @@ fn cannot_partially_reinit_adt_with_drop() { fn cannot_partially_init_inner_adt_via_outer_with_drop() { let d: D; - d.s.y = 20; - //~^ ERROR assign to part of possibly-uninitialized variable: `d` [E0381] + d.s.y = 20; //~ ERROR E0381 } fn cannot_partially_init_inner_adt_via_mutable_outer_with_drop() { let mut d: D; - d.s.y = 20; - //~^ ERROR assign to part of possibly-uninitialized variable: `d` [E0381] + d.s.y = 20; //~ ERROR E0381 } fn cannot_partially_reinit_inner_adt_via_outer_with_drop() { diff --git a/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr b/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr index 1b66e034d3785..71029065db1cf 100644 --- a/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr +++ b/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr @@ -1,17 +1,21 @@ -error[E0381]: assign of possibly-uninitialized variable: `d` +error[E0381]: binding `d` isn't initialized --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:28:5 | +LL | let d: D; + | - variable declared here LL | d.x = 10; - | ^^^^^^^^ use of possibly-uninitialized `d` + | ^^^^^^^^ `d` assigned here but it isn't initialized -error[E0381]: assign of possibly-uninitialized variable: `d` - --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:34:5 +error[E0381]: binding `d` isn't initialized + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:33:5 | +LL | let mut d: D; + | ----- variable declared here LL | d.x = 10; - | ^^^^^^^^ use of possibly-uninitialized `d` + | ^^^^^^^^ `d` assigned here but it isn't initialized error[E0382]: assign of moved value: `d` - --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:41:5 + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:39:5 | LL | let mut d = D { x: 0, s: S{ y: 0, z: 0 } }; | ----- move occurs because `d` has type `D`, which does not implement the `Copy` trait @@ -20,20 +24,28 @@ LL | drop(d); LL | d.x = 10; | ^^^^^^^^ value assigned here after move -error[E0381]: assign to part of possibly-uninitialized variable: `d` - --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:47:5 +error[E0381]: binding `d.s` isn't fully initialized + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:45:5 | +LL | let d: D; + | - variable declared here LL | d.s.y = 20; - | ^^^^^^^^^^ use of possibly-uninitialized `d.s` + | ^^^^^^^^^^ `d.s` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` -error[E0381]: assign to part of possibly-uninitialized variable: `d` - --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:53:5 +error[E0381]: binding `d.s` isn't fully initialized + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:50:5 | +LL | let mut d: D; + | ----- variable declared here LL | d.s.y = 20; - | ^^^^^^^^^^ use of possibly-uninitialized `d.s` + | ^^^^^^^^^^ `d.s` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` error[E0382]: assign to part of moved value: `d` - --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:60:5 + --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:56:5 | LL | let mut d = D { x: 0, s: S{ y: 0, z: 0} }; | ----- move occurs because `d` has type `D`, which does not implement the `Copy` trait diff --git a/src/test/ui/nll/issue-21232-partial-init-and-use.rs b/src/test/ui/nll/issue-21232-partial-init-and-use.rs index 1836f766cc7ef..4cd1e406f9440 100644 --- a/src/test/ui/nll/issue-21232-partial-init-and-use.rs +++ b/src/test/ui/nll/issue-21232-partial-init-and-use.rs @@ -94,15 +94,13 @@ macro_rules! use_part { fn test_0000_local_fully_init_and_use_struct() { let s: S; - s.x = 10; s.y = Box::new(20); - //~^ ERROR assign to part of possibly-uninitialized variable: `s` [E0381] + s.x = 10; s.y = Box::new(20); //~ ERROR E0381 use_fully!(struct s); } fn test_0001_local_fully_init_and_use_tuple() { let t: T; - t.0 = 10; t.1 = Box::new(20); - //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381] + t.0 = 10; t.1 = Box::new(20); //~ ERROR E0381 use_fully!(tuple t); } @@ -122,15 +120,13 @@ fn test_0011_local_fully_reinit_and_use_tuple() { fn test_0100_local_partial_init_and_use_struct() { let s: S; - s.x = 10; - //~^ ERROR assign to part of possibly-uninitialized variable: `s` [E0381] + s.x = 10; //~ ERROR E0381 use_part!(struct s); } fn test_0101_local_partial_init_and_use_tuple() { let t: T; - t.0 = 10; - //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381] + t.0 = 10; //~ ERROR E0381 use_part!(tuple t); } @@ -150,15 +146,13 @@ fn test_0111_local_partial_reinit_and_use_tuple() { fn test_0200_local_void_init_and_use_struct() { let s: S; - s.x = 10; - //~^ ERROR assign to part of possibly-uninitialized variable: `s` [E0381] + s.x = 10; //~ ERROR E0381 use_part!(struct s); } fn test_0201_local_void_init_and_use_tuple() { let t: Tvoid; - t.0 = 10; - //~^ ERROR assign to part of possibly-uninitialized variable: `t` [E0381] + t.0 = 10; //~ ERROR E0381 use_part!(tuple t); } @@ -173,15 +167,13 @@ fn test_0201_local_void_init_and_use_tuple() { fn test_1000_field_fully_init_and_use_struct() { let q: Q>; - q.r.f.x = 10; q.r.f.y = Box::new(20); - //~^ ERROR assign to part of possibly-uninitialized variable: `q` [E0381] + q.r.f.x = 10; q.r.f.y = Box::new(20); //~ ERROR E0381 use_fully!(struct q.r.f); } fn test_1001_field_fully_init_and_use_tuple() { let q: Q; - q.r.f.0 = 10; q.r.f.1 = Box::new(20); - //~^ ERROR assign to part of possibly-uninitialized variable: `q` [E0381] + q.r.f.0 = 10; q.r.f.1 = Box::new(20); //~ ERROR E0381 use_fully!(tuple q.r.f); } @@ -201,15 +193,13 @@ fn test_1011_field_fully_reinit_and_use_tuple() { fn test_1100_field_partial_init_and_use_struct() { let q: Q>; - q.r.f.x = 10; - //~^ ERROR assign to part of possibly-uninitialized variable: `q` [E0381] + q.r.f.x = 10; //~ ERROR E0381 use_part!(struct q.r.f); } fn test_1101_field_partial_init_and_use_tuple() { let q: Q; - q.r.f.0 = 10; - //~^ ERROR assign to part of possibly-uninitialized variable: `q` [E0381] + q.r.f.0 = 10; //~ ERROR E0381 use_part!(tuple q.r.f); } @@ -229,15 +219,13 @@ fn test_1111_field_partial_reinit_and_use_tuple() { fn test_1200_field_void_init_and_use_struct() { let mut q: Q>; - q.r.f.x = 10; - //~^ ERROR assign to part of possibly-uninitialized variable: `q` [E0381] + q.r.f.x = 10; //~ ERROR E0381 use_part!(struct q.r.f); } fn test_1201_field_void_init_and_use_tuple() { let mut q: Q; - q.r.f.0 = 10; - //~^ ERROR assign to part of possibly-uninitialized variable: `q` [E0381] + q.r.f.0 = 10; //~ ERROR E0381 use_part!(tuple q.r.f); } diff --git a/src/test/ui/nll/issue-21232-partial-init-and-use.stderr b/src/test/ui/nll/issue-21232-partial-init-and-use.stderr index 77fa484c21d7e..df60868d840c0 100644 --- a/src/test/ui/nll/issue-21232-partial-init-and-use.stderr +++ b/src/test/ui/nll/issue-21232-partial-init-and-use.stderr @@ -1,17 +1,25 @@ -error[E0381]: assign to part of possibly-uninitialized variable: `s` +error[E0381]: binding `s` isn't fully initialized --> $DIR/issue-21232-partial-init-and-use.rs:97:5 | +LL | let s: S; + | - variable declared here LL | s.x = 10; s.y = Box::new(20); - | ^^^^^^^^ use of possibly-uninitialized `s` + | ^^^^^^^^ `s` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` -error[E0381]: assign to part of possibly-uninitialized variable: `t` - --> $DIR/issue-21232-partial-init-and-use.rs:104:5 +error[E0381]: binding `t` isn't fully initialized + --> $DIR/issue-21232-partial-init-and-use.rs:103:5 | +LL | let t: T; + | - variable declared here LL | t.0 = 10; t.1 = Box::new(20); - | ^^^^^^^^ use of possibly-uninitialized `t` + | ^^^^^^^^ `t` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` error[E0382]: assign to part of moved value: `s` - --> $DIR/issue-21232-partial-init-and-use.rs:111:5 + --> $DIR/issue-21232-partial-init-and-use.rs:109:5 | LL | let mut s: S = S::new(); drop(s); | ----- - value moved here @@ -21,7 +29,7 @@ LL | s.x = 10; s.y = Box::new(20); | ^^^^^^^^ value partially assigned here after move error[E0382]: assign to part of moved value: `t` - --> $DIR/issue-21232-partial-init-and-use.rs:118:5 + --> $DIR/issue-21232-partial-init-and-use.rs:116:5 | LL | let mut t: T = (0, Box::new(0)); drop(t); | ----- - value moved here @@ -30,20 +38,28 @@ LL | let mut t: T = (0, Box::new(0)); drop(t); LL | t.0 = 10; t.1 = Box::new(20); | ^^^^^^^^ value partially assigned here after move -error[E0381]: assign to part of possibly-uninitialized variable: `s` - --> $DIR/issue-21232-partial-init-and-use.rs:125:5 +error[E0381]: binding `s` isn't fully initialized + --> $DIR/issue-21232-partial-init-and-use.rs:123:5 | +LL | let s: S; + | - variable declared here LL | s.x = 10; - | ^^^^^^^^ use of possibly-uninitialized `s` + | ^^^^^^^^ `s` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` -error[E0381]: assign to part of possibly-uninitialized variable: `t` - --> $DIR/issue-21232-partial-init-and-use.rs:132:5 +error[E0381]: binding `t` isn't fully initialized + --> $DIR/issue-21232-partial-init-and-use.rs:129:5 | +LL | let t: T; + | - variable declared here LL | t.0 = 10; - | ^^^^^^^^ use of possibly-uninitialized `t` + | ^^^^^^^^ `t` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` error[E0382]: assign to part of moved value: `s` - --> $DIR/issue-21232-partial-init-and-use.rs:139:5 + --> $DIR/issue-21232-partial-init-and-use.rs:135:5 | LL | let mut s: S = S::new(); drop(s); | ----- - value moved here @@ -53,7 +69,7 @@ LL | s.x = 10; | ^^^^^^^^ value partially assigned here after move error[E0382]: assign to part of moved value: `t` - --> $DIR/issue-21232-partial-init-and-use.rs:146:5 + --> $DIR/issue-21232-partial-init-and-use.rs:142:5 | LL | let mut t: T = (0, Box::new(0)); drop(t); | ----- - value moved here @@ -62,32 +78,48 @@ LL | let mut t: T = (0, Box::new(0)); drop(t); LL | t.0 = 10; | ^^^^^^^^ value partially assigned here after move -error[E0381]: assign to part of possibly-uninitialized variable: `s` - --> $DIR/issue-21232-partial-init-and-use.rs:153:5 +error[E0381]: binding `s` isn't fully initialized + --> $DIR/issue-21232-partial-init-and-use.rs:149:5 | +LL | let s: S; + | - variable declared here LL | s.x = 10; - | ^^^^^^^^ use of possibly-uninitialized `s` + | ^^^^^^^^ `s` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` -error[E0381]: assign to part of possibly-uninitialized variable: `t` - --> $DIR/issue-21232-partial-init-and-use.rs:160:5 +error[E0381]: binding `t` isn't fully initialized + --> $DIR/issue-21232-partial-init-and-use.rs:155:5 | +LL | let t: Tvoid; + | - variable declared here LL | t.0 = 10; - | ^^^^^^^^ use of possibly-uninitialized `t` + | ^^^^^^^^ `t` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` -error[E0381]: assign to part of possibly-uninitialized variable: `q` - --> $DIR/issue-21232-partial-init-and-use.rs:176:5 +error[E0381]: binding `q.r.f` isn't fully initialized + --> $DIR/issue-21232-partial-init-and-use.rs:170:5 | +LL | let q: Q>; + | - variable declared here LL | q.r.f.x = 10; q.r.f.y = Box::new(20); - | ^^^^^^^^^^^^ use of possibly-uninitialized `q.r.f` + | ^^^^^^^^^^^^ `q.r.f` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` -error[E0381]: assign to part of possibly-uninitialized variable: `q` - --> $DIR/issue-21232-partial-init-and-use.rs:183:5 +error[E0381]: binding `q.r.f` isn't fully initialized + --> $DIR/issue-21232-partial-init-and-use.rs:176:5 | +LL | let q: Q; + | - variable declared here LL | q.r.f.0 = 10; q.r.f.1 = Box::new(20); - | ^^^^^^^^^^^^ use of possibly-uninitialized `q.r.f` + | ^^^^^^^^^^^^ `q.r.f` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` error[E0382]: assign to part of moved value: `q.r` - --> $DIR/issue-21232-partial-init-and-use.rs:190:5 + --> $DIR/issue-21232-partial-init-and-use.rs:182:5 | LL | let mut q: Q> = Q::new(S::new()); drop(q.r); | --- value moved here @@ -97,7 +129,7 @@ LL | q.r.f.x = 10; q.r.f.y = Box::new(20); = note: move occurs because `q.r` has type `R>>`, which does not implement the `Copy` trait error[E0382]: assign to part of moved value: `q.r` - --> $DIR/issue-21232-partial-init-and-use.rs:197:5 + --> $DIR/issue-21232-partial-init-and-use.rs:189:5 | LL | let mut q: Q = Q::new((0, Box::new(0))); drop(q.r); | --- value moved here @@ -106,20 +138,28 @@ LL | q.r.f.0 = 10; q.r.f.1 = Box::new(20); | = note: move occurs because `q.r` has type `R<(u32, Box)>`, which does not implement the `Copy` trait -error[E0381]: assign to part of possibly-uninitialized variable: `q` - --> $DIR/issue-21232-partial-init-and-use.rs:204:5 +error[E0381]: binding `q.r.f` isn't fully initialized + --> $DIR/issue-21232-partial-init-and-use.rs:196:5 | +LL | let q: Q>; + | - variable declared here LL | q.r.f.x = 10; - | ^^^^^^^^^^^^ use of possibly-uninitialized `q.r.f` + | ^^^^^^^^^^^^ `q.r.f` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` -error[E0381]: assign to part of possibly-uninitialized variable: `q` - --> $DIR/issue-21232-partial-init-and-use.rs:211:5 +error[E0381]: binding `q.r.f` isn't fully initialized + --> $DIR/issue-21232-partial-init-and-use.rs:202:5 | +LL | let q: Q; + | - variable declared here LL | q.r.f.0 = 10; - | ^^^^^^^^^^^^ use of possibly-uninitialized `q.r.f` + | ^^^^^^^^^^^^ `q.r.f` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` error[E0382]: assign to part of moved value: `q.r` - --> $DIR/issue-21232-partial-init-and-use.rs:218:5 + --> $DIR/issue-21232-partial-init-and-use.rs:208:5 | LL | let mut q: Q> = Q::new(S::new()); drop(q.r); | --- value moved here @@ -129,7 +169,7 @@ LL | q.r.f.x = 10; = note: move occurs because `q.r` has type `R>>`, which does not implement the `Copy` trait error[E0382]: assign to part of moved value: `q.r` - --> $DIR/issue-21232-partial-init-and-use.rs:225:5 + --> $DIR/issue-21232-partial-init-and-use.rs:215:5 | LL | let mut q: Q = Q::new((0, Box::new(0))); drop(q.r); | --- value moved here @@ -138,20 +178,28 @@ LL | q.r.f.0 = 10; | = note: move occurs because `q.r` has type `R<(u32, Box)>`, which does not implement the `Copy` trait -error[E0381]: assign to part of possibly-uninitialized variable: `q` - --> $DIR/issue-21232-partial-init-and-use.rs:232:5 +error[E0381]: binding `q.r.f` isn't fully initialized + --> $DIR/issue-21232-partial-init-and-use.rs:222:5 | +LL | let mut q: Q>; + | ----- variable declared here LL | q.r.f.x = 10; - | ^^^^^^^^^^^^ use of possibly-uninitialized `q.r.f` + | ^^^^^^^^^^^^ `q.r.f` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` -error[E0381]: assign to part of possibly-uninitialized variable: `q` - --> $DIR/issue-21232-partial-init-and-use.rs:239:5 +error[E0381]: binding `q.r.f` isn't fully initialized + --> $DIR/issue-21232-partial-init-and-use.rs:228:5 | +LL | let mut q: Q; + | ----- variable declared here LL | q.r.f.0 = 10; - | ^^^^^^^^^^^^ use of possibly-uninitialized `q.r.f` + | ^^^^^^^^^^^^ `q.r.f` partially assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` error[E0382]: assign to part of moved value: `c` - --> $DIR/issue-21232-partial-init-and-use.rs:257:13 + --> $DIR/issue-21232-partial-init-and-use.rs:245:13 | LL | let mut c = (1, "".to_owned()); | ----- move occurs because `c` has type `(i32, String)`, which does not implement the `Copy` trait @@ -162,7 +210,7 @@ LL | c.0 = 2; | ^^^^^^^ value partially assigned here after move error[E0382]: assign to part of moved value: `c` - --> $DIR/issue-21232-partial-init-and-use.rs:267:13 + --> $DIR/issue-21232-partial-init-and-use.rs:255:13 | LL | let mut c = (1, (1, "".to_owned())); | ----- move occurs because `c` has type `(i32, (i32, String))`, which does not implement the `Copy` trait @@ -173,7 +221,7 @@ LL | (c.1).0 = 2; | ^^^^^^^^^^^ value partially assigned here after move error[E0382]: assign to part of moved value: `c.1` - --> $DIR/issue-21232-partial-init-and-use.rs:275:13 + --> $DIR/issue-21232-partial-init-and-use.rs:263:13 | LL | c2 => { | -- value moved here diff --git a/src/test/ui/nll/match-cfg-fake-edges.rs b/src/test/ui/nll/match-cfg-fake-edges.rs index 2e6d675fb641e..252f7f8ba07cf 100644 --- a/src/test/ui/nll/match-cfg-fake-edges.rs +++ b/src/test/ui/nll/match-cfg-fake-edges.rs @@ -18,7 +18,7 @@ fn guard_may_be_skipped(y: i32) { match y { _ if { x = 2; true } => 1, _ if { - x; //~ ERROR use of possibly-uninitialized variable: `x` + x; //~ ERROR E0381 false } => 2, _ => 3, diff --git a/src/test/ui/nll/match-cfg-fake-edges.stderr b/src/test/ui/nll/match-cfg-fake-edges.stderr index 4b3817929fd84..43950433e621d 100644 --- a/src/test/ui/nll/match-cfg-fake-edges.stderr +++ b/src/test/ui/nll/match-cfg-fake-edges.stderr @@ -1,8 +1,13 @@ -error[E0381]: use of possibly-uninitialized variable: `x` +error[E0381]: binding `x` isn't initialized in all conditions --> $DIR/match-cfg-fake-edges.rs:21:13 | +LL | let x; + | - variable declared here +... +LL | _ if { + | - `x` is uninitialized if this pattern is matched LL | x; - | ^ use of possibly-uninitialized `x` + | ^ `x` used here but it isn't initialized in all conditions error[E0382]: use of moved value: `x` --> $DIR/match-cfg-fake-edges.rs:35:13 diff --git a/src/test/ui/nll/match-on-borrowed.stderr b/src/test/ui/nll/match-on-borrowed.stderr index 2121b59b02da3..0480aaa99c274 100644 --- a/src/test/ui/nll/match-on-borrowed.stderr +++ b/src/test/ui/nll/match-on-borrowed.stderr @@ -33,11 +33,13 @@ LL | match t { LL | x; | - borrow later used here -error[E0381]: use of possibly-uninitialized variable: `n` +error[E0381]: binding `n` isn't initialized --> $DIR/match-on-borrowed.rs:93:11 | +LL | let n: Never; + | - variable declared here LL | match n {} - | ^ use of possibly-uninitialized `n` + | ^ `n` used here but it isn't initialized error: aborting due to 4 previous errors diff --git a/src/test/ui/rfc-2497-if-let-chains/chains-without-let.rs b/src/test/ui/rfc-2497-if-let-chains/chains-without-let.rs index a7e108d72d1ff..e0dded1521760 100644 --- a/src/test/ui/rfc-2497-if-let-chains/chains-without-let.rs +++ b/src/test/ui/rfc-2497-if-let-chains/chains-without-let.rs @@ -1,19 +1,19 @@ fn and_chain() { let z; if true && { z = 3; true} && z == 3 {} - //~^ ERROR use of possibly-uninitialized + //~^ ERROR E0381 } fn and_chain_2() { let z; true && { z = 3; true} && z == 3; - //~^ ERROR use of possibly-uninitialized + //~^ ERROR E0381 } fn or_chain() { let z; if false || { z = 3; false} || z == 3 {} - //~^ ERROR use of possibly-uninitialized + //~^ ERROR E0381 } fn main() { diff --git a/src/test/ui/rfc-2497-if-let-chains/chains-without-let.stderr b/src/test/ui/rfc-2497-if-let-chains/chains-without-let.stderr index 3c47040cc8c24..1fb643b98aebe 100644 --- a/src/test/ui/rfc-2497-if-let-chains/chains-without-let.stderr +++ b/src/test/ui/rfc-2497-if-let-chains/chains-without-let.stderr @@ -1,20 +1,32 @@ -error[E0381]: use of possibly-uninitialized variable: `z` +error[E0381]: binding `z` isn't initialized in all conditions --> $DIR/chains-without-let.rs:3:34 | +LL | let z; + | - variable declared here LL | if true && { z = 3; true} && z == 3 {} - | ^ use of possibly-uninitialized `z` + | ----- ^ `z` used here but it isn't initialized in all conditions + | | + | binding initialized here in some conditions -error[E0381]: use of possibly-uninitialized variable: `z` +error[E0381]: binding `z` isn't initialized in all conditions --> $DIR/chains-without-let.rs:9:31 | +LL | let z; + | - variable declared here LL | true && { z = 3; true} && z == 3; - | ^ use of possibly-uninitialized `z` + | ----- ^ `z` used here but it isn't initialized in all conditions + | | + | binding initialized here in some conditions -error[E0381]: use of possibly-uninitialized variable: `z` +error[E0381]: binding `z` isn't initialized in all conditions --> $DIR/chains-without-let.rs:15:36 | +LL | let z; + | - variable declared here LL | if false || { z = 3; false} || z == 3 {} - | ^ use of possibly-uninitialized `z` + | ----- ^ `z` used here but it isn't initialized in all conditions + | | + | binding initialized here in some conditions error: aborting due to 3 previous errors diff --git a/src/test/ui/try-block/try-block-opt-init.rs b/src/test/ui/try-block/try-block-opt-init.rs index ef10b47fd1305..f4f45abcc75b1 100644 --- a/src/test/ui/try-block/try-block-opt-init.rs +++ b/src/test/ui/try-block/try-block-opt-init.rs @@ -12,5 +12,5 @@ pub fn main() { Ok::<(), ()>(())?; use_val(cfg_res); }; - assert_eq!(cfg_res, 5); //~ ERROR borrow of possibly-uninitialized variable: `cfg_res` + assert_eq!(cfg_res, 5); //~ ERROR E0381 } diff --git a/src/test/ui/try-block/try-block-opt-init.stderr b/src/test/ui/try-block/try-block-opt-init.stderr index bd145fd64e765..17349f9c9f35a 100644 --- a/src/test/ui/try-block/try-block-opt-init.stderr +++ b/src/test/ui/try-block/try-block-opt-init.stderr @@ -1,8 +1,14 @@ -error[E0381]: borrow of possibly-uninitialized variable: `cfg_res` +error[E0381]: binding `cfg_res` isn't initialized in all conditions --> $DIR/try-block-opt-init.rs:15:5 | +LL | let cfg_res; + | ------- variable declared here +... +LL | cfg_res = 5; + | ----------- binding initialized here in some conditions +... LL | assert_eq!(cfg_res, 5); - | ^^^^^^^^^^^^^^^^^^^^^^ use of possibly-uninitialized `cfg_res` + | ^^^^^^^^^^^^^^^^^^^^^^ `cfg_res` borrowed here but it isn't initialized in all conditions | = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/uninhabited/privately-uninhabited-mir-call.rs b/src/test/ui/uninhabited/privately-uninhabited-mir-call.rs index b37ec2696de2f..2764bb563d307 100644 --- a/src/test/ui/uninhabited/privately-uninhabited-mir-call.rs +++ b/src/test/ui/uninhabited/privately-uninhabited-mir-call.rs @@ -25,5 +25,5 @@ fn main() { widget::Widget::new(); // Error. Widget type is not known to be uninhabited here, // so the following code is considered reachable. - *y = 2; //~ ERROR use of possibly-uninitialized variable + *y = 2; //~ ERROR E0381 } diff --git a/src/test/ui/uninhabited/privately-uninhabited-mir-call.stderr b/src/test/ui/uninhabited/privately-uninhabited-mir-call.stderr index fb1953411685e..61e6295fa3f2c 100644 --- a/src/test/ui/uninhabited/privately-uninhabited-mir-call.stderr +++ b/src/test/ui/uninhabited/privately-uninhabited-mir-call.stderr @@ -1,8 +1,11 @@ -error[E0381]: use of possibly-uninitialized variable: `y` +error[E0381]: binding `y` isn't initialized --> $DIR/privately-uninhabited-mir-call.rs:28:5 | +LL | let y: &mut u32; + | - variable declared here +... LL | *y = 2; - | ^^^^^^ use of possibly-uninitialized `y` + | ^^^^^^ `y` used here but it isn't initialized error: aborting due to previous error From a944456d3a787524a2dd0e835f86f278fb2c337d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Tue, 21 Jun 2022 15:54:17 -0700 Subject: [PATCH 06/20] Tweak wording and spans --- .../src/diagnostics/conflict_errors.rs | 82 +++++++++++++------ compiler/rustc_borrowck/src/lib.rs | 10 +++ src/test/ui/asm/x86_64/type-check-5.stderr | 8 +- .../no-non-guaranteed-initialization.stderr | 6 +- ...partial-initialization-across-await.stderr | 18 ++-- .../ui/borrowck/assign_mutable_fields.stderr | 12 +-- src/test/ui/borrowck/borrowck-and-init.stderr | 6 +- .../ui/borrowck/borrowck-block-unint.stderr | 6 +- .../borrowck/borrowck-break-uninit-2.stderr | 6 +- .../ui/borrowck/borrowck-break-uninit.stderr | 6 +- .../borrowck-field-sensitivity.stderr | 18 ++-- .../ui/borrowck/borrowck-if-no-else.stderr | 6 +- .../ui/borrowck/borrowck-if-with-else.stderr | 4 +- .../borrowck-init-in-called-fn-expr.stderr | 4 +- .../borrowck/borrowck-init-in-fn-expr.stderr | 4 +- .../ui/borrowck/borrowck-init-in-fru.stderr | 4 +- .../ui/borrowck/borrowck-init-op-equal.stderr | 4 +- .../borrowck/borrowck-init-plus-equal.stderr | 4 +- src/test/ui/borrowck/borrowck-or-init.stderr | 6 +- .../borrowck/borrowck-partial-reinit-4.stderr | 4 +- src/test/ui/borrowck/borrowck-return.stderr | 4 +- .../ui/borrowck/borrowck-storage-dead.stderr | 4 +- .../borrowck-uninit-after-item.stderr | 4 +- .../borrowck-uninit-field-access.stderr | 4 +- .../borrowck-uninit-in-assignop.stderr | 40 ++++----- .../borrowck/borrowck-uninit-ref-chain.stderr | 42 +++++----- src/test/ui/borrowck/borrowck-uninit.stderr | 4 +- .../borrowck-union-uninitialized.stderr | 12 +-- .../borrowck-use-in-index-lvalue.stderr | 8 +- ...wck-use-uninitialized-in-cast-trait.stderr | 6 +- .../borrowck-use-uninitialized-in-cast.stderr | 6 +- .../ui/borrowck/borrowck-while-break.stderr | 8 +- .../ui/borrowck/borrowck-while-cond.stderr | 4 +- src/test/ui/borrowck/borrowck-while.stderr | 6 +- .../disallow-possibly-uninitialized.stderr | 24 +++--- .../ui/borrowck/issue-24267-flow-exit.stderr | 12 +-- ...99-field-mutation-marks-mut-as-used.stderr | 18 ++-- ...-54499-field-mutation-of-never-init.stderr | 18 ++-- .../issue-62107-match-arm-scopes.stderr | 4 +- .../reassignment_immutable_fields.stderr | 12 +-- ...gnment_immutable_fields_overlapping.stderr | 6 +- ...reassignment_immutable_fields_twice.stderr | 6 +- .../match/pattern-matching-should-fail.stderr | 34 ++++---- ...const-generic-default-wont-borrowck.stderr | 6 +- src/test/ui/consts/issue-78655.stderr | 6 +- src/test/ui/drop/repeat-drop-2.stderr | 4 +- ...partial-initialization-across-yield.stderr | 18 ++-- src/test/ui/loops/loop-proper-liveness.stderr | 6 +- ...op-elaboration-after-borrowck-error.stderr | 4 +- .../ui/moves/issue-72649-uninit-in-loop.rs | 4 +- .../moves/issue-72649-uninit-in-loop.stderr | 8 +- .../ui/moves/move-into-dead-array-1.stderr | 4 +- src/test/ui/moves/move-of-addr-of-mut.stderr | 6 +- ...1232-partial-init-and-erroneous-use.stderr | 20 ++--- .../issue-21232-partial-init-and-use.stderr | 72 ++++++++-------- src/test/ui/nll/match-cfg-fake-edges.stderr | 6 +- src/test/ui/nll/match-on-borrowed.stderr | 4 +- .../chains-without-let.stderr | 12 +-- .../ui/try-block/try-block-opt-init.stderr | 6 +- .../privately-uninhabited-mir-call.stderr | 4 +- 60 files changed, 368 insertions(+), 326 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 1f7cb972fcec8..daeaac9415def 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -21,6 +21,7 @@ use rustc_middle::ty::{ self, subst::Subst, suggest_constraining_type_params, EarlyBinder, PredicateKind, Ty, }; use rustc_mir_dataflow::move_paths::{InitKind, MoveOutIndex, MovePathIndex}; +use rustc_span::hygiene::DesugaringKind; use rustc_span::symbol::sym; use rustc_span::{BytePos, Span}; use rustc_trait_selection::infer::InferCtxtExt; @@ -331,7 +332,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { spans.push(span); } - let (item_msg, name, desc) = + let (binding, name, desc) = match self.describe_place_with_options(used_place, IncludingDowncast(true)) { Some(name) => (format!("`{name}`"), format!("`{name}`"), format!("`{name}` ")), None => ("value".to_string(), "the variable".to_string(), String::new()), @@ -351,7 +352,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } else { "initialized in all conditions" }; - let mut err = struct_span_err!(self, span, E0381, "binding {desc}isn't {initialized}"); + let used = desired_action.as_general_verb_in_past_tense(); + let mut err = + struct_span_err!(self, span, E0381, "{used} binding {desc}isn't {initialized}"); use_spans.var_span_label_path_only( &mut err, format!("{} occurs due to use{}", desired_action.as_noun(), use_spans.describe()), @@ -359,12 +362,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { if let InitializationRequiringAction::PartialAssignment = desired_action { err.help( - "partial initialization isn't supported, fully initialize the binding with \ - a default value and mutate, or use `std::mem::MaybeUninit`", + "partial initialization isn't supported, fully initialize the binding with a \ + default value and mutate it, or use `std::mem::MaybeUninit`", ); } - let verb = desired_action.as_verb_in_past_tense(); - err.span_label(span, format!("{item_msg} {verb} here but it isn't {initialized}",)); + err.span_label(span, format!("{binding} {used} here but it isn't {initialized}")); // We use the statements were the binding was initialized, and inspect the HIR to look // for the branching codepaths that aren't covered, to point at them. @@ -400,7 +402,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { err.span_label(sp, &label); } } - err.span_label(decl_span, "variable declared here"); + err.span_label(decl_span, "binding declared here but left uninitialized"); err } @@ -2559,10 +2561,10 @@ impl<'b, 'v> Visitor<'v> for ConditionVisitor<'b> { v.visit_expr(body); if v.1 { self.errors.push(( - cond.span, + ex.span.to(cond.span), format!( - "this `if` expression might be missing an `else` arm where {} is \ - initialized", + "this `if` expression might be missing an `else` arm that initializes \ + {}", self.name, ), )); @@ -2578,10 +2580,24 @@ impl<'b, 'v> Visitor<'v> for ConditionVisitor<'b> { match (a.1, b.1) { (true, true) | (false, false) => {} (true, false) => { - self.errors.push(( - cond.span, - format!("{} is uninitialized if this condition isn't met", self.name,), - )); + if other.span.is_desugaring(DesugaringKind::WhileLoop) { + self.errors.push(( + cond.span, + format!( + "{} is uninitialized if this condition isn't met and the \ + `while` loop runs 0 times", + self.name + ), + )); + } else { + self.errors.push(( + body.span.shrink_to_hi().until(other.span), + format!( + "{} is uninitialized if this `else` arm is executed", + self.name + ), + )); + } } (false, true) => { self.errors.push(( @@ -2591,7 +2607,7 @@ impl<'b, 'v> Visitor<'v> for ConditionVisitor<'b> { } } } - hir::ExprKind::Match(_, arms, _) => { + hir::ExprKind::Match(e, arms, loop_desugar) => { // If the binding is initialized in one of the match arms, then the other match // arms might be missing an initialization. let results: Vec = arms @@ -2605,13 +2621,32 @@ impl<'b, 'v> Visitor<'v> for ConditionVisitor<'b> { if results.iter().any(|x| *x) && !results.iter().all(|x| *x) { for (arm, seen) in arms.iter().zip(results) { if !seen { - self.errors.push(( - arm.pat.span, - format!( - "{} is uninitialized if this pattern is matched", - self.name - ), - )); + if loop_desugar == hir::MatchSource::ForLoopDesugar { + self.errors.push(( + e.span, + format!( + "{} is uninitialized if the `for` loop runs 0 times", + self.name + ), + )); + } else if let Some(guard) = &arm.guard { + self.errors.push(( + arm.pat.span.to(guard.body().span), + format!( + "{} is uninitialized if this pattern and condition are \ + matched", + self.name + ), + )); + } else { + self.errors.push(( + arm.pat.span, + format!( + "{} is uninitialized if this pattern is matched", + self.name + ), + )); + } } } } @@ -2619,8 +2654,7 @@ impl<'b, 'v> Visitor<'v> for ConditionVisitor<'b> { // FIXME: should we also account for binops, particularly `&&` and `||`? `try` should // also be accounted for. For now it is fine, as if we don't find *any* relevant // branching code paths, we point at the places where the binding *is* initialized for - // *some* context. We should also specialize the output for `while` and `for` loops, - // but for now we can rely on their desugaring to provide appropriate output. + // *some* context. _ => {} } walk_expr(self, ex); diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs index 8ef2974c37232..3e31dc199a084 100644 --- a/compiler/rustc_borrowck/src/lib.rs +++ b/compiler/rustc_borrowck/src/lib.rs @@ -905,6 +905,16 @@ impl InitializationRequiringAction { InitializationRequiringAction::PartialAssignment => "partially assigned", } } + + fn as_general_verb_in_past_tense(self) -> &'static str { + match self { + InitializationRequiringAction::Borrow + | InitializationRequiringAction::MatchOn + | InitializationRequiringAction::Use => "used", + InitializationRequiringAction::Assignment => "assigned", + InitializationRequiringAction::PartialAssignment => "partially assigned", + } + } } impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { diff --git a/src/test/ui/asm/x86_64/type-check-5.stderr b/src/test/ui/asm/x86_64/type-check-5.stderr index 26aac4ed2c1e0..e9c93fea561a8 100644 --- a/src/test/ui/asm/x86_64/type-check-5.stderr +++ b/src/test/ui/asm/x86_64/type-check-5.stderr @@ -1,16 +1,16 @@ -error[E0381]: binding `x` isn't initialized +error[E0381]: used binding `x` isn't initialized --> $DIR/type-check-5.rs:15:28 | LL | let x: u64; - | - variable declared here + | - binding declared here but left uninitialized LL | asm!("{}", in(reg) x); | ^ `x` used here but it isn't initialized -error[E0381]: binding `y` isn't initialized +error[E0381]: used binding `y` isn't initialized --> $DIR/type-check-5.rs:18:9 | LL | let mut y: u64; - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | asm!("{}", inout(reg) y); | ^^^^^^^^^^^^^^^^^^^^^^^^ `y` used here but it isn't initialized diff --git a/src/test/ui/async-await/no-non-guaranteed-initialization.stderr b/src/test/ui/async-await/no-non-guaranteed-initialization.stderr index c6490c7bf4dbf..b23e2da0e0920 100644 --- a/src/test/ui/async-await/no-non-guaranteed-initialization.stderr +++ b/src/test/ui/async-await/no-non-guaranteed-initialization.stderr @@ -1,10 +1,10 @@ -error[E0381]: binding `y` isn't initialized in all conditions +error[E0381]: used binding `y` isn't initialized in all conditions --> $DIR/no-non-guaranteed-initialization.rs:9:5 | LL | let y; - | - variable declared here + | - binding declared here but left uninitialized LL | if x > 5 { - | ----- this `if` expression might be missing an `else` arm where `y` is initialized + | ----- this `if` expression might be missing an `else` arm that initializes `y` ... LL | y | ^ `y` used here but it isn't initialized in all conditions diff --git a/src/test/ui/async-await/partial-initialization-across-await.stderr b/src/test/ui/async-await/partial-initialization-across-await.stderr index 981e32cadd9de..6a0eeffb94611 100644 --- a/src/test/ui/async-await/partial-initialization-across-await.stderr +++ b/src/test/ui/async-await/partial-initialization-across-await.stderr @@ -1,32 +1,32 @@ -error[E0381]: binding `t` isn't fully initialized +error[E0381]: partially assigned binding `t` isn't fully initialized --> $DIR/partial-initialization-across-await.rs:13:5 | LL | let mut t: (i32, i32); - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | t.0 = 42; | ^^^^^^^^ `t` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: binding `t` isn't fully initialized +error[E0381]: partially assigned binding `t` isn't fully initialized --> $DIR/partial-initialization-across-await.rs:21:5 | LL | let mut t: T; - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | t.0 = 42; | ^^^^^^^^ `t` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: binding `t` isn't fully initialized +error[E0381]: partially assigned binding `t` isn't fully initialized --> $DIR/partial-initialization-across-await.rs:29:5 | LL | let mut t: S; - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | t.x = 42; | ^^^^^^^^ `t` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error: aborting due to 3 previous errors diff --git a/src/test/ui/borrowck/assign_mutable_fields.stderr b/src/test/ui/borrowck/assign_mutable_fields.stderr index 57787b8924998..1ed92865da55b 100644 --- a/src/test/ui/borrowck/assign_mutable_fields.stderr +++ b/src/test/ui/borrowck/assign_mutable_fields.stderr @@ -1,22 +1,22 @@ -error[E0381]: binding `x` isn't fully initialized +error[E0381]: partially assigned binding `x` isn't fully initialized --> $DIR/assign_mutable_fields.rs:9:5 | LL | let mut x: (u32, u32); - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | x.0 = 1; | ^^^^^^^ `x` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: binding `x` isn't fully initialized +error[E0381]: partially assigned binding `x` isn't fully initialized --> $DIR/assign_mutable_fields.rs:17:5 | LL | let mut x: (u32, u32); - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | x.0 = 1; | ^^^^^^^ `x` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error: aborting due to 2 previous errors diff --git a/src/test/ui/borrowck/borrowck-and-init.stderr b/src/test/ui/borrowck/borrowck-and-init.stderr index de57243a5dbf7..a78ac1e593a05 100644 --- a/src/test/ui/borrowck/borrowck-and-init.stderr +++ b/src/test/ui/borrowck/borrowck-and-init.stderr @@ -1,13 +1,13 @@ -error[E0381]: binding `i` isn't initialized in all conditions +error[E0381]: used binding `i` isn't initialized in all conditions --> $DIR/borrowck-and-init.rs:5:20 | LL | let i: isize; - | - variable declared here + | - binding declared here but left uninitialized LL | LL | println!("{}", false && { i = 5; true }); | ----- binding initialized here in some conditions LL | println!("{}", i); - | ^ `i` borrowed here but it isn't initialized in all conditions + | ^ `i` used here but it isn't initialized in all conditions | = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/borrowck/borrowck-block-unint.stderr b/src/test/ui/borrowck/borrowck-block-unint.stderr index 0f0fbedaf17e7..e720db1c6961b 100644 --- a/src/test/ui/borrowck/borrowck-block-unint.stderr +++ b/src/test/ui/borrowck/borrowck-block-unint.stderr @@ -1,10 +1,10 @@ -error[E0381]: binding `x` isn't initialized +error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-block-unint.rs:4:11 | LL | let x: isize; - | - variable declared here + | - binding declared here but left uninitialized LL | force(|| { - | ^^ `x` borrowed here but it isn't initialized + | ^^ `x` used here but it isn't initialized LL | println!("{}", x); | - borrow occurs due to use in closure diff --git a/src/test/ui/borrowck/borrowck-break-uninit-2.stderr b/src/test/ui/borrowck/borrowck-break-uninit-2.stderr index 2b5547dbf9556..23ea1a2de7fc7 100644 --- a/src/test/ui/borrowck/borrowck-break-uninit-2.stderr +++ b/src/test/ui/borrowck/borrowck-break-uninit-2.stderr @@ -1,11 +1,11 @@ -error[E0381]: binding `x` isn't initialized +error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-break-uninit-2.rs:9:20 | LL | let x: isize; - | - variable declared here + | - binding declared here but left uninitialized ... LL | println!("{}", x); - | ^ `x` borrowed here but it isn't initialized + | ^ `x` used here but it isn't initialized | = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/borrowck/borrowck-break-uninit.stderr b/src/test/ui/borrowck/borrowck-break-uninit.stderr index 9d0fd5dac933f..2b9b0a190f6c8 100644 --- a/src/test/ui/borrowck/borrowck-break-uninit.stderr +++ b/src/test/ui/borrowck/borrowck-break-uninit.stderr @@ -1,11 +1,11 @@ -error[E0381]: binding `x` isn't initialized +error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-break-uninit.rs:9:20 | LL | let x: isize; - | - variable declared here + | - binding declared here but left uninitialized ... LL | println!("{}", x); - | ^ `x` borrowed here but it isn't initialized + | ^ `x` used here but it isn't initialized | = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/borrowck/borrowck-field-sensitivity.stderr b/src/test/ui/borrowck/borrowck-field-sensitivity.stderr index 492bbfa9eb2d4..e009f5913edd0 100644 --- a/src/test/ui/borrowck/borrowck-field-sensitivity.stderr +++ b/src/test/ui/borrowck/borrowck-field-sensitivity.stderr @@ -108,35 +108,35 @@ LL | let _z = A { a: 4, .. x }; | = note: move occurs because `x.b` has type `Box`, which does not implement the `Copy` trait -error[E0381]: binding `x` isn't fully initialized +error[E0381]: partially assigned binding `x` isn't fully initialized --> $DIR/borrowck-field-sensitivity.rs:81:5 | LL | let mut x: A; - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | x.a = 1; | ^^^^^^^ `x` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: binding `x` isn't fully initialized +error[E0381]: partially assigned binding `x` isn't fully initialized --> $DIR/borrowck-field-sensitivity.rs:87:5 | LL | let mut x: A; - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | x.a = 1; | ^^^^^^^ `x` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: binding `x` isn't fully initialized +error[E0381]: partially assigned binding `x` isn't fully initialized --> $DIR/borrowck-field-sensitivity.rs:94:5 | LL | let mut x: A; - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | x.b = Box::new(1); | ^^^ `x` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error: aborting due to 14 previous errors diff --git a/src/test/ui/borrowck/borrowck-if-no-else.stderr b/src/test/ui/borrowck/borrowck-if-no-else.stderr index 178381e847786..134e7d5df4b09 100644 --- a/src/test/ui/borrowck/borrowck-if-no-else.stderr +++ b/src/test/ui/borrowck/borrowck-if-no-else.stderr @@ -1,10 +1,10 @@ -error[E0381]: binding `x` isn't initialized in all conditions +error[E0381]: used binding `x` isn't initialized in all conditions --> $DIR/borrowck-if-no-else.rs:5:9 | LL | let x: isize; if 1 > 2 { x = 10; } - | - ----- this `if` expression might be missing an `else` arm where `x` is initialized + | - ----- this `if` expression might be missing an `else` arm that initializes `x` | | - | variable declared here + | binding declared here but left uninitialized LL | foo(x); | ^ `x` used here but it isn't initialized in all conditions diff --git a/src/test/ui/borrowck/borrowck-if-with-else.stderr b/src/test/ui/borrowck/borrowck-if-with-else.stderr index f1af7b67b1c1b..f4b0c39307452 100644 --- a/src/test/ui/borrowck/borrowck-if-with-else.stderr +++ b/src/test/ui/borrowck/borrowck-if-with-else.stderr @@ -1,8 +1,8 @@ -error[E0381]: binding `x` isn't initialized in all conditions +error[E0381]: used binding `x` isn't initialized in all conditions --> $DIR/borrowck-if-with-else.rs:10:9 | LL | let x: isize; - | - variable declared here + | - binding declared here but left uninitialized LL | if 1 > 2 { | ----- `x` is uninitialized if this condition is met ... diff --git a/src/test/ui/borrowck/borrowck-init-in-called-fn-expr.stderr b/src/test/ui/borrowck/borrowck-init-in-called-fn-expr.stderr index 8bdccd0dad6d2..e8a2fbc91ea64 100644 --- a/src/test/ui/borrowck/borrowck-init-in-called-fn-expr.stderr +++ b/src/test/ui/borrowck/borrowck-init-in-called-fn-expr.stderr @@ -1,8 +1,8 @@ -error[E0381]: binding `i` isn't initialized +error[E0381]: used binding `i` isn't initialized --> $DIR/borrowck-init-in-called-fn-expr.rs:4:9 | LL | let i: isize; - | - variable declared here + | - binding declared here but left uninitialized LL | i | ^ `i` used here but it isn't initialized diff --git a/src/test/ui/borrowck/borrowck-init-in-fn-expr.stderr b/src/test/ui/borrowck/borrowck-init-in-fn-expr.stderr index 84ec5598abb89..1e950d6a20def 100644 --- a/src/test/ui/borrowck/borrowck-init-in-fn-expr.stderr +++ b/src/test/ui/borrowck/borrowck-init-in-fn-expr.stderr @@ -1,8 +1,8 @@ -error[E0381]: binding `i` isn't initialized +error[E0381]: used binding `i` isn't initialized --> $DIR/borrowck-init-in-fn-expr.rs:4:9 | LL | let i: isize; - | - variable declared here + | - binding declared here but left uninitialized LL | i | ^ `i` used here but it isn't initialized diff --git a/src/test/ui/borrowck/borrowck-init-in-fru.stderr b/src/test/ui/borrowck/borrowck-init-in-fru.stderr index ddb2473d1ebee..7a35a9a537cac 100644 --- a/src/test/ui/borrowck/borrowck-init-in-fru.stderr +++ b/src/test/ui/borrowck/borrowck-init-in-fru.stderr @@ -1,8 +1,8 @@ -error[E0381]: binding `origin.y` isn't initialized +error[E0381]: used binding `origin.y` isn't initialized --> $DIR/borrowck-init-in-fru.rs:9:14 | LL | let mut origin: Point; - | ---------- variable declared here + | ---------- binding declared here but left uninitialized LL | origin = Point { x: 10, ..origin }; | ^^^^^^^^^^^^^^^^^^^^^^^^^ `origin.y` used here but it isn't initialized diff --git a/src/test/ui/borrowck/borrowck-init-op-equal.stderr b/src/test/ui/borrowck/borrowck-init-op-equal.stderr index f1d7ec6a446d4..74704b2abfee8 100644 --- a/src/test/ui/borrowck/borrowck-init-op-equal.stderr +++ b/src/test/ui/borrowck/borrowck-init-op-equal.stderr @@ -1,8 +1,8 @@ -error[E0381]: binding `v` isn't initialized +error[E0381]: used binding `v` isn't initialized --> $DIR/borrowck-init-op-equal.rs:3:5 | LL | let v: isize; - | - variable declared here + | - binding declared here but left uninitialized LL | v += 1; | ^^^^^^ `v` used here but it isn't initialized diff --git a/src/test/ui/borrowck/borrowck-init-plus-equal.stderr b/src/test/ui/borrowck/borrowck-init-plus-equal.stderr index 26422af9c639a..7542576d636be 100644 --- a/src/test/ui/borrowck/borrowck-init-plus-equal.stderr +++ b/src/test/ui/borrowck/borrowck-init-plus-equal.stderr @@ -1,8 +1,8 @@ -error[E0381]: binding `v` isn't initialized +error[E0381]: used binding `v` isn't initialized --> $DIR/borrowck-init-plus-equal.rs:3:9 | LL | let mut v: isize; - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | v = v + 1; | ^ `v` used here but it isn't initialized diff --git a/src/test/ui/borrowck/borrowck-or-init.stderr b/src/test/ui/borrowck/borrowck-or-init.stderr index 7fcec3046474d..633c4017d16ac 100644 --- a/src/test/ui/borrowck/borrowck-or-init.stderr +++ b/src/test/ui/borrowck/borrowck-or-init.stderr @@ -1,13 +1,13 @@ -error[E0381]: binding `i` isn't initialized in all conditions +error[E0381]: used binding `i` isn't initialized in all conditions --> $DIR/borrowck-or-init.rs:5:20 | LL | let i: isize; - | - variable declared here + | - binding declared here but left uninitialized LL | LL | println!("{}", false || { i = 5; true }); | ----- binding initialized here in some conditions LL | println!("{}", i); - | ^ `i` borrowed here but it isn't initialized in all conditions + | ^ `i` used here but it isn't initialized in all conditions | = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/borrowck/borrowck-partial-reinit-4.stderr b/src/test/ui/borrowck/borrowck-partial-reinit-4.stderr index be5de8a0a5a61..06351a943064b 100644 --- a/src/test/ui/borrowck/borrowck-partial-reinit-4.stderr +++ b/src/test/ui/borrowck/borrowck-partial-reinit-4.stderr @@ -1,8 +1,8 @@ -error[E0381]: binding `x.0` isn't initialized +error[E0381]: assigned binding `x.0` isn't initialized --> $DIR/borrowck-partial-reinit-4.rs:17:5 | LL | let mut x : (Test2, Test2); - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | (x.0).0 = Some(Test); | ^^^^^^^ `x.0` assigned here but it isn't initialized diff --git a/src/test/ui/borrowck/borrowck-return.stderr b/src/test/ui/borrowck/borrowck-return.stderr index f42ac9fc54159..1c916e223175c 100644 --- a/src/test/ui/borrowck/borrowck-return.stderr +++ b/src/test/ui/borrowck/borrowck-return.stderr @@ -1,8 +1,8 @@ -error[E0381]: binding `x` isn't initialized +error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-return.rs:3:12 | LL | let x: isize; - | - variable declared here + | - binding declared here but left uninitialized LL | return x; | ^ `x` used here but it isn't initialized diff --git a/src/test/ui/borrowck/borrowck-storage-dead.stderr b/src/test/ui/borrowck/borrowck-storage-dead.stderr index 6168961bd16db..2cea4392d6adb 100644 --- a/src/test/ui/borrowck/borrowck-storage-dead.stderr +++ b/src/test/ui/borrowck/borrowck-storage-dead.stderr @@ -1,8 +1,8 @@ -error[E0381]: binding `x` isn't initialized +error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-storage-dead.rs:16:17 | LL | let x: i32; - | - variable declared here + | - binding declared here but left uninitialized LL | let _ = x + 1; | ^ `x` used here but it isn't initialized diff --git a/src/test/ui/borrowck/borrowck-uninit-after-item.stderr b/src/test/ui/borrowck/borrowck-uninit-after-item.stderr index 64bccecf68a94..588b1b0c9729c 100644 --- a/src/test/ui/borrowck/borrowck-uninit-after-item.stderr +++ b/src/test/ui/borrowck/borrowck-uninit-after-item.stderr @@ -1,8 +1,8 @@ -error[E0381]: binding `bar` isn't initialized +error[E0381]: used binding `bar` isn't initialized --> $DIR/borrowck-uninit-after-item.rs:4:9 | LL | let bar; - | --- variable declared here + | --- binding declared here but left uninitialized LL | fn baz(_x: isize) { } LL | baz(bar); | ^^^ `bar` used here but it isn't initialized diff --git a/src/test/ui/borrowck/borrowck-uninit-field-access.stderr b/src/test/ui/borrowck/borrowck-uninit-field-access.stderr index 0ffa5cee5f167..3bc3a47778778 100644 --- a/src/test/ui/borrowck/borrowck-uninit-field-access.stderr +++ b/src/test/ui/borrowck/borrowck-uninit-field-access.stderr @@ -1,8 +1,8 @@ -error[E0381]: binding `a.x` isn't initialized +error[E0381]: used binding `a.x` isn't initialized --> $DIR/borrowck-uninit-field-access.rs:21:13 | LL | let mut a: Point; - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | let _ = a.x + 1; | ^^^ `a.x` used here but it isn't initialized diff --git a/src/test/ui/borrowck/borrowck-uninit-in-assignop.stderr b/src/test/ui/borrowck/borrowck-uninit-in-assignop.stderr index 273370a4eef3a..744cb14e662b3 100644 --- a/src/test/ui/borrowck/borrowck-uninit-in-assignop.stderr +++ b/src/test/ui/borrowck/borrowck-uninit-in-assignop.stderr @@ -1,80 +1,80 @@ -error[E0381]: binding `x` isn't initialized +error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-uninit-in-assignop.rs:6:5 | LL | let x: isize; - | - variable declared here + | - binding declared here but left uninitialized LL | x += 1; | ^^^^^^ `x` used here but it isn't initialized -error[E0381]: binding `x` isn't initialized +error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-uninit-in-assignop.rs:9:5 | LL | let x: isize; - | - variable declared here + | - binding declared here but left uninitialized LL | x -= 1; | ^^^^^^ `x` used here but it isn't initialized -error[E0381]: binding `x` isn't initialized +error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-uninit-in-assignop.rs:12:5 | LL | let x: isize; - | - variable declared here + | - binding declared here but left uninitialized LL | x *= 1; | ^^^^^^ `x` used here but it isn't initialized -error[E0381]: binding `x` isn't initialized +error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-uninit-in-assignop.rs:15:5 | LL | let x: isize; - | - variable declared here + | - binding declared here but left uninitialized LL | x /= 1; | ^^^^^^ `x` used here but it isn't initialized -error[E0381]: binding `x` isn't initialized +error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-uninit-in-assignop.rs:18:5 | LL | let x: isize; - | - variable declared here + | - binding declared here but left uninitialized LL | x %= 1; | ^^^^^^ `x` used here but it isn't initialized -error[E0381]: binding `x` isn't initialized +error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-uninit-in-assignop.rs:21:5 | LL | let x: isize; - | - variable declared here + | - binding declared here but left uninitialized LL | x ^= 1; | ^^^^^^ `x` used here but it isn't initialized -error[E0381]: binding `x` isn't initialized +error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-uninit-in-assignop.rs:24:5 | LL | let x: isize; - | - variable declared here + | - binding declared here but left uninitialized LL | x &= 1; | ^^^^^^ `x` used here but it isn't initialized -error[E0381]: binding `x` isn't initialized +error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-uninit-in-assignop.rs:27:5 | LL | let x: isize; - | - variable declared here + | - binding declared here but left uninitialized LL | x |= 1; | ^^^^^^ `x` used here but it isn't initialized -error[E0381]: binding `x` isn't initialized +error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-uninit-in-assignop.rs:30:5 | LL | let x: isize; - | - variable declared here + | - binding declared here but left uninitialized LL | x <<= 1; | ^^^^^^^ `x` used here but it isn't initialized -error[E0381]: binding `x` isn't initialized +error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-uninit-in-assignop.rs:33:5 | LL | let x: isize; - | - variable declared here + | - binding declared here but left uninitialized LL | x >>= 1; | ^^^^^^^ `x` used here but it isn't initialized diff --git a/src/test/ui/borrowck/borrowck-uninit-ref-chain.stderr b/src/test/ui/borrowck/borrowck-uninit-ref-chain.stderr index e78f5888df62d..9f33a163e084f 100644 --- a/src/test/ui/borrowck/borrowck-uninit-ref-chain.stderr +++ b/src/test/ui/borrowck/borrowck-uninit-ref-chain.stderr @@ -1,66 +1,66 @@ -error[E0381]: binding `**x` isn't initialized +error[E0381]: used binding `**x` isn't initialized --> $DIR/borrowck-uninit-ref-chain.rs:8:14 | LL | let x: &&Box; - | - variable declared here + | - binding declared here but left uninitialized LL | let _y = &**x; - | ^^^^ `**x` borrowed here but it isn't initialized + | ^^^^ `**x` used here but it isn't initialized -error[E0381]: binding `**x` isn't initialized +error[E0381]: used binding `**x` isn't initialized --> $DIR/borrowck-uninit-ref-chain.rs:11:14 | LL | let x: &&S; - | - variable declared here + | - binding declared here but left uninitialized LL | let _y = &**x; - | ^^^^ `**x` borrowed here but it isn't initialized + | ^^^^ `**x` used here but it isn't initialized -error[E0381]: binding `**x` isn't initialized +error[E0381]: used binding `**x` isn't initialized --> $DIR/borrowck-uninit-ref-chain.rs:14:14 | LL | let x: &&i32; - | - variable declared here + | - binding declared here but left uninitialized LL | let _y = &**x; - | ^^^^ `**x` borrowed here but it isn't initialized + | ^^^^ `**x` used here but it isn't initialized -error[E0381]: binding `a` isn't fully initialized +error[E0381]: partially assigned binding `a` isn't fully initialized --> $DIR/borrowck-uninit-ref-chain.rs:18:5 | LL | let mut a: S; - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | a.x = 0; | ^^^^^^^ `a` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: binding `a` isn't fully initialized +error[E0381]: partially assigned binding `a` isn't fully initialized --> $DIR/borrowck-uninit-ref-chain.rs:22:5 | LL | let mut a: S<&&i32, &&i32>; - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | a.x = &&0; | ^^^^^^^^^ `a` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: binding `a` isn't fully initialized +error[E0381]: partially assigned binding `a` isn't fully initialized --> $DIR/borrowck-uninit-ref-chain.rs:27:5 | LL | let mut a: S; - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | a.x = 0; | ^^^^^^^ `a` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: binding `a` isn't fully initialized +error[E0381]: partially assigned binding `a` isn't fully initialized --> $DIR/borrowck-uninit-ref-chain.rs:31:5 | LL | let mut a: S<&&i32, &&i32>; - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | a.x = &&0; | ^^^^^^^^^ `a` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error: aborting due to 7 previous errors diff --git a/src/test/ui/borrowck/borrowck-uninit.stderr b/src/test/ui/borrowck/borrowck-uninit.stderr index c5ee9cfd29747..d5566691a8200 100644 --- a/src/test/ui/borrowck/borrowck-uninit.stderr +++ b/src/test/ui/borrowck/borrowck-uninit.stderr @@ -1,8 +1,8 @@ -error[E0381]: binding `x` isn't initialized +error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-uninit.rs:5:9 | LL | let x: isize; - | - variable declared here + | - binding declared here but left uninitialized LL | foo(x); | ^ `x` used here but it isn't initialized diff --git a/src/test/ui/borrowck/borrowck-union-uninitialized.stderr b/src/test/ui/borrowck/borrowck-union-uninitialized.stderr index eee04f790337e..b7ff5f3955ee5 100644 --- a/src/test/ui/borrowck/borrowck-union-uninitialized.stderr +++ b/src/test/ui/borrowck/borrowck-union-uninitialized.stderr @@ -1,24 +1,24 @@ -error[E0381]: binding `s` isn't fully initialized +error[E0381]: partially assigned binding `s` isn't fully initialized --> $DIR/borrowck-union-uninitialized.rs:13:9 | LL | let mut s: S; - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | let mut u: U; LL | s.a = 0; | ^^^^^^^ `s` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: binding `u` isn't fully initialized +error[E0381]: partially assigned binding `u` isn't fully initialized --> $DIR/borrowck-union-uninitialized.rs:14:9 | LL | let mut u: U; - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | s.a = 0; LL | u.a = 0; | ^^^^^^^ `u` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error: aborting due to 2 previous errors diff --git a/src/test/ui/borrowck/borrowck-use-in-index-lvalue.stderr b/src/test/ui/borrowck/borrowck-use-in-index-lvalue.stderr index f7975c8ac920f..6372096caef02 100644 --- a/src/test/ui/borrowck/borrowck-use-in-index-lvalue.stderr +++ b/src/test/ui/borrowck/borrowck-use-in-index-lvalue.stderr @@ -1,16 +1,16 @@ -error[E0381]: binding `*w` isn't initialized +error[E0381]: used binding `*w` isn't initialized --> $DIR/borrowck-use-in-index-lvalue.rs:3:5 | LL | let w: &mut [isize]; - | - variable declared here + | - binding declared here but left uninitialized LL | w[5] = 0; | ^^^^ `*w` used here but it isn't initialized -error[E0381]: binding `*w` isn't initialized +error[E0381]: used binding `*w` isn't initialized --> $DIR/borrowck-use-in-index-lvalue.rs:6:5 | LL | let mut w: &mut [isize]; - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | w[5] = 0; | ^^^^ `*w` used here but it isn't initialized diff --git a/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.stderr b/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.stderr index 3d024b531ef7c..fea69c2e40d66 100644 --- a/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.stderr +++ b/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.stderr @@ -1,10 +1,10 @@ -error[E0381]: binding `*x` isn't initialized +error[E0381]: used binding `*x` isn't initialized --> $DIR/borrowck-use-uninitialized-in-cast-trait.rs:9:13 | LL | let x: &i32; - | - variable declared here + | - binding declared here but left uninitialized LL | let y = x as *const dyn Foo; - | ^ `*x` borrowed here but it isn't initialized + | ^ `*x` used here but it isn't initialized error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.stderr b/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.stderr index 20a5dcaade7e2..e75e033529607 100644 --- a/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.stderr +++ b/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.stderr @@ -1,10 +1,10 @@ -error[E0381]: binding `*x` isn't initialized +error[E0381]: used binding `*x` isn't initialized --> $DIR/borrowck-use-uninitialized-in-cast.rs:7:13 | LL | let x: &i32; - | - variable declared here + | - binding declared here but left uninitialized LL | let y = x as *const i32; - | ^ `*x` borrowed here but it isn't initialized + | ^ `*x` used here but it isn't initialized error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-while-break.stderr b/src/test/ui/borrowck/borrowck-while-break.stderr index 501f0c6515177..ab7d50b834a4e 100644 --- a/src/test/ui/borrowck/borrowck-while-break.stderr +++ b/src/test/ui/borrowck/borrowck-while-break.stderr @@ -1,13 +1,13 @@ -error[E0381]: binding `v` isn't initialized in all conditions +error[E0381]: used binding `v` isn't initialized in all conditions --> $DIR/borrowck-while-break.rs:7:20 | LL | let v; - | - variable declared here + | - binding declared here but left uninitialized LL | while cond { - | ---- `v` is uninitialized if this condition isn't met + | ---- `v` is uninitialized if this condition isn't met and the `while` loop runs 0 times ... LL | println!("{}", v); - | ^ `v` borrowed here but it isn't initialized in all conditions + | ^ `v` used here but it isn't initialized in all conditions | = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/borrowck/borrowck-while-cond.stderr b/src/test/ui/borrowck/borrowck-while-cond.stderr index 87d505b5fbbcd..e41c1c55e6024 100644 --- a/src/test/ui/borrowck/borrowck-while-cond.stderr +++ b/src/test/ui/borrowck/borrowck-while-cond.stderr @@ -1,8 +1,8 @@ -error[E0381]: binding `x` isn't initialized +error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-while-cond.rs:3:11 | LL | let x: bool; - | - variable declared here + | - binding declared here but left uninitialized LL | while x { } | ^ `x` used here but it isn't initialized diff --git a/src/test/ui/borrowck/borrowck-while.stderr b/src/test/ui/borrowck/borrowck-while.stderr index 36dda8ee13f77..5bb86b11ba503 100644 --- a/src/test/ui/borrowck/borrowck-while.stderr +++ b/src/test/ui/borrowck/borrowck-while.stderr @@ -1,10 +1,10 @@ -error[E0381]: binding `x` isn't initialized in all conditions +error[E0381]: used binding `x` isn't initialized in all conditions --> $DIR/borrowck-while.rs:4:12 | LL | let mut x: isize; - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | while 1 == 1 { x = 10; } - | ------ `x` is uninitialized if this condition isn't met + | ------ `x` is uninitialized if this condition isn't met and the `while` loop runs 0 times LL | return x; | ^ `x` used here but it isn't initialized in all conditions diff --git a/src/test/ui/borrowck/disallow-possibly-uninitialized.stderr b/src/test/ui/borrowck/disallow-possibly-uninitialized.stderr index f6a0e3dbae053..9a84c6fefae59 100644 --- a/src/test/ui/borrowck/disallow-possibly-uninitialized.stderr +++ b/src/test/ui/borrowck/disallow-possibly-uninitialized.stderr @@ -1,42 +1,42 @@ -error[E0381]: binding `t` isn't fully initialized +error[E0381]: partially assigned binding `t` isn't fully initialized --> $DIR/disallow-possibly-uninitialized.rs:6:5 | LL | let mut t: (u64, u64); - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | t.0 = 1; | ^^^^^^^ `t` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: binding `t` isn't fully initialized +error[E0381]: partially assigned binding `t` isn't fully initialized --> $DIR/disallow-possibly-uninitialized.rs:11:5 | LL | let mut t: (u64, u64); - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | t.1 = 1; | ^^^^^^^ `t` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: binding `t` isn't fully initialized +error[E0381]: partially assigned binding `t` isn't fully initialized --> $DIR/disallow-possibly-uninitialized.rs:16:5 | LL | let mut t: (u64, u64); - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | t.0 = 1; | ^^^^^^^ `t` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: binding `t` isn't fully initialized +error[E0381]: partially assigned binding `t` isn't fully initialized --> $DIR/disallow-possibly-uninitialized.rs:20:5 | LL | let mut t: (u64,); - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | t.0 = 1; | ^^^^^^^ `t` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error: aborting due to 4 previous errors diff --git a/src/test/ui/borrowck/issue-24267-flow-exit.stderr b/src/test/ui/borrowck/issue-24267-flow-exit.stderr index 25f7df4f58243..d436e8ff9096c 100644 --- a/src/test/ui/borrowck/issue-24267-flow-exit.stderr +++ b/src/test/ui/borrowck/issue-24267-flow-exit.stderr @@ -1,22 +1,22 @@ -error[E0381]: binding `x` isn't initialized +error[E0381]: used binding `x` isn't initialized --> $DIR/issue-24267-flow-exit.rs:12:20 | LL | let x: i32; - | - variable declared here + | - binding declared here but left uninitialized LL | loop { x = break; } LL | println!("{}", x); - | ^ `x` borrowed here but it isn't initialized + | ^ `x` used here but it isn't initialized | = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) -error[E0381]: binding `x` isn't initialized +error[E0381]: used binding `x` isn't initialized --> $DIR/issue-24267-flow-exit.rs:18:20 | LL | let x: i32; - | - variable declared here + | - binding declared here but left uninitialized LL | for _ in 0..10 { x = continue; } LL | println!("{}", x); - | ^ `x` borrowed here but it isn't initialized + | ^ `x` used here but it isn't initialized | = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.stderr b/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.stderr index 99c25ad5446a2..2a0eba396f144 100644 --- a/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.stderr +++ b/src/test/ui/borrowck/issue-54499-field-mutation-marks-mut-as-used.stderr @@ -1,32 +1,32 @@ -error[E0381]: binding `t` isn't fully initialized +error[E0381]: partially assigned binding `t` isn't fully initialized --> $DIR/issue-54499-field-mutation-marks-mut-as-used.rs:12:9 | LL | let mut t: Tuple; - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | t.0 = S(1); | ^^^^^^^^^^ `t` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: binding `u` isn't fully initialized +error[E0381]: partially assigned binding `u` isn't fully initialized --> $DIR/issue-54499-field-mutation-marks-mut-as-used.rs:20:9 | LL | let mut u: Tpair; - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | u.0 = S(1); | ^^^^^^^^^^ `u` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: binding `v` isn't fully initialized +error[E0381]: partially assigned binding `v` isn't fully initialized --> $DIR/issue-54499-field-mutation-marks-mut-as-used.rs:28:9 | LL | let mut v: Spair; - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | v.x = S(1); | ^^^^^^^^^^ `v` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error: aborting due to 3 previous errors diff --git a/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.stderr b/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.stderr index 1c78524a1b1a8..67a62583057f6 100644 --- a/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.stderr +++ b/src/test/ui/borrowck/issue-54499-field-mutation-of-never-init.stderr @@ -1,32 +1,32 @@ -error[E0381]: binding `t` isn't fully initialized +error[E0381]: partially assigned binding `t` isn't fully initialized --> $DIR/issue-54499-field-mutation-of-never-init.rs:12:9 | LL | let t: Tuple; - | - variable declared here + | - binding declared here but left uninitialized LL | t.0 = S(1); | ^^^^^^^^^^ `t` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: binding `u` isn't fully initialized +error[E0381]: partially assigned binding `u` isn't fully initialized --> $DIR/issue-54499-field-mutation-of-never-init.rs:20:9 | LL | let u: Tpair; - | - variable declared here + | - binding declared here but left uninitialized LL | u.0 = S(1); | ^^^^^^^^^^ `u` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: binding `v` isn't fully initialized +error[E0381]: partially assigned binding `v` isn't fully initialized --> $DIR/issue-54499-field-mutation-of-never-init.rs:28:9 | LL | let v: Spair; - | - variable declared here + | - binding declared here but left uninitialized LL | v.x = S(1); | ^^^^^^^^^^ `v` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error: aborting due to 3 previous errors diff --git a/src/test/ui/borrowck/issue-62107-match-arm-scopes.stderr b/src/test/ui/borrowck/issue-62107-match-arm-scopes.stderr index f809b7d4c3b0c..f5d2eecfa91a3 100644 --- a/src/test/ui/borrowck/issue-62107-match-arm-scopes.stderr +++ b/src/test/ui/borrowck/issue-62107-match-arm-scopes.stderr @@ -1,8 +1,8 @@ -error[E0381]: binding `e` isn't initialized +error[E0381]: used binding `e` isn't initialized --> $DIR/issue-62107-match-arm-scopes.rs:3:11 | LL | let e: i32; - | - variable declared here + | - binding declared here but left uninitialized LL | match e { | ^ `e` used here but it isn't initialized diff --git a/src/test/ui/borrowck/reassignment_immutable_fields.stderr b/src/test/ui/borrowck/reassignment_immutable_fields.stderr index 045f95632d83e..e6b25573e7040 100644 --- a/src/test/ui/borrowck/reassignment_immutable_fields.stderr +++ b/src/test/ui/borrowck/reassignment_immutable_fields.stderr @@ -1,22 +1,22 @@ -error[E0381]: binding `x` isn't fully initialized +error[E0381]: partially assigned binding `x` isn't fully initialized --> $DIR/reassignment_immutable_fields.rs:7:5 | LL | let x: (u32, u32); - | - variable declared here + | - binding declared here but left uninitialized LL | x.0 = 1; | ^^^^^^^ `x` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: binding `x` isn't fully initialized +error[E0381]: partially assigned binding `x` isn't fully initialized --> $DIR/reassignment_immutable_fields.rs:15:5 | LL | let x: (u32, u32); - | - variable declared here + | - binding declared here but left uninitialized LL | x.0 = 1; | ^^^^^^^ `x` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error: aborting due to 2 previous errors diff --git a/src/test/ui/borrowck/reassignment_immutable_fields_overlapping.stderr b/src/test/ui/borrowck/reassignment_immutable_fields_overlapping.stderr index d848679272375..a3885b5f5caea 100644 --- a/src/test/ui/borrowck/reassignment_immutable_fields_overlapping.stderr +++ b/src/test/ui/borrowck/reassignment_immutable_fields_overlapping.stderr @@ -1,12 +1,12 @@ -error[E0381]: binding `x` isn't fully initialized +error[E0381]: partially assigned binding `x` isn't fully initialized --> $DIR/reassignment_immutable_fields_overlapping.rs:12:5 | LL | let x: Foo; - | - variable declared here + | - binding declared here but left uninitialized LL | x.a = 1; | ^^^^^^^ `x` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error[E0594]: cannot assign to `x.b`, as `x` is not declared as mutable --> $DIR/reassignment_immutable_fields_overlapping.rs:13:5 diff --git a/src/test/ui/borrowck/reassignment_immutable_fields_twice.stderr b/src/test/ui/borrowck/reassignment_immutable_fields_twice.stderr index db69f0b0db704..49c81adad4937 100644 --- a/src/test/ui/borrowck/reassignment_immutable_fields_twice.stderr +++ b/src/test/ui/borrowck/reassignment_immutable_fields_twice.stderr @@ -7,15 +7,15 @@ LL | x = (22, 44); LL | x.0 = 1; | ^^^^^^^ cannot assign -error[E0381]: binding `x` isn't fully initialized +error[E0381]: partially assigned binding `x` isn't fully initialized --> $DIR/reassignment_immutable_fields_twice.rs:12:5 | LL | let x: (u32, u32); - | - variable declared here + | - binding declared here but left uninitialized LL | x.0 = 1; | ^^^^^^^ `x` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error: aborting due to 2 previous errors diff --git a/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr b/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr index c891fff228a27..fea5441ec673d 100644 --- a/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr +++ b/src/test/ui/closures/2229_closure_analysis/match/pattern-matching-should-fail.stderr @@ -12,68 +12,68 @@ LL + _ => todo!(), LL ~ }; | -error[E0381]: binding `x` isn't initialized +error[E0381]: used binding `x` isn't initialized --> $DIR/pattern-matching-should-fail.rs:8:23 | LL | let x: !; - | - variable declared here + | - binding declared here but left uninitialized LL | let c1 = || match x { }; | ^ `x` used here but it isn't initialized -error[E0381]: binding `x` isn't initialized +error[E0381]: used binding `x` isn't initialized --> $DIR/pattern-matching-should-fail.rs:15:14 | LL | let x: !; - | - variable declared here + | - binding declared here but left uninitialized LL | let c2 = || match x { _ => () }; | ^^ - borrow occurs due to use in closure | | - | `x` borrowed here but it isn't initialized + | `x` used here but it isn't initialized -error[E0381]: binding `variant` isn't initialized +error[E0381]: used binding `variant` isn't initialized --> $DIR/pattern-matching-should-fail.rs:27:13 | LL | let variant: !; - | ------- variable declared here + | ------- binding declared here but left uninitialized LL | let c = || { - | ^^ `variant` borrowed here but it isn't initialized + | ^^ `variant` used here but it isn't initialized LL | LL | match variant { | ------- borrow occurs due to use in closure -error[E0381]: binding `variant` isn't initialized +error[E0381]: used binding `variant` isn't initialized --> $DIR/pattern-matching-should-fail.rs:39:13 | LL | let variant: !; - | ------- variable declared here + | ------- binding declared here but left uninitialized LL | let c = || { - | ^^ `variant` borrowed here but it isn't initialized + | ^^ `variant` used here but it isn't initialized LL | match variant { | ------- borrow occurs due to use in closure -error[E0381]: binding `g` isn't initialized +error[E0381]: used binding `g` isn't initialized --> $DIR/pattern-matching-should-fail.rs:54:15 | LL | let g: !; - | - variable declared here + | - binding declared here but left uninitialized ... LL | match g { }; | ^ `g` used here but it isn't initialized -error[E0381]: binding `t` isn't initialized +error[E0381]: used binding `t` isn't initialized --> $DIR/pattern-matching-should-fail.rs:56:19 | LL | let t: !; - | - variable declared here + | - binding declared here but left uninitialized ... LL | match t { }; | ^ `t` used here but it isn't initialized -error[E0381]: binding `x` isn't initialized +error[E0381]: used binding `x` isn't initialized --> $DIR/pattern-matching-should-fail.rs:67:23 | LL | let x: u8; - | - variable declared here + | - binding declared here but left uninitialized LL | let c1 = || match x { }; | ^ `x` used here but it isn't initialized diff --git a/src/test/ui/const-generics/const-generic-default-wont-borrowck.stderr b/src/test/ui/const-generics/const-generic-default-wont-borrowck.stderr index 0638a9c61c17e..33f839c2866e9 100644 --- a/src/test/ui/const-generics/const-generic-default-wont-borrowck.stderr +++ b/src/test/ui/const-generics/const-generic-default-wont-borrowck.stderr @@ -1,10 +1,10 @@ -error[E0381]: binding `*s` isn't initialized +error[E0381]: used binding `*s` isn't initialized --> $DIR/const-generic-default-wont-borrowck.rs:2:26 | LL | let s: &'static str; s.len() - | - ^^^^^^^ `*s` borrowed here but it isn't initialized + | - ^^^^^^^ `*s` used here but it isn't initialized | | - | variable declared here + | binding declared here but left uninitialized error: aborting due to previous error diff --git a/src/test/ui/consts/issue-78655.stderr b/src/test/ui/consts/issue-78655.stderr index 1c1a30d405d70..f5b1123e7f343 100644 --- a/src/test/ui/consts/issue-78655.stderr +++ b/src/test/ui/consts/issue-78655.stderr @@ -1,10 +1,10 @@ -error[E0381]: binding `x` isn't initialized +error[E0381]: used binding `x` isn't initialized --> $DIR/issue-78655.rs:3:5 | LL | let x; - | - variable declared here + | - binding declared here but left uninitialized LL | &x - | ^^ `x` borrowed here but it isn't initialized + | ^^ `x` used here but it isn't initialized error: could not evaluate constant pattern --> $DIR/issue-78655.rs:7:9 diff --git a/src/test/ui/drop/repeat-drop-2.stderr b/src/test/ui/drop/repeat-drop-2.stderr index 845b6de798fa7..48fa2bfa975c0 100644 --- a/src/test/ui/drop/repeat-drop-2.stderr +++ b/src/test/ui/drop/repeat-drop-2.stderr @@ -17,11 +17,11 @@ LL | const _: [String; 0] = [String::new(); 0]; | |constants cannot evaluate destructors | value is dropped here -error[E0381]: binding `x` isn't initialized +error[E0381]: used binding `x` isn't initialized --> $DIR/repeat-drop-2.rs:12:14 | LL | let x: u8; - | - variable declared here + | - binding declared here but left uninitialized LL | let _ = [x; 0]; | ^ `x` used here but it isn't initialized diff --git a/src/test/ui/generator/partial-initialization-across-yield.stderr b/src/test/ui/generator/partial-initialization-across-yield.stderr index 26f45538023bb..3f9f1c046ba4b 100644 --- a/src/test/ui/generator/partial-initialization-across-yield.stderr +++ b/src/test/ui/generator/partial-initialization-across-yield.stderr @@ -1,32 +1,32 @@ -error[E0381]: binding `t` isn't fully initialized +error[E0381]: partially assigned binding `t` isn't fully initialized --> $DIR/partial-initialization-across-yield.rs:12:9 | LL | let mut t: (i32, i32); - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | t.0 = 42; | ^^^^^^^^ `t` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: binding `t` isn't fully initialized +error[E0381]: partially assigned binding `t` isn't fully initialized --> $DIR/partial-initialization-across-yield.rs:22:9 | LL | let mut t: T; - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | t.0 = 42; | ^^^^^^^^ `t` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: binding `t` isn't fully initialized +error[E0381]: partially assigned binding `t` isn't fully initialized --> $DIR/partial-initialization-across-yield.rs:32:9 | LL | let mut t: S; - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | t.x = 42; | ^^^^^^^^ `t` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error: aborting due to 3 previous errors diff --git a/src/test/ui/loops/loop-proper-liveness.stderr b/src/test/ui/loops/loop-proper-liveness.stderr index dd6949b19f624..7504103173652 100644 --- a/src/test/ui/loops/loop-proper-liveness.stderr +++ b/src/test/ui/loops/loop-proper-liveness.stderr @@ -1,11 +1,11 @@ -error[E0381]: binding `x` isn't initialized +error[E0381]: used binding `x` isn't initialized --> $DIR/loop-proper-liveness.rs:9:22 | LL | let x: i32; - | - variable declared here + | - binding declared here but left uninitialized ... LL | println!("{:?}", x); - | ^ `x` borrowed here but it isn't initialized + | ^ `x` used here but it isn't initialized | = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/mir/drop-elaboration-after-borrowck-error.stderr b/src/test/ui/mir/drop-elaboration-after-borrowck-error.stderr index ad2e5c9f64373..d8154f8d2cbc4 100644 --- a/src/test/ui/mir/drop-elaboration-after-borrowck-error.stderr +++ b/src/test/ui/mir/drop-elaboration-after-borrowck-error.stderr @@ -16,11 +16,11 @@ LL | let a: [String; 1]; LL | }; | - value is dropped here -error[E0381]: binding `a` isn't initialized +error[E0381]: used binding `a` isn't initialized --> $DIR/drop-elaboration-after-borrowck-error.rs:7:5 | LL | let a: [String; 1]; - | - variable declared here + | - binding declared here but left uninitialized LL | LL | a[0] = String::new(); | ^^^^ `a` used here but it isn't initialized diff --git a/src/test/ui/moves/issue-72649-uninit-in-loop.rs b/src/test/ui/moves/issue-72649-uninit-in-loop.rs index e796466397b1e..d76b69ecdc8bb 100644 --- a/src/test/ui/moves/issue-72649-uninit-in-loop.rs +++ b/src/test/ui/moves/issue-72649-uninit-in-loop.rs @@ -57,14 +57,14 @@ fn moved_loop_2() { fn uninit_1() { loop { - let value: NonCopy; //~ NOTE variable declared here + let value: NonCopy; //~ NOTE declared here let _used = value; //~ ERROR binding `value` isn't initialized //~^ NOTE `value` used here but it isn't initialized } } fn uninit_2() { - let mut value: NonCopy; //~ NOTE variable declared here + let mut value: NonCopy; //~ NOTE declared here loop { let _used = value; //~ ERROR binding `value` isn't initialized //~^ NOTE `value` used here but it isn't initialized diff --git a/src/test/ui/moves/issue-72649-uninit-in-loop.stderr b/src/test/ui/moves/issue-72649-uninit-in-loop.stderr index 52dab5cabf817..c7373b5be9d8d 100644 --- a/src/test/ui/moves/issue-72649-uninit-in-loop.stderr +++ b/src/test/ui/moves/issue-72649-uninit-in-loop.stderr @@ -40,19 +40,19 @@ LL | let mut value = NonCopy{}; LL | let _used2 = value; | ^^^^^ value moved here, in previous iteration of loop -error[E0381]: binding `value` isn't initialized +error[E0381]: used binding `value` isn't initialized --> $DIR/issue-72649-uninit-in-loop.rs:61:21 | LL | let value: NonCopy; - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | let _used = value; | ^^^^^ `value` used here but it isn't initialized -error[E0381]: binding `value` isn't initialized +error[E0381]: used binding `value` isn't initialized --> $DIR/issue-72649-uninit-in-loop.rs:69:21 | LL | let mut value: NonCopy; - | --------- variable declared here + | --------- binding declared here but left uninitialized LL | loop { LL | let _used = value; | ^^^^^ `value` used here but it isn't initialized diff --git a/src/test/ui/moves/move-into-dead-array-1.stderr b/src/test/ui/moves/move-into-dead-array-1.stderr index b5478196ef668..344a6bbf0c92c 100644 --- a/src/test/ui/moves/move-into-dead-array-1.stderr +++ b/src/test/ui/moves/move-into-dead-array-1.stderr @@ -1,8 +1,8 @@ -error[E0381]: binding `a` isn't initialized +error[E0381]: used binding `a` isn't initialized --> $DIR/move-into-dead-array-1.rs:14:5 | LL | let mut a: [D; 4]; - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | a[i] = d(); | ^^^^ `a` used here but it isn't initialized diff --git a/src/test/ui/moves/move-of-addr-of-mut.stderr b/src/test/ui/moves/move-of-addr-of-mut.stderr index a145b6223c187..e75f2b1c0894c 100644 --- a/src/test/ui/moves/move-of-addr-of-mut.stderr +++ b/src/test/ui/moves/move-of-addr-of-mut.stderr @@ -1,10 +1,10 @@ -error[E0381]: binding `x` isn't initialized +error[E0381]: used binding `x` isn't initialized --> $DIR/move-of-addr-of-mut.rs:8:5 | LL | let mut x: S; - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | std::ptr::addr_of_mut!(x); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ `x` borrowed here but it isn't initialized + | ^^^^^^^^^^^^^^^^^^^^^^^^^ `x` used here but it isn't initialized | = note: this error originates in the macro `std::ptr::addr_of_mut` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr b/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr index 71029065db1cf..f56b6294c2093 100644 --- a/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr +++ b/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr @@ -1,16 +1,16 @@ -error[E0381]: binding `d` isn't initialized +error[E0381]: assigned binding `d` isn't initialized --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:28:5 | LL | let d: D; - | - variable declared here + | - binding declared here but left uninitialized LL | d.x = 10; | ^^^^^^^^ `d` assigned here but it isn't initialized -error[E0381]: binding `d` isn't initialized +error[E0381]: assigned binding `d` isn't initialized --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:33:5 | LL | let mut d: D; - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | d.x = 10; | ^^^^^^^^ `d` assigned here but it isn't initialized @@ -24,25 +24,25 @@ LL | drop(d); LL | d.x = 10; | ^^^^^^^^ value assigned here after move -error[E0381]: binding `d.s` isn't fully initialized +error[E0381]: partially assigned binding `d.s` isn't fully initialized --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:45:5 | LL | let d: D; - | - variable declared here + | - binding declared here but left uninitialized LL | d.s.y = 20; | ^^^^^^^^^^ `d.s` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: binding `d.s` isn't fully initialized +error[E0381]: partially assigned binding `d.s` isn't fully initialized --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:50:5 | LL | let mut d: D; - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | d.s.y = 20; | ^^^^^^^^^^ `d.s` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error[E0382]: assign to part of moved value: `d` --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:56:5 diff --git a/src/test/ui/nll/issue-21232-partial-init-and-use.stderr b/src/test/ui/nll/issue-21232-partial-init-and-use.stderr index df60868d840c0..2f5883b156300 100644 --- a/src/test/ui/nll/issue-21232-partial-init-and-use.stderr +++ b/src/test/ui/nll/issue-21232-partial-init-and-use.stderr @@ -1,22 +1,22 @@ -error[E0381]: binding `s` isn't fully initialized +error[E0381]: partially assigned binding `s` isn't fully initialized --> $DIR/issue-21232-partial-init-and-use.rs:97:5 | LL | let s: S; - | - variable declared here + | - binding declared here but left uninitialized LL | s.x = 10; s.y = Box::new(20); | ^^^^^^^^ `s` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: binding `t` isn't fully initialized +error[E0381]: partially assigned binding `t` isn't fully initialized --> $DIR/issue-21232-partial-init-and-use.rs:103:5 | LL | let t: T; - | - variable declared here + | - binding declared here but left uninitialized LL | t.0 = 10; t.1 = Box::new(20); | ^^^^^^^^ `t` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error[E0382]: assign to part of moved value: `s` --> $DIR/issue-21232-partial-init-and-use.rs:109:5 @@ -38,25 +38,25 @@ LL | let mut t: T = (0, Box::new(0)); drop(t); LL | t.0 = 10; t.1 = Box::new(20); | ^^^^^^^^ value partially assigned here after move -error[E0381]: binding `s` isn't fully initialized +error[E0381]: partially assigned binding `s` isn't fully initialized --> $DIR/issue-21232-partial-init-and-use.rs:123:5 | LL | let s: S; - | - variable declared here + | - binding declared here but left uninitialized LL | s.x = 10; | ^^^^^^^^ `s` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: binding `t` isn't fully initialized +error[E0381]: partially assigned binding `t` isn't fully initialized --> $DIR/issue-21232-partial-init-and-use.rs:129:5 | LL | let t: T; - | - variable declared here + | - binding declared here but left uninitialized LL | t.0 = 10; | ^^^^^^^^ `t` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error[E0382]: assign to part of moved value: `s` --> $DIR/issue-21232-partial-init-and-use.rs:135:5 @@ -78,45 +78,45 @@ LL | let mut t: T = (0, Box::new(0)); drop(t); LL | t.0 = 10; | ^^^^^^^^ value partially assigned here after move -error[E0381]: binding `s` isn't fully initialized +error[E0381]: partially assigned binding `s` isn't fully initialized --> $DIR/issue-21232-partial-init-and-use.rs:149:5 | LL | let s: S; - | - variable declared here + | - binding declared here but left uninitialized LL | s.x = 10; | ^^^^^^^^ `s` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: binding `t` isn't fully initialized +error[E0381]: partially assigned binding `t` isn't fully initialized --> $DIR/issue-21232-partial-init-and-use.rs:155:5 | LL | let t: Tvoid; - | - variable declared here + | - binding declared here but left uninitialized LL | t.0 = 10; | ^^^^^^^^ `t` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: binding `q.r.f` isn't fully initialized +error[E0381]: partially assigned binding `q.r.f` isn't fully initialized --> $DIR/issue-21232-partial-init-and-use.rs:170:5 | LL | let q: Q>; - | - variable declared here + | - binding declared here but left uninitialized LL | q.r.f.x = 10; q.r.f.y = Box::new(20); | ^^^^^^^^^^^^ `q.r.f` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: binding `q.r.f` isn't fully initialized +error[E0381]: partially assigned binding `q.r.f` isn't fully initialized --> $DIR/issue-21232-partial-init-and-use.rs:176:5 | LL | let q: Q; - | - variable declared here + | - binding declared here but left uninitialized LL | q.r.f.0 = 10; q.r.f.1 = Box::new(20); | ^^^^^^^^^^^^ `q.r.f` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error[E0382]: assign to part of moved value: `q.r` --> $DIR/issue-21232-partial-init-and-use.rs:182:5 @@ -138,25 +138,25 @@ LL | q.r.f.0 = 10; q.r.f.1 = Box::new(20); | = note: move occurs because `q.r` has type `R<(u32, Box)>`, which does not implement the `Copy` trait -error[E0381]: binding `q.r.f` isn't fully initialized +error[E0381]: partially assigned binding `q.r.f` isn't fully initialized --> $DIR/issue-21232-partial-init-and-use.rs:196:5 | LL | let q: Q>; - | - variable declared here + | - binding declared here but left uninitialized LL | q.r.f.x = 10; | ^^^^^^^^^^^^ `q.r.f` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: binding `q.r.f` isn't fully initialized +error[E0381]: partially assigned binding `q.r.f` isn't fully initialized --> $DIR/issue-21232-partial-init-and-use.rs:202:5 | LL | let q: Q; - | - variable declared here + | - binding declared here but left uninitialized LL | q.r.f.0 = 10; | ^^^^^^^^^^^^ `q.r.f` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error[E0382]: assign to part of moved value: `q.r` --> $DIR/issue-21232-partial-init-and-use.rs:208:5 @@ -178,25 +178,25 @@ LL | q.r.f.0 = 10; | = note: move occurs because `q.r` has type `R<(u32, Box)>`, which does not implement the `Copy` trait -error[E0381]: binding `q.r.f` isn't fully initialized +error[E0381]: partially assigned binding `q.r.f` isn't fully initialized --> $DIR/issue-21232-partial-init-and-use.rs:222:5 | LL | let mut q: Q>; - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | q.r.f.x = 10; | ^^^^^^^^^^^^ `q.r.f` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: binding `q.r.f` isn't fully initialized +error[E0381]: partially assigned binding `q.r.f` isn't fully initialized --> $DIR/issue-21232-partial-init-and-use.rs:228:5 | LL | let mut q: Q; - | ----- variable declared here + | ----- binding declared here but left uninitialized LL | q.r.f.0 = 10; | ^^^^^^^^^^^^ `q.r.f` partially assigned here but it isn't fully initialized | - = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate, or use `std::mem::MaybeUninit` + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error[E0382]: assign to part of moved value: `c` --> $DIR/issue-21232-partial-init-and-use.rs:245:13 diff --git a/src/test/ui/nll/match-cfg-fake-edges.stderr b/src/test/ui/nll/match-cfg-fake-edges.stderr index 43950433e621d..39933db364803 100644 --- a/src/test/ui/nll/match-cfg-fake-edges.stderr +++ b/src/test/ui/nll/match-cfg-fake-edges.stderr @@ -1,11 +1,9 @@ -error[E0381]: binding `x` isn't initialized in all conditions +error[E0381]: used binding `x` isn't initialized in all conditions --> $DIR/match-cfg-fake-edges.rs:21:13 | LL | let x; - | - variable declared here + | - binding declared here but left uninitialized ... -LL | _ if { - | - `x` is uninitialized if this pattern is matched LL | x; | ^ `x` used here but it isn't initialized in all conditions diff --git a/src/test/ui/nll/match-on-borrowed.stderr b/src/test/ui/nll/match-on-borrowed.stderr index 0480aaa99c274..664f36f695cf3 100644 --- a/src/test/ui/nll/match-on-borrowed.stderr +++ b/src/test/ui/nll/match-on-borrowed.stderr @@ -33,11 +33,11 @@ LL | match t { LL | x; | - borrow later used here -error[E0381]: binding `n` isn't initialized +error[E0381]: used binding `n` isn't initialized --> $DIR/match-on-borrowed.rs:93:11 | LL | let n: Never; - | - variable declared here + | - binding declared here but left uninitialized LL | match n {} | ^ `n` used here but it isn't initialized diff --git a/src/test/ui/rfc-2497-if-let-chains/chains-without-let.stderr b/src/test/ui/rfc-2497-if-let-chains/chains-without-let.stderr index 1fb643b98aebe..a3d8c608f4b8b 100644 --- a/src/test/ui/rfc-2497-if-let-chains/chains-without-let.stderr +++ b/src/test/ui/rfc-2497-if-let-chains/chains-without-let.stderr @@ -1,28 +1,28 @@ -error[E0381]: binding `z` isn't initialized in all conditions +error[E0381]: used binding `z` isn't initialized in all conditions --> $DIR/chains-without-let.rs:3:34 | LL | let z; - | - variable declared here + | - binding declared here but left uninitialized LL | if true && { z = 3; true} && z == 3 {} | ----- ^ `z` used here but it isn't initialized in all conditions | | | binding initialized here in some conditions -error[E0381]: binding `z` isn't initialized in all conditions +error[E0381]: used binding `z` isn't initialized in all conditions --> $DIR/chains-without-let.rs:9:31 | LL | let z; - | - variable declared here + | - binding declared here but left uninitialized LL | true && { z = 3; true} && z == 3; | ----- ^ `z` used here but it isn't initialized in all conditions | | | binding initialized here in some conditions -error[E0381]: binding `z` isn't initialized in all conditions +error[E0381]: used binding `z` isn't initialized in all conditions --> $DIR/chains-without-let.rs:15:36 | LL | let z; - | - variable declared here + | - binding declared here but left uninitialized LL | if false || { z = 3; false} || z == 3 {} | ----- ^ `z` used here but it isn't initialized in all conditions | | diff --git a/src/test/ui/try-block/try-block-opt-init.stderr b/src/test/ui/try-block/try-block-opt-init.stderr index 17349f9c9f35a..72e732599c00e 100644 --- a/src/test/ui/try-block/try-block-opt-init.stderr +++ b/src/test/ui/try-block/try-block-opt-init.stderr @@ -1,14 +1,14 @@ -error[E0381]: binding `cfg_res` isn't initialized in all conditions +error[E0381]: used binding `cfg_res` isn't initialized in all conditions --> $DIR/try-block-opt-init.rs:15:5 | LL | let cfg_res; - | ------- variable declared here + | ------- binding declared here but left uninitialized ... LL | cfg_res = 5; | ----------- binding initialized here in some conditions ... LL | assert_eq!(cfg_res, 5); - | ^^^^^^^^^^^^^^^^^^^^^^ `cfg_res` borrowed here but it isn't initialized in all conditions + | ^^^^^^^^^^^^^^^^^^^^^^ `cfg_res` used here but it isn't initialized in all conditions | = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/uninhabited/privately-uninhabited-mir-call.stderr b/src/test/ui/uninhabited/privately-uninhabited-mir-call.stderr index 61e6295fa3f2c..95c209f47c92a 100644 --- a/src/test/ui/uninhabited/privately-uninhabited-mir-call.stderr +++ b/src/test/ui/uninhabited/privately-uninhabited-mir-call.stderr @@ -1,8 +1,8 @@ -error[E0381]: binding `y` isn't initialized +error[E0381]: used binding `y` isn't initialized --> $DIR/privately-uninhabited-mir-call.rs:28:5 | LL | let y: &mut u32; - | - variable declared here + | - binding declared here but left uninitialized ... LL | *y = 2; | ^^^^^^ `y` used here but it isn't initialized From 328522e3cdc3c485cd022edf537c13866b74e89f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 22 Jun 2022 11:04:36 -0700 Subject: [PATCH 07/20] Review comments: wording --- .../src/diagnostics/conflict_errors.rs | 69 +++++++++++-------- .../no-non-guaranteed-initialization.stderr | 10 +-- src/test/ui/borrowck/borrowck-and-init.stderr | 4 +- .../ui/borrowck/borrowck-if-no-else.stderr | 9 +-- .../ui/borrowck/borrowck-if-with-else.stderr | 6 +- src/test/ui/borrowck/borrowck-or-init.stderr | 4 +- .../ui/borrowck/borrowck-while-break.stderr | 6 +- src/test/ui/borrowck/borrowck-while.stderr | 6 +- src/test/ui/nll/match-cfg-fake-edges.stderr | 4 +- .../chains-without-let.stderr | 12 ++-- .../ui/try-block/try-block-opt-init.stderr | 4 +- 11 files changed, 74 insertions(+), 60 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index daeaac9415def..54dff1b6c6b14 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -329,7 +329,9 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { for init_idx in inits { let init = &self.move_data.inits[*init_idx]; let span = init.span(&self.body); - spans.push(span); + if !span.is_dummy() { + spans.push(span); + } } let (binding, name, desc) = @@ -337,24 +339,26 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { Some(name) => (format!("`{name}`"), format!("`{name}`"), format!("`{name}` ")), None => ("value".to_string(), "the variable".to_string(), String::new()), }; - let initialized = if let InitializationRequiringAction::PartialAssignment = desired_action { - // The same error is emitted for bindings that are *sometimes* initialized and the ones - // that are *partially* initialized by assigning to a field of an uninitialized - // binding. We differentiate between them for more accurate wording here. - "fully initialized" - } else if spans.iter().filter(|i| !i.contains(span)).count() == 0 { - // We filter above to avoid misleading wording in cases like: - // ``` - // let x; - // x += 1; - // ``` - "initialized" - } else { - "initialized in all conditions" - }; + let isnt_initialized = + if let InitializationRequiringAction::PartialAssignment = desired_action { + // The same error is emitted for bindings that are *sometimes* initialized and the ones + // that are *partially* initialized by assigning to a field of an uninitialized + // binding. We differentiate between them for more accurate wording here. + "isn't fully initialized" + } else if spans.iter().filter(|i| !i.contains(span)).count() == 0 { + // We filter above to avoid misleading wording in cases like the following, where `x` + // has an `init`, but it is in the same place we're looking at: + // ``` + // let x; + // x += 1; + // ``` + "isn't initialized" + } else { + "is possibly-uninitialized" + }; let used = desired_action.as_general_verb_in_past_tense(); let mut err = - struct_span_err!(self, span, E0381, "{used} binding {desc}isn't {initialized}"); + struct_span_err!(self, span, E0381, "{used} binding {desc}{isnt_initialized}"); use_spans.var_span_label_path_only( &mut err, format!("{} occurs due to use{}", desired_action.as_noun(), use_spans.describe()), @@ -366,7 +370,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { default value and mutate it, or use `std::mem::MaybeUninit`", ); } - err.span_label(span, format!("{binding} {used} here but it isn't {initialized}")); + err.span_label(span, format!("{binding} {used} here but it {isnt_initialized}")); // We use the statements were the binding was initialized, and inspect the HIR to look // for the branching codepaths that aren't covered, to point at them. @@ -2561,13 +2565,16 @@ impl<'b, 'v> Visitor<'v> for ConditionVisitor<'b> { v.visit_expr(body); if v.1 { self.errors.push(( - ex.span.to(cond.span), + cond.span, format!( - "this `if` expression might be missing an `else` arm that initializes \ - {}", + "if this `if` condition is `false`, {} is not initialized", self.name, ), )); + self.errors.push(( + ex.span.shrink_to_hi(), + format!("an `else` arm might be missing here, initializing {}", self.name), + )); } } hir::ExprKind::If(cond, body, Some(other)) => { @@ -2584,8 +2591,8 @@ impl<'b, 'v> Visitor<'v> for ConditionVisitor<'b> { self.errors.push(( cond.span, format!( - "{} is uninitialized if this condition isn't met and the \ - `while` loop runs 0 times", + "if this condition isn't met and the `while` loop runs 0 \ + times, {} is not initialized", self.name ), )); @@ -2593,7 +2600,8 @@ impl<'b, 'v> Visitor<'v> for ConditionVisitor<'b> { self.errors.push(( body.span.shrink_to_hi().until(other.span), format!( - "{} is uninitialized if this `else` arm is executed", + "if the `if` condition is `false` and this `else` arm is \ + executed, {} is not initialized", self.name ), )); @@ -2602,7 +2610,10 @@ impl<'b, 'v> Visitor<'v> for ConditionVisitor<'b> { (false, true) => { self.errors.push(( cond.span, - format!("{} is uninitialized if this condition is met", self.name), + format!( + "if this condition is `true`, {} is not initialized", + self.name + ), )); } } @@ -2625,7 +2636,7 @@ impl<'b, 'v> Visitor<'v> for ConditionVisitor<'b> { self.errors.push(( e.span, format!( - "{} is uninitialized if the `for` loop runs 0 times", + "if the `for` loop runs 0 times, {} is not initialized ", self.name ), )); @@ -2633,8 +2644,8 @@ impl<'b, 'v> Visitor<'v> for ConditionVisitor<'b> { self.errors.push(( arm.pat.span.to(guard.body().span), format!( - "{} is uninitialized if this pattern and condition are \ - matched", + "if this pattern and condition are matched, {} is not \ + initialized", self.name ), )); @@ -2642,7 +2653,7 @@ impl<'b, 'v> Visitor<'v> for ConditionVisitor<'b> { self.errors.push(( arm.pat.span, format!( - "{} is uninitialized if this pattern is matched", + "if this pattern is matched, {} is not initialized", self.name ), )); diff --git a/src/test/ui/async-await/no-non-guaranteed-initialization.stderr b/src/test/ui/async-await/no-non-guaranteed-initialization.stderr index b23e2da0e0920..12c15bf56ce22 100644 --- a/src/test/ui/async-await/no-non-guaranteed-initialization.stderr +++ b/src/test/ui/async-await/no-non-guaranteed-initialization.stderr @@ -1,13 +1,15 @@ -error[E0381]: used binding `y` isn't initialized in all conditions +error[E0381]: used binding `y` is possibly-uninitialized --> $DIR/no-non-guaranteed-initialization.rs:9:5 | LL | let y; | - binding declared here but left uninitialized LL | if x > 5 { - | ----- this `if` expression might be missing an `else` arm that initializes `y` -... + | ----- if this `if` condition is `false`, `y` is not initialized +LL | y = echo(10).await; +LL | } + | - an `else` arm might be missing here, initializing `y` LL | y - | ^ `y` used here but it isn't initialized in all conditions + | ^ `y` used here but it is possibly-uninitialized error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-and-init.stderr b/src/test/ui/borrowck/borrowck-and-init.stderr index a78ac1e593a05..7f3d27d6091d8 100644 --- a/src/test/ui/borrowck/borrowck-and-init.stderr +++ b/src/test/ui/borrowck/borrowck-and-init.stderr @@ -1,4 +1,4 @@ -error[E0381]: used binding `i` isn't initialized in all conditions +error[E0381]: used binding `i` is possibly-uninitialized --> $DIR/borrowck-and-init.rs:5:20 | LL | let i: isize; @@ -7,7 +7,7 @@ LL | LL | println!("{}", false && { i = 5; true }); | ----- binding initialized here in some conditions LL | println!("{}", i); - | ^ `i` used here but it isn't initialized in all conditions + | ^ `i` used here but it is possibly-uninitialized | = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/borrowck/borrowck-if-no-else.stderr b/src/test/ui/borrowck/borrowck-if-no-else.stderr index 134e7d5df4b09..9eafc2c2a86e6 100644 --- a/src/test/ui/borrowck/borrowck-if-no-else.stderr +++ b/src/test/ui/borrowck/borrowck-if-no-else.stderr @@ -1,12 +1,13 @@ -error[E0381]: used binding `x` isn't initialized in all conditions +error[E0381]: used binding `x` is possibly-uninitialized --> $DIR/borrowck-if-no-else.rs:5:9 | LL | let x: isize; if 1 > 2 { x = 10; } - | - ----- this `if` expression might be missing an `else` arm that initializes `x` - | | + | - ----- - an `else` arm might be missing here, initializing `x` + | | | + | | if this `if` condition is `false`, `x` is not initialized | binding declared here but left uninitialized LL | foo(x); - | ^ `x` used here but it isn't initialized in all conditions + | ^ `x` used here but it is possibly-uninitialized error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-if-with-else.stderr b/src/test/ui/borrowck/borrowck-if-with-else.stderr index f4b0c39307452..3f0fe291ca250 100644 --- a/src/test/ui/borrowck/borrowck-if-with-else.stderr +++ b/src/test/ui/borrowck/borrowck-if-with-else.stderr @@ -1,13 +1,13 @@ -error[E0381]: used binding `x` isn't initialized in all conditions +error[E0381]: used binding `x` is possibly-uninitialized --> $DIR/borrowck-if-with-else.rs:10:9 | LL | let x: isize; | - binding declared here but left uninitialized LL | if 1 > 2 { - | ----- `x` is uninitialized if this condition is met + | ----- if this condition is `true`, `x` is not initialized ... LL | foo(x); - | ^ `x` used here but it isn't initialized in all conditions + | ^ `x` used here but it is possibly-uninitialized error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-or-init.stderr b/src/test/ui/borrowck/borrowck-or-init.stderr index 633c4017d16ac..0bc24f1b6932f 100644 --- a/src/test/ui/borrowck/borrowck-or-init.stderr +++ b/src/test/ui/borrowck/borrowck-or-init.stderr @@ -1,4 +1,4 @@ -error[E0381]: used binding `i` isn't initialized in all conditions +error[E0381]: used binding `i` is possibly-uninitialized --> $DIR/borrowck-or-init.rs:5:20 | LL | let i: isize; @@ -7,7 +7,7 @@ LL | LL | println!("{}", false || { i = 5; true }); | ----- binding initialized here in some conditions LL | println!("{}", i); - | ^ `i` used here but it isn't initialized in all conditions + | ^ `i` used here but it is possibly-uninitialized | = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/borrowck/borrowck-while-break.stderr b/src/test/ui/borrowck/borrowck-while-break.stderr index ab7d50b834a4e..44674febf4973 100644 --- a/src/test/ui/borrowck/borrowck-while-break.stderr +++ b/src/test/ui/borrowck/borrowck-while-break.stderr @@ -1,13 +1,13 @@ -error[E0381]: used binding `v` isn't initialized in all conditions +error[E0381]: used binding `v` is possibly-uninitialized --> $DIR/borrowck-while-break.rs:7:20 | LL | let v; | - binding declared here but left uninitialized LL | while cond { - | ---- `v` is uninitialized if this condition isn't met and the `while` loop runs 0 times + | ---- if this condition isn't met and the `while` loop runs 0 times, `v` is not initialized ... LL | println!("{}", v); - | ^ `v` used here but it isn't initialized in all conditions + | ^ `v` used here but it is possibly-uninitialized | = note: this error originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) diff --git a/src/test/ui/borrowck/borrowck-while.stderr b/src/test/ui/borrowck/borrowck-while.stderr index 5bb86b11ba503..c45235990c383 100644 --- a/src/test/ui/borrowck/borrowck-while.stderr +++ b/src/test/ui/borrowck/borrowck-while.stderr @@ -1,12 +1,12 @@ -error[E0381]: used binding `x` isn't initialized in all conditions +error[E0381]: used binding `x` is possibly-uninitialized --> $DIR/borrowck-while.rs:4:12 | LL | let mut x: isize; | ----- binding declared here but left uninitialized LL | while 1 == 1 { x = 10; } - | ------ `x` is uninitialized if this condition isn't met and the `while` loop runs 0 times + | ------ if this condition isn't met and the `while` loop runs 0 times, `x` is not initialized LL | return x; - | ^ `x` used here but it isn't initialized in all conditions + | ^ `x` used here but it is possibly-uninitialized error: aborting due to previous error diff --git a/src/test/ui/nll/match-cfg-fake-edges.stderr b/src/test/ui/nll/match-cfg-fake-edges.stderr index 39933db364803..b7529389f0276 100644 --- a/src/test/ui/nll/match-cfg-fake-edges.stderr +++ b/src/test/ui/nll/match-cfg-fake-edges.stderr @@ -1,11 +1,11 @@ -error[E0381]: used binding `x` isn't initialized in all conditions +error[E0381]: used binding `x` is possibly-uninitialized --> $DIR/match-cfg-fake-edges.rs:21:13 | LL | let x; | - binding declared here but left uninitialized ... LL | x; - | ^ `x` used here but it isn't initialized in all conditions + | ^ `x` used here but it is possibly-uninitialized error[E0382]: use of moved value: `x` --> $DIR/match-cfg-fake-edges.rs:35:13 diff --git a/src/test/ui/rfc-2497-if-let-chains/chains-without-let.stderr b/src/test/ui/rfc-2497-if-let-chains/chains-without-let.stderr index a3d8c608f4b8b..30d5a6779fcd7 100644 --- a/src/test/ui/rfc-2497-if-let-chains/chains-without-let.stderr +++ b/src/test/ui/rfc-2497-if-let-chains/chains-without-let.stderr @@ -1,30 +1,30 @@ -error[E0381]: used binding `z` isn't initialized in all conditions +error[E0381]: used binding `z` is possibly-uninitialized --> $DIR/chains-without-let.rs:3:34 | LL | let z; | - binding declared here but left uninitialized LL | if true && { z = 3; true} && z == 3 {} - | ----- ^ `z` used here but it isn't initialized in all conditions + | ----- ^ `z` used here but it is possibly-uninitialized | | | binding initialized here in some conditions -error[E0381]: used binding `z` isn't initialized in all conditions +error[E0381]: used binding `z` is possibly-uninitialized --> $DIR/chains-without-let.rs:9:31 | LL | let z; | - binding declared here but left uninitialized LL | true && { z = 3; true} && z == 3; - | ----- ^ `z` used here but it isn't initialized in all conditions + | ----- ^ `z` used here but it is possibly-uninitialized | | | binding initialized here in some conditions -error[E0381]: used binding `z` isn't initialized in all conditions +error[E0381]: used binding `z` is possibly-uninitialized --> $DIR/chains-without-let.rs:15:36 | LL | let z; | - binding declared here but left uninitialized LL | if false || { z = 3; false} || z == 3 {} - | ----- ^ `z` used here but it isn't initialized in all conditions + | ----- ^ `z` used here but it is possibly-uninitialized | | | binding initialized here in some conditions diff --git a/src/test/ui/try-block/try-block-opt-init.stderr b/src/test/ui/try-block/try-block-opt-init.stderr index 72e732599c00e..c397385017ff4 100644 --- a/src/test/ui/try-block/try-block-opt-init.stderr +++ b/src/test/ui/try-block/try-block-opt-init.stderr @@ -1,4 +1,4 @@ -error[E0381]: used binding `cfg_res` isn't initialized in all conditions +error[E0381]: used binding `cfg_res` is possibly-uninitialized --> $DIR/try-block-opt-init.rs:15:5 | LL | let cfg_res; @@ -8,7 +8,7 @@ LL | cfg_res = 5; | ----------- binding initialized here in some conditions ... LL | assert_eq!(cfg_res, 5); - | ^^^^^^^^^^^^^^^^^^^^^^ `cfg_res` used here but it isn't initialized in all conditions + | ^^^^^^^^^^^^^^^^^^^^^^ `cfg_res` used here but it is possibly-uninitialized | = note: this error originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) From 0e69340c2a475b72b1a7261fa5aea06edd75dad7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 22 Jun 2022 11:26:08 -0700 Subject: [PATCH 08/20] Add test for `for` loop maybe initializing binding --- .../borrowck-for-loop-uninitialized-binding.rs | 7 +++++++ .../borrowck-for-loop-uninitialized-binding.stderr | 13 +++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 src/test/ui/borrowck/borrowck-for-loop-uninitialized-binding.rs create mode 100644 src/test/ui/borrowck/borrowck-for-loop-uninitialized-binding.stderr diff --git a/src/test/ui/borrowck/borrowck-for-loop-uninitialized-binding.rs b/src/test/ui/borrowck/borrowck-for-loop-uninitialized-binding.rs new file mode 100644 index 0000000000000..f619c045b250f --- /dev/null +++ b/src/test/ui/borrowck/borrowck-for-loop-uninitialized-binding.rs @@ -0,0 +1,7 @@ +fn f() -> isize { + let mut x: isize; + for _ in 0..0 { x = 10; } + return x; //~ ERROR E0381 +} + +fn main() { f(); } diff --git a/src/test/ui/borrowck/borrowck-for-loop-uninitialized-binding.stderr b/src/test/ui/borrowck/borrowck-for-loop-uninitialized-binding.stderr new file mode 100644 index 0000000000000..c08c93f361726 --- /dev/null +++ b/src/test/ui/borrowck/borrowck-for-loop-uninitialized-binding.stderr @@ -0,0 +1,13 @@ +error[E0381]: used binding `x` is possibly-uninitialized + --> $DIR/borrowck-for-loop-uninitialized-binding.rs:4:12 + | +LL | let mut x: isize; + | ----- binding declared here but left uninitialized +LL | for _ in 0..0 { x = 10; } + | ---- if the `for` loop runs 0 times, `x` is not initialized +LL | return x; + | ^ `x` used here but it is possibly-uninitialized + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0381`. From 6eadf6ee6a3163288e8324ee53af11aba9f97659 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 22 Jun 2022 12:59:48 -0700 Subject: [PATCH 09/20] Avoid misleading message/label in `match-cfg-fake-edges.rs` test --- .../src/diagnostics/conflict_errors.rs | 64 ++++++++++++------- src/test/ui/nll/match-cfg-fake-edges.stderr | 7 +- 2 files changed, 46 insertions(+), 25 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 54dff1b6c6b14..7598b9a265977 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -339,23 +339,48 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { Some(name) => (format!("`{name}`"), format!("`{name}`"), format!("`{name}` ")), None => ("value".to_string(), "the variable".to_string(), String::new()), }; + + // We use the statements were the binding was initialized, and inspect the HIR to look + // for the branching codepaths that aren't covered, to point at them. + let hir_id = self.mir_hir_id(); + let map = self.infcx.tcx.hir(); + let body_id = map.body_owned_by(hir_id); + let body = map.body(body_id); + + let mut visitor = ConditionVisitor { spans: &spans, name: &name, errors: vec![] }; + visitor.visit_body(&body); + let isnt_initialized = if let InitializationRequiringAction::PartialAssignment = desired_action { // The same error is emitted for bindings that are *sometimes* initialized and the ones // that are *partially* initialized by assigning to a field of an uninitialized // binding. We differentiate between them for more accurate wording here. "isn't fully initialized" - } else if spans.iter().filter(|i| !i.contains(span)).count() == 0 { - // We filter above to avoid misleading wording in cases like the following, where `x` - // has an `init`, but it is in the same place we're looking at: - // ``` - // let x; - // x += 1; - // ``` + } else if spans + .iter() + .filter(|i| { + // We filter these to avoid misleading wording in cases like the following, + // where `x` has an `init`, but it is in the same place we're looking at: + // ``` + // let x; + // x += 1; + // ``` + !i.contains(span) + // We filter these to avoid incorrect main message on `match-cfg-fake-edges.rs` + && !visitor + .errors + .iter() + .map(|(sp, _)| *sp) + .any(|sp| span < sp && !sp.contains(span)) + }) + .count() + == 0 + { "isn't initialized" } else { "is possibly-uninitialized" }; + let used = desired_action.as_general_verb_in_past_tense(); let mut err = struct_span_err!(self, span, E0381, "{used} binding {desc}{isnt_initialized}"); @@ -372,22 +397,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } err.span_label(span, format!("{binding} {used} here but it {isnt_initialized}")); - // We use the statements were the binding was initialized, and inspect the HIR to look - // for the branching codepaths that aren't covered, to point at them. - let hir_id = self.mir_hir_id(); - let map = self.infcx.tcx.hir(); - let body_id = map.body_owned_by(hir_id); - let body = map.body(body_id); - - let mut visitor = ConditionVisitor { spans: &spans, name: &name, errors: vec![] }; - visitor.visit_body(&body); - if visitor.errors.is_empty() { - for sp in &spans { - if *sp < span && !sp.overlaps(span) { - err.span_label(*sp, "binding initialized here in some conditions"); - } - } - } + let mut shown = false; for (sp, label) in visitor.errors { if sp < span && !sp.overlaps(span) { // When we have a case like `match-cfg-fake-edges.rs`, we don't want to mention @@ -404,6 +414,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { // }; // ``` err.span_label(sp, &label); + shown = true; + } + } + if !shown { + for sp in &spans { + if *sp < span && !sp.overlaps(span) { + err.span_label(*sp, "binding initialized here in some conditions"); + } } } err.span_label(decl_span, "binding declared here but left uninitialized"); diff --git a/src/test/ui/nll/match-cfg-fake-edges.stderr b/src/test/ui/nll/match-cfg-fake-edges.stderr index b7529389f0276..250aa482e5c67 100644 --- a/src/test/ui/nll/match-cfg-fake-edges.stderr +++ b/src/test/ui/nll/match-cfg-fake-edges.stderr @@ -1,11 +1,14 @@ -error[E0381]: used binding `x` is possibly-uninitialized +error[E0381]: used binding `x` isn't initialized --> $DIR/match-cfg-fake-edges.rs:21:13 | LL | let x; | - binding declared here but left uninitialized ... +LL | _ if { x = 2; true } => 1, + | ----- binding initialized here in some conditions +LL | _ if { LL | x; - | ^ `x` used here but it is possibly-uninitialized + | ^ `x` used here but it isn't initialized error[E0382]: use of moved value: `x` --> $DIR/match-cfg-fake-edges.rs:35:13 From cc4f804829ae56753acd2ef9c0f4bb741f5b3bae Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 20 Jun 2022 16:28:52 +0200 Subject: [PATCH 10/20] Move help popup into a pocket menu as well --- src/librustdoc/html/static/css/rustdoc.css | 74 ++++---- src/librustdoc/html/static/css/settings.css | 21 --- src/librustdoc/html/static/css/themes/ayu.css | 9 +- .../html/static/css/themes/dark.css | 9 +- .../html/static/css/themes/light.css | 9 +- src/librustdoc/html/static/js/main.js | 176 +++++++++++------- src/librustdoc/html/static/js/settings.js | 30 +-- src/librustdoc/html/templates/page.html | 4 +- 8 files changed, 173 insertions(+), 159 deletions(-) diff --git a/src/librustdoc/html/static/css/rustdoc.css b/src/librustdoc/html/static/css/rustdoc.css index d0229bdb5f23c..77062770c189d 100644 --- a/src/librustdoc/html/static/css/rustdoc.css +++ b/src/librustdoc/html/static/css/rustdoc.css @@ -979,42 +979,51 @@ table, font-weight: normal; } -body.blur > :not(#help) { - filter: blur(8px); - -webkit-filter: blur(8px); - opacity: .7; +.popover { + font-size: 1rem; + position: absolute; + right: 0; + z-index: 2; + display: block; + margin-top: 7px; + border-radius: 3px; + border: 1px solid; + font-size: 1rem; } -#help { - width: 100%; - height: 100vh; - position: fixed; - top: 0; - left: 0; - display: flex; - justify-content: center; - align-items: center; +/* This rule is to draw the little arrow connecting the settings menu to the gear icon. */ +.popover::before { + content: ''; + position: absolute; + right: 11px; + border: solid; + border-width: 1px 1px 0 0; + display: inline-block; + padding: 4px; + transform: rotate(-45deg); + top: -5px; } -#help > div { - flex: 0 0 auto; - box-shadow: 0 0 6px rgba(0,0,0,.2); - width: 550px; - height: auto; - border: 1px solid; + +#help-button .popover { + max-width: 600px; } -#help dt { + +#help-button .popover::before { + right: 48px; +} + +#help-button dt { float: left; clear: left; display: block; margin-right: 0.5rem; } -#help span.top, #help span.bottom { +#help-button span.top, #help-button span.bottom { text-align: center; display: block; font-size: 1.125rem; - } -#help span.top { +#help-button span.top { text-align: center; display: block; margin: 10px 0; @@ -1022,17 +1031,17 @@ body.blur > :not(#help) { padding-bottom: 4px; margin-bottom: 6px; } -#help span.bottom { +#help-button span.bottom { clear: both; border-top: 1px solid; } -#help dd { margin: 5px 35px; } -#help .infos { padding-left: 0; } -#help h1, #help h2 { margin-top: 0; } -#help > div div { +.side-by-side { + text-align: initial; +} +.side-by-side > div { width: 50%; float: left; - padding: 0 20px 20px 17px;; + padding: 0 20px 20px 17px; } .item-info .stab { @@ -1387,7 +1396,7 @@ pre.rust { #copy-path { height: 34px; } -#settings-menu > a, #help-button, #copy-path { +#settings-menu > a, #help-button > button, #copy-path { padding: 5px; width: 33px; border: 1px solid; @@ -1397,9 +1406,8 @@ pre.rust { #settings-menu { padding: 0; } -#settings-menu > a { +#settings-menu > a, #help-button > button { padding: 5px; - width: 100%; height: 100%; display: block; } @@ -1416,7 +1424,7 @@ pre.rust { animation: rotating 2s linear infinite; } -#help-button { +#help-button > button { font-family: "Fira Sans", Arial, sans-serif; text-align: center; /* Rare exception to specifying font sizes in rem. Since this is acting diff --git a/src/librustdoc/html/static/css/settings.css b/src/librustdoc/html/static/css/settings.css index 1cd8e39e03648..e531e6ce6bbde 100644 --- a/src/librustdoc/html/static/css/settings.css +++ b/src/librustdoc/html/static/css/settings.css @@ -86,27 +86,6 @@ input:checked + .slider:before { display: block; } -div#settings { - position: absolute; - right: 0; - z-index: 1; - display: block; - margin-top: 7px; - border-radius: 3px; - border: 1px solid; -} #settings .setting-line { margin: 1.2em 0.6em; } -/* This rule is to draw the little arrow connecting the settings menu to the gear icon. */ -div#settings::before { - content: ''; - position: absolute; - right: 11px; - border: solid; - border-width: 1px 1px 0 0; - display: inline-block; - padding: 4px; - transform: rotate(-45deg); - top: -5px; -} diff --git a/src/librustdoc/html/static/css/themes/ayu.css b/src/librustdoc/html/static/css/themes/ayu.css index 8e0521d9ad6a1..d27294657192c 100644 --- a/src/librustdoc/html/static/css/themes/ayu.css +++ b/src/librustdoc/html/static/css/themes/ayu.css @@ -5,7 +5,7 @@ Original by Dempfi (https://github.com/dempfi/ayu) /* General structure and fonts */ -body, #settings-menu #settings, #settings-menu #settings::before { +body, .popover, .popover::before { background-color: #0f1419; color: #c5c5c5; } @@ -567,7 +567,7 @@ kbd { box-shadow: inset 0 -1px 0 #5c6773; } -#settings-menu > a, #help-button { +#settings-menu > a, #help-button > button { border-color: #5c6773; background-color: #0f1419; color: #fff; @@ -577,7 +577,8 @@ kbd { filter: invert(100); } -#settings-menu #settings, #settings-menu #settings::before { +.popover, .popover::before, +#help-button span.top, #help-button span.bottom { border-color: #5c6773; } @@ -592,7 +593,7 @@ kbd { } #settings-menu > a:hover, #settings-menu > a:focus, -#help-button:hover, #help-button:focus { +#help-button > button:hover, #help-button > button:focus { border-color: #e0e0e0; } diff --git a/src/librustdoc/html/static/css/themes/dark.css b/src/librustdoc/html/static/css/themes/dark.css index 071ad006ed350..48079ea2f3041 100644 --- a/src/librustdoc/html/static/css/themes/dark.css +++ b/src/librustdoc/html/static/css/themes/dark.css @@ -1,4 +1,4 @@ -body, #settings-menu #settings, #settings-menu #settings::before { +body, .popover, .popover::before { background-color: #353535; color: #ddd; } @@ -442,18 +442,19 @@ kbd { box-shadow: inset 0 -1px 0 #c6cbd1; } -#settings-menu > a, #help-button { +#settings-menu > a, #help-button > button { border-color: #e0e0e0; background: #f0f0f0; color: #000; } #settings-menu > a:hover, #settings-menu > a:focus, -#help-button:hover, #help-button:focus { +#help-button > button:hover, #help-button > button:focus { border-color: #ffb900; } -#settings-menu #settings, #settings-menu #settings::before { +.popover, .popover::before, +#help-button span.top, #help-button span.bottom { border-color: #d2d2d2; } diff --git a/src/librustdoc/html/static/css/themes/light.css b/src/librustdoc/html/static/css/themes/light.css index 5c3789bf4630a..f4016be967963 100644 --- a/src/librustdoc/html/static/css/themes/light.css +++ b/src/librustdoc/html/static/css/themes/light.css @@ -1,6 +1,6 @@ /* General structure and fonts */ -body, #settings-menu #settings, #settings-menu #settings::before { +body, .popover, .popover::before { background-color: white; color: black; } @@ -427,17 +427,18 @@ kbd { box-shadow: inset 0 -1px 0 #c6cbd1; } -#settings-menu > a, #help-button { +#settings-menu > a, #help-button > button { border-color: #e0e0e0; background-color: #fff; } #settings-menu > a:hover, #settings-menu > a:focus, -#help-button:hover, #help-button:focus { +#help-button > button:hover, #help-button > button:focus { border-color: #717171; } -#settings-menu #settings, #settings-menu #settings::before { +.popover, .popover::before, +#help-button span.top, #help-button span.bottom { border-color: #DDDDDD; } diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index b320db9104612..1ea645d3e6594 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -63,6 +63,24 @@ function showMain() { removeClass(document.getElementById(MAIN_ID), "hidden"); } +function elemIsInParent(elem, parent) { + while (elem && elem !== document.body) { + if (elem === parent) { + return true; + } + elem = elem.parentElement; + } + return false; +} + +function blurHandler(event, parentElem, hideCallback) { + if (!elemIsInParent(document.activeElement, parentElem) && + !elemIsInParent(event.relatedTarget, parentElem) + ) { + hideCallback(); + } +} + (function() { window.rootPath = getVar("root-path"); window.currentCrate = getVar("current-crate"); @@ -104,11 +122,16 @@ const MAIN_ID = "main-content"; const SETTINGS_BUTTON_ID = "settings-menu"; const ALTERNATIVE_DISPLAY_ID = "alternative-display"; const NOT_DISPLAYED_ID = "not-displayed"; +const HELP_BUTTON_ID = "help-button"; function getSettingsButton() { return document.getElementById(SETTINGS_BUTTON_ID); } +function getHelpButton() { + return document.getElementById(HELP_BUTTON_ID); +} + // Returns the current URL without any query parameter or hash. function getNakedUrl() { return window.location.href.split("?")[0].split("#")[0]; @@ -381,55 +404,17 @@ function loadCss(cssFileName) { openParentDetails(document.getElementById(id)); } - function getHelpElement(build) { - if (build) { - buildHelperPopup(); - } - return document.getElementById("help"); - } - - /** - * Show the help popup. - * - * @param {boolean} display - Whether to show or hide the popup - * @param {Event} ev - The event that triggered this call - * @param {Element} [help] - The help element if it already exists - */ - function displayHelp(display, ev, help) { - if (display) { - help = help ? help : getHelpElement(true); - if (hasClass(help, "hidden")) { - ev.preventDefault(); - removeClass(help, "hidden"); - addClass(document.body, "blur"); - } - } else { - // No need to build the help popup if we want to hide it in case it hasn't been - // built yet... - help = help ? help : getHelpElement(false); - if (help && !hasClass(help, "hidden")) { - ev.preventDefault(); - addClass(help, "hidden"); - removeClass(document.body, "blur"); - } - } - } - function handleEscape(ev) { searchState.clearInputTimeout(); - const help = getHelpElement(false); - if (help && !hasClass(help, "hidden")) { - displayHelp(false, ev, help); - } else { - switchDisplayedElement(null); - if (browserSupportsHistoryApi()) { - history.replaceState(null, window.currentCrate + " - Rust", - getNakedUrl() + window.location.hash); - } - ev.preventDefault(); + switchDisplayedElement(null); + if (browserSupportsHistoryApi()) { + history.replaceState(null, window.currentCrate + " - Rust", + getNakedUrl() + window.location.hash); } + ev.preventDefault(); searchState.defocus(); window.hideSettings(); + hideHelp(); } const disableShortcuts = getSettingValue("disable-shortcuts") === "true"; @@ -453,7 +438,6 @@ function loadCss(cssFileName) { case "s": case "S": - displayHelp(false, ev); ev.preventDefault(); searchState.focus(); break; @@ -465,7 +449,7 @@ function loadCss(cssFileName) { break; case "?": - displayHelp(true, ev); + showHelp(); break; default: @@ -796,9 +780,6 @@ function loadCss(cssFileName) { elem.addEventListener("click", f); } } - handleClick("help-button", ev => { - displayHelp(true, ev); - }); handleClick(MAIN_ID, () => { hideSidebar(); }); @@ -842,24 +823,16 @@ function loadCss(cssFileName) { }); } - let buildHelperPopup = () => { - const popup = document.createElement("aside"); - addClass(popup, "hidden"); - popup.id = "help"; - - popup.addEventListener("click", ev => { - if (ev.target === popup) { - // Clicked the blurred zone outside the help popup; dismiss help. - displayHelp(false, ev); - } - }); + function helpBlurHandler(event) { + blurHandler(event, getHelpButton(), hideHelp); + } + function buildHelpMenu() { const book_info = document.createElement("span"); book_info.className = "top"; book_info.innerHTML = "You can find more information in \ the rustdoc book."; - const container = document.createElement("div"); const shortcuts = [ ["?", "Show this help dialog"], ["S", "Focus the search field"], @@ -895,23 +868,86 @@ function loadCss(cssFileName) { addClass(div_infos, "infos"); div_infos.innerHTML = "

Search Tricks

" + infos; - container.appendChild(book_info); - container.appendChild(div_shortcuts); - container.appendChild(div_infos); - const rustdoc_version = document.createElement("span"); rustdoc_version.className = "bottom"; const rustdoc_version_code = document.createElement("code"); rustdoc_version_code.innerText = "rustdoc " + getVar("rustdoc-version"); rustdoc_version.appendChild(rustdoc_version_code); + const container = document.createElement("div"); + container.className = "popover"; + container.style.display = "none"; + + const side_by_side = document.createElement("div"); + side_by_side.className = "side-by-side"; + side_by_side.appendChild(div_shortcuts); + side_by_side.appendChild(div_infos); + + container.appendChild(book_info); + container.appendChild(side_by_side); container.appendChild(rustdoc_version); - popup.appendChild(container); - insertAfter(popup, document.querySelector("main")); - // So that it's only built once and then it'll do nothing when called! - buildHelperPopup = () => {}; - }; + const help_button = getHelpButton(); + help_button.appendChild(container); + + container.onblur = helpBlurHandler; + container.onclick = event => { + event.preventDefault(); + }; + help_button.onblur = helpBlurHandler; + help_button.children[0].onblur = helpBlurHandler; + + return container; + } + + /** + * Returns the help menu element (not the button). + * + * @param {boolean} buildNeeded - If this argument is `false`, the help menu element won't be + * built if it doesn't exist. + * + * @return {HTMLElement} + */ + function getHelpMenu(buildNeeded) { + let menu = getHelpButton().querySelector(".popover"); + if (!menu && buildNeeded) { + menu = buildHelpMenu(); + } + return menu; + } + + /** + * Show the help popup menu. + */ + function showHelp() { + const menu = getHelpMenu(true); + if (menu.style.display === "none") { + menu.style.display = ""; + } + } + + /** + * Hide the help popup menu. + */ + function hideHelp() { + const menu = getHelpMenu(false); + if (menu && menu.style.display !== "none") { + menu.style.display = "none"; + } + } + + document.querySelector(`#${HELP_BUTTON_ID} > button`).addEventListener("click", event => { + const target = event.target; + if (target.tagName !== "BUTTON" || target.parentElement.id !== HELP_BUTTON_ID) { + return; + } + const menu = getHelpMenu(true); + if (menu.style.display !== "none") { + hideHelp(); + } else { + showHelp(); + } + }); setMobileTopbar(); addSidebarItems(); diff --git a/src/librustdoc/html/static/js/settings.js b/src/librustdoc/html/static/js/settings.js index 41bf0ec895580..2445773a96542 100644 --- a/src/librustdoc/html/static/js/settings.js +++ b/src/librustdoc/html/static/js/settings.js @@ -1,6 +1,6 @@ // Local js definitions: /* global getSettingValue, getVirtualKey, updateLocalStorage, updateSystemTheme */ -/* global addClass, removeClass, onEach, onEachLazy */ +/* global addClass, removeClass, onEach, onEachLazy, blurHandler, elemIsInParent */ /* global MAIN_ID, getVar, getSettingsButton */ "use strict"; @@ -209,6 +209,7 @@ const innerHTML = `
${buildSettingsPageSections(settings)}
`; const el = document.createElement(elementKind); el.id = "settings"; + el.className = "popover"; el.innerHTML = innerHTML; if (isSettingsPage) { @@ -226,23 +227,8 @@ settingsMenu.style.display = ""; } - function elemIsInParent(elem, parent) { - while (elem && elem !== document.body) { - if (elem === parent) { - return true; - } - elem = elem.parentElement; - } - return false; - } - - function blurHandler(event) { - const settingsButton = getSettingsButton(); - if (!elemIsInParent(document.activeElement, settingsButton) && - !elemIsInParent(event.relatedTarget, settingsButton) - ) { - window.hideSettings(); - } + function settingsBlurHandler(event) { + blurHandler(event, getSettingsButton(), window.hideSettings); } if (isSettingsPage) { @@ -268,12 +254,12 @@ displaySettings(); } }; - settingsButton.onblur = blurHandler; - settingsButton.querySelector("a").onblur = blurHandler; + settingsButton.onblur = settingsBlurHandler; + settingsButton.querySelector("a").onblur = settingsBlurHandler; onEachLazy(settingsMenu.querySelectorAll("input"), el => { - el.onblur = blurHandler; + el.onblur = settingsBlurHandler; }); - settingsMenu.onblur = blurHandler; + settingsMenu.onblur = settingsBlurHandler; } // We now wait a bit for the web browser to end re-computing the DOM... diff --git a/src/librustdoc/html/templates/page.html b/src/librustdoc/html/templates/page.html index c4999e2c74fce..dfb3e4e6a2ccd 100644 --- a/src/librustdoc/html/templates/page.html +++ b/src/librustdoc/html/templates/page.html @@ -119,7 +119,9 @@

spellcheck="false" {# -#} placeholder="Click or press ‘S’ to search, ‘?’ for more options…" {# -#} type="search"> {#- -#} - {#- -#} +
{#- -#} + {#- -#} +
{#- -#}
{#- -#} Change settings Date: Mon, 20 Jun 2022 16:29:16 +0200 Subject: [PATCH 11/20] Add/update GUI tests for help pocket menu --- src/test/rustdoc-gui/escape-key.goml | 12 ----- src/test/rustdoc-gui/pocket-menu.goml | 72 +++++++++++++++++++++++++++ src/test/rustdoc-gui/shortcuts.goml | 5 +- 3 files changed, 74 insertions(+), 15 deletions(-) create mode 100644 src/test/rustdoc-gui/pocket-menu.goml diff --git a/src/test/rustdoc-gui/escape-key.goml b/src/test/rustdoc-gui/escape-key.goml index 8713bf65c8432..d083b0ae0c931 100644 --- a/src/test/rustdoc-gui/escape-key.goml +++ b/src/test/rustdoc-gui/escape-key.goml @@ -21,17 +21,6 @@ wait-for: "#alternative-display #search" assert-attribute: ("#main-content", {"class": "content hidden"}) assert-document-property: ({"URL": "index.html?search=test"}, ENDS_WITH) -// Now let's check that when the help popup is displayed and we press Escape, it doesn't -// hide the search results too. -click: "#help-button" -assert-document-property: ({"URL": "index.html?search=test"}, [ENDS_WITH]) -assert-attribute: ("#help", {"class": ""}) -press-key: "Escape" -wait-for: "#alternative-display #search" -assert-attribute: ("#help", {"class": "hidden"}) -assert-attribute: ("#main-content", {"class": "content hidden"}) -assert-document-property: ({"URL": "index.html?search=test"}, [ENDS_WITH]) - // Check that Escape hides the search results when a search result is focused. focus: ".search-input" assert: ".search-input:focus" @@ -39,7 +28,6 @@ press-key: "ArrowDown" assert-false: ".search-input:focus" assert: "#results a:focus" press-key: "Escape" -assert-attribute: ("#help", {"class": "hidden"}) wait-for: "#not-displayed #search" assert-false: "#alternative-display #search" assert-attribute: ("#main-content", {"class": "content"}) diff --git a/src/test/rustdoc-gui/pocket-menu.goml b/src/test/rustdoc-gui/pocket-menu.goml new file mode 100644 index 0000000000000..ba2986e969a35 --- /dev/null +++ b/src/test/rustdoc-gui/pocket-menu.goml @@ -0,0 +1,72 @@ +// This test ensures that the "pocket menus" are working as expected. +goto: file://|DOC_PATH|/test_docs/index.html +// First we check that the help menu doesn't exist yet. +assert-false: "#help-button .popover" +// Then we display the help menu. +click: "#help-button" +assert: "#help-button .popover" +assert-css: ("#help-button .popover", {"display": "block"}) + +// Now we click somewhere else on the page to ensure it is handling the blur event +// correctly. +click: ".sidebar" +assert-css: ("#help-button .popover", {"display": "none"}) + +// Now we will check that we cannot have two "pocket menus" displayed at the same time. +click: "#help-button" +assert-css: ("#help-button .popover", {"display": "block"}) +click: "#settings-menu" +assert-css: ("#help-button .popover", {"display": "none"}) +assert-css: ("#settings-menu .popover", {"display": "block"}) + +// Now the other way. +click: "#help-button" +assert-css: ("#help-button .popover", {"display": "block"}) +assert-css: ("#settings-menu .popover", {"display": "none"}) + +// We check the borders color now: + +// Ayu theme +local-storage: { + "rustdoc-theme": "ayu", + "rustdoc-use-system-theme": "false", +} +reload: + +click: "#help-button" +assert-css: ( + "#help-button .popover", + {"display": "block", "border-color": "rgb(92, 103, 115)"}, +) +compare-elements-css: ("#help-button .popover", "#help-button .top", ["border-color"]) +compare-elements-css: ("#help-button .popover", "#help-button .bottom", ["border-color"]) + +// Dark theme +local-storage: { + "rustdoc-theme": "dark", + "rustdoc-use-system-theme": "false", +} +reload: + +click: "#help-button" +assert-css: ( + "#help-button .popover", + {"display": "block", "border-color": "rgb(210, 210, 210)"}, +) +compare-elements-css: ("#help-button .popover", "#help-button .top", ["border-color"]) +compare-elements-css: ("#help-button .popover", "#help-button .bottom", ["border-color"]) + +// Light theme +local-storage: { + "rustdoc-theme": "light", + "rustdoc-use-system-theme": "false", +} +reload: + +click: "#help-button" +assert-css: ( + "#help-button .popover", + {"display": "block", "border-color": "rgb(221, 221, 221)"}, +) +compare-elements-css: ("#help-button .popover", "#help-button .top", ["border-color"]) +compare-elements-css: ("#help-button .popover", "#help-button .bottom", ["border-color"]) diff --git a/src/test/rustdoc-gui/shortcuts.goml b/src/test/rustdoc-gui/shortcuts.goml index 37a7c1662949d..1f20a0eaa9982 100644 --- a/src/test/rustdoc-gui/shortcuts.goml +++ b/src/test/rustdoc-gui/shortcuts.goml @@ -8,7 +8,6 @@ press-key: "Escape" assert-false: "input.search-input:focus" // We now check for the help popup. press-key: "?" -assert-css: ("#help", {"display": "flex"}) -assert-false: "#help.hidden" +assert-css: ("#help-button .popover", {"display": "block"}) press-key: "Escape" -assert-css: ("#help.hidden", {"display": "none"}) +assert-css: ("#help-button .popover", {"display": "none"}) From e4b2b41290f6b49441b5b9c8e013458bc23caeeb Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 22 Jun 2022 20:49:26 +0200 Subject: [PATCH 12/20] Merge all popover hide functions into one --- src/librustdoc/html/static/js/main.js | 33 +++++++++-------------- src/librustdoc/html/static/js/settings.js | 12 ++++----- 2 files changed, 18 insertions(+), 27 deletions(-) diff --git a/src/librustdoc/html/static/js/main.js b/src/librustdoc/html/static/js/main.js index 1ea645d3e6594..70dbfd4442540 100644 --- a/src/librustdoc/html/static/js/main.js +++ b/src/librustdoc/html/static/js/main.js @@ -137,10 +137,6 @@ function getNakedUrl() { return window.location.href.split("?")[0].split("#")[0]; } -window.hideSettings = () => { - // Does nothing by default. -}; - /** * This function inserts `newNode` after `referenceNode`. It doesn't work if `referenceNode` * doesn't have a parent node. @@ -413,8 +409,7 @@ function loadCss(cssFileName) { } ev.preventDefault(); searchState.defocus(); - window.hideSettings(); - hideHelp(); + window.hidePopoverMenus(); } const disableShortcuts = getSettingValue("disable-shortcuts") === "true"; @@ -824,7 +819,7 @@ function loadCss(cssFileName) { } function helpBlurHandler(event) { - blurHandler(event, getHelpButton(), hideHelp); + blurHandler(event, getHelpButton(), window.hidePopoverMenus); } function buildHelpMenu() { @@ -900,6 +895,15 @@ function loadCss(cssFileName) { return container; } + /** + * Hide all the popover menus. + */ + window.hidePopoverMenus = function() { + onEachLazy(document.querySelectorAll(".search-container .popover"), elem => { + elem.style.display = "none"; + }); + }; + /** * Returns the help menu element (not the button). * @@ -926,25 +930,14 @@ function loadCss(cssFileName) { } } - /** - * Hide the help popup menu. - */ - function hideHelp() { - const menu = getHelpMenu(false); - if (menu && menu.style.display !== "none") { - menu.style.display = "none"; - } - } - document.querySelector(`#${HELP_BUTTON_ID} > button`).addEventListener("click", event => { const target = event.target; if (target.tagName !== "BUTTON" || target.parentElement.id !== HELP_BUTTON_ID) { return; } const menu = getHelpMenu(true); - if (menu.style.display !== "none") { - hideHelp(); - } else { + const shouldShowHelp = menu.style.display === "none"; + if (shouldShowHelp) { showHelp(); } }); diff --git a/src/librustdoc/html/static/js/settings.js b/src/librustdoc/html/static/js/settings.js index 2445773a96542..797b931afc643 100644 --- a/src/librustdoc/html/static/js/settings.js +++ b/src/librustdoc/html/static/js/settings.js @@ -228,7 +228,7 @@ } function settingsBlurHandler(event) { - blurHandler(event, getSettingsButton(), window.hideSettings); + blurHandler(event, getSettingsButton(), window.hidePopoverMenus); } if (isSettingsPage) { @@ -240,17 +240,15 @@ // We replace the existing "onclick" callback. const settingsButton = getSettingsButton(); const settingsMenu = document.getElementById("settings"); - window.hideSettings = function() { - settingsMenu.style.display = "none"; - }; settingsButton.onclick = function(event) { if (elemIsInParent(event.target, settingsMenu)) { return; } event.preventDefault(); - if (settingsMenu.style.display !== "none") { - window.hideSettings(); - } else { + const shouldDisplaySettings = settingsMenu.style.display === "none"; + + window.hidePopoverMenus(); + if (shouldDisplaySettings) { displaySettings(); } }; From 8495c640bc8b263788422319dc3eee50fad23dbd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Wed, 22 Jun 2022 15:36:26 -0700 Subject: [PATCH 13/20] Fix label on uninit binding field assignment --- .../src/diagnostics/conflict_errors.rs | 49 ++++++++++--------- .../borrowck/borrowck-partial-reinit-4.stderr | 4 +- ...1232-partial-init-and-erroneous-use.stderr | 8 +-- 3 files changed, 31 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 7598b9a265977..73baad614c8f1 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -350,36 +350,37 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { let mut visitor = ConditionVisitor { spans: &spans, name: &name, errors: vec![] }; visitor.visit_body(&body); - let isnt_initialized = - if let InitializationRequiringAction::PartialAssignment = desired_action { - // The same error is emitted for bindings that are *sometimes* initialized and the ones - // that are *partially* initialized by assigning to a field of an uninitialized - // binding. We differentiate between them for more accurate wording here. - "isn't fully initialized" - } else if spans - .iter() - .filter(|i| { - // We filter these to avoid misleading wording in cases like the following, - // where `x` has an `init`, but it is in the same place we're looking at: - // ``` - // let x; - // x += 1; - // ``` - !i.contains(span) + let isnt_initialized = if let InitializationRequiringAction::PartialAssignment + | InitializationRequiringAction::Assignment = desired_action + { + // The same error is emitted for bindings that are *sometimes* initialized and the ones + // that are *partially* initialized by assigning to a field of an uninitialized + // binding. We differentiate between them for more accurate wording here. + "isn't fully initialized" + } else if spans + .iter() + .filter(|i| { + // We filter these to avoid misleading wording in cases like the following, + // where `x` has an `init`, but it is in the same place we're looking at: + // ``` + // let x; + // x += 1; + // ``` + !i.contains(span) // We filter these to avoid incorrect main message on `match-cfg-fake-edges.rs` && !visitor .errors .iter() .map(|(sp, _)| *sp) .any(|sp| span < sp && !sp.contains(span)) - }) - .count() - == 0 - { - "isn't initialized" - } else { - "is possibly-uninitialized" - }; + }) + .count() + == 0 + { + "isn't initialized" + } else { + "is possibly-uninitialized" + }; let used = desired_action.as_general_verb_in_past_tense(); let mut err = diff --git a/src/test/ui/borrowck/borrowck-partial-reinit-4.stderr b/src/test/ui/borrowck/borrowck-partial-reinit-4.stderr index 06351a943064b..7b5b64ff8cd23 100644 --- a/src/test/ui/borrowck/borrowck-partial-reinit-4.stderr +++ b/src/test/ui/borrowck/borrowck-partial-reinit-4.stderr @@ -1,10 +1,10 @@ -error[E0381]: assigned binding `x.0` isn't initialized +error[E0381]: assigned binding `x.0` isn't fully initialized --> $DIR/borrowck-partial-reinit-4.rs:17:5 | LL | let mut x : (Test2, Test2); | ----- binding declared here but left uninitialized LL | (x.0).0 = Some(Test); - | ^^^^^^^ `x.0` assigned here but it isn't initialized + | ^^^^^^^ `x.0` assigned here but it isn't fully initialized error: aborting due to previous error diff --git a/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr b/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr index f56b6294c2093..9ecfe2f754ac5 100644 --- a/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr +++ b/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr @@ -1,18 +1,18 @@ -error[E0381]: assigned binding `d` isn't initialized +error[E0381]: assigned binding `d` isn't fully initialized --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:28:5 | LL | let d: D; | - binding declared here but left uninitialized LL | d.x = 10; - | ^^^^^^^^ `d` assigned here but it isn't initialized + | ^^^^^^^^ `d` assigned here but it isn't fully initialized -error[E0381]: assigned binding `d` isn't initialized +error[E0381]: assigned binding `d` isn't fully initialized --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:33:5 | LL | let mut d: D; | ----- binding declared here but left uninitialized LL | d.x = 10; - | ^^^^^^^^ `d` assigned here but it isn't initialized + | ^^^^^^^^ `d` assigned here but it isn't fully initialized error[E0382]: assign of moved value: `d` --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:39:5 From 6dd32f2742610d98fcf096a7f5141a70b17c6521 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Esteban=20K=C3=BCber?= Date: Thu, 23 Jun 2022 10:42:17 -0700 Subject: [PATCH 14/20] Wording tweak --- .../src/diagnostics/conflict_errors.rs | 29 ++++++++++++++----- .../ui/borrowck/borrowck-init-in-fru.stderr | 2 +- .../borrowck/borrowck-partial-reinit-4.stderr | 2 ++ .../borrowck-uninit-field-access.stderr | 2 +- .../borrowck/borrowck-uninit-ref-chain.stderr | 6 ++-- .../borrowck-use-in-index-lvalue.stderr | 4 +-- ...wck-use-uninitialized-in-cast-trait.stderr | 2 +- .../borrowck-use-uninitialized-in-cast.stderr | 2 +- ...const-generic-default-wont-borrowck.stderr | 2 +- ...1232-partial-init-and-erroneous-use.stderr | 8 +++-- .../issue-21232-partial-init-and-use.stderr | 12 ++++---- 11 files changed, 45 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs index 73baad614c8f1..2820ac7401b28 100644 --- a/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs +++ b/compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs @@ -98,8 +98,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { return; } - let err = - self.report_use_of_uninitialized(mpi, used_place, desired_action, span, use_spans); + let err = self.report_use_of_uninitialized( + mpi, + used_place, + moved_place, + desired_action, + span, + use_spans, + ); self.buffer_error(err); } else { if let Some((reported_place, _)) = self.has_move_error(&move_out_indices) { @@ -316,6 +322,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { &self, mpi: MovePathIndex, used_place: PlaceRef<'tcx>, + moved_place: PlaceRef<'tcx>, desired_action: InitializationRequiringAction, span: Span, use_spans: UseSpans<'tcx>, @@ -334,11 +341,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { } } - let (binding, name, desc) = - match self.describe_place_with_options(used_place, IncludingDowncast(true)) { - Some(name) => (format!("`{name}`"), format!("`{name}`"), format!("`{name}` ")), - None => ("value".to_string(), "the variable".to_string(), String::new()), + let (name, desc) = + match self.describe_place_with_options(moved_place, IncludingDowncast(true)) { + Some(name) => (format!("`{name}`"), format!("`{name}` ")), + None => ("the variable".to_string(), String::new()), }; + let path = match self.describe_place_with_options(used_place, IncludingDowncast(true)) { + Some(name) => format!("`{name}`"), + None => "value".to_string(), + }; // We use the statements were the binding was initialized, and inspect the HIR to look // for the branching codepaths that aren't covered, to point at them. @@ -390,13 +401,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> { format!("{} occurs due to use{}", desired_action.as_noun(), use_spans.describe()), ); - if let InitializationRequiringAction::PartialAssignment = desired_action { + if let InitializationRequiringAction::PartialAssignment + | InitializationRequiringAction::Assignment = desired_action + { err.help( "partial initialization isn't supported, fully initialize the binding with a \ default value and mutate it, or use `std::mem::MaybeUninit`", ); } - err.span_label(span, format!("{binding} {used} here but it {isnt_initialized}")); + err.span_label(span, format!("{path} {used} here but it {isnt_initialized}")); let mut shown = false; for (sp, label) in visitor.errors { diff --git a/src/test/ui/borrowck/borrowck-init-in-fru.stderr b/src/test/ui/borrowck/borrowck-init-in-fru.stderr index 7a35a9a537cac..83a3e3e0e3ae0 100644 --- a/src/test/ui/borrowck/borrowck-init-in-fru.stderr +++ b/src/test/ui/borrowck/borrowck-init-in-fru.stderr @@ -1,4 +1,4 @@ -error[E0381]: used binding `origin.y` isn't initialized +error[E0381]: used binding `origin` isn't initialized --> $DIR/borrowck-init-in-fru.rs:9:14 | LL | let mut origin: Point; diff --git a/src/test/ui/borrowck/borrowck-partial-reinit-4.stderr b/src/test/ui/borrowck/borrowck-partial-reinit-4.stderr index 7b5b64ff8cd23..d12a482cb69a9 100644 --- a/src/test/ui/borrowck/borrowck-partial-reinit-4.stderr +++ b/src/test/ui/borrowck/borrowck-partial-reinit-4.stderr @@ -5,6 +5,8 @@ LL | let mut x : (Test2, Test2); | ----- binding declared here but left uninitialized LL | (x.0).0 = Some(Test); | ^^^^^^^ `x.0` assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error: aborting due to previous error diff --git a/src/test/ui/borrowck/borrowck-uninit-field-access.stderr b/src/test/ui/borrowck/borrowck-uninit-field-access.stderr index 3bc3a47778778..6a38a79891970 100644 --- a/src/test/ui/borrowck/borrowck-uninit-field-access.stderr +++ b/src/test/ui/borrowck/borrowck-uninit-field-access.stderr @@ -1,4 +1,4 @@ -error[E0381]: used binding `a.x` isn't initialized +error[E0381]: used binding `a` isn't initialized --> $DIR/borrowck-uninit-field-access.rs:21:13 | LL | let mut a: Point; diff --git a/src/test/ui/borrowck/borrowck-uninit-ref-chain.stderr b/src/test/ui/borrowck/borrowck-uninit-ref-chain.stderr index 9f33a163e084f..c486cb6dd0cd3 100644 --- a/src/test/ui/borrowck/borrowck-uninit-ref-chain.stderr +++ b/src/test/ui/borrowck/borrowck-uninit-ref-chain.stderr @@ -1,4 +1,4 @@ -error[E0381]: used binding `**x` isn't initialized +error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-uninit-ref-chain.rs:8:14 | LL | let x: &&Box; @@ -6,7 +6,7 @@ LL | let x: &&Box; LL | let _y = &**x; | ^^^^ `**x` used here but it isn't initialized -error[E0381]: used binding `**x` isn't initialized +error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-uninit-ref-chain.rs:11:14 | LL | let x: &&S; @@ -14,7 +14,7 @@ LL | let x: &&S; LL | let _y = &**x; | ^^^^ `**x` used here but it isn't initialized -error[E0381]: used binding `**x` isn't initialized +error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-uninit-ref-chain.rs:14:14 | LL | let x: &&i32; diff --git a/src/test/ui/borrowck/borrowck-use-in-index-lvalue.stderr b/src/test/ui/borrowck/borrowck-use-in-index-lvalue.stderr index 6372096caef02..459cf1398b750 100644 --- a/src/test/ui/borrowck/borrowck-use-in-index-lvalue.stderr +++ b/src/test/ui/borrowck/borrowck-use-in-index-lvalue.stderr @@ -1,4 +1,4 @@ -error[E0381]: used binding `*w` isn't initialized +error[E0381]: used binding `w` isn't initialized --> $DIR/borrowck-use-in-index-lvalue.rs:3:5 | LL | let w: &mut [isize]; @@ -6,7 +6,7 @@ LL | let w: &mut [isize]; LL | w[5] = 0; | ^^^^ `*w` used here but it isn't initialized -error[E0381]: used binding `*w` isn't initialized +error[E0381]: used binding `w` isn't initialized --> $DIR/borrowck-use-in-index-lvalue.rs:6:5 | LL | let mut w: &mut [isize]; diff --git a/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.stderr b/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.stderr index fea69c2e40d66..942ed4fc6cabf 100644 --- a/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.stderr +++ b/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast-trait.stderr @@ -1,4 +1,4 @@ -error[E0381]: used binding `*x` isn't initialized +error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-use-uninitialized-in-cast-trait.rs:9:13 | LL | let x: &i32; diff --git a/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.stderr b/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.stderr index e75e033529607..f3289e239818a 100644 --- a/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.stderr +++ b/src/test/ui/borrowck/borrowck-use-uninitialized-in-cast.stderr @@ -1,4 +1,4 @@ -error[E0381]: used binding `*x` isn't initialized +error[E0381]: used binding `x` isn't initialized --> $DIR/borrowck-use-uninitialized-in-cast.rs:7:13 | LL | let x: &i32; diff --git a/src/test/ui/const-generics/const-generic-default-wont-borrowck.stderr b/src/test/ui/const-generics/const-generic-default-wont-borrowck.stderr index 33f839c2866e9..c62f1d1d23061 100644 --- a/src/test/ui/const-generics/const-generic-default-wont-borrowck.stderr +++ b/src/test/ui/const-generics/const-generic-default-wont-borrowck.stderr @@ -1,4 +1,4 @@ -error[E0381]: used binding `*s` isn't initialized +error[E0381]: used binding `s` isn't initialized --> $DIR/const-generic-default-wont-borrowck.rs:2:26 | LL | let s: &'static str; s.len() diff --git a/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr b/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr index 9ecfe2f754ac5..63f230be7d4b3 100644 --- a/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr +++ b/src/test/ui/nll/issue-21232-partial-init-and-erroneous-use.stderr @@ -5,6 +5,8 @@ LL | let d: D; | - binding declared here but left uninitialized LL | d.x = 10; | ^^^^^^^^ `d` assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error[E0381]: assigned binding `d` isn't fully initialized --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:33:5 @@ -13,6 +15,8 @@ LL | let mut d: D; | ----- binding declared here but left uninitialized LL | d.x = 10; | ^^^^^^^^ `d` assigned here but it isn't fully initialized + | + = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` error[E0382]: assign of moved value: `d` --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:39:5 @@ -24,7 +28,7 @@ LL | drop(d); LL | d.x = 10; | ^^^^^^^^ value assigned here after move -error[E0381]: partially assigned binding `d.s` isn't fully initialized +error[E0381]: partially assigned binding `d` isn't fully initialized --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:45:5 | LL | let d: D; @@ -34,7 +38,7 @@ LL | d.s.y = 20; | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: partially assigned binding `d.s` isn't fully initialized +error[E0381]: partially assigned binding `d` isn't fully initialized --> $DIR/issue-21232-partial-init-and-erroneous-use.rs:50:5 | LL | let mut d: D; diff --git a/src/test/ui/nll/issue-21232-partial-init-and-use.stderr b/src/test/ui/nll/issue-21232-partial-init-and-use.stderr index 2f5883b156300..947c9e29b4508 100644 --- a/src/test/ui/nll/issue-21232-partial-init-and-use.stderr +++ b/src/test/ui/nll/issue-21232-partial-init-and-use.stderr @@ -98,7 +98,7 @@ LL | t.0 = 10; | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: partially assigned binding `q.r.f` isn't fully initialized +error[E0381]: partially assigned binding `q` isn't fully initialized --> $DIR/issue-21232-partial-init-and-use.rs:170:5 | LL | let q: Q>; @@ -108,7 +108,7 @@ LL | q.r.f.x = 10; q.r.f.y = Box::new(20); | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: partially assigned binding `q.r.f` isn't fully initialized +error[E0381]: partially assigned binding `q` isn't fully initialized --> $DIR/issue-21232-partial-init-and-use.rs:176:5 | LL | let q: Q; @@ -138,7 +138,7 @@ LL | q.r.f.0 = 10; q.r.f.1 = Box::new(20); | = note: move occurs because `q.r` has type `R<(u32, Box)>`, which does not implement the `Copy` trait -error[E0381]: partially assigned binding `q.r.f` isn't fully initialized +error[E0381]: partially assigned binding `q` isn't fully initialized --> $DIR/issue-21232-partial-init-and-use.rs:196:5 | LL | let q: Q>; @@ -148,7 +148,7 @@ LL | q.r.f.x = 10; | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: partially assigned binding `q.r.f` isn't fully initialized +error[E0381]: partially assigned binding `q` isn't fully initialized --> $DIR/issue-21232-partial-init-and-use.rs:202:5 | LL | let q: Q; @@ -178,7 +178,7 @@ LL | q.r.f.0 = 10; | = note: move occurs because `q.r` has type `R<(u32, Box)>`, which does not implement the `Copy` trait -error[E0381]: partially assigned binding `q.r.f` isn't fully initialized +error[E0381]: partially assigned binding `q` isn't fully initialized --> $DIR/issue-21232-partial-init-and-use.rs:222:5 | LL | let mut q: Q>; @@ -188,7 +188,7 @@ LL | q.r.f.x = 10; | = help: partial initialization isn't supported, fully initialize the binding with a default value and mutate it, or use `std::mem::MaybeUninit` -error[E0381]: partially assigned binding `q.r.f` isn't fully initialized +error[E0381]: partially assigned binding `q` isn't fully initialized --> $DIR/issue-21232-partial-init-and-use.rs:228:5 | LL | let mut q: Q; From 20cea3ebb468df74447ed3aa5e646f741208bea8 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Tue, 21 Jun 2022 21:27:15 -0700 Subject: [PATCH 15/20] Fix printing impl trait under binders --- compiler/rustc_middle/src/ty/print/pretty.rs | 246 ++++++++++-------- src/test/ui/impl-trait/printing-binder.rs | 14 + src/test/ui/impl-trait/printing-binder.stderr | 31 +++ 3 files changed, 178 insertions(+), 113 deletions(-) create mode 100644 src/test/ui/impl-trait/printing-binder.rs create mode 100644 src/test/ui/impl-trait/printing-binder.stderr diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 200253d575599..d0f53f8f74b26 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -226,7 +226,7 @@ pub trait PrettyPrinter<'tcx>: value.as_ref().skip_binder().print(self) } - fn wrap_binder Result>( + fn wrap_binder Result>( self, value: &ty::Binder<'tcx, T>, f: F, @@ -773,18 +773,18 @@ pub trait PrettyPrinter<'tcx>: def_id: DefId, substs: &'tcx ty::List>, ) -> Result { - define_scoped_cx!(self); + let tcx = self.tcx(); // Grab the "TraitA + TraitB" from `impl TraitA + TraitB`, // by looking up the projections associated with the def_id. - let bounds = self.tcx().bound_explicit_item_bounds(def_id); + let bounds = tcx.bound_explicit_item_bounds(def_id); let mut traits = FxIndexMap::default(); let mut fn_traits = FxIndexMap::default(); let mut is_sized = false; for predicate in bounds.transpose_iter().map(|e| e.map_bound(|(p, _)| *p)) { - let predicate = predicate.subst(self.tcx(), substs); + let predicate = predicate.subst(tcx, substs); let bound_predicate = predicate.kind(); match bound_predicate.skip_binder() { @@ -792,7 +792,7 @@ pub trait PrettyPrinter<'tcx>: let trait_ref = bound_predicate.rebind(pred.trait_ref); // Don't print + Sized, but rather + ?Sized if absent. - if Some(trait_ref.def_id()) == self.tcx().lang_items().sized_trait() { + if Some(trait_ref.def_id()) == tcx.lang_items().sized_trait() { is_sized = true; continue; } @@ -801,7 +801,7 @@ pub trait PrettyPrinter<'tcx>: } ty::PredicateKind::Projection(pred) => { let proj_ref = bound_predicate.rebind(pred); - let trait_ref = proj_ref.required_poly_trait_ref(self.tcx()); + let trait_ref = proj_ref.required_poly_trait_ref(tcx); // Projection type entry -- the def-id for naming, and the ty. let proj_ty = (proj_ref.projection_def_id(), proj_ref.term()); @@ -817,148 +817,168 @@ pub trait PrettyPrinter<'tcx>: } } + { + define_scoped_cx!(self); + p!("impl "); + } + let mut first = true; // Insert parenthesis around (Fn(A, B) -> C) if the opaque ty has more than one other trait let paren_needed = fn_traits.len() > 1 || traits.len() > 0 || !is_sized; - p!("impl"); - for (fn_once_trait_ref, entry) in fn_traits { - // Get the (single) generic ty (the args) of this FnOnce trait ref. - let generics = self.tcx().generics_of(fn_once_trait_ref.def_id()); - let args = - generics.own_substs_no_defaults(self.tcx(), fn_once_trait_ref.skip_binder().substs); - - match (entry.return_ty, args[0].expect_ty()) { - // We can only print `impl Fn() -> ()` if we have a tuple of args and we recorded - // a return type. - (Some(return_ty), arg_tys) if matches!(arg_tys.kind(), ty::Tuple(_)) => { - let name = if entry.fn_trait_ref.is_some() { - "Fn" - } else if entry.fn_mut_trait_ref.is_some() { - "FnMut" - } else { - "FnOnce" - }; + { + define_scoped_cx!(self); + p!( + write("{}", if first { "" } else { " + " }), + write("{}", if paren_needed { "(" } else { "" }) + ); + } + + self = self.wrap_binder(&fn_once_trait_ref, |trait_ref, mut self_| { + // Get the (single) generic ty (the args) of this FnOnce trait ref. + let generics = tcx.generics_of(trait_ref.def_id); + let args = generics.own_substs_no_defaults(tcx, trait_ref.substs); + + match (entry.return_ty, args[0].expect_ty()) { + // We can only print `impl Fn() -> ()` if we have a tuple of args and we recorded + // a return type. + (Some(return_ty), arg_tys) if matches!(arg_tys.kind(), ty::Tuple(_)) => { + let name = if entry.fn_trait_ref.is_some() { + "Fn" + } else if entry.fn_mut_trait_ref.is_some() { + "FnMut" + } else { + "FnOnce" + }; - p!( - write("{}", if first { " " } else { " + " }), - write("{}{}(", if paren_needed { "(" } else { "" }, name) - ); + define_scoped_cx!(self_); + p!(write("{}(", name)); - for (idx, ty) in arg_tys.tuple_fields().iter().enumerate() { - if idx > 0 { - p!(", "); + for (idx, ty) in arg_tys.tuple_fields().iter().enumerate() { + if idx > 0 { + p!(", "); + } + p!(print(ty)); } - p!(print(ty)); - } - p!(")"); - if let Term::Ty(ty) = return_ty.skip_binder() { - if !ty.is_unit() { - p!(" -> ", print(return_ty)); + p!(")"); + if let Term::Ty(ty) = return_ty.skip_binder() { + if !ty.is_unit() { + p!(" -> ", print(return_ty)); + } } - } - p!(write("{}", if paren_needed { ")" } else { "" })); + p!(write("{}", if paren_needed { ")" } else { "" })); - first = false; - } - // If we got here, we can't print as a `impl Fn(A, B) -> C`. Just record the - // trait_refs we collected in the OpaqueFnEntry as normal trait refs. - _ => { - if entry.has_fn_once { - traits.entry(fn_once_trait_ref).or_default().extend( - // Group the return ty with its def id, if we had one. - entry - .return_ty - .map(|ty| (self.tcx().lang_items().fn_once_output().unwrap(), ty)), - ); - } - if let Some(trait_ref) = entry.fn_mut_trait_ref { - traits.entry(trait_ref).or_default(); + first = false; } - if let Some(trait_ref) = entry.fn_trait_ref { - traits.entry(trait_ref).or_default(); + // If we got here, we can't print as a `impl Fn(A, B) -> C`. Just record the + // trait_refs we collected in the OpaqueFnEntry as normal trait refs. + _ => { + if entry.has_fn_once { + traits.entry(fn_once_trait_ref).or_default().extend( + // Group the return ty with its def id, if we had one. + entry + .return_ty + .map(|ty| (tcx.lang_items().fn_once_output().unwrap(), ty)), + ); + } + if let Some(trait_ref) = entry.fn_mut_trait_ref { + traits.entry(trait_ref).or_default(); + } + if let Some(trait_ref) = entry.fn_trait_ref { + traits.entry(trait_ref).or_default(); + } } } - } + + Ok(self_) + })?; } // Print the rest of the trait types (that aren't Fn* family of traits) for (trait_ref, assoc_items) in traits { - p!( - write("{}", if first { " " } else { " + " }), - print(trait_ref.skip_binder().print_only_trait_name()) - ); + { + define_scoped_cx!(self); + p!(write("{}", if first { "" } else { " + " })); + } - let generics = self.tcx().generics_of(trait_ref.def_id()); - let args = generics.own_substs_no_defaults(self.tcx(), trait_ref.skip_binder().substs); + self = self.wrap_binder(&trait_ref, |trait_ref, mut self_| { + define_scoped_cx!(self_); + p!(print(trait_ref.print_only_trait_name())); - if !args.is_empty() || !assoc_items.is_empty() { - let mut first = true; + let generics = tcx.generics_of(trait_ref.def_id); + let args = generics.own_substs_no_defaults(tcx, trait_ref.substs); - for ty in args { - if first { - p!("<"); - first = false; - } else { - p!(", "); + if !args.is_empty() || !assoc_items.is_empty() { + let mut first = true; + + for ty in args { + if first { + p!("<"); + first = false; + } else { + p!(", "); + } + p!(print(ty)); } - p!(print(trait_ref.rebind(*ty))); - } - for (assoc_item_def_id, term) in assoc_items { - // Skip printing `<[generator@] as Generator<_>>::Return` from async blocks, - // unless we can find out what generator return type it comes from. - let term = if let Some(ty) = term.skip_binder().ty() - && let ty::Projection(ty::ProjectionTy { item_def_id, substs }) = ty.kind() - && Some(*item_def_id) == self.tcx().lang_items().generator_return() - { - if let ty::Generator(_, substs, _) = substs.type_at(0).kind() { - let return_ty = substs.as_generator().return_ty(); - if !return_ty.is_ty_infer() { - return_ty.into() + for (assoc_item_def_id, term) in assoc_items { + // Skip printing `<[generator@] as Generator<_>>::Return` from async blocks, + // unless we can find out what generator return type it comes from. + let term = if let Some(ty) = term.skip_binder().ty() + && let ty::Projection(ty::ProjectionTy { item_def_id, substs }) = ty.kind() + && Some(*item_def_id) == tcx.lang_items().generator_return() + { + if let ty::Generator(_, substs, _) = substs.type_at(0).kind() { + let return_ty = substs.as_generator().return_ty(); + if !return_ty.is_ty_infer() { + return_ty.into() + } else { + continue; + } } else { continue; } } else { - continue; - } - } else { - term.skip_binder() - }; + term.skip_binder() + }; - if first { - p!("<"); - first = false; - } else { - p!(", "); - } + if first { + p!("<"); + first = false; + } else { + p!(", "); + } - p!(write("{} = ", self.tcx().associated_item(assoc_item_def_id).name)); + p!(write("{} = ", tcx.associated_item(assoc_item_def_id).name)); - match term { - Term::Ty(ty) => { - p!(print(ty)) - } - Term::Const(c) => { - p!(print(c)); - } - }; - } + match term { + Term::Ty(ty) => { + p!(print(ty)) + } + Term::Const(c) => { + p!(print(c)); + } + }; + } - if !first { - p!(">"); + if !first { + p!(">"); + } } - } - first = false; + first = false; + Ok(self_) + })?; } + define_scoped_cx!(self); + if !is_sized { - p!(write("{}?Sized", if first { " " } else { " + " })); + p!(write("{}?Sized", if first { "" } else { " + " })); } else if first { - p!(" Sized"); + p!("Sized"); } Ok(self) @@ -1869,7 +1889,7 @@ impl<'tcx> PrettyPrinter<'tcx> for FmtPrinter<'_, 'tcx> { self.pretty_in_binder(value) } - fn wrap_binder Result>( + fn wrap_binder Result>( self, value: &ty::Binder<'tcx, T>, f: C, @@ -2256,7 +2276,7 @@ impl<'tcx> FmtPrinter<'_, 'tcx> { Ok(inner) } - pub fn pretty_wrap_binder Result>( + pub fn pretty_wrap_binder Result>( self, value: &ty::Binder<'tcx, T>, f: C, diff --git a/src/test/ui/impl-trait/printing-binder.rs b/src/test/ui/impl-trait/printing-binder.rs new file mode 100644 index 0000000000000..273b5dcdb0985 --- /dev/null +++ b/src/test/ui/impl-trait/printing-binder.rs @@ -0,0 +1,14 @@ +trait Trait<'a> {} +impl Trait<'_> for T {} +fn whatever() -> impl for<'a> Trait<'a> + for<'b> Trait<'b> {} + +fn whatever2() -> impl for<'c> Fn(&'c ()) { + |_: &()| {} +} + +fn main() { + let x: u32 = whatever(); + //~^ ERROR mismatched types + let x2: u32 = whatever2(); + //~^ ERROR mismatched types +} diff --git a/src/test/ui/impl-trait/printing-binder.stderr b/src/test/ui/impl-trait/printing-binder.stderr new file mode 100644 index 0000000000000..5ffec8af10289 --- /dev/null +++ b/src/test/ui/impl-trait/printing-binder.stderr @@ -0,0 +1,31 @@ +error[E0308]: mismatched types + --> $DIR/printing-binder.rs:10:18 + | +LL | fn whatever() -> impl for<'a> Trait<'a> + for<'b> Trait<'b> {} + | ------------------------------------------ the found opaque type +... +LL | let x: u32 = whatever(); + | --- ^^^^^^^^^^ expected `u32`, found opaque type + | | + | expected due to this + | + = note: expected type `u32` + found opaque type `impl for<'a> Trait<'a> + for<'b> Trait<'b>` + +error[E0308]: mismatched types + --> $DIR/printing-binder.rs:12:19 + | +LL | fn whatever2() -> impl for<'c> Fn(&'c ()) { + | ----------------------- the found opaque type +... +LL | let x2: u32 = whatever2(); + | --- ^^^^^^^^^^^ expected `u32`, found opaque type + | | + | expected due to this + | + = note: expected type `u32` + found opaque type `impl for<'c> Fn(&'c ())` + +error: aborting due to 2 previous errors + +For more information about this error, try `rustc --explain E0308`. From e80ccedbaeeb5b97880d83ea95c79fc1d0dcf418 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Wed, 22 Jun 2022 10:21:24 -0700 Subject: [PATCH 16/20] Use write! instead of p! to avoid having to use weird scoping --- compiler/rustc_middle/src/ty/print/pretty.rs | 37 ++++++------------- ...e-70935-complex-spans.drop_tracking.stderr | 2 +- 2 files changed, 13 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index d0f53f8f74b26..c56909ba18b14 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -817,25 +817,18 @@ pub trait PrettyPrinter<'tcx>: } } - { - define_scoped_cx!(self); - p!("impl "); - } + write!(self, "impl ")?; let mut first = true; // Insert parenthesis around (Fn(A, B) -> C) if the opaque ty has more than one other trait let paren_needed = fn_traits.len() > 1 || traits.len() > 0 || !is_sized; for (fn_once_trait_ref, entry) in fn_traits { - { - define_scoped_cx!(self); - p!( - write("{}", if first { "" } else { " + " }), - write("{}", if paren_needed { "(" } else { "" }) - ); - } + write!(self, "{}", if first { "" } else { " + " })?; + write!(self, "{}", if paren_needed { "(" } else { "" })?; - self = self.wrap_binder(&fn_once_trait_ref, |trait_ref, mut self_| { + self = self.wrap_binder(&fn_once_trait_ref, |trait_ref, mut cx| { + define_scoped_cx!(cx); // Get the (single) generic ty (the args) of this FnOnce trait ref. let generics = tcx.generics_of(trait_ref.def_id); let args = generics.own_substs_no_defaults(tcx, trait_ref.substs); @@ -852,7 +845,6 @@ pub trait PrettyPrinter<'tcx>: "FnOnce" }; - define_scoped_cx!(self_); p!(write("{}(", name)); for (idx, ty) in arg_tys.tuple_fields().iter().enumerate() { @@ -892,19 +884,16 @@ pub trait PrettyPrinter<'tcx>: } } - Ok(self_) + Ok(cx) })?; } // Print the rest of the trait types (that aren't Fn* family of traits) for (trait_ref, assoc_items) in traits { - { - define_scoped_cx!(self); - p!(write("{}", if first { "" } else { " + " })); - } + write!(self, "{}", if first { "" } else { " + " })?; - self = self.wrap_binder(&trait_ref, |trait_ref, mut self_| { - define_scoped_cx!(self_); + self = self.wrap_binder(&trait_ref, |trait_ref, mut cx| { + define_scoped_cx!(cx); p!(print(trait_ref.print_only_trait_name())); let generics = tcx.generics_of(trait_ref.def_id); @@ -969,16 +958,14 @@ pub trait PrettyPrinter<'tcx>: } first = false; - Ok(self_) + Ok(cx) })?; } - define_scoped_cx!(self); - if !is_sized { - p!(write("{}?Sized", if first { "" } else { " + " })); + write!(self, "{}?Sized", if first { "" } else { " + " })?; } else if first { - p!("Sized"); + write!(self, "Sized")?; } Ok(self) diff --git a/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr b/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr index 43b7cb8cece36..e9b76b19dc407 100644 --- a/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr +++ b/src/test/ui/async-await/issue-70935-complex-spans.drop_tracking.stderr @@ -22,7 +22,7 @@ LL | async fn baz(_c: impl FnMut() -> T) where T: Future { LL | | LL | | } | |_^ - = note: required because it captures the following types: `ResumeTy`, `impl Future`, `()` + = note: required because it captures the following types: `ResumeTy`, `impl for<'r, 's, 't0> Future`, `()` note: required because it's used within this `async` block --> $DIR/issue-70935-complex-spans.rs:23:16 | From 9169905eb2d0e5df5c554396495df49283812abc Mon Sep 17 00:00:00 2001 From: David Tolnay Date: Fri, 24 Jun 2022 17:55:40 -0700 Subject: [PATCH 17/20] x.py: Support systems with only `python3` not `python` --- x.py | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/x.py b/x.py index 4f64ea9fae8b8..0289056fdcb16 100755 --- a/x.py +++ b/x.py @@ -1,5 +1,25 @@ -#!/usr/bin/env python +#!/usr/bin/env bash +# Modern Linux and macOS systems commonly only have a thing called `python3` and +# not `python`, while Windows commonly does not have `python3`, so we cannot +# directly use python in the shebang and have it consistently work. Instead we +# embed some bash to look for a python to run the rest of the script. +# +# On Windows, `py -3` sometimes works. We need to try it first because `python3` +# sometimes tries to launch the app store on Windows. +'''': +for PYTHON in "py -3" python3 python python2; do + if command -v $PYTHON >/dev/null; then + exec $PYTHON "$0" "$@" + break + fi +done +echo "$0: error: did not find python installed" >&2 +exit 1 +''' + +# The rest of this file is Python. +# # This file is only a "symlink" to bootstrap.py, all logic should go there. import os @@ -7,11 +27,12 @@ # If this is python2, check if python3 is available and re-execute with that # interpreter. +# +# `./x.py` would not normally benefit from this because the bash above tries +# python3 before 2, but this matters if someone ran `python x.py` and their +# system's `python` is python2. if sys.version_info.major < 3: try: - # On Windows, `py -3` sometimes works. - # Try this first, because 'python3' sometimes tries to launch the app - # store on Windows os.execvp("py", ["py", "-3"] + sys.argv) except OSError: try: From 747586732b1bb21c1ef318428fe179a77db2d963 Mon Sep 17 00:00:00 2001 From: Caio Date: Sat, 25 Jun 2022 08:08:38 -0300 Subject: [PATCH 18/20] [rustc_parse] Forbid lets in certain places --- compiler/rustc_parse/src/parser/expr.rs | 30 +- compiler/rustc_parse/src/parser/mod.rs | 6 +- src/test/ui/mir/issue-92893.rs | 3 +- src/test/ui/mir/issue-92893.stderr | 8 +- .../ui/rfc-2294-if-let-guard/feature-gate.rs | 2 + .../rfc-2294-if-let-guard/feature-gate.stderr | 20 +- .../disallowed-positions.rs | 88 +++- .../disallowed-positions.stderr | 442 ++++++++++++------ ...-else-does-not-interact-with-let-chains.rs | 1 + ...e-does-not-interact-with-let-chains.stderr | 26 +- .../ui/rfc-2497-if-let-chains/feature-gate.rs | 3 +- .../feature-gate.stderr | 18 +- .../invalid-let-in-a-valid-let-context.rs | 17 + 13 files changed, 468 insertions(+), 196 deletions(-) create mode 100644 src/test/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.rs diff --git a/compiler/rustc_parse/src/parser/expr.rs b/compiler/rustc_parse/src/parser/expr.rs index 81bab0e3513c9..2c43563b10474 100644 --- a/compiler/rustc_parse/src/parser/expr.rs +++ b/compiler/rustc_parse/src/parser/expr.rs @@ -7,6 +7,7 @@ use super::{ }; use crate::maybe_recover_from_interpolated_ty_qpath; +use core::mem; use rustc_ast::ptr::P; use rustc_ast::token::{self, Delimiter, Token, TokenKind}; use rustc_ast::tokenstream::Spacing; @@ -26,7 +27,6 @@ use rustc_session::lint::BuiltinLintDiagnostics; use rustc_span::source_map::{self, Span, Spanned}; use rustc_span::symbol::{kw, sym, Ident, Symbol}; use rustc_span::{BytePos, Pos}; -use std::mem; /// Possibly accepts an `token::Interpolated` expression (a pre-parsed expression /// dropped into the token stream, which happens while parsing the result of @@ -2343,7 +2343,9 @@ impl<'a> Parser<'a> { /// Parses the condition of a `if` or `while` expression. fn parse_cond_expr(&mut self) -> PResult<'a, P> { - let cond = self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None)?; + let cond = self.with_let_management(true, |local_self| { + local_self.parse_expr_res(Restrictions::NO_STRUCT_LITERAL, None) + })?; if let ExprKind::Let(..) = cond.kind { // Remove the last feature gating of a `let` expression since it's stable. @@ -2356,6 +2358,13 @@ impl<'a> Parser<'a> { /// Parses a `let $pat = $expr` pseudo-expression. /// The `let` token has already been eaten. fn parse_let_expr(&mut self, attrs: AttrVec) -> PResult<'a, P> { + if !self.let_expr_allowed { + self.struct_span_err( + self.prev_token.span, + "expected expression, found `let` statement", + ) + .emit(); + } let lo = self.prev_token.span; let pat = self.parse_pat_allow_top_alt( None, @@ -2672,6 +2681,8 @@ impl<'a> Parser<'a> { } pub(super) fn parse_arm(&mut self) -> PResult<'a, Arm> { + // Used to check the `let_chains` and `if_let_guard` features mostly by scaning + // `&&` tokens. fn check_let_expr(expr: &Expr) -> (bool, bool) { match expr.kind { ExprKind::Binary(_, ref lhs, ref rhs) => { @@ -2694,7 +2705,7 @@ impl<'a> Parser<'a> { )?; let guard = if this.eat_keyword(kw::If) { let if_span = this.prev_token.span; - let cond = this.parse_expr()?; + let cond = this.with_let_management(true, |local_this| local_this.parse_expr())?; let (has_let_expr, does_not_have_bin_op) = check_let_expr(&cond); if has_let_expr { if does_not_have_bin_op { @@ -3256,4 +3267,17 @@ impl<'a> Parser<'a> { Ok((res, trailing)) }) } + + // Calls `f` with the internal `let_expr_allowed` set to `let_expr_allowed` and then + // sets the internal `let_expr_allowed` back to its original value. + fn with_let_management( + &mut self, + let_expr_allowed: bool, + f: impl FnOnce(&mut Self) -> T, + ) -> T { + let last_let_expr_allowed = mem::replace(&mut self.let_expr_allowed, let_expr_allowed); + let rslt = f(self); + self.let_expr_allowed = last_let_expr_allowed; + rslt + } } diff --git a/compiler/rustc_parse/src/parser/mod.rs b/compiler/rustc_parse/src/parser/mod.rs index 6d6667717f0a3..acdf121522ad9 100644 --- a/compiler/rustc_parse/src/parser/mod.rs +++ b/compiler/rustc_parse/src/parser/mod.rs @@ -147,12 +147,15 @@ pub struct Parser<'a> { /// This allows us to recover when the user forget to add braces around /// multiple statements in the closure body. pub current_closure: Option, + /// Used to track where `let`s are allowed. For example, `if true && let 1 = 1` is valid + /// but `[1, 2, 3][let _ = ()]` is not. + let_expr_allowed: bool, } // This type is used a lot, e.g. it's cloned when matching many declarative macro rules. Make sure // it doesn't unintentionally get bigger. #[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))] -rustc_data_structures::static_assert_size!(Parser<'_>, 328); +rustc_data_structures::static_assert_size!(Parser<'_>, 336); /// Stores span information about a closure. #[derive(Clone)] @@ -455,6 +458,7 @@ impl<'a> Parser<'a> { inner_attr_ranges: Default::default(), }, current_closure: None, + let_expr_allowed: false, }; // Make parser point to the first token. diff --git a/src/test/ui/mir/issue-92893.rs b/src/test/ui/mir/issue-92893.rs index d2bbb4f110114..635050f376c8a 100644 --- a/src/test/ui/mir/issue-92893.rs +++ b/src/test/ui/mir/issue-92893.rs @@ -1,6 +1,7 @@ struct Bug { //~^ `let` expressions are not supported here - //~^^ `let` expressions in this position are unstable [E0658] + //~| `let` expressions in this position are unstable [E0658] + //~| expected expression, found `let` statement a: A } diff --git a/src/test/ui/mir/issue-92893.stderr b/src/test/ui/mir/issue-92893.stderr index 063b5d66feb45..4a0fcce31d7c7 100644 --- a/src/test/ui/mir/issue-92893.stderr +++ b/src/test/ui/mir/issue-92893.stderr @@ -1,3 +1,9 @@ +error: expected expression, found `let` statement + --> $DIR/issue-92893.rs:1:22 + | +LL | struct Bug { + | ^^^ + error: `let` expressions are not supported here --> $DIR/issue-92893.rs:1:22 | @@ -15,6 +21,6 @@ LL | struct Bug { = note: see issue #53667 for more information = help: add `#![feature(let_chains)]` to the crate attributes to enable -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs b/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs index 4a36515b99128..bb1aff70d8995 100644 --- a/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs +++ b/src/test/ui/rfc-2294-if-let-guard/feature-gate.rs @@ -58,8 +58,10 @@ fn _macros() { } use_expr!((let 0 = 1 && 0 == 0)); //~^ ERROR `let` expressions in this position are unstable + //~| ERROR expected expression, found `let` statement use_expr!((let 0 = 1)); //~^ ERROR `let` expressions in this position are unstable + //~| ERROR expected expression, found `let` statement match () { #[cfg(FALSE)] () if let 0 = 1 => {} diff --git a/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr b/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr index 8d93fb87f7ad1..370a57318fdd0 100644 --- a/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr +++ b/src/test/ui/rfc-2294-if-let-guard/feature-gate.stderr @@ -1,5 +1,17 @@ +error: expected expression, found `let` statement + --> $DIR/feature-gate.rs:59:16 + | +LL | use_expr!((let 0 = 1 && 0 == 0)); + | ^^^ + +error: expected expression, found `let` statement + --> $DIR/feature-gate.rs:62:16 + | +LL | use_expr!((let 0 = 1)); + | ^^^ + error: no rules expected the token `let` - --> $DIR/feature-gate.rs:69:15 + --> $DIR/feature-gate.rs:71:15 | LL | macro_rules! use_expr { | --------------------- when calling this macro @@ -58,7 +70,7 @@ LL | () if let Range { start: _, end: _ } = (true..true) && false => {} = help: you can write `if matches!(, )` instead of `if let = ` error[E0658]: `if let` guards are experimental - --> $DIR/feature-gate.rs:65:12 + --> $DIR/feature-gate.rs:67:12 | LL | () if let 0 = 1 => {} | ^^^^^^^^^^^^ @@ -203,7 +215,7 @@ LL | use_expr!((let 0 = 1 && 0 == 0)); = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:61:16 + --> $DIR/feature-gate.rs:62:16 | LL | use_expr!((let 0 = 1)); | ^^^^^^^^^ @@ -211,6 +223,6 @@ LL | use_expr!((let 0 = 1)); = note: see issue #53667 for more information = help: add `#![feature(let_chains)]` to the crate attributes to enable -error: aborting due to 23 previous errors +error: aborting due to 25 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs index 1bd8b74240eac..36b730505c29e 100644 --- a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs +++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.rs @@ -81,9 +81,11 @@ fn _macros() { use_expr!((let 0 = 1 && 0 == 0)); //~^ ERROR `let` expressions are not supported here //~| ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement use_expr!((let 0 = 1)); //~^ ERROR `let` expressions are not supported here //~| ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement } fn nested_within_if_expr() { @@ -147,7 +149,8 @@ fn nested_within_if_expr() { //~| ERROR mismatched types //~| ERROR mismatched types - if let true = let true = true {} //~ ERROR `let` expressions are not supported here + if let true = let true = true {} + //~^ ERROR `let` expressions are not supported here } fn nested_within_while_expr() { @@ -211,7 +214,8 @@ fn nested_within_while_expr() { //~| ERROR mismatched types //~| ERROR mismatched types - while let true = let true = true {} //~ ERROR `let` expressions are not supported here + while let true = let true = true {} + //~^ ERROR `let` expressions are not supported here } fn not_error_because_clarified_intent() { @@ -225,45 +229,85 @@ fn not_error_because_clarified_intent() { } fn outside_if_and_while_expr() { - &let 0 = 0; //~ ERROR `let` expressions are not supported here + &let 0 = 0; + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement - !let 0 = 0; //~ ERROR `let` expressions are not supported here - *let 0 = 0; //~ ERROR `let` expressions are not supported here - //~^ ERROR type `bool` cannot be dereferenced - -let 0 = 0; //~ ERROR `let` expressions are not supported here - //~^ ERROR cannot apply unary operator `-` to type `bool` + !let 0 = 0; + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + *let 0 = 0; + //~^ ERROR `let` expressions are not supported here + //~| ERROR type `bool` cannot be dereferenced + //~| ERROR expected expression, found `let` statement + -let 0 = 0; + //~^ ERROR `let` expressions are not supported here + //~| ERROR cannot apply unary operator `-` to type `bool` + //~| ERROR expected expression, found `let` statement fn _check_try_binds_tighter() -> Result<(), ()> { let 0 = 0?; //~^ ERROR the `?` operator can only be applied to values that implement `Try` Ok(()) } - (let 0 = 0)?; //~ ERROR `let` expressions are not supported here - //~^ ERROR the `?` operator can only be used in a function that returns `Result` + (let 0 = 0)?; + //~^ ERROR `let` expressions are not supported here + //~| ERROR the `?` operator can only be used in a function that returns `Result` //~| ERROR the `?` operator can only be applied to values that implement `Try` + //~| ERROR expected expression, found `let` statement - true || let 0 = 0; //~ ERROR `let` expressions are not supported here - (true || let 0 = 0); //~ ERROR `let` expressions are not supported here - true && (true || let 0 = 0); //~ ERROR `let` expressions are not supported here + true || let 0 = 0; + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + (true || let 0 = 0); + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + true && (true || let 0 = 0); + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement let mut x = true; - x = let 0 = 0; //~ ERROR `let` expressions are not supported here + x = let 0 = 0; + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement - true..(let 0 = 0); //~ ERROR `let` expressions are not supported here - ..(let 0 = 0); //~ ERROR `let` expressions are not supported here - (let 0 = 0)..; //~ ERROR `let` expressions are not supported here + true..(let 0 = 0); + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + ..(let 0 = 0); + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + (let 0 = 0)..; + //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement (let Range { start: _, end: _ } = true..true || false); //~^ ERROR `let` expressions are not supported here //~| ERROR mismatched types + //~| ERROR expected expression, found `let` statement (let true = let true = true); //~^ ERROR `let` expressions are not supported here + //~| ERROR expected expression, found `let` statement + //~| ERROR expected expression, found `let` statement + + { + #[cfg(FALSE)] + let x = true && let y = 1; + //~^ ERROR expected expression, found `let` statement + } + + #[cfg(FALSE)] + { + [1, 2, 3][let _ = ()] + //~^ ERROR expected expression, found `let` statement + } // Check function tail position. &let 0 = 0 //~^ ERROR `let` expressions are not supported here //~| ERROR mismatched types + //~| ERROR expected expression, found `let` statement } // Let's make sure that `let` inside const generic arguments are considered. @@ -335,4 +379,14 @@ fn with_parenthesis() { let fun = || true; if let true = (true && fun()) && (true) { } + + #[cfg(FALSE)] + let x = (true && let y = 1); + //~^ ERROR expected expression, found `let` statement + + #[cfg(FALSE)] + { + ([1, 2, 3][let _ = ()]) + //~^ ERROR expected expression, found `let` statement + } } diff --git a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr index f7f39bd0b9a07..5cf06cf4b27cd 100644 --- a/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr +++ b/src/test/ui/rfc-2497-if-let-chains/disallowed-positions.stderr @@ -1,5 +1,113 @@ +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:232:6 + | +LL | &let 0 = 0; + | ^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:236:6 + | +LL | !let 0 = 0; + | ^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:239:6 + | +LL | *let 0 = 0; + | ^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:243:6 + | +LL | -let 0 = 0; + | ^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:253:6 + | +LL | (let 0 = 0)?; + | ^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:259:13 + | +LL | true || let 0 = 0; + | ^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:262:14 + | +LL | (true || let 0 = 0); + | ^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:265:22 + | +LL | true && (true || let 0 = 0); + | ^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:270:9 + | +LL | x = let 0 = 0; + | ^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:274:12 + | +LL | true..(let 0 = 0); + | ^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:277:8 + | +LL | ..(let 0 = 0); + | ^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:280:6 + | +LL | (let 0 = 0)..; + | ^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:284:6 + | +LL | (let Range { start: _, end: _ } = true..true || false); + | ^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:289:6 + | +LL | (let true = let true = true); + | ^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:289:17 + | +LL | (let true = let true = true); + | ^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:296:25 + | +LL | let x = true && let y = 1; + | ^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:302:19 + | +LL | [1, 2, 3][let _ = ()] + | ^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:307:6 + | +LL | &let 0 = 0 + | ^^^ + error: expressions must be enclosed in braces to be used as const generic arguments - --> $DIR/disallowed-positions.rs:293:9 + --> $DIR/disallowed-positions.rs:337:9 | LL | true && let 1 = 1 | ^^^^^^^^^^^^^^^^^ @@ -9,6 +117,30 @@ help: enclose the `const` expression in braces LL | { true && let 1 = 1 } | + + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:384:22 + | +LL | let x = (true && let y = 1); + | ^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:389:20 + | +LL | ([1, 2, 3][let _ = ()]) + | ^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:81:16 + | +LL | use_expr!((let 0 = 1 && 0 == 0)); + | ^^^ + +error: expected expression, found `let` statement + --> $DIR/disallowed-positions.rs:85:16 + | +LL | use_expr!((let 0 = 1)); + | ^^^ + error: `let` expressions are not supported here --> $DIR/disallowed-positions.rs:29:9 | @@ -270,33 +402,33 @@ LL | use_expr!((let 0 = 1 && 0 == 0)); | ^^^^^^^^^^^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:84:16 + --> $DIR/disallowed-positions.rs:85:16 | LL | use_expr!((let 0 = 1)); | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:84:16 + --> $DIR/disallowed-positions.rs:85:16 | LL | use_expr!((let 0 = 1)); | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:84:16 + --> $DIR/disallowed-positions.rs:85:16 | LL | use_expr!((let 0 = 1)); | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:84:16 + --> $DIR/disallowed-positions.rs:85:16 | LL | use_expr!((let 0 = 1)); | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:90:9 + --> $DIR/disallowed-positions.rs:92:9 | LL | if &let 0 = 0 {} | ^^^^^^^^^ @@ -304,7 +436,7 @@ LL | if &let 0 = 0 {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:93:9 + --> $DIR/disallowed-positions.rs:95:9 | LL | if !let 0 = 0 {} | ^^^^^^^^^ @@ -312,7 +444,7 @@ LL | if !let 0 = 0 {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:94:9 + --> $DIR/disallowed-positions.rs:96:9 | LL | if *let 0 = 0 {} | ^^^^^^^^^ @@ -320,7 +452,7 @@ LL | if *let 0 = 0 {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:96:9 + --> $DIR/disallowed-positions.rs:98:9 | LL | if -let 0 = 0 {} | ^^^^^^^^^ @@ -328,72 +460,72 @@ LL | if -let 0 = 0 {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:104:9 + --> $DIR/disallowed-positions.rs:106:9 | LL | if (let 0 = 0)? {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:104:9 + --> $DIR/disallowed-positions.rs:106:9 | LL | if (let 0 = 0)? {} | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:108:16 + --> $DIR/disallowed-positions.rs:110:16 | LL | if true || let 0 = 0 {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `||` operators are not supported in let chain expressions - --> $DIR/disallowed-positions.rs:108:13 + --> $DIR/disallowed-positions.rs:110:13 | LL | if true || let 0 = 0 {} | ^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:109:17 + --> $DIR/disallowed-positions.rs:111:17 | LL | if (true || let 0 = 0) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `||` operators are not supported in let chain expressions - --> $DIR/disallowed-positions.rs:109:14 + --> $DIR/disallowed-positions.rs:111:14 | LL | if (true || let 0 = 0) {} | ^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:110:25 + --> $DIR/disallowed-positions.rs:112:25 | LL | if true && (true || let 0 = 0) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `||` operators are not supported in let chain expressions - --> $DIR/disallowed-positions.rs:110:22 + --> $DIR/disallowed-positions.rs:112:22 | LL | if true && (true || let 0 = 0) {} | ^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:111:25 + --> $DIR/disallowed-positions.rs:113:25 | LL | if true || (true && let 0 = 0) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:111:17 + --> $DIR/disallowed-positions.rs:113:17 | LL | if true || (true && let 0 = 0) {} | ^^^^^^^^^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:114:12 + --> $DIR/disallowed-positions.rs:116:12 | LL | if x = let 0 = 0 {} | ^^^^^^^^^ @@ -401,46 +533,46 @@ LL | if x = let 0 = 0 {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:117:15 + --> $DIR/disallowed-positions.rs:119:15 | LL | if true..(let 0 = 0) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:117:15 + --> $DIR/disallowed-positions.rs:119:15 | LL | if true..(let 0 = 0) {} | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:119:11 + --> $DIR/disallowed-positions.rs:121:11 | LL | if ..(let 0 = 0) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:119:11 + --> $DIR/disallowed-positions.rs:121:11 | LL | if ..(let 0 = 0) {} | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:121:9 + --> $DIR/disallowed-positions.rs:123:9 | LL | if (let 0 = 0).. {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:121:9 + --> $DIR/disallowed-positions.rs:123:9 | LL | if (let 0 = 0).. {} | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:125:8 + --> $DIR/disallowed-positions.rs:127:8 | LL | if let Range { start: _, end: _ } = true..true && false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -448,7 +580,7 @@ LL | if let Range { start: _, end: _ } = true..true && false {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:129:8 + --> $DIR/disallowed-positions.rs:131:8 | LL | if let Range { start: _, end: _ } = true..true || false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -456,7 +588,7 @@ LL | if let Range { start: _, end: _ } = true..true || false {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:136:8 + --> $DIR/disallowed-positions.rs:138:8 | LL | if let Range { start: F, end } = F..|| true {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -464,7 +596,7 @@ LL | if let Range { start: F, end } = F..|| true {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:144:8 + --> $DIR/disallowed-positions.rs:146:8 | LL | if let Range { start: true, end } = t..&&false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -472,7 +604,7 @@ LL | if let Range { start: true, end } = t..&&false {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:150:19 + --> $DIR/disallowed-positions.rs:152:19 | LL | if let true = let true = true {} | ^^^^^^^^^^^^^^^ @@ -480,7 +612,7 @@ LL | if let true = let true = true {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:154:12 + --> $DIR/disallowed-positions.rs:157:12 | LL | while &let 0 = 0 {} | ^^^^^^^^^ @@ -488,7 +620,7 @@ LL | while &let 0 = 0 {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:157:12 + --> $DIR/disallowed-positions.rs:160:12 | LL | while !let 0 = 0 {} | ^^^^^^^^^ @@ -496,7 +628,7 @@ LL | while !let 0 = 0 {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:158:12 + --> $DIR/disallowed-positions.rs:161:12 | LL | while *let 0 = 0 {} | ^^^^^^^^^ @@ -504,7 +636,7 @@ LL | while *let 0 = 0 {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:160:12 + --> $DIR/disallowed-positions.rs:163:12 | LL | while -let 0 = 0 {} | ^^^^^^^^^ @@ -512,72 +644,72 @@ LL | while -let 0 = 0 {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:168:12 + --> $DIR/disallowed-positions.rs:171:12 | LL | while (let 0 = 0)? {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:168:12 + --> $DIR/disallowed-positions.rs:171:12 | LL | while (let 0 = 0)? {} | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:172:19 + --> $DIR/disallowed-positions.rs:175:19 | LL | while true || let 0 = 0 {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `||` operators are not supported in let chain expressions - --> $DIR/disallowed-positions.rs:172:16 + --> $DIR/disallowed-positions.rs:175:16 | LL | while true || let 0 = 0 {} | ^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:173:20 + --> $DIR/disallowed-positions.rs:176:20 | LL | while (true || let 0 = 0) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `||` operators are not supported in let chain expressions - --> $DIR/disallowed-positions.rs:173:17 + --> $DIR/disallowed-positions.rs:176:17 | LL | while (true || let 0 = 0) {} | ^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:174:28 + --> $DIR/disallowed-positions.rs:177:28 | LL | while true && (true || let 0 = 0) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `||` operators are not supported in let chain expressions - --> $DIR/disallowed-positions.rs:174:25 + --> $DIR/disallowed-positions.rs:177:25 | LL | while true && (true || let 0 = 0) {} | ^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:175:28 + --> $DIR/disallowed-positions.rs:178:28 | LL | while true || (true && let 0 = 0) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:175:20 + --> $DIR/disallowed-positions.rs:178:20 | LL | while true || (true && let 0 = 0) {} | ^^^^^^^^^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:178:15 + --> $DIR/disallowed-positions.rs:181:15 | LL | while x = let 0 = 0 {} | ^^^^^^^^^ @@ -585,46 +717,46 @@ LL | while x = let 0 = 0 {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:181:18 + --> $DIR/disallowed-positions.rs:184:18 | LL | while true..(let 0 = 0) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:181:18 + --> $DIR/disallowed-positions.rs:184:18 | LL | while true..(let 0 = 0) {} | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:183:14 + --> $DIR/disallowed-positions.rs:186:14 | LL | while ..(let 0 = 0) {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:183:14 + --> $DIR/disallowed-positions.rs:186:14 | LL | while ..(let 0 = 0) {} | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:185:12 + --> $DIR/disallowed-positions.rs:188:12 | LL | while (let 0 = 0).. {} | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:185:12 + --> $DIR/disallowed-positions.rs:188:12 | LL | while (let 0 = 0).. {} | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:189:11 + --> $DIR/disallowed-positions.rs:192:11 | LL | while let Range { start: _, end: _ } = true..true && false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -632,7 +764,7 @@ LL | while let Range { start: _, end: _ } = true..true && false {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:193:11 + --> $DIR/disallowed-positions.rs:196:11 | LL | while let Range { start: _, end: _ } = true..true || false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -640,7 +772,7 @@ LL | while let Range { start: _, end: _ } = true..true || false {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:200:11 + --> $DIR/disallowed-positions.rs:203:11 | LL | while let Range { start: F, end } = F..|| true {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -648,7 +780,7 @@ LL | while let Range { start: F, end } = F..|| true {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:208:11 + --> $DIR/disallowed-positions.rs:211:11 | LL | while let Range { start: true, end } = t..&&false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -656,7 +788,7 @@ LL | while let Range { start: true, end } = t..&&false {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:214:22 + --> $DIR/disallowed-positions.rs:217:22 | LL | while let true = let true = true {} | ^^^^^^^^^^^^^^^ @@ -664,7 +796,7 @@ LL | while let true = let true = true {} = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:228:6 + --> $DIR/disallowed-positions.rs:232:6 | LL | &let 0 = 0; | ^^^^^^^^^ @@ -672,7 +804,7 @@ LL | &let 0 = 0; = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:230:6 + --> $DIR/disallowed-positions.rs:236:6 | LL | !let 0 = 0; | ^^^^^^^^^ @@ -680,7 +812,7 @@ LL | !let 0 = 0; = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:231:6 + --> $DIR/disallowed-positions.rs:239:6 | LL | *let 0 = 0; | ^^^^^^^^^ @@ -688,7 +820,7 @@ LL | *let 0 = 0; = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:233:6 + --> $DIR/disallowed-positions.rs:243:6 | LL | -let 0 = 0; | ^^^^^^^^^ @@ -696,59 +828,59 @@ LL | -let 0 = 0; = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:241:6 + --> $DIR/disallowed-positions.rs:253:6 | LL | (let 0 = 0)?; | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:241:6 + --> $DIR/disallowed-positions.rs:253:6 | LL | (let 0 = 0)?; | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:245:13 + --> $DIR/disallowed-positions.rs:259:13 | LL | true || let 0 = 0; | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `||` operators are not supported in let chain expressions - --> $DIR/disallowed-positions.rs:245:10 + --> $DIR/disallowed-positions.rs:259:10 | LL | true || let 0 = 0; | ^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:246:14 + --> $DIR/disallowed-positions.rs:262:14 | LL | (true || let 0 = 0); | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `||` operators are not supported in let chain expressions - --> $DIR/disallowed-positions.rs:246:11 + --> $DIR/disallowed-positions.rs:262:11 | LL | (true || let 0 = 0); | ^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:247:22 + --> $DIR/disallowed-positions.rs:265:22 | LL | true && (true || let 0 = 0); | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `||` operators are not supported in let chain expressions - --> $DIR/disallowed-positions.rs:247:19 + --> $DIR/disallowed-positions.rs:265:19 | LL | true && (true || let 0 = 0); | ^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:250:9 + --> $DIR/disallowed-positions.rs:270:9 | LL | x = let 0 = 0; | ^^^^^^^^^ @@ -756,46 +888,46 @@ LL | x = let 0 = 0; = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:252:12 + --> $DIR/disallowed-positions.rs:274:12 | LL | true..(let 0 = 0); | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:252:12 + --> $DIR/disallowed-positions.rs:274:12 | LL | true..(let 0 = 0); | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:253:8 + --> $DIR/disallowed-positions.rs:277:8 | LL | ..(let 0 = 0); | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:253:8 + --> $DIR/disallowed-positions.rs:277:8 | LL | ..(let 0 = 0); | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:254:6 + --> $DIR/disallowed-positions.rs:280:6 | LL | (let 0 = 0)..; | ^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:254:6 + --> $DIR/disallowed-positions.rs:280:6 | LL | (let 0 = 0)..; | ^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:256:6 + --> $DIR/disallowed-positions.rs:284:6 | LL | (let Range { start: _, end: _ } = true..true || false); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ @@ -803,20 +935,20 @@ LL | (let Range { start: _, end: _ } = true..true || false); = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:260:6 + --> $DIR/disallowed-positions.rs:289:6 | LL | (let true = let true = true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:260:6 + --> $DIR/disallowed-positions.rs:289:6 | LL | (let true = let true = true); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:264:6 + --> $DIR/disallowed-positions.rs:307:6 | LL | &let 0 = 0 | ^^^^^^^^^ @@ -824,7 +956,7 @@ LL | &let 0 = 0 = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:275:17 + --> $DIR/disallowed-positions.rs:319:17 | LL | true && let 1 = 1 | ^^^^^^^^^ @@ -832,7 +964,7 @@ LL | true && let 1 = 1 = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:279:17 + --> $DIR/disallowed-positions.rs:323:17 | LL | true && let 1 = 1 | ^^^^^^^^^ @@ -840,7 +972,7 @@ LL | true && let 1 = 1 = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:283:17 + --> $DIR/disallowed-positions.rs:327:17 | LL | true && let 1 = 1 | ^^^^^^^^^ @@ -848,7 +980,7 @@ LL | true && let 1 = 1 = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:293:17 + --> $DIR/disallowed-positions.rs:337:17 | LL | true && let 1 = 1 | ^^^^^^^^^ @@ -856,124 +988,124 @@ LL | true && let 1 = 1 = note: only supported directly in conditions of `if` and `while` expressions error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:302:9 + --> $DIR/disallowed-positions.rs:346:9 | LL | if (let Some(a) = opt && true) { | ^^^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:302:9 + --> $DIR/disallowed-positions.rs:346:9 | LL | if (let Some(a) = opt && true) { | ^^^^^^^^^^^^^^^^^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:306:9 + --> $DIR/disallowed-positions.rs:350:9 | LL | if (let Some(a) = opt) && true { | ^^^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:306:9 + --> $DIR/disallowed-positions.rs:350:9 | LL | if (let Some(a) = opt) && true { | ^^^^^^^^^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:309:9 + --> $DIR/disallowed-positions.rs:353:9 | LL | if (let Some(a) = opt) && (let Some(b) = a) { | ^^^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:309:9 + --> $DIR/disallowed-positions.rs:353:9 | LL | if (let Some(a) = opt) && (let Some(b) = a) { | ^^^^^^^^^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:309:32 + --> $DIR/disallowed-positions.rs:353:32 | LL | if (let Some(a) = opt) && (let Some(b) = a) { | ^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:309:32 + --> $DIR/disallowed-positions.rs:353:32 | LL | if (let Some(a) = opt) && (let Some(b) = a) { | ^^^^^^^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:316:9 + --> $DIR/disallowed-positions.rs:360:9 | LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 { | ^^^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:316:9 + --> $DIR/disallowed-positions.rs:360:9 | LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:316:31 + --> $DIR/disallowed-positions.rs:360:31 | LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 { | ^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:316:31 + --> $DIR/disallowed-positions.rs:360:31 | LL | if (let Some(a) = opt && (let Some(b) = a)) && b == 1 { | ^^^^^^^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:320:9 + --> $DIR/disallowed-positions.rs:364:9 | LL | if (let Some(a) = opt && (let Some(b) = a)) && true { | ^^^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:320:9 + --> $DIR/disallowed-positions.rs:364:9 | LL | if (let Some(a) = opt && (let Some(b) = a)) && true { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:320:31 + --> $DIR/disallowed-positions.rs:364:31 | LL | if (let Some(a) = opt && (let Some(b) = a)) && true { | ^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:320:31 + --> $DIR/disallowed-positions.rs:364:31 | LL | if (let Some(a) = opt && (let Some(b) = a)) && true { | ^^^^^^^^^^^^^^^ error: `let` expressions are not supported here - --> $DIR/disallowed-positions.rs:324:9 + --> $DIR/disallowed-positions.rs:368:9 | LL | if (let Some(a) = opt && (true)) && true { | ^^^^^^^^^^^^^^^^^ | = note: only supported directly in conditions of `if` and `while` expressions note: `let`s wrapped in parentheses are not supported in a context with let chains - --> $DIR/disallowed-positions.rs:324:9 + --> $DIR/disallowed-positions.rs:368:9 | LL | if (let Some(a) = opt && (true)) && true { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:90:8 + --> $DIR/disallowed-positions.rs:92:8 | LL | if &let 0 = 0 {} | ^^^^^^^^^^ expected `bool`, found `&bool` @@ -985,19 +1117,19 @@ LL + if let 0 = 0 {} | error[E0614]: type `bool` cannot be dereferenced - --> $DIR/disallowed-positions.rs:94:8 + --> $DIR/disallowed-positions.rs:96:8 | LL | if *let 0 = 0 {} | ^^^^^^^^^^ error[E0600]: cannot apply unary operator `-` to type `bool` - --> $DIR/disallowed-positions.rs:96:8 + --> $DIR/disallowed-positions.rs:98:8 | LL | if -let 0 = 0 {} | ^^^^^^^^^^ cannot apply unary operator `-` error[E0277]: the `?` operator can only be applied to values that implement `Try` - --> $DIR/disallowed-positions.rs:104:8 + --> $DIR/disallowed-positions.rs:106:8 | LL | if (let 0 = 0)? {} | ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool` @@ -1005,7 +1137,7 @@ LL | if (let 0 = 0)? {} = help: the trait `Try` is not implemented for `bool` error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`) - --> $DIR/disallowed-positions.rs:104:19 + --> $DIR/disallowed-positions.rs:106:19 | LL | / fn nested_within_if_expr() { LL | | if &let 0 = 0 {} @@ -1015,14 +1147,14 @@ LL | | LL | | if (let 0 = 0)? {} | | ^ cannot use the `?` operator in a function that returns `()` ... | -LL | | if let true = let true = true {} +LL | | LL | | } | |_- this function should return `Result` or `Option` to accept `?` | = help: the trait `FromResidual<_>` is not implemented for `()` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:114:8 + --> $DIR/disallowed-positions.rs:116:8 | LL | if x = let 0 = 0 {} | ^^^^^^^^^^^^^ expected `bool`, found `()` @@ -1033,7 +1165,7 @@ LL | if x == let 0 = 0 {} | ~~ error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:117:8 + --> $DIR/disallowed-positions.rs:119:8 | LL | if true..(let 0 = 0) {} | ^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range` @@ -1042,7 +1174,7 @@ LL | if true..(let 0 = 0) {} found struct `std::ops::Range` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:119:8 + --> $DIR/disallowed-positions.rs:121:8 | LL | if ..(let 0 = 0) {} | ^^^^^^^^^^^^^ expected `bool`, found struct `RangeTo` @@ -1051,7 +1183,7 @@ LL | if ..(let 0 = 0) {} found struct `RangeTo` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:121:8 + --> $DIR/disallowed-positions.rs:123:8 | LL | if (let 0 = 0).. {} | ^^^^^^^^^^^^^ expected `bool`, found struct `RangeFrom` @@ -1060,7 +1192,7 @@ LL | if (let 0 = 0).. {} found struct `RangeFrom` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:125:12 + --> $DIR/disallowed-positions.rs:127:12 | LL | if let Range { start: _, end: _ } = true..true && false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool` @@ -1071,7 +1203,7 @@ LL | if let Range { start: _, end: _ } = true..true && false {} found struct `std::ops::Range<_>` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:125:8 + --> $DIR/disallowed-positions.rs:127:8 | LL | if let Range { start: _, end: _ } = true..true && false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range` @@ -1080,7 +1212,7 @@ LL | if let Range { start: _, end: _ } = true..true && false {} found struct `std::ops::Range` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:129:12 + --> $DIR/disallowed-positions.rs:131:12 | LL | if let Range { start: _, end: _ } = true..true || false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool` @@ -1091,7 +1223,7 @@ LL | if let Range { start: _, end: _ } = true..true || false {} found struct `std::ops::Range<_>` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:129:8 + --> $DIR/disallowed-positions.rs:131:8 | LL | if let Range { start: _, end: _ } = true..true || false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range` @@ -1100,7 +1232,7 @@ LL | if let Range { start: _, end: _ } = true..true || false {} found struct `std::ops::Range` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:136:12 + --> $DIR/disallowed-positions.rs:138:12 | LL | if let Range { start: F, end } = F..|| true {} | ^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `fn() -> bool` @@ -1111,20 +1243,20 @@ LL | if let Range { start: F, end } = F..|| true {} found struct `std::ops::Range<_>` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:136:41 + --> $DIR/disallowed-positions.rs:138:41 | LL | if let Range { start: F, end } = F..|| true {} | ^^^^^^^ expected `bool`, found closure | = note: expected type `bool` - found closure `[closure@$DIR/disallowed-positions.rs:136:41: 136:48]` + found closure `[closure@$DIR/disallowed-positions.rs:138:41: 138:48]` help: use parentheses to call this closure | LL | if let Range { start: F, end } = F..(|| true)() {} | + +++ error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:136:8 + --> $DIR/disallowed-positions.rs:138:8 | LL | if let Range { start: F, end } = F..|| true {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range` @@ -1133,7 +1265,7 @@ LL | if let Range { start: F, end } = F..|| true {} found struct `std::ops::Range` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:144:12 + --> $DIR/disallowed-positions.rs:146:12 | LL | if let Range { start: true, end } = t..&&false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `&&bool` @@ -1144,7 +1276,7 @@ LL | if let Range { start: true, end } = t..&&false {} found struct `std::ops::Range<_>` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:144:44 + --> $DIR/disallowed-positions.rs:146:44 | LL | if let Range { start: true, end } = t..&&false {} | ^^^^^^^ expected `bool`, found `&&bool` @@ -1156,7 +1288,7 @@ LL + if let Range { start: true, end } = t..false {} | error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:144:8 + --> $DIR/disallowed-positions.rs:146:8 | LL | if let Range { start: true, end } = t..&&false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range` @@ -1165,7 +1297,7 @@ LL | if let Range { start: true, end } = t..&&false {} found struct `std::ops::Range` error[E0277]: the `?` operator can only be applied to values that implement `Try` - --> $DIR/disallowed-positions.rs:100:20 + --> $DIR/disallowed-positions.rs:102:20 | LL | if let 0 = 0? {} | ^^ the `?` operator cannot be applied to type `{integer}` @@ -1173,7 +1305,7 @@ LL | if let 0 = 0? {} = help: the trait `Try` is not implemented for `{integer}` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:154:11 + --> $DIR/disallowed-positions.rs:157:11 | LL | while &let 0 = 0 {} | ^^^^^^^^^^ expected `bool`, found `&bool` @@ -1185,19 +1317,19 @@ LL + while let 0 = 0 {} | error[E0614]: type `bool` cannot be dereferenced - --> $DIR/disallowed-positions.rs:158:11 + --> $DIR/disallowed-positions.rs:161:11 | LL | while *let 0 = 0 {} | ^^^^^^^^^^ error[E0600]: cannot apply unary operator `-` to type `bool` - --> $DIR/disallowed-positions.rs:160:11 + --> $DIR/disallowed-positions.rs:163:11 | LL | while -let 0 = 0 {} | ^^^^^^^^^^ cannot apply unary operator `-` error[E0277]: the `?` operator can only be applied to values that implement `Try` - --> $DIR/disallowed-positions.rs:168:11 + --> $DIR/disallowed-positions.rs:171:11 | LL | while (let 0 = 0)? {} | ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool` @@ -1205,7 +1337,7 @@ LL | while (let 0 = 0)? {} = help: the trait `Try` is not implemented for `bool` error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`) - --> $DIR/disallowed-positions.rs:168:22 + --> $DIR/disallowed-positions.rs:171:22 | LL | / fn nested_within_while_expr() { LL | | while &let 0 = 0 {} @@ -1215,14 +1347,14 @@ LL | | LL | | while (let 0 = 0)? {} | | ^ cannot use the `?` operator in a function that returns `()` ... | -LL | | while let true = let true = true {} +LL | | LL | | } | |_- this function should return `Result` or `Option` to accept `?` | = help: the trait `FromResidual<_>` is not implemented for `()` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:178:11 + --> $DIR/disallowed-positions.rs:181:11 | LL | while x = let 0 = 0 {} | ^^^^^^^^^^^^^ expected `bool`, found `()` @@ -1233,7 +1365,7 @@ LL | while x == let 0 = 0 {} | ~~ error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:181:11 + --> $DIR/disallowed-positions.rs:184:11 | LL | while true..(let 0 = 0) {} | ^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range` @@ -1242,7 +1374,7 @@ LL | while true..(let 0 = 0) {} found struct `std::ops::Range` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:183:11 + --> $DIR/disallowed-positions.rs:186:11 | LL | while ..(let 0 = 0) {} | ^^^^^^^^^^^^^ expected `bool`, found struct `RangeTo` @@ -1251,7 +1383,7 @@ LL | while ..(let 0 = 0) {} found struct `RangeTo` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:185:11 + --> $DIR/disallowed-positions.rs:188:11 | LL | while (let 0 = 0).. {} | ^^^^^^^^^^^^^ expected `bool`, found struct `RangeFrom` @@ -1260,7 +1392,7 @@ LL | while (let 0 = 0).. {} found struct `RangeFrom` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:189:15 + --> $DIR/disallowed-positions.rs:192:15 | LL | while let Range { start: _, end: _ } = true..true && false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool` @@ -1271,7 +1403,7 @@ LL | while let Range { start: _, end: _ } = true..true && false {} found struct `std::ops::Range<_>` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:189:11 + --> $DIR/disallowed-positions.rs:192:11 | LL | while let Range { start: _, end: _ } = true..true && false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range` @@ -1280,7 +1412,7 @@ LL | while let Range { start: _, end: _ } = true..true && false {} found struct `std::ops::Range` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:193:15 + --> $DIR/disallowed-positions.rs:196:15 | LL | while let Range { start: _, end: _ } = true..true || false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool` @@ -1291,7 +1423,7 @@ LL | while let Range { start: _, end: _ } = true..true || false {} found struct `std::ops::Range<_>` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:193:11 + --> $DIR/disallowed-positions.rs:196:11 | LL | while let Range { start: _, end: _ } = true..true || false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range` @@ -1300,7 +1432,7 @@ LL | while let Range { start: _, end: _ } = true..true || false {} found struct `std::ops::Range` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:200:15 + --> $DIR/disallowed-positions.rs:203:15 | LL | while let Range { start: F, end } = F..|| true {} | ^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `fn() -> bool` @@ -1311,20 +1443,20 @@ LL | while let Range { start: F, end } = F..|| true {} found struct `std::ops::Range<_>` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:200:44 + --> $DIR/disallowed-positions.rs:203:44 | LL | while let Range { start: F, end } = F..|| true {} | ^^^^^^^ expected `bool`, found closure | = note: expected type `bool` - found closure `[closure@$DIR/disallowed-positions.rs:200:44: 200:51]` + found closure `[closure@$DIR/disallowed-positions.rs:203:44: 203:51]` help: use parentheses to call this closure | LL | while let Range { start: F, end } = F..(|| true)() {} | + +++ error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:200:11 + --> $DIR/disallowed-positions.rs:203:11 | LL | while let Range { start: F, end } = F..|| true {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range` @@ -1333,7 +1465,7 @@ LL | while let Range { start: F, end } = F..|| true {} found struct `std::ops::Range` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:208:15 + --> $DIR/disallowed-positions.rs:211:15 | LL | while let Range { start: true, end } = t..&&false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^ - this expression has type `&&bool` @@ -1344,7 +1476,7 @@ LL | while let Range { start: true, end } = t..&&false {} found struct `std::ops::Range<_>` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:208:47 + --> $DIR/disallowed-positions.rs:211:47 | LL | while let Range { start: true, end } = t..&&false {} | ^^^^^^^ expected `bool`, found `&&bool` @@ -1356,7 +1488,7 @@ LL + while let Range { start: true, end } = t..false {} | error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:208:11 + --> $DIR/disallowed-positions.rs:211:11 | LL | while let Range { start: true, end } = t..&&false {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `bool`, found struct `std::ops::Range` @@ -1365,7 +1497,7 @@ LL | while let Range { start: true, end } = t..&&false {} found struct `std::ops::Range` error[E0277]: the `?` operator can only be applied to values that implement `Try` - --> $DIR/disallowed-positions.rs:164:23 + --> $DIR/disallowed-positions.rs:167:23 | LL | while let 0 = 0? {} | ^^ the `?` operator cannot be applied to type `{integer}` @@ -1373,19 +1505,19 @@ LL | while let 0 = 0? {} = help: the trait `Try` is not implemented for `{integer}` error[E0614]: type `bool` cannot be dereferenced - --> $DIR/disallowed-positions.rs:231:5 + --> $DIR/disallowed-positions.rs:239:5 | LL | *let 0 = 0; | ^^^^^^^^^^ error[E0600]: cannot apply unary operator `-` to type `bool` - --> $DIR/disallowed-positions.rs:233:5 + --> $DIR/disallowed-positions.rs:243:5 | LL | -let 0 = 0; | ^^^^^^^^^^ cannot apply unary operator `-` error[E0277]: the `?` operator can only be applied to values that implement `Try` - --> $DIR/disallowed-positions.rs:241:5 + --> $DIR/disallowed-positions.rs:253:5 | LL | (let 0 = 0)?; | ^^^^^^^^^^^^ the `?` operator cannot be applied to type `bool` @@ -1393,12 +1525,12 @@ LL | (let 0 = 0)?; = help: the trait `Try` is not implemented for `bool` error[E0277]: the `?` operator can only be used in a function that returns `Result` or `Option` (or another type that implements `FromResidual`) - --> $DIR/disallowed-positions.rs:241:16 + --> $DIR/disallowed-positions.rs:253:16 | LL | / fn outside_if_and_while_expr() { LL | | &let 0 = 0; LL | | -LL | | !let 0 = 0; +LL | | ... | LL | | (let 0 = 0)?; | | ^ cannot use the `?` operator in a function that returns `()` @@ -1410,7 +1542,7 @@ LL | | } = help: the trait `FromResidual<_>` is not implemented for `()` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:256:10 + --> $DIR/disallowed-positions.rs:284:10 | LL | (let Range { start: _, end: _ } = true..true || false); | ^^^^^^^^^^^^^^^^^^^^^^^^^^ ---- this expression has type `bool` @@ -1421,7 +1553,7 @@ LL | (let Range { start: _, end: _ } = true..true || false); found struct `std::ops::Range<_>` error[E0308]: mismatched types - --> $DIR/disallowed-positions.rs:264:5 + --> $DIR/disallowed-positions.rs:307:5 | LL | fn outside_if_and_while_expr() { | - help: try adding a return type: `-> &bool` @@ -1430,14 +1562,14 @@ LL | &let 0 = 0 | ^^^^^^^^^^ expected `()`, found `&bool` error[E0277]: the `?` operator can only be applied to values that implement `Try` - --> $DIR/disallowed-positions.rs:237:17 + --> $DIR/disallowed-positions.rs:249:17 | LL | let 0 = 0?; | ^^ the `?` operator cannot be applied to type `{integer}` | = help: the trait `Try` is not implemented for `{integer}` -error: aborting due to 134 previous errors +error: aborting due to 156 previous errors Some errors have detailed explanations: E0277, E0308, E0600, E0614. For more information about an error, try `rustc --explain E0277`. diff --git a/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs b/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs index e66caa19ec96b..12befc637c787 100644 --- a/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs +++ b/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.rs @@ -17,6 +17,7 @@ fn main() { //~| ERROR `let` expressions are not supported here //~| ERROR mismatched types //~| ERROR mismatched types + //~| ERROR expected expression, found `let` statement return; }; diff --git a/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr b/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr index eea8ed0c9633e..498a112fa9bb3 100644 --- a/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr +++ b/src/test/ui/rfc-2497-if-let-chains/ensure-that-let-else-does-not-interact-with-let-chains.stderr @@ -9,6 +9,12 @@ help: wrap the expression in parentheses LL | let Some(n) = (opt && n == 1) else { | + + +error: expected expression, found `let` statement + --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:15:26 + | +LL | let Some(n) = opt && let another = n else { + | ^^^ + error: a `&&` expression cannot be directly assigned in `let...else` --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:15:19 | @@ -21,43 +27,43 @@ LL | let Some(n) = (opt && let another = n) else { | + + error: this `if` expression is missing a block after the condition - --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:23:5 + --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:24:5 | LL | if let Some(n) = opt else { | ^^ | help: add a block here - --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:23:25 + --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:24:25 | LL | if let Some(n) = opt else { | ^ error: this `if` expression is missing a block after the condition - --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:27:5 + --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:28:5 | LL | if let Some(n) = opt && n == 1 else { | ^^ | help: add a block here - --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:27:35 + --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:28:35 | LL | if let Some(n) = opt && n == 1 else { | ^ error: this `if` expression is missing a block after the condition - --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:31:5 + --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:32:5 | LL | if let Some(n) = opt && let another = n else { | ^^ | help: add a block here - --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:31:44 + --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:32:44 | LL | if let Some(n) = opt && let another = n else { | ^ error: expected `{`, found keyword `else` - --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:37:33 + --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:38:33 | LL | while let Some(n) = opt else { | ----- ----------------- ^^^^ expected `{` @@ -66,7 +72,7 @@ LL | while let Some(n) = opt else { | while parsing the body of this `while` expression error: expected `{`, found keyword `else` - --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:43:43 + --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:44:43 | LL | while let Some(n) = opt && n == 1 else { | ----- --------------------------- ^^^^ expected `{` @@ -75,7 +81,7 @@ LL | while let Some(n) = opt && n == 1 else { | while parsing the body of this `while` expression error: expected `{`, found keyword `else` - --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:49:52 + --> $DIR/ensure-that-let-else-does-not-interact-with-let-chains.rs:50:52 | LL | while let Some(n) = opt && let another = n else { | ----- ------------------------------------ ^^^^ expected `{` @@ -131,6 +137,6 @@ LL | let Some(n) = opt && let another = n else { = note: expected type `bool` found enum `Option<_>` -error: aborting due to 13 previous errors +error: aborting due to 14 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/rfc-2497-if-let-chains/feature-gate.rs b/src/test/ui/rfc-2497-if-let-chains/feature-gate.rs index ac60bc7e57fd4..8771821130848 100644 --- a/src/test/ui/rfc-2497-if-let-chains/feature-gate.rs +++ b/src/test/ui/rfc-2497-if-let-chains/feature-gate.rs @@ -39,6 +39,7 @@ fn _macros() { noop_expr!((let 0 = 1)); //~^ ERROR `let` expressions in this position are unstable [E0658] + //~| ERROR expected expression, found `let` statement macro_rules! use_expr { ($e:expr) => { @@ -48,9 +49,9 @@ fn _macros() { } #[cfg(FALSE)] (let 0 = 1); //~^ ERROR `let` expressions in this position are unstable [E0658] + //~| ERROR expected expression, found `let` statement use_expr!(let 0 = 1); //~^ ERROR no rules expected the token `let` - // ^--- FIXME(53667): Consider whether `Let` can be added to `ident_can_begin_expr`. } fn main() {} diff --git a/src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr b/src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr index 1eabee47c64ac..bcea8bbaa730b 100644 --- a/src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr +++ b/src/test/ui/rfc-2497-if-let-chains/feature-gate.stderr @@ -1,5 +1,17 @@ +error: expected expression, found `let` statement + --> $DIR/feature-gate.rs:50:20 + | +LL | #[cfg(FALSE)] (let 0 = 1); + | ^^^ + +error: expected expression, found `let` statement + --> $DIR/feature-gate.rs:40:17 + | +LL | noop_expr!((let 0 = 1)); + | ^^^ + error: no rules expected the token `let` - --> $DIR/feature-gate.rs:51:15 + --> $DIR/feature-gate.rs:53:15 | LL | macro_rules! use_expr { | --------------------- when calling this macro @@ -62,7 +74,7 @@ LL | while let Range { start: _, end: _ } = (true..true) && false {} = help: add `#![feature(let_chains)]` to the crate attributes to enable error[E0658]: `let` expressions in this position are unstable - --> $DIR/feature-gate.rs:49:20 + --> $DIR/feature-gate.rs:50:20 | LL | #[cfg(FALSE)] (let 0 = 1); | ^^^^^^^^^ @@ -79,6 +91,6 @@ LL | noop_expr!((let 0 = 1)); = note: see issue #53667 for more information = help: add `#![feature(let_chains)]` to the crate attributes to enable -error: aborting due to 9 previous errors +error: aborting due to 11 previous errors For more information about this error, try `rustc --explain E0658`. diff --git a/src/test/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.rs b/src/test/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.rs new file mode 100644 index 0000000000000..6cc53a1935b95 --- /dev/null +++ b/src/test/ui/rfc-2497-if-let-chains/invalid-let-in-a-valid-let-context.rs @@ -0,0 +1,17 @@ +// check-pass +// known-bug + +#![feature(let_chains)] + +fn main() { + let _opt = Some(1i32); + + #[cfg(FALSE)] + { + if let Some(elem) = _opt && { + [1, 2, 3][let _ = ()]; + true + } { + } + } +} From 557793c2a4c5b4713d51c5c55e4f54c285bdc084 Mon Sep 17 00:00:00 2001 From: Mark Rousskov Date: Sat, 25 Jun 2022 09:56:56 -0400 Subject: [PATCH 19/20] Bump RLS to latest master on rust-lang/rls Of primary interest, this merges rust-lang/rls@ece09b88c0365947af79c0ffdeea02bc6c1eec25 into rust-lang/rust, which brings in the changes that fix RLS tests broken by #97853. #97853 already introduced that commit's changes (under 27f4044df03d15c7c38a483c3e4635cf4f51807d) but without putting those changes on rust-lang/rls as a branch, so we ended up with an orphan commit that caused trouble when updating submodules in rust-lang/rust. This commit, once merged into rust-lang/rust, should continue to let RLS tests to pass on rust-lang/rust's side and move us back into a healthy state where tip of the submodule points to a valid master commit in the rust-lang/rls repository. --- Cargo.lock | 3 +-- src/tools/rls | 2 +- 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 1108c1f4d4c20..b6f17ad7838c3 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -3101,7 +3101,6 @@ name = "racer" version = "2.2.2" dependencies = [ "bitflags", - "clap 2.34.0", "derive_more", "env_logger 0.7.1", "humantime 2.0.1", @@ -3325,7 +3324,7 @@ dependencies = [ "difference", "env_logger 0.9.0", "futures 0.3.19", - "heck 0.3.1", + "heck 0.4.0", "home", "itertools", "jsonrpc-core", diff --git a/src/tools/rls b/src/tools/rls index 27f4044df03d1..ece09b88c0365 160000 --- a/src/tools/rls +++ b/src/tools/rls @@ -1 +1 @@ -Subproject commit 27f4044df03d15c7c38a483c3e4635cf4f51807d +Subproject commit ece09b88c0365947af79c0ffdeea02bc6c1eec25 From 50a46b92f6b09e5cab6e8b4f4683cf8518102115 Mon Sep 17 00:00:00 2001 From: Antoni Boucher Date: Sat, 25 Jun 2022 11:48:26 -0400 Subject: [PATCH 20/20] Fix backtrace UI test when panic=abort is used --- src/test/ui/backtrace.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/test/ui/backtrace.rs b/src/test/ui/backtrace.rs index c2d9e222b84a4..01b276d67ed87 100644 --- a/src/test/ui/backtrace.rs +++ b/src/test/ui/backtrace.rs @@ -43,6 +43,7 @@ fn expected(fn_name: &str) -> String { format!(" backtrace::{}", fn_name) } +#[cfg(not(panic = "abort"))] fn contains_verbose_expected(s: &str, fn_name: &str) -> bool { // HACK(eddyb) work around the fact that verbosely demangled stack traces // (from `RUST_BACKTRACE=full`, or, as is the case here, panic-in-panic)