From fd76552a4b41d132701dc0857a9fee9a3850088e Mon Sep 17 00:00:00 2001 From: joboet Date: Wed, 18 May 2022 12:18:51 +0200 Subject: [PATCH 01/21] 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/21] 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/21] 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 5823d7b56346247d6def30c946a49e47e7fe9848 Mon Sep 17 00:00:00 2001 From: Iago-lito Date: Mon, 30 May 2022 14:01:24 +0200 Subject: [PATCH 04/21] Partial stabilization of "nonzero_unchecked_ops". --- library/core/src/num/nonzero.rs | 52 ++++++++++++++++----------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index 70969edd6eaf7..5a7e8ef82c87a 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -316,7 +316,6 @@ macro_rules! nonzero_unsigned_operations { /// # Examples /// /// ``` - /// #![feature(nonzero_ops)] #[doc = concat!("# use std::num::", stringify!($Ty), ";")] /// /// # fn main() { test().unwrap(); } @@ -331,7 +330,8 @@ macro_rules! nonzero_unsigned_operations { /// # Some(()) /// # } /// ``` - #[unstable(feature = "nonzero_ops", issue = "84186")] + #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] + #[rustc_const_unstable(feature = "const_nonzero_checked_ops", issue = "97547")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -351,7 +351,6 @@ macro_rules! nonzero_unsigned_operations { /// # Examples /// /// ``` - /// #![feature(nonzero_ops)] #[doc = concat!("# use std::num::", stringify!($Ty), ";")] /// /// # fn main() { test().unwrap(); } @@ -366,7 +365,8 @@ macro_rules! nonzero_unsigned_operations { /// # Some(()) /// # } /// ``` - #[unstable(feature = "nonzero_ops", issue = "84186")] + #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] + #[rustc_const_unstable(feature = "const_nonzero_checked_ops", issue = "97547")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -415,7 +415,6 @@ macro_rules! nonzero_unsigned_operations { /// # Examples /// /// ``` - /// #![feature(nonzero_ops)] #[doc = concat!("# use std::num::", stringify!($Ty), ";")] /// /// # fn main() { test().unwrap(); } @@ -432,7 +431,8 @@ macro_rules! nonzero_unsigned_operations { /// # Some(()) /// # } /// ``` - #[unstable(feature = "nonzero_ops", issue = "84186")] + #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] + #[rustc_const_unstable(feature = "const_nonzero_checked_ops", issue = "97547")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -521,7 +521,6 @@ macro_rules! nonzero_signed_operations { /// # Example /// /// ``` - /// #![feature(nonzero_ops)] #[doc = concat!("# use std::num::", stringify!($Ty), ";")] /// /// # fn main() { test().unwrap(); } @@ -534,7 +533,8 @@ macro_rules! nonzero_signed_operations { /// # Some(()) /// # } /// ``` - #[unstable(feature = "nonzero_ops", issue = "84186")] + #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] + #[rustc_const_unstable(feature = "const_nonzero_checked_ops", issue = "97547")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -551,7 +551,6 @@ macro_rules! nonzero_signed_operations { /// # Example /// /// ``` - /// #![feature(nonzero_ops)] #[doc = concat!("# use std::num::", stringify!($Ty), ";")] /// /// # fn main() { test().unwrap(); } @@ -566,7 +565,8 @@ macro_rules! nonzero_signed_operations { /// # Some(()) /// # } /// ``` - #[unstable(feature = "nonzero_ops", issue = "84186")] + #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] + #[rustc_const_unstable(feature = "const_nonzero_checked_ops", issue = "97547")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -586,7 +586,6 @@ macro_rules! nonzero_signed_operations { /// # Example /// /// ``` - /// #![feature(nonzero_ops)] #[doc = concat!("# use std::num::", stringify!($Ty), ";")] /// /// # fn main() { test().unwrap(); } @@ -602,7 +601,8 @@ macro_rules! nonzero_signed_operations { /// # Some(()) /// # } /// ``` - #[unstable(feature = "nonzero_ops", issue = "84186")] + #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] + #[rustc_const_unstable(feature = "const_nonzero_checked_ops", issue = "97547")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -621,7 +621,6 @@ macro_rules! nonzero_signed_operations { /// # Example /// /// ``` - /// #![feature(nonzero_ops)] #[doc = concat!("# use std::num::", stringify!($Ty), ";")] /// /// # fn main() { test().unwrap(); } @@ -642,7 +641,8 @@ macro_rules! nonzero_signed_operations { /// # Some(()) /// # } /// ``` - #[unstable(feature = "nonzero_ops", issue = "84186")] + #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] + #[rustc_const_unstable(feature = "const_nonzero_checked_ops", issue = "97547")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -657,7 +657,6 @@ macro_rules! nonzero_signed_operations { /// # Example /// /// ``` - /// #![feature(nonzero_ops)] #[doc = concat!("# use std::num::", stringify!($Ty), ";")] /// /// # fn main() { test().unwrap(); } @@ -677,7 +676,8 @@ macro_rules! nonzero_signed_operations { /// # Some(()) /// # } /// ``` - #[unstable(feature = "nonzero_ops", issue = "84186")] + #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] + #[rustc_const_unstable(feature = "const_nonzero_checked_ops", issue = "97547")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -692,7 +692,6 @@ macro_rules! nonzero_signed_operations { /// # Example /// /// ``` - /// #![feature(nonzero_ops)] #[doc = concat!("# use std::num::", stringify!($Ty), ";")] #[doc = concat!("# use std::num::", stringify!($Uty), ";")] /// @@ -712,7 +711,8 @@ macro_rules! nonzero_signed_operations { /// # Some(()) /// # } /// ``` - #[unstable(feature = "nonzero_ops", issue = "84186")] + #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] + #[rustc_const_unstable(feature = "const_nonzero_checked_ops", issue = "97547")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -746,7 +746,6 @@ macro_rules! nonzero_unsigned_signed_operations { /// # Examples /// /// ``` - /// #![feature(nonzero_ops)] #[doc = concat!("# use std::num::", stringify!($Ty), ";")] /// /// # fn main() { test().unwrap(); } @@ -761,7 +760,8 @@ macro_rules! nonzero_unsigned_signed_operations { /// # Some(()) /// # } /// ``` - #[unstable(feature = "nonzero_ops", issue = "84186")] + #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] + #[rustc_const_unstable(feature = "const_nonzero_checked_ops", issue = "97547")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -782,7 +782,6 @@ macro_rules! nonzero_unsigned_signed_operations { /// # Examples /// /// ``` - /// #![feature(nonzero_ops)] #[doc = concat!("# use std::num::", stringify!($Ty), ";")] /// /// # fn main() { test().unwrap(); } @@ -797,7 +796,8 @@ macro_rules! nonzero_unsigned_signed_operations { /// # Some(()) /// # } /// ``` - #[unstable(feature = "nonzero_ops", issue = "84186")] + #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] + #[rustc_const_unstable(feature = "const_nonzero_checked_ops", issue = "97547")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -855,7 +855,6 @@ macro_rules! nonzero_unsigned_signed_operations { /// # Examples /// /// ``` - /// #![feature(nonzero_ops)] #[doc = concat!("# use std::num::", stringify!($Ty), ";")] /// /// # fn main() { test().unwrap(); } @@ -870,7 +869,8 @@ macro_rules! nonzero_unsigned_signed_operations { /// # Some(()) /// # } /// ``` - #[unstable(feature = "nonzero_ops", issue = "84186")] + #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] + #[rustc_const_unstable(feature = "const_nonzero_checked_ops", issue = "97547")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -899,7 +899,6 @@ macro_rules! nonzero_unsigned_signed_operations { /// # Examples /// /// ``` - /// #![feature(nonzero_ops)] #[doc = concat!("# use std::num::", stringify!($Ty), ";")] /// /// # fn main() { test().unwrap(); } @@ -914,7 +913,8 @@ macro_rules! nonzero_unsigned_signed_operations { /// # Some(()) /// # } /// ``` - #[unstable(feature = "nonzero_ops", issue = "84186")] + #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] + #[rustc_const_unstable(feature = "const_nonzero_checked_ops", issue = "97547")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] From 69e8e7e73b7e56e518a2552097578d590043a30e Mon Sep 17 00:00:00 2001 From: Iago-lito Date: Thu, 9 Jun 2022 09:17:06 +0200 Subject: [PATCH 05/21] Stabilize NonZero* checked operations constness. --- library/core/src/num/nonzero.rs | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-) diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index 5a7e8ef82c87a..5e95edaee19ff 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -331,7 +331,7 @@ macro_rules! nonzero_unsigned_operations { /// # } /// ``` #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] - #[rustc_const_unstable(feature = "const_nonzero_checked_ops", issue = "97547")] + #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.63.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -366,7 +366,7 @@ macro_rules! nonzero_unsigned_operations { /// # } /// ``` #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] - #[rustc_const_unstable(feature = "const_nonzero_checked_ops", issue = "97547")] + #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.63.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -432,7 +432,7 @@ macro_rules! nonzero_unsigned_operations { /// # } /// ``` #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] - #[rustc_const_unstable(feature = "const_nonzero_checked_ops", issue = "97547")] + #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.63.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -534,7 +534,7 @@ macro_rules! nonzero_signed_operations { /// # } /// ``` #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] - #[rustc_const_unstable(feature = "const_nonzero_checked_ops", issue = "97547")] + #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.63.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -566,7 +566,7 @@ macro_rules! nonzero_signed_operations { /// # } /// ``` #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] - #[rustc_const_unstable(feature = "const_nonzero_checked_ops", issue = "97547")] + #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.63.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -602,7 +602,7 @@ macro_rules! nonzero_signed_operations { /// # } /// ``` #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] - #[rustc_const_unstable(feature = "const_nonzero_checked_ops", issue = "97547")] + #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.63.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -642,7 +642,7 @@ macro_rules! nonzero_signed_operations { /// # } /// ``` #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] - #[rustc_const_unstable(feature = "const_nonzero_checked_ops", issue = "97547")] + #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.63.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -677,7 +677,7 @@ macro_rules! nonzero_signed_operations { /// # } /// ``` #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] - #[rustc_const_unstable(feature = "const_nonzero_checked_ops", issue = "97547")] + #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.63.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -712,7 +712,7 @@ macro_rules! nonzero_signed_operations { /// # } /// ``` #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] - #[rustc_const_unstable(feature = "const_nonzero_checked_ops", issue = "97547")] + #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.63.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -761,7 +761,7 @@ macro_rules! nonzero_unsigned_signed_operations { /// # } /// ``` #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] - #[rustc_const_unstable(feature = "const_nonzero_checked_ops", issue = "97547")] + #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.63.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -797,7 +797,7 @@ macro_rules! nonzero_unsigned_signed_operations { /// # } /// ``` #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] - #[rustc_const_unstable(feature = "const_nonzero_checked_ops", issue = "97547")] + #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.63.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -870,7 +870,7 @@ macro_rules! nonzero_unsigned_signed_operations { /// # } /// ``` #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] - #[rustc_const_unstable(feature = "const_nonzero_checked_ops", issue = "97547")] + #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.63.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -914,7 +914,7 @@ macro_rules! nonzero_unsigned_signed_operations { /// # } /// ``` #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] - #[rustc_const_unstable(feature = "const_nonzero_checked_ops", issue = "97547")] + #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.63.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] From caff72361f9a3d9938032be703295ef7a0c0dd5d Mon Sep 17 00:00:00 2001 From: joboet Date: Tue, 7 Jun 2022 11:06:19 +0200 Subject: [PATCH 06/21] 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 cc4f804829ae56753acd2ef9c0f4bb741f5b3bae Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Mon, 20 Jun 2022 16:28:52 +0200 Subject: [PATCH 07/21] 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 08/21] 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 09/21] 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 99bc97940314176bc6ed38cea11723cc1fd9ee3b Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 23 Jun 2022 14:51:44 +0100 Subject: [PATCH 10/21] macros: use typed identifiers in diag derive Using typed identifiers instead of strings with the Fluent identifier enables the diagnostic derive to benefit from the compile-time validation that comes with typed identifiers - use of a non-existent Fluent identifier will not compile. Signed-off-by: David Wood --- compiler/rustc_builtin_macros/src/cfg.rs | 4 +- .../locales/en-US/builtin_macros.ftl | 4 +- .../src/diagnostics/diagnostic.rs | 460 +++++++++++------- .../rustc_macros/src/diagnostics/error.rs | 37 +- .../rustc_macros/src/diagnostics/fluent.rs | 11 + compiler/rustc_macros/src/diagnostics/mod.rs | 4 +- .../rustc_parse/src/parser/diagnostics.rs | 18 +- compiler/rustc_typeck/src/errors.rs | 62 +-- .../ui-fulldeps/internal-lints/diagnostics.rs | 2 +- .../session-diagnostic/diagnostic-derive.rs | 239 +++++---- .../diagnostic-derive.stderr | 287 ++++++----- 11 files changed, 673 insertions(+), 455 deletions(-) diff --git a/compiler/rustc_builtin_macros/src/cfg.rs b/compiler/rustc_builtin_macros/src/cfg.rs index c75d83bd0a0e3..aa355150b4f81 100644 --- a/compiler/rustc_builtin_macros/src/cfg.rs +++ b/compiler/rustc_builtin_macros/src/cfg.rs @@ -36,7 +36,7 @@ pub fn expand_cfg( } #[derive(SessionDiagnostic)] -#[error(slug = "builtin-macros-requires-cfg-pattern")] +#[error(builtin_macros::requires_cfg_pattern)] struct RequiresCfgPattern { #[primary_span] #[label] @@ -44,7 +44,7 @@ struct RequiresCfgPattern { } #[derive(SessionDiagnostic)] -#[error(slug = "builtin-macros-expected-one-cfg-pattern")] +#[error(builtin_macros::expected_one_cfg_pattern)] struct OneCfgPattern { #[primary_span] span: Span, diff --git a/compiler/rustc_error_messages/locales/en-US/builtin_macros.ftl b/compiler/rustc_error_messages/locales/en-US/builtin_macros.ftl index 1d3e33c81851f..4a42d52f71004 100644 --- a/compiler/rustc_error_messages/locales/en-US/builtin_macros.ftl +++ b/compiler/rustc_error_messages/locales/en-US/builtin_macros.ftl @@ -1,5 +1,5 @@ -builtin-macros-requires-cfg-pattern = +builtin_macros-requires-cfg-pattern = macro requires a cfg-pattern as an argument .label = cfg-pattern required -builtin-macros-expected-one-cfg-pattern = expected 1 cfg-pattern +builtin_macros-expected-one-cfg-pattern = expected 1 cfg-pattern diff --git a/compiler/rustc_macros/src/diagnostics/diagnostic.rs b/compiler/rustc_macros/src/diagnostics/diagnostic.rs index 95ee0d4a060d2..d0c8652718969 100644 --- a/compiler/rustc_macros/src/diagnostics/diagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/diagnostic.rs @@ -12,7 +12,9 @@ use proc_macro2::{Ident, TokenStream}; use quote::{format_ident, quote}; use std::collections::HashMap; use std::str::FromStr; -use syn::{spanned::Spanned, Attribute, Meta, MetaList, MetaNameValue, Type}; +use syn::{ + parse_quote, spanned::Spanned, Attribute, Meta, MetaList, MetaNameValue, NestedMeta, Path, Type, +}; use synstructure::{BindingInfo, Structure}; /// The central struct for constructing the `into_diagnostic` method from an annotated struct. @@ -118,23 +120,23 @@ impl<'a> SessionDiagnosticDerive<'a> { return SessionDiagnosticDeriveError::ErrorHandled.to_compile_error(); } (Some((kind, _)), None) => { - span_err(span, "`slug` not specified") - .help(&format!("use the `#[{}(slug = \"...\")]` attribute to set this diagnostic's slug", kind.descr())) + span_err(span, "diagnostic slug not specified") + .help(&format!( + "specify the slug as the first argument to the attribute, such as \ + `#[{}(typeck::example_error)]`", + kind.descr() + )) .emit(); return SessionDiagnosticDeriveError::ErrorHandled.to_compile_error(); } (Some((SessionDiagnosticKind::Error, _)), Some((slug, _))) => { quote! { - let mut #diag = #sess.struct_err( - rustc_errors::DiagnosticMessage::new(#slug), - ); + let mut #diag = #sess.struct_err(rustc_errors::fluent::#slug); } } (Some((SessionDiagnosticKind::Warn, _)), Some((slug, _))) => { quote! { - let mut #diag = #sess.struct_warn( - rustc_errors::DiagnosticMessage::new(#slug), - ); + let mut #diag = #sess.struct_warn(rustc_errors::fluent::#slug); } } }; @@ -226,7 +228,7 @@ struct SessionDiagnosticDeriveBuilder { kind: Option<(SessionDiagnosticKind, proc_macro::Span)>, /// Slug is a mandatory part of the struct attribute as corresponds to the Fluent message that /// has the actual diagnostic message. - slug: Option<(String, proc_macro::Span)>, + slug: Option<(Path, proc_macro::Span)>, /// Error codes are a optional part of the struct attribute - this is only set to detect /// multiple specifications. code: Option<(String, proc_macro::Span)>, @@ -240,50 +242,79 @@ impl HasFieldMap for SessionDiagnosticDeriveBuilder { impl SessionDiagnosticDeriveBuilder { /// Establishes state in the `SessionDiagnosticDeriveBuilder` resulting from the struct - /// attributes like `#[error(..)#`, such as the diagnostic kind and slug. Generates + /// attributes like `#[error(..)`, such as the diagnostic kind and slug. Generates /// diagnostic builder calls for setting error code and creating note/help messages. fn generate_structure_code( &mut self, attr: &Attribute, ) -> Result { + let diag = &self.diag; let span = attr.span().unwrap(); let name = attr.path.segments.last().unwrap().ident.to_string(); let name = name.as_str(); let meta = attr.parse_meta()?; - if matches!(name, "help" | "note") && matches!(meta, Meta::Path(_) | Meta::NameValue(_)) { - let diag = &self.diag; - let id = match meta { - Meta::Path(..) => quote! { #name }, - Meta::NameValue(MetaNameValue { lit: syn::Lit::Str(s), .. }) => { - quote! { #s } - } - _ => unreachable!(), - }; - let fn_name = proc_macro2::Ident::new(name, attr.span()); - - return Ok(quote! { - #diag.#fn_name(rustc_errors::SubdiagnosticMessage::attr(#id)); - }); - } + let is_help_or_note = matches!(name, "help" | "note"); let nested = match meta { + // Most attributes are lists, like `#[error(..)]`/`#[warning(..)]` for most cases or + // `#[help(..)]`/`#[note(..)]` when the user is specifying a alternative slug. Meta::List(MetaList { ref nested, .. }) => nested, + // Subdiagnostics without spans can be applied to the type too, and these are just + // paths: `#[help]` and `#[note]` + Meta::Path(_) if is_help_or_note => { + let fn_name = proc_macro2::Ident::new(name, attr.span()); + return Ok(quote! { #diag.#fn_name(rustc_errors::fluent::_subdiag::#fn_name); }); + } _ => throw_invalid_attr!(attr, &meta), }; - let kind = match name { - "error" => SessionDiagnosticKind::Error, - "warning" => SessionDiagnosticKind::Warn, + // Check the kind before doing any further processing so that there aren't misleading + // "no kind specified" errors if there are failures later. + match name { + "error" => self.kind.set_once((SessionDiagnosticKind::Error, span)), + "warning" => self.kind.set_once((SessionDiagnosticKind::Warn, span)), + "help" | "note" => (), _ => throw_invalid_attr!(attr, &meta, |diag| { - diag.help("only `error` and `warning` are valid attributes") + diag.help("only `error`, `warning`, `help` and `note` are valid attributes") }), - }; - self.kind.set_once((kind, span)); + } + + // First nested element should always be the path, e.g. `#[error(typeck::invalid)]` or + // `#[help(typeck::another_help)]`. + let mut nested_iter = nested.into_iter(); + if let Some(nested_attr) = nested_iter.next() { + // Report an error if there are any other list items after the path. + if is_help_or_note && nested_iter.next().is_some() { + throw_invalid_nested_attr!(attr, &nested_attr, |diag| { + diag.help("`help` and `note` struct attributes can only have one argument") + }); + } + match nested_attr { + NestedMeta::Meta(Meta::Path(path)) if is_help_or_note => { + let fn_name = proc_macro2::Ident::new(name, attr.span()); + return Ok(quote! { #diag.#fn_name(rustc_errors::fluent::#path); }); + } + NestedMeta::Meta(Meta::Path(path)) => { + self.slug.set_once((path.clone(), span)); + } + NestedMeta::Meta(meta @ Meta::NameValue(_)) + if !is_help_or_note + && meta.path().segments.last().unwrap().ident.to_string() == "code" => + { + // don't error for valid follow-up attributes + } + nested_attr => throw_invalid_nested_attr!(attr, &nested_attr, |diag| { + diag.help("first argument of the attribute should be the diagnostic slug") + }), + }; + } + + // Remaining attributes are optional, only `code = ".."` at the moment. let mut tokens = Vec::new(); - for nested_attr in nested { + for nested_attr in nested_iter { let meta = match nested_attr { syn::NestedMeta::Meta(meta) => meta, _ => throw_invalid_nested_attr!(attr, &nested_attr), @@ -291,28 +322,24 @@ impl SessionDiagnosticDeriveBuilder { let path = meta.path(); let nested_name = path.segments.last().unwrap().ident.to_string(); - match &meta { - // Struct attributes are only allowed to be applied once, and the diagnostic - // changes will be set in the initialisation code. - Meta::NameValue(MetaNameValue { lit: syn::Lit::Str(s), .. }) => { - let span = s.span().unwrap(); - match nested_name.as_str() { - "slug" => { - self.slug.set_once((s.value(), span)); - } - "code" => { - self.code.set_once((s.value(), span)); - let (diag, code) = (&self.diag, &self.code.as_ref().map(|(v, _)| v)); - tokens.push(quote! { - #diag.code(rustc_errors::DiagnosticId::Error(#code.to_string())); - }); - } - _ => invalid_nested_attr(attr, &nested_attr) - .help("only `slug` and `code` are valid nested attributes") - .emit(), + // Struct attributes are only allowed to be applied once, and the diagnostic + // changes will be set in the initialisation code. + if let Meta::NameValue(MetaNameValue { lit: syn::Lit::Str(s), .. }) = &meta { + let span = s.span().unwrap(); + match nested_name.as_str() { + "code" => { + self.code.set_once((s.value(), span)); + let code = &self.code.as_ref().map(|(v, _)| v); + tokens.push(quote! { + #diag.code(rustc_errors::DiagnosticId::Error(#code.to_string())); + }); } + _ => invalid_nested_attr(attr, &nested_attr) + .help("only `code` is a valid nested attributes following the slug") + .emit(), } - _ => invalid_nested_attr(attr, &nested_attr).emit(), + } else { + invalid_nested_attr(attr, &nested_attr).emit() } } @@ -382,142 +409,215 @@ impl SessionDiagnosticDeriveBuilder { info: FieldInfo<'_>, binding: TokenStream, ) -> Result { + let meta = attr.parse_meta()?; + match meta { + Meta::Path(_) => self.generate_inner_field_code_path(attr, info, binding), + Meta::List(MetaList { .. }) => self.generate_inner_field_code_list(attr, info, binding), + _ => throw_invalid_attr!(attr, &meta), + } + } + + fn generate_inner_field_code_path( + &mut self, + attr: &Attribute, + info: FieldInfo<'_>, + binding: TokenStream, + ) -> Result { + assert!(matches!(attr.parse_meta()?, Meta::Path(_))); let diag = &self.diag; + let meta = attr.parse_meta()?; + let ident = &attr.path.segments.last().unwrap().ident; let name = ident.to_string(); let name = name.as_str(); + match name { + "skip_arg" => { + // Don't need to do anything - by virtue of the attribute existing, the + // `set_arg` call will not be generated. + Ok(quote! {}) + } + "primary_span" => { + report_error_if_not_applied_to_span(attr, &info)?; + Ok(quote! { + #diag.set_span(#binding); + }) + } + "label" => { + report_error_if_not_applied_to_span(attr, &info)?; + Ok(self.add_spanned_subdiagnostic(binding, ident, parse_quote! { _subdiag::label })) + } + "note" | "help" => { + let path = match name { + "note" => parse_quote! { _subdiag::note }, + "help" => parse_quote! { _subdiag::help }, + _ => unreachable!(), + }; + if type_matches_path(&info.ty, &["rustc_span", "Span"]) { + Ok(self.add_spanned_subdiagnostic(binding, ident, path)) + } else if type_is_unit(&info.ty) { + Ok(self.add_subdiagnostic(ident, path)) + } else { + report_type_error(attr, "`Span` or `()`")?; + } + } + "subdiagnostic" => Ok(quote! { #diag.subdiagnostic(#binding); }), + _ => throw_invalid_attr!(attr, &meta, |diag| { + diag.help( + "only `skip_arg`, `primary_span`, `label`, `note`, `help` and `subdiagnostic` \ + are valid field attributes", + ) + }), + } + } + fn generate_inner_field_code_list( + &mut self, + attr: &Attribute, + info: FieldInfo<'_>, + binding: TokenStream, + ) -> Result { let meta = attr.parse_meta()?; - match meta { - Meta::Path(_) => match name { - "skip_arg" => { - // Don't need to do anything - by virtue of the attribute existing, the - // `set_arg` call will not be generated. - Ok(quote! {}) - } - "primary_span" => { - report_error_if_not_applied_to_span(attr, &info)?; - Ok(quote! { - #diag.set_span(#binding); - }) - } - "label" => { - report_error_if_not_applied_to_span(attr, &info)?; - Ok(self.add_spanned_subdiagnostic(binding, ident, name)) - } - "note" | "help" => { - if type_matches_path(&info.ty, &["rustc_span", "Span"]) { - Ok(self.add_spanned_subdiagnostic(binding, ident, name)) - } else if type_is_unit(&info.ty) { - Ok(self.add_subdiagnostic(ident, name)) - } else { - report_type_error(attr, "`Span` or `()`")?; - } - } - "subdiagnostic" => Ok(quote! { #diag.subdiagnostic(#binding); }), - _ => throw_invalid_attr!(attr, &meta, |diag| { - diag - .help("only `skip_arg`, `primary_span`, `label`, `note`, `help` and `subdiagnostic` are valid field attributes") - }), - }, - Meta::NameValue(MetaNameValue { lit: syn::Lit::Str(ref s), .. }) => match name { - "label" => { - report_error_if_not_applied_to_span(attr, &info)?; - Ok(self.add_spanned_subdiagnostic(binding, ident, &s.value())) - } - "note" | "help" => { - if type_matches_path(&info.ty, &["rustc_span", "Span"]) { - Ok(self.add_spanned_subdiagnostic(binding, ident, &s.value())) - } else if type_is_unit(&info.ty) { - Ok(self.add_subdiagnostic(ident, &s.value())) - } else { - report_type_error(attr, "`Span` or `()`")?; - } - } - _ => throw_invalid_attr!(attr, &meta, |diag| { - diag.help("only `label`, `note` and `help` are valid field attributes") - }), - }, - Meta::List(MetaList { ref path, ref nested, .. }) => { - let name = path.segments.last().unwrap().ident.to_string(); - let name = name.as_ref(); - - match name { - "suggestion" | "suggestion_short" | "suggestion_hidden" - | "suggestion_verbose" => (), - _ => throw_invalid_attr!(attr, &meta, |diag| { - diag - .help("only `suggestion{,_short,_hidden,_verbose}` are valid field attributes") - }), - }; + let Meta::List(MetaList { ref path, ref nested, .. }) = meta else { unreachable!() }; - let (span_field, mut applicability) = self.span_and_applicability_of_ty(info)?; + let ident = &attr.path.segments.last().unwrap().ident; + let name = path.segments.last().unwrap().ident.to_string(); + let name = name.as_ref(); + match name { + "suggestion" | "suggestion_short" | "suggestion_hidden" | "suggestion_verbose" => { + return self.generate_inner_field_code_suggestion(attr, info); + } + "label" | "help" | "note" => (), + _ => throw_invalid_attr!(attr, &meta, |diag| { + diag.help( + "only `label`, `note`, `help` or `suggestion{,_short,_hidden,_verbose}` are \ + valid field attributes", + ) + }), + } - let mut msg = None; - let mut code = None; + // For `#[label(..)]`, `#[note(..)]` and `#[help(..)]`, the first nested element must be a + // path, e.g. `#[label(typeck::label)]`. + let mut nested_iter = nested.into_iter(); + let msg = match nested_iter.next() { + Some(NestedMeta::Meta(Meta::Path(path))) => path.clone(), + Some(nested_attr) => throw_invalid_nested_attr!(attr, &nested_attr), + None => throw_invalid_attr!(attr, &meta), + }; - for nested_attr in nested { - let meta = match nested_attr { - syn::NestedMeta::Meta(ref meta) => meta, - syn::NestedMeta::Lit(_) => throw_invalid_nested_attr!(attr, &nested_attr), - }; + // None of these attributes should have anything following the slug. + if nested_iter.next().is_some() { + throw_invalid_attr!(attr, &meta); + } - let nested_name = meta.path().segments.last().unwrap().ident.to_string(); - let nested_name = nested_name.as_str(); - match meta { - Meta::NameValue(MetaNameValue { lit: syn::Lit::Str(s), .. }) => { - let span = meta.span().unwrap(); - match nested_name { - "message" => { - msg = Some(s.value()); - } - "code" => { - let formatted_str = self.build_format(&s.value(), s.span()); - code = Some(formatted_str); + match name { + "label" => { + report_error_if_not_applied_to_span(attr, &info)?; + Ok(self.add_spanned_subdiagnostic(binding, ident, msg)) + } + "note" | "help" if type_matches_path(&info.ty, &["rustc_span", "Span"]) => { + Ok(self.add_spanned_subdiagnostic(binding, ident, msg)) + } + "note" | "help" if type_is_unit(&info.ty) => Ok(self.add_subdiagnostic(ident, msg)), + "note" | "help" => { + report_type_error(attr, "`Span` or `()`")?; + } + _ => unreachable!(), + } + } + + fn generate_inner_field_code_suggestion( + &mut self, + attr: &Attribute, + info: FieldInfo<'_>, + ) -> Result { + let diag = &self.diag; + + let mut meta = attr.parse_meta()?; + let Meta::List(MetaList { ref path, ref mut nested, .. }) = meta else { unreachable!() }; + + let (span_field, mut applicability) = self.span_and_applicability_of_ty(info)?; + + let mut msg = None; + let mut code = None; + + let mut nested_iter = nested.into_iter().peekable(); + if let Some(nested_attr) = nested_iter.peek() { + if let NestedMeta::Meta(Meta::Path(path)) = nested_attr { + msg = Some(path.clone()); + } + }; + // Move the iterator forward if a path was found (don't otherwise so that + // code/applicability can be found or an error emitted). + if msg.is_some() { + let _ = nested_iter.next(); + } + + for nested_attr in nested_iter { + let meta = match nested_attr { + syn::NestedMeta::Meta(ref meta) => meta, + syn::NestedMeta::Lit(_) => throw_invalid_nested_attr!(attr, &nested_attr), + }; + + let nested_name = meta.path().segments.last().unwrap().ident.to_string(); + let nested_name = nested_name.as_str(); + match meta { + Meta::NameValue(MetaNameValue { lit: syn::Lit::Str(s), .. }) => { + let span = meta.span().unwrap(); + match nested_name { + "code" => { + let formatted_str = self.build_format(&s.value(), s.span()); + code = Some(formatted_str); + } + "applicability" => { + applicability = match applicability { + Some(v) => { + span_err( + span, + "applicability cannot be set in both the field and \ + attribute", + ) + .emit(); + Some(v) } - "applicability" => { - applicability = match applicability { - Some(v) => { - span_err( - span, - "applicability cannot be set in both the field and attribute" - ).emit(); - Some(v) - } - None => match Applicability::from_str(&s.value()) { - Ok(v) => Some(quote! { #v }), - Err(()) => { - span_err(span, "invalid applicability").emit(); - None - } - }, + None => match Applicability::from_str(&s.value()) { + Ok(v) => Some(quote! { #v }), + Err(()) => { + span_err(span, "invalid applicability").emit(); + None } - } - _ => throw_invalid_nested_attr!(attr, &nested_attr, |diag| { - diag.help( - "only `message`, `code` and `applicability` are valid field attributes", - ) - }), + }, } } - _ => throw_invalid_nested_attr!(attr, &nested_attr), + _ => throw_invalid_nested_attr!(attr, &nested_attr, |diag| { + diag.help( + "only `message`, `code` and `applicability` are valid field \ + attributes", + ) + }), } } + _ => throw_invalid_nested_attr!(attr, &nested_attr, |diag| { + if matches!(meta, Meta::Path(_)) { + diag.help("a diagnostic slug must be the first argument to the attribute") + } else { + diag + } + }), + } + } - let applicability = applicability - .unwrap_or_else(|| quote!(rustc_errors::Applicability::Unspecified)); + let applicability = + applicability.unwrap_or_else(|| quote!(rustc_errors::Applicability::Unspecified)); - let method = format_ident!("span_{}", name); + let name = path.segments.last().unwrap().ident.to_string(); + let method = format_ident!("span_{}", name); - let msg = msg.as_deref().unwrap_or("suggestion"); - let msg = quote! { rustc_errors::SubdiagnosticMessage::attr(#msg) }; - let code = code.unwrap_or_else(|| quote! { String::new() }); + let msg = msg.unwrap_or_else(|| parse_quote! { _subdiag::suggestion }); + let msg = quote! { rustc_errors::fluent::#msg }; + let code = code.unwrap_or_else(|| quote! { String::new() }); - Ok(quote! { #diag.#method(#span_field, #msg, #code, #applicability); }) - } - _ => throw_invalid_attr!(attr, &meta), - } + Ok(quote! { #diag.#method(#span_field, #msg, #code, #applicability); }) } /// Adds a spanned subdiagnostic by generating a `diag.span_$kind` call with the current slug @@ -526,24 +626,24 @@ impl SessionDiagnosticDeriveBuilder { &self, field_binding: TokenStream, kind: &Ident, - fluent_attr_identifier: &str, + fluent_attr_identifier: Path, ) -> TokenStream { let diag = &self.diag; let fn_name = format_ident!("span_{}", kind); quote! { #diag.#fn_name( #field_binding, - rustc_errors::SubdiagnosticMessage::attr(#fluent_attr_identifier) + rustc_errors::fluent::#fluent_attr_identifier ); } } /// Adds a subdiagnostic by generating a `diag.span_$kind` call with the current slug /// and `fluent_attr_identifier`. - fn add_subdiagnostic(&self, kind: &Ident, fluent_attr_identifier: &str) -> TokenStream { + fn add_subdiagnostic(&self, kind: &Ident, fluent_attr_identifier: Path) -> TokenStream { let diag = &self.diag; quote! { - #diag.#kind(rustc_errors::SubdiagnosticMessage::attr(#fluent_attr_identifier)); + #diag.#kind(rustc_errors::fluent::#fluent_attr_identifier); } } @@ -569,7 +669,8 @@ impl SessionDiagnosticDeriveBuilder { } else { throw_span_err!( info.span.unwrap(), - "type of field annotated with `#[suggestion(...)]` contains more than one `Span`" + "type of field annotated with `#[suggestion(...)]` contains more \ + than one `Span`" ); } } else if type_matches_path(elem, &["rustc_errors", "Applicability"]) { @@ -578,7 +679,8 @@ impl SessionDiagnosticDeriveBuilder { } else { throw_span_err!( info.span.unwrap(), - "type of field annotated with `#[suggestion(...)]` contains more than one Applicability" + "type of field annotated with `#[suggestion(...)]` contains more \ + than one Applicability" ); } } @@ -595,12 +697,18 @@ impl SessionDiagnosticDeriveBuilder { } throw_span_err!(info.span.unwrap(), "wrong types for suggestion", |diag| { - diag.help("`#[suggestion(...)]` on a tuple field must be applied to fields of type `(Span, Applicability)`") + diag.help( + "`#[suggestion(...)]` on a tuple field must be applied to fields of type \ + `(Span, Applicability)`", + ) }); } // If `ty` isn't a `Span` or `(Span, Applicability)` then emit an error. _ => throw_span_err!(info.span.unwrap(), "wrong field type for suggestion", |diag| { - diag.help("`#[suggestion(...)]` should be applied to fields of type `Span` or `(Span, Applicability)`") + diag.help( + "`#[suggestion(...)]` should be applied to fields of type `Span` or \ + `(Span, Applicability)`", + ) }), } } diff --git a/compiler/rustc_macros/src/diagnostics/error.rs b/compiler/rustc_macros/src/diagnostics/error.rs index fd1dc2f307397..d088402abc6da 100644 --- a/compiler/rustc_macros/src/diagnostics/error.rs +++ b/compiler/rustc_macros/src/diagnostics/error.rs @@ -39,6 +39,19 @@ pub(crate) fn _throw_err( SessionDiagnosticDeriveError::ErrorHandled } +/// Helper function for printing `syn::Path` - doesn't handle arguments in paths and these are +/// unlikely to come up much in use of the macro. +fn path_to_string(path: &syn::Path) -> String { + let mut out = String::new(); + for (i, segment) in path.segments.iter().enumerate() { + if i > 0 || path.leading_colon.is_some() { + out.push_str("::"); + } + out.push_str(&segment.ident.to_string()); + } + out +} + /// Returns an error diagnostic on span `span` with msg `msg`. pub(crate) fn span_err(span: impl MultiSpan, msg: &str) -> Diagnostic { Diagnostic::spanned(span, Level::Error, msg) @@ -61,15 +74,13 @@ pub(crate) use throw_span_err; /// Returns an error diagnostic for an invalid attribute. pub(crate) fn invalid_attr(attr: &Attribute, meta: &Meta) -> Diagnostic { let span = attr.span().unwrap(); - let name = attr.path.segments.last().unwrap().ident.to_string(); - let name = name.as_str(); - + let path = path_to_string(&attr.path); match meta { - Meta::Path(_) => span_err(span, &format!("`#[{}]` is not a valid attribute", name)), + Meta::Path(_) => span_err(span, &format!("`#[{}]` is not a valid attribute", path)), Meta::NameValue(_) => { - span_err(span, &format!("`#[{} = ...]` is not a valid attribute", name)) + span_err(span, &format!("`#[{} = ...]` is not a valid attribute", path)) } - Meta::List(_) => span_err(span, &format!("`#[{}(...)]` is not a valid attribute", name)), + Meta::List(_) => span_err(span, &format!("`#[{}(...)]` is not a valid attribute", path)), } } @@ -101,18 +112,16 @@ pub(crate) fn invalid_nested_attr(attr: &Attribute, nested: &NestedMeta) -> Diag }; let span = meta.span().unwrap(); - let nested_name = meta.path().segments.last().unwrap().ident.to_string(); - let nested_name = nested_name.as_str(); + let path = path_to_string(meta.path()); match meta { - Meta::NameValue(..) => span_err( - span, - &format!("`#[{}({} = ...)]` is not a valid attribute", name, nested_name), - ), + Meta::NameValue(..) => { + span_err(span, &format!("`#[{}({} = ...)]` is not a valid attribute", name, path)) + } Meta::Path(..) => { - span_err(span, &format!("`#[{}({})]` is not a valid attribute", name, nested_name)) + span_err(span, &format!("`#[{}({})]` is not a valid attribute", name, path)) } Meta::List(..) => { - span_err(span, &format!("`#[{}({}(...))]` is not a valid attribute", name, nested_name)) + span_err(span, &format!("`#[{}({}(...))]` is not a valid attribute", name, path)) } } } diff --git a/compiler/rustc_macros/src/diagnostics/fluent.rs b/compiler/rustc_macros/src/diagnostics/fluent.rs index 42a9bf477a41c..2317186e65502 100644 --- a/compiler/rustc_macros/src/diagnostics/fluent.rs +++ b/compiler/rustc_macros/src/diagnostics/fluent.rs @@ -254,6 +254,17 @@ pub(crate) fn fluent_messages(input: proc_macro::TokenStream) -> proc_macro::Tok ]; #generated + + pub mod _subdiag { + pub const note: crate::SubdiagnosticMessage = + crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("note")); + pub const help: crate::SubdiagnosticMessage = + crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("help")); + pub const label: crate::SubdiagnosticMessage = + crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("label")); + pub const suggestion: crate::SubdiagnosticMessage = + crate::SubdiagnosticMessage::FluentAttr(std::borrow::Cow::Borrowed("suggestion")); + } } } .into() diff --git a/compiler/rustc_macros/src/diagnostics/mod.rs b/compiler/rustc_macros/src/diagnostics/mod.rs index 69573d904d4a9..88182ed5a1224 100644 --- a/compiler/rustc_macros/src/diagnostics/mod.rs +++ b/compiler/rustc_macros/src/diagnostics/mod.rs @@ -22,14 +22,14 @@ use synstructure::Structure; /// # extern crate rust_middle; /// # use rustc_middle::ty::Ty; /// #[derive(SessionDiagnostic)] -/// #[error(code = "E0505", slug = "borrowck-move-out-of-borrow")] +/// #[error(borrowck::move_out_of_borrow, code = "E0505")] /// pub struct MoveOutOfBorrowError<'tcx> { /// pub name: Ident, /// pub ty: Ty<'tcx>, /// #[primary_span] /// #[label] /// pub span: Span, -/// #[label = "first-borrow-label"] +/// #[label(borrowck::first_borrow_label)] /// pub first_borrow_span: Span, /// #[suggestion(code = "{name}.clone()")] /// pub clone_sugg: Option<(Span, Applicability)> diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index ba325d704228d..30869f055f5fa 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -244,7 +244,7 @@ impl MultiSugg { } #[derive(SessionDiagnostic)] -#[error(slug = "parser-maybe-report-ambiguous-plus")] +#[error(parser::maybe_report_ambiguous_plus)] struct AmbiguousPlus { pub sum_ty: String, #[primary_span] @@ -253,7 +253,7 @@ struct AmbiguousPlus { } #[derive(SessionDiagnostic)] -#[error(code = "E0178", slug = "parser-maybe-recover-from-bad-type-plus")] +#[error(parser::maybe_recover_from_bad_type_plus, code = "E0178")] struct BadTypePlus { pub ty: String, #[primary_span] @@ -287,7 +287,7 @@ pub enum BadTypePlusSub { } #[derive(SessionDiagnostic)] -#[error(slug = "parser-maybe-recover-from-bad-qpath-stage-2")] +#[error(parser::maybe_recover_from_bad_qpath_stage_2)] struct BadQPathStage2 { #[primary_span] #[suggestion(applicability = "maybe-incorrect")] @@ -296,7 +296,7 @@ struct BadQPathStage2 { } #[derive(SessionDiagnostic)] -#[error(slug = "parser-incorrect-semicolon")] +#[error(parser::incorrect_semicolon)] struct IncorrectSemicolon<'a> { #[primary_span] #[suggestion_short(applicability = "machine-applicable")] @@ -307,26 +307,26 @@ struct IncorrectSemicolon<'a> { } #[derive(SessionDiagnostic)] -#[error(slug = "parser-incorrect-use-of-await")] +#[error(parser::incorrect_use_of_await)] struct IncorrectUseOfAwait { #[primary_span] - #[suggestion(message = "parentheses-suggestion", applicability = "machine-applicable")] + #[suggestion(parser::parentheses_suggestion, applicability = "machine-applicable")] span: Span, } #[derive(SessionDiagnostic)] -#[error(slug = "parser-incorrect-use-of-await")] +#[error(parser::incorrect_use_of_await)] struct IncorrectAwait { #[primary_span] span: Span, - #[suggestion(message = "postfix-suggestion", code = "{expr}.await{question_mark}")] + #[suggestion(parser::postfix_suggestion, code = "{expr}.await{question_mark}")] sugg_span: (Span, Applicability), expr: String, question_mark: &'static str, } #[derive(SessionDiagnostic)] -#[error(slug = "parser-in-in-typo")] +#[error(parser::in_in_typo)] struct InInTypo { #[primary_span] span: Span, diff --git a/compiler/rustc_typeck/src/errors.rs b/compiler/rustc_typeck/src/errors.rs index 67a3d4a4d020c..758108e5d7170 100644 --- a/compiler/rustc_typeck/src/errors.rs +++ b/compiler/rustc_typeck/src/errors.rs @@ -6,18 +6,18 @@ use rustc_session::{parse::ParseSess, SessionDiagnostic}; use rustc_span::{symbol::Ident, Span, Symbol}; #[derive(SessionDiagnostic)] -#[error(code = "E0062", slug = "typeck-field-multiply-specified-in-initializer")] +#[error(typeck::field_multiply_specified_in_initializer, code = "E0062")] pub struct FieldMultiplySpecifiedInInitializer { #[primary_span] #[label] pub span: Span, - #[label = "previous-use-label"] + #[label(typeck::previous_use_label)] pub prev_span: Span, pub ident: Ident, } #[derive(SessionDiagnostic)] -#[error(code = "E0092", slug = "typeck-unrecognized-atomic-operation")] +#[error(typeck::unrecognized_atomic_operation, code = "E0092")] pub struct UnrecognizedAtomicOperation<'a> { #[primary_span] #[label] @@ -26,7 +26,7 @@ pub struct UnrecognizedAtomicOperation<'a> { } #[derive(SessionDiagnostic)] -#[error(code = "E0094", slug = "typeck-wrong-number-of-generic-arguments-to-intrinsic")] +#[error(typeck::wrong_number_of_generic_arguments_to_intrinsic, code = "E0094")] pub struct WrongNumberOfGenericArgumentsToIntrinsic<'a> { #[primary_span] #[label] @@ -37,7 +37,7 @@ pub struct WrongNumberOfGenericArgumentsToIntrinsic<'a> { } #[derive(SessionDiagnostic)] -#[error(code = "E0093", slug = "typeck-unrecognized-intrinsic-function")] +#[error(typeck::unrecognized_intrinsic_function, code = "E0093")] pub struct UnrecognizedIntrinsicFunction { #[primary_span] #[label] @@ -46,19 +46,19 @@ pub struct UnrecognizedIntrinsicFunction { } #[derive(SessionDiagnostic)] -#[error(code = "E0195", slug = "typeck-lifetimes-or-bounds-mismatch-on-trait")] +#[error(typeck::lifetimes_or_bounds_mismatch_on_trait, code = "E0195")] pub struct LifetimesOrBoundsMismatchOnTrait { #[primary_span] #[label] pub span: Span, - #[label = "generics-label"] + #[label(typeck::generics_label)] pub generics_span: Option, pub item_kind: &'static str, pub ident: Ident, } #[derive(SessionDiagnostic)] -#[error(code = "E0120", slug = "typeck-drop-impl-on-wrong-item")] +#[error(typeck::drop_impl_on_wrong_item, code = "E0120")] pub struct DropImplOnWrongItem { #[primary_span] #[label] @@ -66,18 +66,18 @@ pub struct DropImplOnWrongItem { } #[derive(SessionDiagnostic)] -#[error(code = "E0124", slug = "typeck-field-already-declared")] +#[error(typeck::field_already_declared, code = "E0124")] pub struct FieldAlreadyDeclared { pub field_name: Ident, #[primary_span] #[label] pub span: Span, - #[label = "previous-decl-label"] + #[label(typeck::previous_decl_label)] pub prev_span: Span, } #[derive(SessionDiagnostic)] -#[error(code = "E0184", slug = "typeck-copy-impl-on-type-with-dtor")] +#[error(typeck::copy_impl_on_type_with_dtor, code = "E0184")] pub struct CopyImplOnTypeWithDtor { #[primary_span] #[label] @@ -85,14 +85,14 @@ pub struct CopyImplOnTypeWithDtor { } #[derive(SessionDiagnostic)] -#[error(code = "E0203", slug = "typeck-multiple-relaxed-default-bounds")] +#[error(typeck::multiple_relaxed_default_bounds, code = "E0203")] pub struct MultipleRelaxedDefaultBounds { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(code = "E0206", slug = "typeck-copy-impl-on-non-adt")] +#[error(typeck::copy_impl_on_non_adt, code = "E0206")] pub struct CopyImplOnNonAdt { #[primary_span] #[label] @@ -100,23 +100,23 @@ pub struct CopyImplOnNonAdt { } #[derive(SessionDiagnostic)] -#[error(code = "E0224", slug = "typeck-trait-object-declared-with-no-traits")] +#[error(typeck::trait_object_declared_with_no_traits, code = "E0224")] pub struct TraitObjectDeclaredWithNoTraits { #[primary_span] pub span: Span, - #[label = "alias-span"] + #[label(typeck::alias_span)] pub trait_alias_span: Option, } #[derive(SessionDiagnostic)] -#[error(code = "E0227", slug = "typeck-ambiguous-lifetime-bound")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0227")] pub struct AmbiguousLifetimeBound { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(code = "E0229", slug = "typeck-assoc-type-binding-not-allowed")] +#[error(typeck::assoc_type_binding_not_allowed, code = "E0229")] pub struct AssocTypeBindingNotAllowed { #[primary_span] #[label] @@ -124,14 +124,14 @@ pub struct AssocTypeBindingNotAllowed { } #[derive(SessionDiagnostic)] -#[error(code = "E0436", slug = "typeck-functional-record-update-on-non-struct")] +#[error(typeck::functional_record_update_on_non_struct, code = "E0436")] pub struct FunctionalRecordUpdateOnNonStruct { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(code = "E0516", slug = "typeck-typeof-reserved-keyword-used")] +#[error(typeck::typeof_reserved_keyword_used, code = "E0516")] pub struct TypeofReservedKeywordUsed<'tcx> { pub ty: Ty<'tcx>, #[primary_span] @@ -142,25 +142,25 @@ pub struct TypeofReservedKeywordUsed<'tcx> { } #[derive(SessionDiagnostic)] -#[error(code = "E0572", slug = "typeck-return-stmt-outside-of-fn-body")] +#[error(typeck::return_stmt_outside_of_fn_body, code = "E0572")] pub struct ReturnStmtOutsideOfFnBody { #[primary_span] pub span: Span, - #[label = "encl-body-label"] + #[label(typeck::encl_body_label)] pub encl_body_span: Option, - #[label = "encl-fn-label"] + #[label(typeck::encl_fn_label)] pub encl_fn_span: Option, } #[derive(SessionDiagnostic)] -#[error(code = "E0627", slug = "typeck-yield-expr-outside-of-generator")] +#[error(typeck::yield_expr_outside_of_generator, code = "E0627")] pub struct YieldExprOutsideOfGenerator { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(code = "E0639", slug = "typeck-struct-expr-non-exhaustive")] +#[error(typeck::struct_expr_non_exhaustive, code = "E0639")] pub struct StructExprNonExhaustive { #[primary_span] pub span: Span, @@ -168,26 +168,26 @@ pub struct StructExprNonExhaustive { } #[derive(SessionDiagnostic)] -#[error(code = "E0699", slug = "typeck-method-call-on-unknown-type")] +#[error(typeck::method_call_on_unknown_type, code = "E0699")] pub struct MethodCallOnUnknownType { #[primary_span] pub span: Span, } #[derive(SessionDiagnostic)] -#[error(code = "E0719", slug = "typeck-value-of-associated-struct-already-specified")] +#[error(typeck::value_of_associated_struct_already_specified, code = "E0719")] pub struct ValueOfAssociatedStructAlreadySpecified { #[primary_span] #[label] pub span: Span, - #[label = "previous-bound-label"] + #[label(typeck::previous_bound_label)] pub prev_span: Span, pub item_name: Ident, pub def_path: String, } #[derive(SessionDiagnostic)] -#[error(code = "E0745", slug = "typeck-address-of-temporary-taken")] +#[error(typeck::address_of_temporary_taken, code = "E0745")] pub struct AddressOfTemporaryTaken { #[primary_span] #[label] @@ -233,7 +233,7 @@ pub enum ExpectedReturnTypeLabel<'tcx> { } #[derive(SessionDiagnostic)] -#[error(slug = "typeck-unconstrained-opaque-type")] +#[error(typeck::unconstrained_opaque_type)] #[note] pub struct UnconstrainedOpaqueType { #[primary_span] @@ -301,7 +301,7 @@ impl<'a> SessionDiagnostic<'a> for MissingTypeParams { } #[derive(SessionDiagnostic)] -#[error(code = "E0183", slug = "typeck-manual-implementation")] +#[error(typeck::manual_implementation, code = "E0183")] #[help] pub struct ManualImplementation { #[primary_span] @@ -311,7 +311,7 @@ pub struct ManualImplementation { } #[derive(SessionDiagnostic)] -#[error(slug = "typeck-substs-on-overridden-impl")] +#[error(typeck::substs_on_overridden_impl)] pub struct SubstsOnOverriddenImpl { #[primary_span] pub span: Span, diff --git a/src/test/ui-fulldeps/internal-lints/diagnostics.rs b/src/test/ui-fulldeps/internal-lints/diagnostics.rs index 817d8531da905..3e349ab02586f 100644 --- a/src/test/ui-fulldeps/internal-lints/diagnostics.rs +++ b/src/test/ui-fulldeps/internal-lints/diagnostics.rs @@ -16,7 +16,7 @@ use rustc_session::{parse::ParseSess, SessionDiagnostic}; use rustc_span::Span; #[derive(SessionDiagnostic)] -#[error(slug = "parser-expect-path")] +#[error(parser::expect_path)] struct DeriveSessionDiagnostic { #[primary_span] span: Span, diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index 84d5de173091b..8cbee4c6d9243 100644 --- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -26,15 +26,15 @@ use rustc_errors::Applicability; extern crate rustc_session; #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "hello-world")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct Hello {} #[derive(SessionDiagnostic)] -#[warning(code = "E0123", slug = "hello-world")] +#[warning(typeck::ambiguous_lifetime_bound, code = "E0123")] struct HelloWarn {} #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] //~^ ERROR `#[derive(SessionDiagnostic)]` can only be used on structs enum SessionDiagnosticOnEnum { Foo, @@ -42,13 +42,13 @@ enum SessionDiagnosticOnEnum { } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] #[error = "E0123"] //~^ ERROR `#[error = ...]` is not a valid attribute struct WrongStructAttrStyle {} #[derive(SessionDiagnostic)] -#[nonsense(code = "E0123", slug = "foo")] +#[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")] //~^ ERROR `#[nonsense(...)]` is not a valid attribute //~^^ ERROR diagnostic kind not specified //~^^^ ERROR cannot find attribute `nonsense` in this scope @@ -57,31 +57,39 @@ struct InvalidStructAttr {} #[derive(SessionDiagnostic)] #[error("E0123")] //~^ ERROR `#[error("...")]` is not a valid attribute -//~^^ ERROR `slug` not specified +//~^^ ERROR diagnostic slug not specified struct InvalidLitNestedAttr {} #[derive(SessionDiagnostic)] -#[error(nonsense, code = "E0123", slug = "foo")] -//~^ ERROR `#[error(nonsense)]` is not a valid attribute +#[error(nonsense, code = "E0123")] +//~^ ERROR cannot find value `nonsense` in module `rustc_errors::fluent` struct InvalidNestedStructAttr {} #[derive(SessionDiagnostic)] #[error(nonsense("foo"), code = "E0123", slug = "foo")] //~^ ERROR `#[error(nonsense(...))]` is not a valid attribute +//~^^ ERROR diagnostic slug not specified struct InvalidNestedStructAttr1 {} #[derive(SessionDiagnostic)] #[error(nonsense = "...", code = "E0123", slug = "foo")] //~^ ERROR `#[error(nonsense = ...)]` is not a valid attribute +//~^^ ERROR diagnostic slug not specified struct InvalidNestedStructAttr2 {} #[derive(SessionDiagnostic)] #[error(nonsense = 4, code = "E0123", slug = "foo")] //~^ ERROR `#[error(nonsense = ...)]` is not a valid attribute +//~^^ ERROR diagnostic slug not specified struct InvalidNestedStructAttr3 {} #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123", slug = "foo")] +//~^ ERROR `#[error(slug = ...)]` is not a valid attribute +struct InvalidNestedStructAttr4 {} + +#[derive(SessionDiagnostic)] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct WrongPlaceField { #[suggestion = "bar"] //~^ ERROR `#[suggestion = ...]` is not a valid attribute @@ -89,44 +97,45 @@ struct WrongPlaceField { } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] -#[error(code = "E0456", slug = "bar")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0456")] //~^ ERROR specified multiple times //~^^ ERROR specified multiple times //~^^^ ERROR specified multiple times struct ErrorSpecifiedTwice {} #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] -#[warning(code = "E0293", slug = "bar")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[warning(typeck::ambiguous_lifetime_bound, code = "E0293")] //~^ ERROR specified multiple times //~^^ ERROR specified multiple times //~^^^ ERROR specified multiple times struct WarnSpecifiedAfterError {} #[derive(SessionDiagnostic)] -#[error(code = "E0456", code = "E0457", slug = "bar")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")] //~^ ERROR specified multiple times struct CodeSpecifiedTwice {} #[derive(SessionDiagnostic)] -#[error(code = "E0456", slug = "foo", slug = "bar")] -//~^ ERROR specified multiple times +#[error(typeck::ambiguous_lifetime_bound, typeck::ambiguous_lifetime_bound, code = "E0456")] +//~^ ERROR `#[error(typeck::ambiguous_lifetime_bound)]` is not a valid attribute struct SlugSpecifiedTwice {} #[derive(SessionDiagnostic)] struct KindNotProvided {} //~ ERROR diagnostic kind not specified #[derive(SessionDiagnostic)] -#[error(code = "E0456")] //~ ERROR `slug` not specified +#[error(code = "E0456")] +//~^ ERROR diagnostic slug not specified struct SlugNotProvided {} #[derive(SessionDiagnostic)] -#[error(slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound)] struct CodeNotProvided {} #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct MessageWrongType { #[primary_span] //~^ ERROR `#[primary_span]` attribute can only be applied to fields of type `Span` @@ -134,7 +143,7 @@ struct MessageWrongType { } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct InvalidPathFieldAttr { #[nonsense] //~^ ERROR `#[nonsense]` is not a valid attribute @@ -143,34 +152,34 @@ struct InvalidPathFieldAttr { } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ErrorWithField { name: String, - #[label = "bar"] + #[label(typeck::label)] span: Span, } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ErrorWithMessageAppliedToField { - #[label = "bar"] - //~^ ERROR the `#[label = ...]` attribute can only be applied to fields of type `Span` + #[label(typeck::label)] + //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` name: String, } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ErrorWithNonexistentField { - #[suggestion(message = "bar", code = "{name}")] + #[suggestion(typeck::suggestion, code = "{name}")] //~^ ERROR `name` doesn't refer to a field on this type suggestion: (Span, Applicability), } #[derive(SessionDiagnostic)] //~^ ERROR invalid format string: expected `'}'` -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ErrorMissingClosingBrace { - #[suggestion(message = "bar", code = "{name")] + #[suggestion(typeck::suggestion, code = "{name")] suggestion: (Span, Applicability), name: String, val: usize, @@ -178,48 +187,48 @@ struct ErrorMissingClosingBrace { #[derive(SessionDiagnostic)] //~^ ERROR invalid format string: unmatched `}` -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ErrorMissingOpeningBrace { - #[suggestion(message = "bar", code = "name}")] + #[suggestion(typeck::suggestion, code = "name}")] suggestion: (Span, Applicability), name: String, val: usize, } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct LabelOnSpan { - #[label = "bar"] + #[label(typeck::label)] sp: Span, } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct LabelOnNonSpan { - #[label = "bar"] - //~^ ERROR the `#[label = ...]` attribute can only be applied to fields of type `Span` + #[label(typeck::label)] + //~^ ERROR the `#[label(...)]` attribute can only be applied to fields of type `Span` id: u32, } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct Suggest { - #[suggestion(message = "bar", code = "This is the suggested code")] - #[suggestion_short(message = "qux", code = "This is the suggested code")] - #[suggestion_hidden(message = "foobar", code = "This is the suggested code")] - #[suggestion_verbose(message = "fooqux", code = "This is the suggested code")] + #[suggestion(typeck::suggestion, code = "This is the suggested code")] + #[suggestion_short(typeck::suggestion, code = "This is the suggested code")] + #[suggestion_hidden(typeck::suggestion, code = "This is the suggested code")] + #[suggestion_verbose(typeck::suggestion, code = "This is the suggested code")] suggestion: (Span, Applicability), } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct SuggestWithoutCode { - #[suggestion(message = "bar")] + #[suggestion(typeck::suggestion)] suggestion: (Span, Applicability), } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct SuggestWithBadKey { #[suggestion(nonsense = "bar")] //~^ ERROR `#[suggestion(nonsense = ...)]` is not a valid attribute @@ -227,7 +236,7 @@ struct SuggestWithBadKey { } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct SuggestWithShorthandMsg { #[suggestion(msg = "bar")] //~^ ERROR `#[suggestion(msg = ...)]` is not a valid attribute @@ -235,91 +244,91 @@ struct SuggestWithShorthandMsg { } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct SuggestWithoutMsg { #[suggestion(code = "bar")] suggestion: (Span, Applicability), } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct SuggestWithTypesSwapped { - #[suggestion(message = "bar", code = "This is suggested code")] + #[suggestion(typeck::suggestion, code = "This is suggested code")] suggestion: (Applicability, Span), } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct SuggestWithWrongTypeApplicabilityOnly { - #[suggestion(message = "bar", code = "This is suggested code")] + #[suggestion(typeck::suggestion, code = "This is suggested code")] //~^ ERROR wrong field type for suggestion suggestion: Applicability, } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct SuggestWithSpanOnly { - #[suggestion(message = "bar", code = "This is suggested code")] + #[suggestion(typeck::suggestion, code = "This is suggested code")] suggestion: Span, } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct SuggestWithDuplicateSpanAndApplicability { - #[suggestion(message = "bar", code = "This is suggested code")] + #[suggestion(typeck::suggestion, code = "This is suggested code")] //~^ ERROR type of field annotated with `#[suggestion(...)]` contains more than one `Span` suggestion: (Span, Span, Applicability), } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct SuggestWithDuplicateApplicabilityAndSpan { - #[suggestion(message = "bar", code = "This is suggested code")] + #[suggestion(typeck::suggestion, code = "This is suggested code")] //~^ ERROR type of field annotated with `#[suggestion(...)]` contains more than one suggestion: (Applicability, Applicability, Span), } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct WrongKindOfAnnotation { - #[label("bar")] - //~^ ERROR `#[label(...)]` is not a valid attribute + #[label = "bar"] + //~^ ERROR `#[label = ...]` is not a valid attribute z: Span, } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct OptionsInErrors { - #[label = "bar"] + #[label(typeck::label)] label: Option, - #[suggestion(message = "bar")] + #[suggestion(typeck::suggestion)] opt_sugg: Option<(Span, Applicability)>, } #[derive(SessionDiagnostic)] -#[error(code = "E0456", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0456")] struct MoveOutOfBorrowError<'tcx> { name: Ident, ty: Ty<'tcx>, #[primary_span] - #[label = "bar"] + #[label(typeck::label)] span: Span, - #[label = "qux"] + #[label(typeck::label)] other_span: Span, - #[suggestion(message = "bar", code = "{name}.clone()")] + #[suggestion(typeck::suggestion, code = "{name}.clone()")] opt_sugg: Option<(Span, Applicability)>, } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ErrorWithLifetime<'a> { - #[label = "bar"] + #[label(typeck::label)] span: Span, name: &'a str, } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ErrorWithDefaultLabelAttr<'a> { #[label] span: Span, @@ -328,7 +337,7 @@ struct ErrorWithDefaultLabelAttr<'a> { #[derive(SessionDiagnostic)] //~^ ERROR the trait bound `Hello: IntoDiagnosticArg` is not satisfied -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ArgFieldWithoutSkip { #[primary_span] span: Span, @@ -336,7 +345,7 @@ struct ArgFieldWithoutSkip { } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ArgFieldWithSkip { #[primary_span] span: Span, @@ -347,116 +356,116 @@ struct ArgFieldWithSkip { } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ErrorWithSpannedNote { #[note] span: Span, } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ErrorWithSpannedNoteCustom { - #[note = "bar"] + #[note(typeck::note)] span: Span, } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] #[note] struct ErrorWithNote { val: String, } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] -#[note = "bar"] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[note(typeck::note)] struct ErrorWithNoteCustom { val: String, } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ErrorWithSpannedHelp { #[help] span: Span, } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ErrorWithSpannedHelpCustom { - #[help = "bar"] + #[help(typeck::help)] span: Span, } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] #[help] struct ErrorWithHelp { val: String, } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] -#[help = "bar"] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +#[help(typeck::help)] struct ErrorWithHelpCustom { val: String, } #[derive(SessionDiagnostic)] #[help] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ErrorWithHelpWrongOrder { val: String, } #[derive(SessionDiagnostic)] -#[help = "bar"] -#[error(code = "E0123", slug = "foo")] +#[help(typeck::help)] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ErrorWithHelpCustomWrongOrder { val: String, } #[derive(SessionDiagnostic)] #[note] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ErrorWithNoteWrongOrder { val: String, } #[derive(SessionDiagnostic)] -#[note = "bar"] -#[error(code = "E0123", slug = "foo")] +#[note(typeck::note)] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ErrorWithNoteCustomWrongOrder { val: String, } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ApplicabilityInBoth { - #[suggestion(message = "bar", code = "...", applicability = "maybe-incorrect")] + #[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")] //~^ ERROR applicability cannot be set in both the field and attribute suggestion: (Span, Applicability), } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct InvalidApplicability { - #[suggestion(message = "bar", code = "...", applicability = "batman")] + #[suggestion(typeck::suggestion, code = "...", applicability = "batman")] //~^ ERROR invalid applicability suggestion: Span, } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct ValidApplicability { - #[suggestion(message = "bar", code = "...", applicability = "maybe-incorrect")] + #[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")] suggestion: Span, } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct NoApplicability { - #[suggestion(message = "bar", code = "...")] + #[suggestion(typeck::suggestion, code = "...")] suggestion: Span, } @@ -465,14 +474,14 @@ struct NoApplicability { struct Note; #[derive(SessionDiagnostic)] -#[error(slug = "subdiagnostic")] +#[error(typeck::ambiguous_lifetime_bound)] struct Subdiagnostic { #[subdiagnostic] note: Note, } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct VecField { #[primary_span] #[label] @@ -480,23 +489,47 @@ struct VecField { } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct UnitField { #[primary_span] spans: Span, #[help] foo: (), - #[help = "a"] + #[help(typeck::help)] bar: (), } #[derive(SessionDiagnostic)] -#[error(code = "E0123", slug = "foo")] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] struct OptUnitField { #[primary_span] spans: Span, #[help] foo: Option<()>, - #[help = "a"] + #[help(typeck::help)] bar: Option<()>, } + +#[derive(SessionDiagnostic)] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +struct LabelWithTrailingPath { + #[label(typeck::label, foo)] + //~^ ERROR `#[label(...)]` is not a valid attribute + span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +struct LabelWithTrailingNameValue { + #[label(typeck::label, foo = "...")] + //~^ ERROR `#[label(...)]` is not a valid attribute + span: Span, +} + +#[derive(SessionDiagnostic)] +#[error(typeck::ambiguous_lifetime_bound, code = "E0123")] +struct LabelWithTrailingList { + #[label(typeck::label, foo("..."))] + //~^ ERROR `#[label(...)]` is not a valid attribute + span: Span, +} diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr index 85ea44ec278c0..0d9690e1f5a99 100644 --- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr +++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.stderr @@ -1,7 +1,7 @@ error: `#[derive(SessionDiagnostic)]` can only be used on structs --> $DIR/diagnostic-derive.rs:37:1 | -LL | / #[error(code = "E0123", slug = "foo")] +LL | / #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] LL | | LL | | enum SessionDiagnosticOnEnum { LL | | Foo, @@ -18,15 +18,15 @@ LL | #[error = "E0123"] error: `#[nonsense(...)]` is not a valid attribute --> $DIR/diagnostic-derive.rs:51:1 | -LL | #[nonsense(code = "E0123", slug = "foo")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = help: only `error` and `warning` are valid attributes + = help: only `error`, `warning`, `help` and `note` are valid attributes error: diagnostic kind not specified --> $DIR/diagnostic-derive.rs:51:1 | -LL | / #[nonsense(code = "E0123", slug = "foo")] +LL | / #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")] LL | | LL | | LL | | @@ -40,8 +40,10 @@ error: `#[error("...")]` is not a valid attribute | LL | #[error("E0123")] | ^^^^^^^ + | + = help: first argument of the attribute should be the diagnostic slug -error: `slug` not specified +error: diagnostic slug not specified --> $DIR/diagnostic-derive.rs:58:1 | LL | / #[error("E0123")] @@ -50,183 +52,215 @@ LL | | LL | | struct InvalidLitNestedAttr {} | |______________________________^ | - = help: use the `#[error(slug = "...")]` attribute to set this diagnostic's slug - -error: `#[error(nonsense)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:64:9 - | -LL | #[error(nonsense, code = "E0123", slug = "foo")] - | ^^^^^^^^ + = help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]` error: `#[error(nonsense(...))]` is not a valid attribute --> $DIR/diagnostic-derive.rs:69:9 | LL | #[error(nonsense("foo"), code = "E0123", slug = "foo")] | ^^^^^^^^^^^^^^^ + | + = help: first argument of the attribute should be the diagnostic slug + +error: diagnostic slug not specified + --> $DIR/diagnostic-derive.rs:69:1 + | +LL | / #[error(nonsense("foo"), code = "E0123", slug = "foo")] +LL | | +LL | | +LL | | struct InvalidNestedStructAttr1 {} + | |__________________________________^ + | + = help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]` error: `#[error(nonsense = ...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:74:9 + --> $DIR/diagnostic-derive.rs:75:9 | LL | #[error(nonsense = "...", code = "E0123", slug = "foo")] | ^^^^^^^^^^^^^^^^ | - = help: only `slug` and `code` are valid nested attributes + = help: first argument of the attribute should be the diagnostic slug + +error: diagnostic slug not specified + --> $DIR/diagnostic-derive.rs:75:1 + | +LL | / #[error(nonsense = "...", code = "E0123", slug = "foo")] +LL | | +LL | | +LL | | struct InvalidNestedStructAttr2 {} + | |__________________________________^ + | + = help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]` error: `#[error(nonsense = ...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:79:9 + --> $DIR/diagnostic-derive.rs:81:9 | LL | #[error(nonsense = 4, code = "E0123", slug = "foo")] | ^^^^^^^^^^^^ + | + = help: first argument of the attribute should be the diagnostic slug -error: `#[suggestion = ...]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:86:5 +error: diagnostic slug not specified + --> $DIR/diagnostic-derive.rs:81:1 | -LL | #[suggestion = "bar"] - | ^^^^^^^^^^^^^^^^^^^^^ +LL | / #[error(nonsense = 4, code = "E0123", slug = "foo")] +LL | | +LL | | +LL | | struct InvalidNestedStructAttr3 {} + | |__________________________________^ | - = help: only `label`, `note` and `help` are valid field attributes + = help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]` -error: specified multiple times - --> $DIR/diagnostic-derive.rs:93:1 +error: `#[error(slug = ...)]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:87:59 | -LL | #[error(code = "E0456", slug = "bar")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123", slug = "foo")] + | ^^^^^^^^^^^^ | -note: previously specified here - --> $DIR/diagnostic-derive.rs:92:1 + = help: only `code` is a valid nested attributes following the slug + +error: `#[suggestion = ...]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:94:5 | -LL | #[error(code = "E0123", slug = "foo")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[suggestion = "bar"] + | ^^^^^^^^^^^^^^^^^^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:93:16 + --> $DIR/diagnostic-derive.rs:101:1 | -LL | #[error(code = "E0456", slug = "bar")] - | ^^^^^^^ +LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:92:16 + --> $DIR/diagnostic-derive.rs:100:1 | -LL | #[error(code = "E0123", slug = "foo")] - | ^^^^^^^ +LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:93:32 + --> $DIR/diagnostic-derive.rs:101:1 | -LL | #[error(code = "E0456", slug = "bar")] - | ^^^^^ +LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:92:32 + --> $DIR/diagnostic-derive.rs:100:1 | -LL | #[error(code = "E0123", slug = "foo")] - | ^^^^^ +LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:101:1 + --> $DIR/diagnostic-derive.rs:101:50 | -LL | #[warning(code = "E0293", slug = "bar")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456")] + | ^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:100:1 + --> $DIR/diagnostic-derive.rs:100:50 | -LL | #[error(code = "E0123", slug = "foo")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] + | ^^^^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:101:18 + --> $DIR/diagnostic-derive.rs:109:1 | -LL | #[warning(code = "E0293", slug = "bar")] - | ^^^^^^^ +LL | #[warning(typeck::ambiguous_lifetime_bound, code = "E0293")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:100:16 + --> $DIR/diagnostic-derive.rs:108:1 | -LL | #[error(code = "E0123", slug = "foo")] - | ^^^^^^^ +LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:101:34 + --> $DIR/diagnostic-derive.rs:109:1 | -LL | #[warning(code = "E0293", slug = "bar")] - | ^^^^^ +LL | #[warning(typeck::ambiguous_lifetime_bound, code = "E0293")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:100:32 + --> $DIR/diagnostic-derive.rs:108:1 | -LL | #[error(code = "E0123", slug = "foo")] - | ^^^^^ +LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:108:32 + --> $DIR/diagnostic-derive.rs:109:52 | -LL | #[error(code = "E0456", code = "E0457", slug = "bar")] - | ^^^^^^^ +LL | #[warning(typeck::ambiguous_lifetime_bound, code = "E0293")] + | ^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:108:16 + --> $DIR/diagnostic-derive.rs:108:50 | -LL | #[error(code = "E0456", code = "E0457", slug = "bar")] - | ^^^^^^^ +LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0123")] + | ^^^^^^^ error: specified multiple times - --> $DIR/diagnostic-derive.rs:113:46 + --> $DIR/diagnostic-derive.rs:116:66 | -LL | #[error(code = "E0456", slug = "foo", slug = "bar")] - | ^^^^^ +LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")] + | ^^^^^^^ | note: previously specified here - --> $DIR/diagnostic-derive.rs:113:32 + --> $DIR/diagnostic-derive.rs:116:50 | -LL | #[error(code = "E0456", slug = "foo", slug = "bar")] - | ^^^^^ +LL | #[error(typeck::ambiguous_lifetime_bound, code = "E0456", code = "E0457")] + | ^^^^^^^ + +error: `#[error(typeck::ambiguous_lifetime_bound)]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:121:43 + | +LL | #[error(typeck::ambiguous_lifetime_bound, typeck::ambiguous_lifetime_bound, code = "E0456")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: diagnostic kind not specified - --> $DIR/diagnostic-derive.rs:118:1 + --> $DIR/diagnostic-derive.rs:126:1 | LL | struct KindNotProvided {} | ^^^^^^^^^^^^^^^^^^^^^^^^^ | = help: use the `#[error(...)]` attribute to create an error -error: `slug` not specified - --> $DIR/diagnostic-derive.rs:121:1 +error: diagnostic slug not specified + --> $DIR/diagnostic-derive.rs:129:1 | LL | / #[error(code = "E0456")] +LL | | LL | | struct SlugNotProvided {} | |_________________________^ | - = help: use the `#[error(slug = "...")]` attribute to set this diagnostic's slug + = help: specify the slug as the first argument to the attribute, such as `#[error(typeck::example_error)]` error: the `#[primary_span]` attribute can only be applied to fields of type `Span` - --> $DIR/diagnostic-derive.rs:131:5 + --> $DIR/diagnostic-derive.rs:140:5 | LL | #[primary_span] | ^^^^^^^^^^^^^^^ error: `#[nonsense]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:139:5 + --> $DIR/diagnostic-derive.rs:148:5 | LL | #[nonsense] | ^^^^^^^^^^^ | = help: only `skip_arg`, `primary_span`, `label`, `note`, `help` and `subdiagnostic` are valid field attributes -error: the `#[label = ...]` attribute can only be applied to fields of type `Span` - --> $DIR/diagnostic-derive.rs:156:5 +error: the `#[label(...)]` attribute can only be applied to fields of type `Span` + --> $DIR/diagnostic-derive.rs:165:5 | -LL | #[label = "bar"] - | ^^^^^^^^^^^^^^^^ +LL | #[label(typeck::label)] + | ^^^^^^^^^^^^^^^^^^^^^^^ error: `name` doesn't refer to a field on this type - --> $DIR/diagnostic-derive.rs:164:42 + --> $DIR/diagnostic-derive.rs:173:45 | -LL | #[suggestion(message = "bar", code = "{name}")] - | ^^^^^^^^ +LL | #[suggestion(typeck::suggestion, code = "{name}")] + | ^^^^^^^^ error: invalid format string: expected `'}'` but string was terminated - --> $DIR/diagnostic-derive.rs:169:16 + --> $DIR/diagnostic-derive.rs:178:16 | LL | #[derive(SessionDiagnostic)] | - ^ expected `'}'` in format string @@ -237,7 +271,7 @@ LL | #[derive(SessionDiagnostic)] = note: this error originates in the derive macro `SessionDiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) error: invalid format string: unmatched `}` found - --> $DIR/diagnostic-derive.rs:179:15 + --> $DIR/diagnostic-derive.rs:188:15 | LL | #[derive(SessionDiagnostic)] | ^ unmatched `}` in format string @@ -245,14 +279,14 @@ LL | #[derive(SessionDiagnostic)] = note: if you intended to print `}`, you can escape it using `}}` = note: this error originates in the derive macro `SessionDiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) -error: the `#[label = ...]` attribute can only be applied to fields of type `Span` - --> $DIR/diagnostic-derive.rs:199:5 +error: the `#[label(...)]` attribute can only be applied to fields of type `Span` + --> $DIR/diagnostic-derive.rs:208:5 | -LL | #[label = "bar"] - | ^^^^^^^^^^^^^^^^ +LL | #[label(typeck::label)] + | ^^^^^^^^^^^^^^^^^^^^^^^ error: `#[suggestion(nonsense = ...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:224:18 + --> $DIR/diagnostic-derive.rs:233:18 | LL | #[suggestion(nonsense = "bar")] | ^^^^^^^^^^^^^^^^ @@ -260,7 +294,7 @@ LL | #[suggestion(nonsense = "bar")] = help: only `message`, `code` and `applicability` are valid field attributes error: `#[suggestion(msg = ...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:232:18 + --> $DIR/diagnostic-derive.rs:241:18 | LL | #[suggestion(msg = "bar")] | ^^^^^^^^^^^ @@ -268,9 +302,9 @@ LL | #[suggestion(msg = "bar")] = help: only `message`, `code` and `applicability` are valid field attributes error: wrong field type for suggestion - --> $DIR/diagnostic-derive.rs:254:5 + --> $DIR/diagnostic-derive.rs:263:5 | -LL | / #[suggestion(message = "bar", code = "This is suggested code")] +LL | / #[suggestion(typeck::suggestion, code = "This is suggested code")] LL | | LL | | suggestion: Applicability, | |_____________________________^ @@ -278,55 +312,77 @@ LL | | suggestion: Applicability, = help: `#[suggestion(...)]` should be applied to fields of type `Span` or `(Span, Applicability)` error: type of field annotated with `#[suggestion(...)]` contains more than one `Span` - --> $DIR/diagnostic-derive.rs:269:5 + --> $DIR/diagnostic-derive.rs:278:5 | -LL | / #[suggestion(message = "bar", code = "This is suggested code")] +LL | / #[suggestion(typeck::suggestion, code = "This is suggested code")] LL | | LL | | suggestion: (Span, Span, Applicability), | |___________________________________________^ error: type of field annotated with `#[suggestion(...)]` contains more than one Applicability - --> $DIR/diagnostic-derive.rs:277:5 + --> $DIR/diagnostic-derive.rs:286:5 | -LL | / #[suggestion(message = "bar", code = "This is suggested code")] +LL | / #[suggestion(typeck::suggestion, code = "This is suggested code")] LL | | LL | | suggestion: (Applicability, Applicability, Span), | |____________________________________________________^ -error: `#[label(...)]` is not a valid attribute - --> $DIR/diagnostic-derive.rs:285:5 - | -LL | #[label("bar")] - | ^^^^^^^^^^^^^^^ +error: `#[label = ...]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:294:5 | - = help: only `suggestion{,_short,_hidden,_verbose}` are valid field attributes +LL | #[label = "bar"] + | ^^^^^^^^^^^^^^^^ error: applicability cannot be set in both the field and attribute - --> $DIR/diagnostic-derive.rs:436:49 + --> $DIR/diagnostic-derive.rs:445:52 | -LL | #[suggestion(message = "bar", code = "...", applicability = "maybe-incorrect")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[suggestion(typeck::suggestion, code = "...", applicability = "maybe-incorrect")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: invalid applicability - --> $DIR/diagnostic-derive.rs:444:49 + --> $DIR/diagnostic-derive.rs:453:52 + | +LL | #[suggestion(typeck::suggestion, code = "...", applicability = "batman")] + | ^^^^^^^^^^^^^^^^^^^^^^^^ + +error: `#[label(...)]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:516:5 + | +LL | #[label(typeck::label, foo)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: `#[label(...)]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:524:5 + | +LL | #[label(typeck::label, foo = "...")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: `#[label(...)]` is not a valid attribute + --> $DIR/diagnostic-derive.rs:532:5 | -LL | #[suggestion(message = "bar", code = "...", applicability = "batman")] - | ^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[label(typeck::label, foo("..."))] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: cannot find attribute `nonsense` in this scope --> $DIR/diagnostic-derive.rs:51:3 | -LL | #[nonsense(code = "E0123", slug = "foo")] +LL | #[nonsense(typeck::ambiguous_lifetime_bound, code = "E0123")] | ^^^^^^^^ error: cannot find attribute `nonsense` in this scope - --> $DIR/diagnostic-derive.rs:139:7 + --> $DIR/diagnostic-derive.rs:148:7 | LL | #[nonsense] | ^^^^^^^^ +error[E0425]: cannot find value `nonsense` in module `rustc_errors::fluent` + --> $DIR/diagnostic-derive.rs:64:9 + | +LL | #[error(nonsense, code = "E0123")] + | ^^^^^^^^ not found in `rustc_errors::fluent` + error[E0277]: the trait bound `Hello: IntoDiagnosticArg` is not satisfied - --> $DIR/diagnostic-derive.rs:329:10 + --> $DIR/diagnostic-derive.rs:338:10 | LL | #[derive(SessionDiagnostic)] | ^^^^^^^^^^^^^^^^^ the trait `IntoDiagnosticArg` is not implemented for `Hello` @@ -345,6 +401,7 @@ LL | arg: impl IntoDiagnosticArg, | ^^^^^^^^^^^^^^^^^ required by this bound in `DiagnosticBuilder::<'a, G>::set_arg` = note: this error originates in the derive macro `SessionDiagnostic` (in Nightly builds, run with -Z macro-backtrace for more info) -error: aborting due to 39 previous errors +error: aborting due to 46 previous errors -For more information about this error, try `rustc --explain E0277`. +Some errors have detailed explanations: E0277, E0425. +For more information about an error, try `rustc --explain E0277`. From abd3467d47ad8f366239100334c31478f075a0de Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 23 Jun 2022 16:12:52 +0100 Subject: [PATCH 11/21] macros: use typed identifiers in subdiag derive As in the diagnostic derive, using typed identifiers in the subdiagnostic derive improves the diagnostics of using the subdiagnostic derive as Fluent messages will be confirmed to exist at compile-time. Signed-off-by: David Wood --- compiler/rustc_error_messages/src/lib.rs | 21 ++ compiler/rustc_macros/src/diagnostics/mod.rs | 6 +- .../src/diagnostics/subdiagnostic.rs | 84 ++++++- .../rustc_parse/src/parser/diagnostics.rs | 6 +- compiler/rustc_typeck/src/errors.rs | 8 +- .../ui-fulldeps/internal-lints/diagnostics.rs | 2 +- .../session-diagnostic/diagnostic-derive.rs | 2 +- .../subdiagnostic-derive.rs | 159 +++++++------- .../subdiagnostic-derive.stderr | 207 +++++++++--------- 9 files changed, 298 insertions(+), 197 deletions(-) diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 7211c05432698..8d5ab1a45173d 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -347,6 +347,27 @@ impl> From for DiagnosticMessage { } } +/// Translating *into* a subdiagnostic message from a diagnostic message is a little strange - but +/// the subdiagnostic functions (e.g. `span_label`) take a `SubdiagnosticMessage` and the +/// subdiagnostic derive refers to typed identifiers that are `DiagnosticMessage`s, so need to be +/// able to convert between these, as much as they'll be converted back into `DiagnosticMessage` +/// using `with_subdiagnostic_message` eventually. Don't use this other than for the derive. +impl Into for DiagnosticMessage { + fn into(self) -> SubdiagnosticMessage { + match self { + DiagnosticMessage::Str(s) => SubdiagnosticMessage::Str(s), + DiagnosticMessage::FluentIdentifier(id, None) => { + SubdiagnosticMessage::FluentIdentifier(id) + } + // There isn't really a sensible behaviour for this because it loses information but + // this is the most sensible of the behaviours. + DiagnosticMessage::FluentIdentifier(_, Some(attr)) => { + SubdiagnosticMessage::FluentAttr(attr) + } + } + } +} + /// A span together with some additional data. #[derive(Clone, Debug)] pub struct SpanLabel { diff --git a/compiler/rustc_macros/src/diagnostics/mod.rs b/compiler/rustc_macros/src/diagnostics/mod.rs index 88182ed5a1224..2eee4bfb5dd45 100644 --- a/compiler/rustc_macros/src/diagnostics/mod.rs +++ b/compiler/rustc_macros/src/diagnostics/mod.rs @@ -72,12 +72,12 @@ pub fn session_diagnostic_derive(s: Structure<'_>) -> TokenStream { /// ```ignore (rust) /// #[derive(SessionSubdiagnostic)] /// pub enum ExpectedIdentifierLabel<'tcx> { -/// #[label(slug = "parser-expected-identifier")] +/// #[label(parser::expected_identifier)] /// WithoutFound { /// #[primary_span] /// span: Span, /// } -/// #[label(slug = "parser-expected-identifier-found")] +/// #[label(parser::expected_identifier_found)] /// WithFound { /// #[primary_span] /// span: Span, @@ -86,7 +86,7 @@ pub fn session_diagnostic_derive(s: Structure<'_>) -> TokenStream { /// } /// /// #[derive(SessionSubdiagnostic)] -/// #[suggestion_verbose(slug = "parser-raw-identifier")] +/// #[suggestion_verbose(parser::raw_identifier)] /// pub struct RawIdentifierSuggestion<'tcx> { /// #[primary_span] /// span: Span, diff --git a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs index 9aeb484bfd52d..eab954a9c1bf9 100644 --- a/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs +++ b/compiler/rustc_macros/src/diagnostics/subdiagnostic.rs @@ -13,7 +13,7 @@ use quote::{format_ident, quote}; use std::collections::HashMap; use std::fmt; use std::str::FromStr; -use syn::{spanned::Spanned, Meta, MetaList, MetaNameValue}; +use syn::{parse_quote, spanned::Spanned, Meta, MetaList, MetaNameValue, NestedMeta, Path}; use synstructure::{BindingInfo, Structure, VariantInfo}; /// Which kind of suggestion is being created? @@ -194,8 +194,8 @@ struct SessionSubdiagnosticDeriveBuilder<'a> { kind: Option<(SubdiagnosticKind, proc_macro::Span)>, /// Slug of the subdiagnostic - corresponds to the Fluent identifier for the message - from the - /// `#[kind(slug = "...")]` attribute on the type or variant. - slug: Option<(String, proc_macro::Span)>, + /// `#[kind(slug)]` attribute on the type or variant. + slug: Option<(Path, proc_macro::Span)>, /// If a suggestion, the code to suggest as a replacement - from the `#[kind(code = "...")]` /// attribute on the type or variant. code: Option<(TokenStream, proc_macro::Span)>, @@ -224,9 +224,34 @@ impl<'a> SessionSubdiagnosticDeriveBuilder<'a> { let meta = attr.parse_meta()?; let kind = match meta { Meta::List(MetaList { ref nested, .. }) => { - for nested_attr in nested { + let mut nested_iter = nested.into_iter(); + if let Some(nested_attr) = nested_iter.next() { + match nested_attr { + NestedMeta::Meta(Meta::Path(path)) => { + self.slug.set_once((path.clone(), span)); + } + NestedMeta::Meta(meta @ Meta::NameValue(_)) + if matches!( + meta.path().segments.last().unwrap().ident.to_string().as_str(), + "code" | "applicability" + ) => + { + // don't error for valid follow-up attributes + } + nested_attr => { + throw_invalid_nested_attr!(attr, &nested_attr, |diag| { + diag.help( + "first argument of the attribute should be the diagnostic \ + slug", + ) + }) + } + }; + } + + for nested_attr in nested_iter { let meta = match nested_attr { - syn::NestedMeta::Meta(ref meta) => meta, + NestedMeta::Meta(ref meta) => meta, _ => throw_invalid_nested_attr!(attr, &nested_attr), }; @@ -241,7 +266,6 @@ impl<'a> SessionSubdiagnosticDeriveBuilder<'a> { let formatted_str = self.build_format(&s.value(), s.span()); self.code.set_once((formatted_str, span)); } - "slug" => self.slug.set_once((s.value(), span)), "applicability" => { let value = match Applicability::from_str(&s.value()) { Ok(v) => v, @@ -253,11 +277,23 @@ impl<'a> SessionSubdiagnosticDeriveBuilder<'a> { self.applicability.set_once((quote! { #value }, span)); } _ => throw_invalid_nested_attr!(attr, &nested_attr, |diag| { - diag.help("only `code`, `slug` and `applicability` are valid nested attributes") + diag.help( + "only `code` and `applicability` are valid nested \ + attributes", + ) }), } } - _ => throw_invalid_nested_attr!(attr, &nested_attr), + _ => throw_invalid_nested_attr!(attr, &nested_attr, |diag| { + if matches!(meta, Meta::Path(_)) { + diag.help( + "a diagnostic slug must be the first argument to the \ + attribute", + ) + } else { + diag + } + }), } } @@ -281,10 +317,27 @@ impl<'a> SessionSubdiagnosticDeriveBuilder<'a> { ); } + if matches!( + kind, + SubdiagnosticKind::Label | SubdiagnosticKind::Help | SubdiagnosticKind::Note + ) && self.applicability.is_some() + { + throw_span_err!( + span, + &format!( + "`applicability` is not a valid nested attribute of a `{}` attribute", + name + ) + ); + } + if self.slug.is_none() { throw_span_err!( span, - &format!("`slug` must be set in a `#[{}(...)]` attribute", name) + &format!( + "diagnostic slug must be first argument of a `#[{}(...)]` attribute", + name + ) ); } @@ -335,7 +388,10 @@ impl<'a> SessionSubdiagnosticDeriveBuilder<'a> { return Ok(quote! {}); } _ => throw_invalid_attr!(attr, &meta, |diag| { - diag.help("only `primary_span`, `applicability` and `skip_arg` are valid field attributes") + diag.help( + "only `primary_span`, `applicability` and `skip_arg` are valid field \ + attributes", + ) }), }, _ => throw_invalid_attr!(attr, &meta), @@ -375,7 +431,11 @@ impl<'a> SessionSubdiagnosticDeriveBuilder<'a> { } // Missing slug errors will already have been reported. - let slug = self.slug.as_ref().map(|(slug, _)| &**slug).unwrap_or("missing-slug"); + let slug = self + .slug + .as_ref() + .map(|(slug, _)| slug.clone()) + .unwrap_or_else(|| parse_quote! { you::need::to::specify::a::slug }); let code = match self.code.as_ref() { Some((code, _)) => Some(quote! { #code }), None if is_suggestion => { @@ -397,7 +457,7 @@ impl<'a> SessionSubdiagnosticDeriveBuilder<'a> { let diag = &self.diag; let name = format_ident!("{}{}", if span_field.is_some() { "span_" } else { "" }, kind); - let message = quote! { rustc_errors::SubdiagnosticMessage::message(#slug) }; + let message = quote! { rustc_errors::fluent::#slug }; let call = if matches!(kind, SubdiagnosticKind::Suggestion(..)) { if let Some(span) = span_field { quote! { #diag.#name(#span, #message, #code, #applicability); } diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 30869f055f5fa..58d5d43cfbfa8 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -265,7 +265,7 @@ struct BadTypePlus { #[derive(SessionSubdiagnostic)] pub enum BadTypePlusSub { #[suggestion( - slug = "parser-add-paren", + parser::add_paren, code = "{sum_with_parens}", applicability = "machine-applicable" )] @@ -274,12 +274,12 @@ pub enum BadTypePlusSub { #[primary_span] span: Span, }, - #[label(slug = "parser-forgot-paren")] + #[label(parser::forgot_paren)] ForgotParen { #[primary_span] span: Span, }, - #[label(slug = "parser-expect-path")] + #[label(parser::expect_path)] ExpectPath { #[primary_span] span: Span, diff --git a/compiler/rustc_typeck/src/errors.rs b/compiler/rustc_typeck/src/errors.rs index 758108e5d7170..4cdec615d8290 100644 --- a/compiler/rustc_typeck/src/errors.rs +++ b/compiler/rustc_typeck/src/errors.rs @@ -197,7 +197,7 @@ pub struct AddressOfTemporaryTaken { #[derive(SessionSubdiagnostic)] pub enum AddReturnTypeSuggestion<'tcx> { #[suggestion( - slug = "typeck-add-return-type-add", + typeck::add_return_type_add, code = "-> {found} ", applicability = "machine-applicable" )] @@ -207,7 +207,7 @@ pub enum AddReturnTypeSuggestion<'tcx> { found: Ty<'tcx>, }, #[suggestion( - slug = "typeck-add-return-type-missing-here", + typeck::add_return_type_missing_here, code = "-> _ ", applicability = "has-placeholders" )] @@ -219,12 +219,12 @@ pub enum AddReturnTypeSuggestion<'tcx> { #[derive(SessionSubdiagnostic)] pub enum ExpectedReturnTypeLabel<'tcx> { - #[label(slug = "typeck-expected-default-return-type")] + #[label(typeck::expected_default_return_type)] Unit { #[primary_span] span: Span, }, - #[label(slug = "typeck-expected-return-type")] + #[label(typeck::expected_return_type)] Other { #[primary_span] span: Span, diff --git a/src/test/ui-fulldeps/internal-lints/diagnostics.rs b/src/test/ui-fulldeps/internal-lints/diagnostics.rs index 3e349ab02586f..d6f63d44ba6a8 100644 --- a/src/test/ui-fulldeps/internal-lints/diagnostics.rs +++ b/src/test/ui-fulldeps/internal-lints/diagnostics.rs @@ -23,7 +23,7 @@ struct DeriveSessionDiagnostic { } #[derive(SessionSubdiagnostic)] -#[note(slug = "note")] +#[note(parser::add_paren)] struct Note { #[primary_span] span: Span, diff --git a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs index 8cbee4c6d9243..7bec1897fa53e 100644 --- a/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs +++ b/src/test/ui-fulldeps/session-diagnostic/diagnostic-derive.rs @@ -470,7 +470,7 @@ struct NoApplicability { } #[derive(SessionSubdiagnostic)] -#[note(slug = "note")] +#[note(parser::add_paren)] struct Note; #[derive(SessionDiagnostic)] diff --git a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs index bb406c35c0eef..6f4b6105b3e49 100644 --- a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs +++ b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.rs @@ -20,7 +20,7 @@ use rustc_span::Span; use rustc_macros::SessionSubdiagnostic; #[derive(SessionSubdiagnostic)] -#[label(slug = "label-a")] +#[label(parser::add_paren)] struct A { #[primary_span] span: Span, @@ -29,13 +29,13 @@ struct A { #[derive(SessionSubdiagnostic)] enum B { - #[label(slug = "label-b-a")] + #[label(parser::add_paren)] A { #[primary_span] span: Span, var: String, }, - #[label(slug = "label-b-b")] + #[label(parser::add_paren)] B { #[primary_span] span: Span, @@ -44,7 +44,7 @@ enum B { } #[derive(SessionSubdiagnostic)] -#[label(slug = "label-c")] +#[label(parser::add_paren)] //~^ ERROR label without `#[primary_span]` field struct C { var: String, @@ -116,7 +116,8 @@ struct K { #[derive(SessionSubdiagnostic)] #[label(slug)] -//~^ ERROR `#[label(slug)]` is not a valid attribute +//~^ ERROR cannot find value `slug` in module `rustc_errors::fluent` +//~^^ NOTE not found in `rustc_errors::fluent` struct L { #[primary_span] span: Span, @@ -125,7 +126,7 @@ struct L { #[derive(SessionSubdiagnostic)] #[label()] -//~^ ERROR `slug` must be set in a `#[label(...)]` attribute +//~^ ERROR diagnostic slug must be first argument of a `#[label(...)]` attribute struct M { #[primary_span] span: Span, @@ -133,7 +134,7 @@ struct M { } #[derive(SessionSubdiagnostic)] -#[label(code = "...")] +#[label(parser::add_paren, code = "...")] //~^ ERROR `code` is not a valid nested attribute of a `label` attribute struct N { #[primary_span] @@ -141,12 +142,21 @@ struct N { var: String, } +#[derive(SessionSubdiagnostic)] +#[label(parser::add_paren, applicability = "machine-applicable")] +//~^ ERROR `applicability` is not a valid nested attribute of a `label` attribute +struct O { + #[primary_span] + span: Span, + var: String, +} + #[derive(SessionSubdiagnostic)] #[foo] //~^ ERROR cannot find attribute `foo` in this scope //~^^ ERROR unsupported type attribute for subdiagnostic enum -enum O { - #[label(slug = "...")] +enum P { + #[label(parser::add_paren)] A { #[primary_span] span: Span, @@ -155,7 +165,7 @@ enum O { } #[derive(SessionSubdiagnostic)] -enum P { +enum Q { #[bar] //~^ ERROR `#[bar]` is not a valid attribute //~^^ ERROR cannot find attribute `bar` in this scope @@ -167,7 +177,7 @@ enum P { } #[derive(SessionSubdiagnostic)] -enum Q { +enum R { #[bar = "..."] //~^ ERROR `#[bar = ...]` is not a valid attribute //~^^ ERROR cannot find attribute `bar` in this scope @@ -179,7 +189,7 @@ enum Q { } #[derive(SessionSubdiagnostic)] -enum R { +enum S { #[bar = 4] //~^ ERROR `#[bar = ...]` is not a valid attribute //~^^ ERROR cannot find attribute `bar` in this scope @@ -191,7 +201,7 @@ enum R { } #[derive(SessionSubdiagnostic)] -enum S { +enum T { #[bar("...")] //~^ ERROR `#[bar("...")]` is not a valid attribute //~^^ ERROR cannot find attribute `bar` in this scope @@ -203,9 +213,9 @@ enum S { } #[derive(SessionSubdiagnostic)] -enum T { +enum U { #[label(code = "...")] -//~^ ERROR `code` is not a valid nested attribute of a `label` +//~^ ERROR diagnostic slug must be first argument of a `#[label(...)]` attribute A { #[primary_span] span: Span, @@ -214,8 +224,8 @@ enum T { } #[derive(SessionSubdiagnostic)] -enum U { - #[label(slug = "label-u")] +enum V { + #[label(parser::add_paren)] A { #[primary_span] span: Span, @@ -230,17 +240,17 @@ enum U { } #[derive(SessionSubdiagnostic)] -#[label(slug = "...")] +#[label(parser::add_paren)] //~^ ERROR label without `#[primary_span]` field -struct V { +struct W { #[primary_span] //~^ ERROR the `#[primary_span]` attribute can only be applied to fields of type `Span` span: String, } #[derive(SessionSubdiagnostic)] -#[label(slug = "...")] -struct W { +#[label(parser::add_paren)] +struct X { #[primary_span] span: Span, #[applicability] @@ -249,8 +259,8 @@ struct W { } #[derive(SessionSubdiagnostic)] -#[label(slug = "...")] -struct X { +#[label(parser::add_paren)] +struct Y { #[primary_span] span: Span, #[bar] @@ -260,8 +270,8 @@ struct X { } #[derive(SessionSubdiagnostic)] -#[label(slug = "...")] -struct Y { +#[label(parser::add_paren)] +struct Z { #[primary_span] span: Span, #[bar = "..."] @@ -271,8 +281,8 @@ struct Y { } #[derive(SessionSubdiagnostic)] -#[label(slug = "...")] -struct Z { +#[label(parser::add_paren)] +struct AA { #[primary_span] span: Span, #[bar("...")] @@ -282,8 +292,8 @@ struct Z { } #[derive(SessionSubdiagnostic)] -#[label(slug = "label-aa")] -struct AA { +#[label(parser::add_paren)] +struct AB { #[primary_span] span: Span, #[skip_arg] @@ -291,36 +301,35 @@ struct AA { } #[derive(SessionSubdiagnostic)] -union AB { +union AC { //~^ ERROR unexpected unsupported untagged union span: u32, b: u64 } #[derive(SessionSubdiagnostic)] -#[label(slug = "label-ac-1")] +#[label(parser::add_paren)] //~^ NOTE previously specified here //~^^ NOTE previously specified here -#[label(slug = "label-ac-2")] +#[label(parser::add_paren)] //~^ ERROR specified multiple times //~^^ ERROR specified multiple times -struct AC { +struct AD { #[primary_span] span: Span, } #[derive(SessionSubdiagnostic)] -#[label(slug = "label-ad-1", slug = "label-ad-2")] -//~^ ERROR specified multiple times -//~^^ NOTE previously specified here -struct AD { +#[label(parser::add_paren, parser::add_paren)] +//~^ ERROR `#[label(parser::add_paren)]` is not a valid attribute +struct AE { #[primary_span] span: Span, } #[derive(SessionSubdiagnostic)] -#[label(slug = "label-ad-1")] -struct AE { +#[label(parser::add_paren)] +struct AF { #[primary_span] //~^ NOTE previously specified here span_a: Span, @@ -330,15 +339,15 @@ struct AE { } #[derive(SessionSubdiagnostic)] -struct AF { +struct AG { //~^ ERROR subdiagnostic kind not specified #[primary_span] span: Span, } #[derive(SessionSubdiagnostic)] -#[suggestion(slug = "suggestion-af", code = "...")] -struct AG { +#[suggestion(parser::add_paren, code = "...")] +struct AH { #[primary_span] span: Span, #[applicability] @@ -347,8 +356,8 @@ struct AG { } #[derive(SessionSubdiagnostic)] -enum AH { - #[suggestion(slug = "suggestion-ag-a", code = "...")] +enum AI { + #[suggestion(parser::add_paren, code = "...")] A { #[primary_span] span: Span, @@ -356,7 +365,7 @@ enum AH { applicability: Applicability, var: String, }, - #[suggestion(slug = "suggestion-ag-b", code = "...")] + #[suggestion(parser::add_paren, code = "...")] B { #[primary_span] span: Span, @@ -367,10 +376,10 @@ enum AH { } #[derive(SessionSubdiagnostic)] -#[suggestion(slug = "...", code = "...", code = "...")] +#[suggestion(parser::add_paren, code = "...", code = "...")] //~^ ERROR specified multiple times //~^^ NOTE previously specified here -struct AI { +struct AJ { #[primary_span] span: Span, #[applicability] @@ -378,8 +387,8 @@ struct AI { } #[derive(SessionSubdiagnostic)] -#[suggestion(slug = "...", code = "...")] -struct AJ { +#[suggestion(parser::add_paren, code = "...")] +struct AK { #[primary_span] span: Span, #[applicability] @@ -391,9 +400,9 @@ struct AJ { } #[derive(SessionSubdiagnostic)] -#[suggestion(slug = "...", code = "...")] +#[suggestion(parser::add_paren, code = "...")] //~^ ERROR suggestion without `applicability` -struct AK { +struct AL { #[primary_span] span: Span, #[applicability] @@ -402,17 +411,17 @@ struct AK { } #[derive(SessionSubdiagnostic)] -#[suggestion(slug = "...", code = "...")] +#[suggestion(parser::add_paren, code = "...")] //~^ ERROR suggestion without `applicability` -struct AL { +struct AM { #[primary_span] span: Span, } #[derive(SessionSubdiagnostic)] -#[suggestion(slug = "...")] +#[suggestion(parser::add_paren)] //~^ ERROR suggestion without `code = "..."` -struct AM { +struct AN { #[primary_span] span: Span, #[applicability] @@ -420,34 +429,34 @@ struct AM { } #[derive(SessionSubdiagnostic)] -#[suggestion(slug = "...", code ="...", applicability = "foo")] +#[suggestion(parser::add_paren, code ="...", applicability = "foo")] //~^ ERROR invalid applicability -struct AN { +struct AO { #[primary_span] span: Span, } #[derive(SessionSubdiagnostic)] -#[help(slug = "label-am")] -struct AO { +#[help(parser::add_paren)] +struct AP { var: String } #[derive(SessionSubdiagnostic)] -#[note(slug = "label-an")] -struct AP; +#[note(parser::add_paren)] +struct AQ; #[derive(SessionSubdiagnostic)] -#[suggestion(slug = "...", code = "...")] +#[suggestion(parser::add_paren, code = "...")] //~^ ERROR suggestion without `applicability` //~^^ ERROR suggestion without `#[primary_span]` field -struct AQ { +struct AR { var: String, } #[derive(SessionSubdiagnostic)] -#[suggestion(slug = "...", code ="...", applicability = "machine-applicable")] -struct AR { +#[suggestion(parser::add_paren, code ="...", applicability = "machine-applicable")] +struct AS { #[primary_span] span: Span, } @@ -455,8 +464,8 @@ struct AR { #[derive(SessionSubdiagnostic)] #[label] //~^ ERROR unsupported type attribute for subdiagnostic enum -enum AS { - #[label(slug = "...")] +enum AT { + #[label(parser::add_paren)] A { #[primary_span] span: Span, @@ -465,24 +474,24 @@ enum AS { } #[derive(SessionSubdiagnostic)] -#[suggestion(slug = "...", code ="{var}", applicability = "machine-applicable")] -struct AT { +#[suggestion(parser::add_paren, code ="{var}", applicability = "machine-applicable")] +struct AU { #[primary_span] span: Span, var: String, } #[derive(SessionSubdiagnostic)] -#[suggestion(slug = "...", code ="{var}", applicability = "machine-applicable")] +#[suggestion(parser::add_paren, code ="{var}", applicability = "machine-applicable")] //~^ ERROR `var` doesn't refer to a field on this type -struct AU { +struct AV { #[primary_span] span: Span, } #[derive(SessionSubdiagnostic)] -enum AV { - #[suggestion(slug = "...", code ="{var}", applicability = "machine-applicable")] +enum AW { + #[suggestion(parser::add_paren, code ="{var}", applicability = "machine-applicable")] A { #[primary_span] span: Span, @@ -491,8 +500,8 @@ enum AV { } #[derive(SessionSubdiagnostic)] -enum AW { - #[suggestion(slug = "...", code ="{var}", applicability = "machine-applicable")] +enum AX { + #[suggestion(parser::add_paren, code ="{var}", applicability = "machine-applicable")] //~^ ERROR `var` doesn't refer to a field on this type A { #[primary_span] diff --git a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr index 4984cc4b3186c..f833bd210f7f5 100644 --- a/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr +++ b/src/test/ui-fulldeps/session-diagnostic/subdiagnostic-derive.stderr @@ -1,7 +1,7 @@ error: label without `#[primary_span]` field --> $DIR/subdiagnostic-derive.rs:47:1 | -LL | / #[label(slug = "label-c")] +LL | / #[label(parser::add_paren)] LL | | LL | | struct C { LL | | var: String, @@ -32,98 +32,106 @@ error: `#[label(bug = ...)]` is not a valid attribute LL | #[label(bug = "...")] | ^^^^^^^^^^^ | - = help: only `code`, `slug` and `applicability` are valid nested attributes + = help: first argument of the attribute should be the diagnostic slug error: `#[label("...")]` is not a valid attribute --> $DIR/subdiagnostic-derive.rs:91:9 | LL | #[label("...")] | ^^^^^ + | + = help: first argument of the attribute should be the diagnostic slug error: `#[label(slug = ...)]` is not a valid attribute --> $DIR/subdiagnostic-derive.rs:100:9 | LL | #[label(slug = 4)] | ^^^^^^^^ + | + = help: first argument of the attribute should be the diagnostic slug error: `#[label(slug(...))]` is not a valid attribute --> $DIR/subdiagnostic-derive.rs:109:9 | LL | #[label(slug("..."))] | ^^^^^^^^^^^ - -error: `#[label(slug)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:118:9 | -LL | #[label(slug)] - | ^^^^ + = help: first argument of the attribute should be the diagnostic slug -error: `slug` must be set in a `#[label(...)]` attribute - --> $DIR/subdiagnostic-derive.rs:127:1 +error: diagnostic slug must be first argument of a `#[label(...)]` attribute + --> $DIR/subdiagnostic-derive.rs:128:1 | LL | #[label()] | ^^^^^^^^^^ error: `code` is not a valid nested attribute of a `label` attribute - --> $DIR/subdiagnostic-derive.rs:136:1 + --> $DIR/subdiagnostic-derive.rs:137:1 + | +LL | #[label(parser::add_paren, code = "...")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +error: `applicability` is not a valid nested attribute of a `label` attribute + --> $DIR/subdiagnostic-derive.rs:146:1 | -LL | #[label(code = "...")] - | ^^^^^^^^^^^^^^^^^^^^^^ +LL | #[label(parser::add_paren, applicability = "machine-applicable")] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: unsupported type attribute for subdiagnostic enum - --> $DIR/subdiagnostic-derive.rs:145:1 + --> $DIR/subdiagnostic-derive.rs:155:1 | LL | #[foo] | ^^^^^^ error: `#[bar]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:159:5 + --> $DIR/subdiagnostic-derive.rs:169:5 | LL | #[bar] | ^^^^^^ error: `#[bar = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:171:5 + --> $DIR/subdiagnostic-derive.rs:181:5 | LL | #[bar = "..."] | ^^^^^^^^^^^^^^ error: `#[bar = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:183:5 + --> $DIR/subdiagnostic-derive.rs:193:5 | LL | #[bar = 4] | ^^^^^^^^^^ error: `#[bar("...")]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:195:11 + --> $DIR/subdiagnostic-derive.rs:205:11 | LL | #[bar("...")] | ^^^^^ + | + = help: first argument of the attribute should be the diagnostic slug -error: `code` is not a valid nested attribute of a `label` attribute - --> $DIR/subdiagnostic-derive.rs:207:5 +error: diagnostic slug must be first argument of a `#[label(...)]` attribute + --> $DIR/subdiagnostic-derive.rs:217:5 | LL | #[label(code = "...")] | ^^^^^^^^^^^^^^^^^^^^^^ error: subdiagnostic kind not specified - --> $DIR/subdiagnostic-derive.rs:224:5 + --> $DIR/subdiagnostic-derive.rs:234:5 | LL | B { | ^ error: the `#[primary_span]` attribute can only be applied to fields of type `Span` - --> $DIR/subdiagnostic-derive.rs:236:5 + --> $DIR/subdiagnostic-derive.rs:246:5 | LL | #[primary_span] | ^^^^^^^^^^^^^^^ error: label without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:233:1 + --> $DIR/subdiagnostic-derive.rs:243:1 | -LL | / #[label(slug = "...")] +LL | / #[label(parser::add_paren)] LL | | -LL | | struct V { +LL | | struct W { LL | | #[primary_span] LL | | LL | | span: String, @@ -131,13 +139,13 @@ LL | | } | |_^ error: `#[applicability]` is only valid on suggestions - --> $DIR/subdiagnostic-derive.rs:246:5 + --> $DIR/subdiagnostic-derive.rs:256:5 | LL | #[applicability] | ^^^^^^^^^^^^^^^^ error: `#[bar]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:256:5 + --> $DIR/subdiagnostic-derive.rs:266:5 | LL | #[bar] | ^^^^^^ @@ -145,21 +153,21 @@ LL | #[bar] = help: only `primary_span`, `applicability` and `skip_arg` are valid field attributes error: `#[bar = ...]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:267:5 + --> $DIR/subdiagnostic-derive.rs:277:5 | LL | #[bar = "..."] | ^^^^^^^^^^^^^^ error: `#[bar(...)]` is not a valid attribute - --> $DIR/subdiagnostic-derive.rs:278:5 + --> $DIR/subdiagnostic-derive.rs:288:5 | LL | #[bar("...")] | ^^^^^^^^^^^^^ error: unexpected unsupported untagged union - --> $DIR/subdiagnostic-derive.rs:294:1 + --> $DIR/subdiagnostic-derive.rs:304:1 | -LL | / union AB { +LL | / union AC { LL | | LL | | span: u32, LL | | b: u64 @@ -167,95 +175,91 @@ LL | | } | |_^ error: specified multiple times - --> $DIR/subdiagnostic-derive.rs:304:9 + --> $DIR/subdiagnostic-derive.rs:314:1 | -LL | #[label(slug = "label-ac-2")] - | ^^^^^^^^^^^^^^^^^^^ +LL | #[label(parser::add_paren)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/subdiagnostic-derive.rs:301:9 + --> $DIR/subdiagnostic-derive.rs:311:1 | -LL | #[label(slug = "label-ac-1")] - | ^^^^^^^^^^^^^^^^^^^ +LL | #[label(parser::add_paren)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: specified multiple times - --> $DIR/subdiagnostic-derive.rs:304:1 + --> $DIR/subdiagnostic-derive.rs:314:1 | -LL | #[label(slug = "label-ac-2")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[label(parser::add_paren)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/subdiagnostic-derive.rs:301:1 + --> $DIR/subdiagnostic-derive.rs:311:1 | -LL | #[label(slug = "label-ac-1")] - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ +LL | #[label(parser::add_paren)] + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ -error: specified multiple times - --> $DIR/subdiagnostic-derive.rs:313:30 +error: `#[label(parser::add_paren)]` is not a valid attribute + --> $DIR/subdiagnostic-derive.rs:323:28 | -LL | #[label(slug = "label-ad-1", slug = "label-ad-2")] - | ^^^^^^^^^^^^^^^^^^^ +LL | #[label(parser::add_paren, parser::add_paren)] + | ^^^^^^^^^^^^^^^^^ | -note: previously specified here - --> $DIR/subdiagnostic-derive.rs:313:9 - | -LL | #[label(slug = "label-ad-1", slug = "label-ad-2")] - | ^^^^^^^^^^^^^^^^^^^ + = help: a diagnostic slug must be the first argument to the attribute error: specified multiple times - --> $DIR/subdiagnostic-derive.rs:327:5 + --> $DIR/subdiagnostic-derive.rs:336:5 | LL | #[primary_span] | ^^^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/subdiagnostic-derive.rs:324:5 + --> $DIR/subdiagnostic-derive.rs:333:5 | LL | #[primary_span] | ^^^^^^^^^^^^^^^ error: subdiagnostic kind not specified - --> $DIR/subdiagnostic-derive.rs:333:8 + --> $DIR/subdiagnostic-derive.rs:342:8 | -LL | struct AF { +LL | struct AG { | ^^ error: specified multiple times - --> $DIR/subdiagnostic-derive.rs:370:42 + --> $DIR/subdiagnostic-derive.rs:379:47 | -LL | #[suggestion(slug = "...", code = "...", code = "...")] - | ^^^^^^^^^^^^ +LL | #[suggestion(parser::add_paren, code = "...", code = "...")] + | ^^^^^^^^^^^^ | note: previously specified here - --> $DIR/subdiagnostic-derive.rs:370:28 + --> $DIR/subdiagnostic-derive.rs:379:33 | -LL | #[suggestion(slug = "...", code = "...", code = "...")] - | ^^^^^^^^^^^^ +LL | #[suggestion(parser::add_paren, code = "...", code = "...")] + | ^^^^^^^^^^^^ error: specified multiple times - --> $DIR/subdiagnostic-derive.rs:388:5 + --> $DIR/subdiagnostic-derive.rs:397:5 | LL | #[applicability] | ^^^^^^^^^^^^^^^^ | note: previously specified here - --> $DIR/subdiagnostic-derive.rs:385:5 + --> $DIR/subdiagnostic-derive.rs:394:5 | LL | #[applicability] | ^^^^^^^^^^^^^^^^ error: the `#[applicability]` attribute can only be applied to fields of type `Applicability` - --> $DIR/subdiagnostic-derive.rs:399:5 + --> $DIR/subdiagnostic-derive.rs:408:5 | LL | #[applicability] | ^^^^^^^^^^^^^^^^ error: suggestion without `applicability` - --> $DIR/subdiagnostic-derive.rs:394:1 + --> $DIR/subdiagnostic-derive.rs:403:1 | -LL | / #[suggestion(slug = "...", code = "...")] +LL | / #[suggestion(parser::add_paren, code = "...")] LL | | -LL | | struct AK { +LL | | struct AL { LL | | #[primary_span] ... | LL | | applicability: Span, @@ -263,22 +267,22 @@ LL | | } | |_^ error: suggestion without `applicability` - --> $DIR/subdiagnostic-derive.rs:405:1 + --> $DIR/subdiagnostic-derive.rs:414:1 | -LL | / #[suggestion(slug = "...", code = "...")] +LL | / #[suggestion(parser::add_paren, code = "...")] LL | | -LL | | struct AL { +LL | | struct AM { LL | | #[primary_span] LL | | span: Span, LL | | } | |_^ error: suggestion without `code = "..."` - --> $DIR/subdiagnostic-derive.rs:413:1 + --> $DIR/subdiagnostic-derive.rs:422:1 | -LL | / #[suggestion(slug = "...")] +LL | / #[suggestion(parser::add_paren)] LL | | -LL | | struct AM { +LL | | struct AN { LL | | #[primary_span] ... | LL | | applicability: Applicability, @@ -286,50 +290,50 @@ LL | | } | |_^ error: invalid applicability - --> $DIR/subdiagnostic-derive.rs:423:41 + --> $DIR/subdiagnostic-derive.rs:432:46 | -LL | #[suggestion(slug = "...", code ="...", applicability = "foo")] - | ^^^^^^^^^^^^^^^^^^^^^ +LL | #[suggestion(parser::add_paren, code ="...", applicability = "foo")] + | ^^^^^^^^^^^^^^^^^^^^^ error: suggestion without `applicability` - --> $DIR/subdiagnostic-derive.rs:441:1 + --> $DIR/subdiagnostic-derive.rs:450:1 | -LL | / #[suggestion(slug = "...", code = "...")] +LL | / #[suggestion(parser::add_paren, code = "...")] LL | | LL | | -LL | | struct AQ { +LL | | struct AR { LL | | var: String, LL | | } | |_^ error: suggestion without `#[primary_span]` field - --> $DIR/subdiagnostic-derive.rs:441:1 + --> $DIR/subdiagnostic-derive.rs:450:1 | -LL | / #[suggestion(slug = "...", code = "...")] +LL | / #[suggestion(parser::add_paren, code = "...")] LL | | LL | | -LL | | struct AQ { +LL | | struct AR { LL | | var: String, LL | | } | |_^ error: unsupported type attribute for subdiagnostic enum - --> $DIR/subdiagnostic-derive.rs:456:1 + --> $DIR/subdiagnostic-derive.rs:465:1 | LL | #[label] | ^^^^^^^^ error: `var` doesn't refer to a field on this type - --> $DIR/subdiagnostic-derive.rs:476:34 + --> $DIR/subdiagnostic-derive.rs:485:39 | -LL | #[suggestion(slug = "...", code ="{var}", applicability = "machine-applicable")] - | ^^^^^^^ +LL | #[suggestion(parser::add_paren, code ="{var}", applicability = "machine-applicable")] + | ^^^^^^^ error: `var` doesn't refer to a field on this type - --> $DIR/subdiagnostic-derive.rs:495:38 + --> $DIR/subdiagnostic-derive.rs:504:43 | -LL | #[suggestion(slug = "...", code ="{var}", applicability = "machine-applicable")] - | ^^^^^^^ +LL | #[suggestion(parser::add_paren, code ="{var}", applicability = "machine-applicable")] + | ^^^^^^^ error: cannot find attribute `foo` in this scope --> $DIR/subdiagnostic-derive.rs:63:3 @@ -338,52 +342,59 @@ LL | #[foo] | ^^^ error: cannot find attribute `foo` in this scope - --> $DIR/subdiagnostic-derive.rs:145:3 + --> $DIR/subdiagnostic-derive.rs:155:3 | LL | #[foo] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:159:7 + --> $DIR/subdiagnostic-derive.rs:169:7 | LL | #[bar] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:171:7 + --> $DIR/subdiagnostic-derive.rs:181:7 | LL | #[bar = "..."] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:183:7 + --> $DIR/subdiagnostic-derive.rs:193:7 | LL | #[bar = 4] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:195:7 + --> $DIR/subdiagnostic-derive.rs:205:7 | LL | #[bar("...")] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:256:7 + --> $DIR/subdiagnostic-derive.rs:266:7 | LL | #[bar] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:267:7 + --> $DIR/subdiagnostic-derive.rs:277:7 | LL | #[bar = "..."] | ^^^ error: cannot find attribute `bar` in this scope - --> $DIR/subdiagnostic-derive.rs:278:7 + --> $DIR/subdiagnostic-derive.rs:288:7 | LL | #[bar("...")] | ^^^ -error: aborting due to 51 previous errors +error[E0425]: cannot find value `slug` in module `rustc_errors::fluent` + --> $DIR/subdiagnostic-derive.rs:118:9 + | +LL | #[label(slug)] + | ^^^^ not found in `rustc_errors::fluent` + +error: aborting due to 52 previous errors +For more information about this error, try `rustc --explain E0425`. From dc90d1d987d74af4950caca0f9b16d7fdf21b6af Mon Sep 17 00:00:00 2001 From: David Wood Date: Thu, 23 Jun 2022 16:14:48 +0100 Subject: [PATCH 12/21] errors: remove diagnostic message ctors Now that typed identifiers are used in both derives, constructors for the `DiagnosticMessage` and `SubdiagnosticMessage` types are not required. Signed-off-by: David Wood --- compiler/rustc_error_messages/src/lib.rs | 17 ----------------- 1 file changed, 17 deletions(-) diff --git a/compiler/rustc_error_messages/src/lib.rs b/compiler/rustc_error_messages/src/lib.rs index 8d5ab1a45173d..673e160cc1e74 100644 --- a/compiler/rustc_error_messages/src/lib.rs +++ b/compiler/rustc_error_messages/src/lib.rs @@ -258,18 +258,6 @@ pub enum SubdiagnosticMessage { FluentAttr(FluentId), } -impl SubdiagnosticMessage { - /// Create a `SubdiagnosticMessage` for the provided Fluent attribute. - pub fn attr(id: impl Into) -> Self { - SubdiagnosticMessage::FluentAttr(id.into()) - } - - /// Create a `SubdiagnosticMessage` for the provided Fluent identifier. - pub fn message(id: impl Into) -> Self { - SubdiagnosticMessage::FluentIdentifier(id.into()) - } -} - /// `From` impl that enables existing diagnostic calls to functions which now take /// `impl Into` to continue to work as before. impl> From for SubdiagnosticMessage { @@ -332,11 +320,6 @@ impl DiagnosticMessage { _ => panic!("expected non-translatable diagnostic message"), } } - - /// Create a `DiagnosticMessage` for the provided Fluent identifier. - pub fn new(id: impl Into) -> Self { - DiagnosticMessage::FluentIdentifier(id.into(), None) - } } /// `From` impl that enables existing diagnostic calls to functions which now take From 747586732b1bb21c1ef318428fe179a77db2d963 Mon Sep 17 00:00:00 2001 From: Caio Date: Sat, 25 Jun 2022 08:08:38 -0300 Subject: [PATCH 13/21] [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 dc2cc109419ac497ac24046297f452c9cced0ec0 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 Jun 2022 11:06:04 -0400 Subject: [PATCH 14/21] make const_err show up in future breakage reports --- compiler/rustc_lint_defs/src/builtin.rs | 1 + .../array_const_index-0.stderr | 13 + .../array_const_index-1.stderr | 13 + .../defaults-not-assumed-fail.stderr | 25 ++ .../ui/consts/assert-type-intrinsics.stderr | 42 +++ .../ui/consts/assoc_const_generic_impl.stderr | 17 ++ src/test/ui/consts/const-err-early.stderr | 85 ++++++ src/test/ui/consts/const-err-multi.stderr | 68 +++++ src/test/ui/consts/const-err.stderr | 17 ++ .../conditional_array_execution.stderr | 33 +++ .../const-eval/const-eval-overflow-2.stderr | 17 ++ .../const-eval/const-eval-overflow2.stderr | 150 ++++++++++ .../const-eval/const-eval-overflow2b.stderr | 150 ++++++++++ .../const-eval/const-eval-overflow2c.stderr | 150 ++++++++++ .../const-eval/const-eval-query-stack.stderr | 17 ++ ...inter-values-in-various-types.64bit.stderr | 260 ++++++++++++++++++ .../const-eval/const_fn_ptr_fail2.stderr | 76 +++++ .../consts/const-eval/erroneous-const.stderr | 17 ++ .../consts/const-eval/erroneous-const2.stderr | 17 ++ .../index-out-of-bounds-never-type.stderr | 17 ++ .../ui/consts/const-eval/issue-43197.stderr | 66 +++++ .../ui/consts/const-eval/issue-44578.stderr | 33 +++ .../ui/consts/const-eval/issue-50814-2.stderr | 13 + .../ui/consts/const-eval/issue-50814.stderr | 13 + .../const-eval/partial_ptr_overwrite.stderr | 19 ++ .../const-eval/promoted_errors.noopt.stderr | 50 ++++ .../const-eval/promoted_errors.opt.stderr | 51 ++++ ...ted_errors.opt_with_overflow_checks.stderr | 50 ++++ .../ui/consts/const-eval/pub_const_err.stderr | 17 ++ .../const-eval/pub_const_err_bin.stderr | 17 ++ .../const-eval/unused-broken-const.stderr | 13 + .../const-external-macro-const-err.stderr | 12 + .../const-len-underflow-separate-spans.stderr | 13 + .../const-prop-read-static-in-const.stderr | 13 + ...ize_of_val-align_of_val-extern-type.stderr | 26 ++ src/test/ui/consts/const-slice-oob.stderr | 13 + .../const_eval_limit_reached.stderr | 18 ++ src/test/ui/consts/invalid-union.64bit.stderr | 11 + src/test/ui/consts/issue-56164.stderr | 11 + src/test/ui/consts/issue-66693.stderr | 11 + src/test/ui/consts/issue-miri-1910.stderr | 25 ++ .../consts/miri_unleashed/assoc_const.stderr | 25 ++ .../miri_unleashed/assoc_const_2.stderr | 17 ++ .../const_refers_to_static.stderr | 55 ++++ ..._refers_to_static_cross_crate.64bit.stderr | 42 +++ src/test/ui/consts/ptr_comparisons.stderr | 26 ++ src/test/ui/consts/recursive.stderr | 19 ++ .../uninhabited-const-issue-61744.stderr | 144 ++++++++++ 48 files changed, 2008 insertions(+) diff --git a/compiler/rustc_lint_defs/src/builtin.rs b/compiler/rustc_lint_defs/src/builtin.rs index b1bfd612b90e5..d52455e2576c9 100644 --- a/compiler/rustc_lint_defs/src/builtin.rs +++ b/compiler/rustc_lint_defs/src/builtin.rs @@ -289,6 +289,7 @@ declare_lint! { "constant evaluation encountered erroneous expression", @future_incompatible = FutureIncompatibleInfo { reference: "issue #71800 ", + reason: FutureIncompatibilityReason::FutureReleaseErrorReportNow, }; report_in_external_macro } diff --git a/src/test/ui/array-slice-vec/array_const_index-0.stderr b/src/test/ui/array-slice-vec/array_const_index-0.stderr index 641705e1c6875..b44251efdea42 100644 --- a/src/test/ui/array-slice-vec/array_const_index-0.stderr +++ b/src/test/ui/array-slice-vec/array_const_index-0.stderr @@ -12,3 +12,16 @@ LL | const B: i32 = (&A)[1]; error: aborting due to previous error +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/array_const_index-0.rs:2:16 + | +LL | const B: i32 = (&A)[1]; + | ---------------^^^^^^^- + | | + | index out of bounds: the length is 0 but the index is 1 + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/array-slice-vec/array_const_index-1.stderr b/src/test/ui/array-slice-vec/array_const_index-1.stderr index 4d52d38af5e17..8beebafb04c32 100644 --- a/src/test/ui/array-slice-vec/array_const_index-1.stderr +++ b/src/test/ui/array-slice-vec/array_const_index-1.stderr @@ -12,3 +12,16 @@ LL | const B: i32 = A[1]; error: aborting due to previous error +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/array_const_index-1.rs:2:16 + | +LL | const B: i32 = A[1]; + | ---------------^^^^- + | | + | index out of bounds: the length is 0 but the index is 1 + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/associated-consts/defaults-not-assumed-fail.stderr b/src/test/ui/associated-consts/defaults-not-assumed-fail.stderr index 7406b2ddee9b2..f04ea0b747705 100644 --- a/src/test/ui/associated-consts/defaults-not-assumed-fail.stderr +++ b/src/test/ui/associated-consts/defaults-not-assumed-fail.stderr @@ -29,3 +29,28 @@ LL | assert_eq!(<() as Tr>::B, 0); // causes the error above error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/defaults-not-assumed-fail.rs:8:19 + | +LL | const B: u8 = Self::A + 1; + | --------------^^^^^^^^^^^- + | | + | attempt to compute `u8::MAX + 1_u8`, which would overflow + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: erroneous constant used + --> $DIR/defaults-not-assumed-fail.rs:34:5 + | +LL | assert_eq!(<() as Tr>::B, 0); // causes the error above + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + = 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/consts/assert-type-intrinsics.stderr b/src/test/ui/consts/assert-type-intrinsics.stderr index bb57ee82cc16f..89f8f2ffc55cb 100644 --- a/src/test/ui/consts/assert-type-intrinsics.stderr +++ b/src/test/ui/consts/assert-type-intrinsics.stderr @@ -37,3 +37,45 @@ LL | | }; error: aborting due to 3 previous errors +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/assert-type-intrinsics.rs:14:9 + | +LL | / const _BAD1: () = unsafe { +LL | | MaybeUninit::::uninit().assume_init(); + | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to instantiate uninhabited type `!` +LL | | }; + | |______- + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/assert-type-intrinsics.rs:17:9 + | +LL | / const _BAD2: () = unsafe { +LL | | intrinsics::assert_uninit_valid::(); + | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to leave type `bool` uninitialized, which is invalid +LL | | }; + | |______- + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/assert-type-intrinsics.rs:20:9 + | +LL | / const _BAD3: () = unsafe { +LL | | intrinsics::assert_zero_valid::<&'static i32>(); + | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ aborted execution: attempted to zero-initialize type `&i32`, which is invalid +LL | | }; + | |______- + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/assoc_const_generic_impl.stderr b/src/test/ui/consts/assoc_const_generic_impl.stderr index 96cb904fa1b19..cccf62a8ff6d3 100644 --- a/src/test/ui/consts/assoc_const_generic_impl.stderr +++ b/src/test/ui/consts/assoc_const_generic_impl.stderr @@ -22,3 +22,20 @@ LL | let () = Self::I_AM_ZERO_SIZED; error: aborting due to previous error; 1 warning emitted +Future incompatibility report: Future breakage diagnostic: +warning: any use of this value will cause an error + --> $DIR/assoc_const_generic_impl.rs:11:34 + | +LL | const I_AM_ZERO_SIZED: () = [()][std::mem::size_of::()]; + | -----------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- + | | + | index out of bounds: the length is 1 but the index is 4 + | +note: the lint level is defined here + --> $DIR/assoc_const_generic_impl.rs:3:9 + | +LL | #![warn(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-err-early.stderr b/src/test/ui/consts/const-err-early.stderr index 2b3d881738762..385e770eb4f01 100644 --- a/src/test/ui/consts/const-err-early.stderr +++ b/src/test/ui/consts/const-err-early.stderr @@ -60,3 +60,88 @@ LL | pub const E: u8 = [5u8][1]; error: aborting due to 5 previous errors +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-err-early.rs:3:19 + | +LL | pub const A: i8 = -i8::MIN; + | ------------------^^^^^^^^- + | | + | attempt to negate `i8::MIN`, which would overflow + | +note: the lint level is defined here + --> $DIR/const-err-early.rs:1:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-err-early.rs:5:19 + | +LL | pub const B: u8 = 200u8 + 200u8; + | ------------------^^^^^^^^^^^^^- + | | + | attempt to compute `200_u8 + 200_u8`, which would overflow + | +note: the lint level is defined here + --> $DIR/const-err-early.rs:1:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-err-early.rs:7:19 + | +LL | pub const C: u8 = 200u8 * 4; + | ------------------^^^^^^^^^- + | | + | attempt to compute `200_u8 * 4_u8`, which would overflow + | +note: the lint level is defined here + --> $DIR/const-err-early.rs:1:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-err-early.rs:9:19 + | +LL | pub const D: u8 = 42u8 - (42u8 + 1); + | ------------------^^^^^^^^^^^^^^^^^- + | | + | attempt to compute `42_u8 - 43_u8`, which would overflow + | +note: the lint level is defined here + --> $DIR/const-err-early.rs:1:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-err-early.rs:11:19 + | +LL | pub const E: u8 = [5u8][1]; + | ------------------^^^^^^^^- + | | + | index out of bounds: the length is 1 but the index is 1 + | +note: the lint level is defined here + --> $DIR/const-err-early.rs:1:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-err-multi.stderr b/src/test/ui/consts/const-err-multi.stderr index c8172e83d10e2..a195459ff0884 100644 --- a/src/test/ui/consts/const-err-multi.stderr +++ b/src/test/ui/consts/const-err-multi.stderr @@ -49,3 +49,71 @@ LL | pub const D: i8 = 50 - A; error: aborting due to 4 previous errors +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-err-multi.rs:3:19 + | +LL | pub const A: i8 = -i8::MIN; + | ------------------^^^^^^^^- + | | + | attempt to negate `i8::MIN`, which would overflow + | +note: the lint level is defined here + --> $DIR/const-err-multi.rs:1:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-err-multi.rs:6:19 + | +LL | pub const B: i8 = A; + | ------------------^- + | | + | referenced constant has errors + | +note: the lint level is defined here + --> $DIR/const-err-multi.rs:1:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-err-multi.rs:9:19 + | +LL | pub const C: u8 = A as u8; + | ------------------^------- + | | + | referenced constant has errors + | +note: the lint level is defined here + --> $DIR/const-err-multi.rs:1:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-err-multi.rs:12:24 + | +LL | pub const D: i8 = 50 - A; + | -----------------------^- + | | + | referenced constant has errors + | +note: the lint level is defined here + --> $DIR/const-err-multi.rs:1:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-err.stderr b/src/test/ui/consts/const-err.stderr index 0c963874a8496..3b03e702dc4ae 100644 --- a/src/test/ui/consts/const-err.stderr +++ b/src/test/ui/consts/const-err.stderr @@ -29,3 +29,20 @@ LL | black_box((FOO, FOO)); error: aborting due to 2 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +warning: any use of this value will cause an error + --> $DIR/const-err.rs:11:17 + | +LL | const FOO: u8 = [5u8][1]; + | ----------------^^^^^^^^- + | | + | index out of bounds: the length is 1 but the index is 1 + | +note: the lint level is defined here + --> $DIR/const-err.rs:5:9 + | +LL | #![warn(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-eval/conditional_array_execution.stderr b/src/test/ui/consts/const-eval/conditional_array_execution.stderr index 9dc40030a6ff8..f88bf4454260b 100644 --- a/src/test/ui/consts/const-eval/conditional_array_execution.stderr +++ b/src/test/ui/consts/const-eval/conditional_array_execution.stderr @@ -33,3 +33,36 @@ LL | println!("{}", FOO); error: aborting due to previous error; 2 warnings emitted For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +warning: any use of this value will cause an error + --> $DIR/conditional_array_execution.rs:7:19 + | +LL | const FOO: u32 = [X - Y, Y - X][(X < Y) as usize]; + | ------------------^^^^^--------------------------- + | | + | attempt to compute `5_u32 - 6_u32`, which would overflow + | +note: the lint level is defined here + --> $DIR/conditional_array_execution.rs:3:9 + | +LL | #![warn(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +warning: erroneous constant used + --> $DIR/conditional_array_execution.rs:12:20 + | +LL | println!("{}", FOO); + | ^^^ referenced constant has errors + | +note: the lint level is defined here + --> $DIR/conditional_array_execution.rs:3:9 + | +LL | #![warn(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + = note: this warning 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/consts/const-eval/const-eval-overflow-2.stderr b/src/test/ui/consts/const-eval/const-eval-overflow-2.stderr index 26728cf541582..1c74b978827c6 100644 --- a/src/test/ui/consts/const-eval/const-eval-overflow-2.stderr +++ b/src/test/ui/consts/const-eval/const-eval-overflow-2.stderr @@ -12,3 +12,20 @@ LL | NEG_NEG_128 => println!("A"), error: aborting due to 2 previous errors +Future incompatibility report: Future breakage diagnostic: +warning: any use of this value will cause an error + --> $DIR/const-eval-overflow-2.rs:11:25 + | +LL | const NEG_NEG_128: i8 = -NEG_128; + | ------------------------^^^^^^^^- + | | + | attempt to negate `i8::MIN`, which would overflow + | +note: the lint level is defined here + --> $DIR/const-eval-overflow-2.rs:4:36 + | +LL | #![allow(unused_imports, warnings, const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-eval/const-eval-overflow2.stderr b/src/test/ui/consts/const-eval/const-eval-overflow2.stderr index 66e86c352d154..948ead521ea34 100644 --- a/src/test/ui/consts/const-eval/const-eval-overflow2.stderr +++ b/src/test/ui/consts/const-eval/const-eval-overflow2.stderr @@ -107,3 +107,153 @@ LL | | ); error: aborting due to 8 previous errors +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-eval-overflow2.rs:14:6 + | +LL | / const VALS_I8: (i8,) = +LL | | ( +LL | | i8::MIN - 1, + | | ^^^^^^^^^^^ attempt to compute `i8::MIN - 1_i8`, which would overflow +LL | | ); + | |_______- + | +note: the lint level is defined here + --> $DIR/const-eval-overflow2.rs:8:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-eval-overflow2.rs:21:6 + | +LL | / const VALS_I16: (i16,) = +LL | | ( +LL | | i16::MIN - 1, + | | ^^^^^^^^^^^^ attempt to compute `i16::MIN - 1_i16`, which would overflow +LL | | ); + | |_______- + | +note: the lint level is defined here + --> $DIR/const-eval-overflow2.rs:8:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-eval-overflow2.rs:28:6 + | +LL | / const VALS_I32: (i32,) = +LL | | ( +LL | | i32::MIN - 1, + | | ^^^^^^^^^^^^ attempt to compute `i32::MIN - 1_i32`, which would overflow +LL | | ); + | |_______- + | +note: the lint level is defined here + --> $DIR/const-eval-overflow2.rs:8:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-eval-overflow2.rs:35:6 + | +LL | / const VALS_I64: (i64,) = +LL | | ( +LL | | i64::MIN - 1, + | | ^^^^^^^^^^^^ attempt to compute `i64::MIN - 1_i64`, which would overflow +LL | | ); + | |_______- + | +note: the lint level is defined here + --> $DIR/const-eval-overflow2.rs:8:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-eval-overflow2.rs:42:6 + | +LL | / const VALS_U8: (u8,) = +LL | | ( +LL | | u8::MIN - 1, + | | ^^^^^^^^^^^ attempt to compute `0_u8 - 1_u8`, which would overflow +LL | | ); + | |_______- + | +note: the lint level is defined here + --> $DIR/const-eval-overflow2.rs:8:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-eval-overflow2.rs:48:6 + | +LL | / const VALS_U16: (u16,) = ( +LL | | u16::MIN - 1, + | | ^^^^^^^^^^^^ attempt to compute `0_u16 - 1_u16`, which would overflow +LL | | ); + | |_______- + | +note: the lint level is defined here + --> $DIR/const-eval-overflow2.rs:8:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-eval-overflow2.rs:54:6 + | +LL | / const VALS_U32: (u32,) = ( +LL | | u32::MIN - 1, + | | ^^^^^^^^^^^^ attempt to compute `0_u32 - 1_u32`, which would overflow +LL | | ); + | |_______- + | +note: the lint level is defined here + --> $DIR/const-eval-overflow2.rs:8:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-eval-overflow2.rs:61:6 + | +LL | / const VALS_U64: (u64,) = +LL | | ( +LL | | u64::MIN - 1, + | | ^^^^^^^^^^^^ attempt to compute `0_u64 - 1_u64`, which would overflow +LL | | ); + | |_______- + | +note: the lint level is defined here + --> $DIR/const-eval-overflow2.rs:8:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-eval/const-eval-overflow2b.stderr b/src/test/ui/consts/const-eval/const-eval-overflow2b.stderr index 3401ba4776500..5db6a49a98b0c 100644 --- a/src/test/ui/consts/const-eval/const-eval-overflow2b.stderr +++ b/src/test/ui/consts/const-eval/const-eval-overflow2b.stderr @@ -107,3 +107,153 @@ LL | | ); error: aborting due to 8 previous errors +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-eval-overflow2b.rs:14:6 + | +LL | / const VALS_I8: (i8,) = +LL | | ( +LL | | i8::MAX + 1, + | | ^^^^^^^^^^^ attempt to compute `i8::MAX + 1_i8`, which would overflow +LL | | ); + | |_______- + | +note: the lint level is defined here + --> $DIR/const-eval-overflow2b.rs:8:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-eval-overflow2b.rs:21:6 + | +LL | / const VALS_I16: (i16,) = +LL | | ( +LL | | i16::MAX + 1, + | | ^^^^^^^^^^^^ attempt to compute `i16::MAX + 1_i16`, which would overflow +LL | | ); + | |_______- + | +note: the lint level is defined here + --> $DIR/const-eval-overflow2b.rs:8:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-eval-overflow2b.rs:28:6 + | +LL | / const VALS_I32: (i32,) = +LL | | ( +LL | | i32::MAX + 1, + | | ^^^^^^^^^^^^ attempt to compute `i32::MAX + 1_i32`, which would overflow +LL | | ); + | |_______- + | +note: the lint level is defined here + --> $DIR/const-eval-overflow2b.rs:8:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-eval-overflow2b.rs:35:6 + | +LL | / const VALS_I64: (i64,) = +LL | | ( +LL | | i64::MAX + 1, + | | ^^^^^^^^^^^^ attempt to compute `i64::MAX + 1_i64`, which would overflow +LL | | ); + | |_______- + | +note: the lint level is defined here + --> $DIR/const-eval-overflow2b.rs:8:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-eval-overflow2b.rs:42:6 + | +LL | / const VALS_U8: (u8,) = +LL | | ( +LL | | u8::MAX + 1, + | | ^^^^^^^^^^^ attempt to compute `u8::MAX + 1_u8`, which would overflow +LL | | ); + | |_______- + | +note: the lint level is defined here + --> $DIR/const-eval-overflow2b.rs:8:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-eval-overflow2b.rs:48:6 + | +LL | / const VALS_U16: (u16,) = ( +LL | | u16::MAX + 1, + | | ^^^^^^^^^^^^ attempt to compute `u16::MAX + 1_u16`, which would overflow +LL | | ); + | |_______- + | +note: the lint level is defined here + --> $DIR/const-eval-overflow2b.rs:8:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-eval-overflow2b.rs:54:6 + | +LL | / const VALS_U32: (u32,) = ( +LL | | u32::MAX + 1, + | | ^^^^^^^^^^^^ attempt to compute `u32::MAX + 1_u32`, which would overflow +LL | | ); + | |_______- + | +note: the lint level is defined here + --> $DIR/const-eval-overflow2b.rs:8:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-eval-overflow2b.rs:61:6 + | +LL | / const VALS_U64: (u64,) = +LL | | ( +LL | | u64::MAX + 1, + | | ^^^^^^^^^^^^ attempt to compute `u64::MAX + 1_u64`, which would overflow +LL | | ); + | |_______- + | +note: the lint level is defined here + --> $DIR/const-eval-overflow2b.rs:8:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-eval/const-eval-overflow2c.stderr b/src/test/ui/consts/const-eval/const-eval-overflow2c.stderr index 93c64090f0eeb..ec3f3c110596b 100644 --- a/src/test/ui/consts/const-eval/const-eval-overflow2c.stderr +++ b/src/test/ui/consts/const-eval/const-eval-overflow2c.stderr @@ -107,3 +107,153 @@ LL | | ); error: aborting due to 8 previous errors +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-eval-overflow2c.rs:14:6 + | +LL | / const VALS_I8: (i8,) = +LL | | ( +LL | | i8::MIN * 2, + | | ^^^^^^^^^^^ attempt to compute `i8::MIN * 2_i8`, which would overflow +LL | | ); + | |_______- + | +note: the lint level is defined here + --> $DIR/const-eval-overflow2c.rs:8:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-eval-overflow2c.rs:21:6 + | +LL | / const VALS_I16: (i16,) = +LL | | ( +LL | | i16::MIN * 2, + | | ^^^^^^^^^^^^ attempt to compute `i16::MIN * 2_i16`, which would overflow +LL | | ); + | |_______- + | +note: the lint level is defined here + --> $DIR/const-eval-overflow2c.rs:8:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-eval-overflow2c.rs:28:6 + | +LL | / const VALS_I32: (i32,) = +LL | | ( +LL | | i32::MIN * 2, + | | ^^^^^^^^^^^^ attempt to compute `i32::MIN * 2_i32`, which would overflow +LL | | ); + | |_______- + | +note: the lint level is defined here + --> $DIR/const-eval-overflow2c.rs:8:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-eval-overflow2c.rs:35:6 + | +LL | / const VALS_I64: (i64,) = +LL | | ( +LL | | i64::MIN * 2, + | | ^^^^^^^^^^^^ attempt to compute `i64::MIN * 2_i64`, which would overflow +LL | | ); + | |_______- + | +note: the lint level is defined here + --> $DIR/const-eval-overflow2c.rs:8:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-eval-overflow2c.rs:42:6 + | +LL | / const VALS_U8: (u8,) = +LL | | ( +LL | | u8::MAX * 2, + | | ^^^^^^^^^^^ attempt to compute `u8::MAX * 2_u8`, which would overflow +LL | | ); + | |_______- + | +note: the lint level is defined here + --> $DIR/const-eval-overflow2c.rs:8:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-eval-overflow2c.rs:48:6 + | +LL | / const VALS_U16: (u16,) = ( +LL | | u16::MAX * 2, + | | ^^^^^^^^^^^^ attempt to compute `u16::MAX * 2_u16`, which would overflow +LL | | ); + | |_______- + | +note: the lint level is defined here + --> $DIR/const-eval-overflow2c.rs:8:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-eval-overflow2c.rs:54:6 + | +LL | / const VALS_U32: (u32,) = ( +LL | | u32::MAX * 2, + | | ^^^^^^^^^^^^ attempt to compute `u32::MAX * 2_u32`, which would overflow +LL | | ); + | |_______- + | +note: the lint level is defined here + --> $DIR/const-eval-overflow2c.rs:8:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-eval-overflow2c.rs:61:6 + | +LL | / const VALS_U64: (u64,) = +LL | | ( +LL | | u64::MAX * 2, + | | ^^^^^^^^^^^^ attempt to compute `u64::MAX * 2_u64`, which would overflow +LL | | ); + | |_______- + | +note: the lint level is defined here + --> $DIR/const-eval-overflow2c.rs:8:9 + | +LL | #![deny(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-eval/const-eval-query-stack.stderr b/src/test/ui/consts/const-eval/const-eval-query-stack.stderr index b74d5a2722bd8..fb4c92861cb74 100644 --- a/src/test/ui/consts/const-eval/const-eval-query-stack.stderr +++ b/src/test/ui/consts/const-eval/const-eval-query-stack.stderr @@ -35,3 +35,20 @@ query stack during panic: #1 [optimized_mir] optimizing MIR for `main` #2 [collect_and_partition_mono_items] collect_and_partition_mono_items end of query stack +Future incompatibility report: Future breakage diagnostic: +warning: any use of this value will cause an error + --> $DIR/const-eval-query-stack.rs:20:16 + | +LL | const X: i32 = 1 / 0; + | ---------------^^^^^- + | | + | attempt to divide `1_i32` by zero + | +note: the lint level is defined here + --> $DIR/const-eval-query-stack.rs:19:8 + | +LL | #[warn(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr index c19f6342b5ba6..9fcb27f04ab99 100644 --- a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr +++ b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr @@ -321,3 +321,263 @@ LL | const STR_CHAR_UNION: char = unsafe { Nonsense { stringy: "3" }.charact error: aborting due to 29 previous errors For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:29:43 + | +LL | const I32_REF_U8_UNION: u8 = unsafe { Nonsense { int_32_ref: &3 }.uint_8 }; + | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:33:45 + | +LL | const I32_REF_U16_UNION: u16 = unsafe { Nonsense { int_32_ref: &3 }.uint_16 }; + | ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:37:45 + | +LL | const I32_REF_U32_UNION: u32 = unsafe { Nonsense { int_32_ref: &3 }.uint_32 }; + | ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:47:43 + | +LL | const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8 }; + | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:51:45 + | +LL | const I32_REF_I16_UNION: i16 = unsafe { Nonsense { int_32_ref: &3 }.int_16 }; + | ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:55:45 + | +LL | const I32_REF_I32_UNION: i32 = unsafe { Nonsense { int_32_ref: &3 }.int_32 }; + | ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:65:45 + | +LL | const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.float_32 }; + | ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:72:47 + | +LL | const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.truthy_falsey }; + | ------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:76:47 + | +LL | const I32_REF_CHAR_UNION: char = unsafe { Nonsense { int_32_ref: &3 }.character }; + | ------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:80:39 + | +LL | const STR_U8_UNION: u8 = unsafe { Nonsense { stringy: "3" }.uint_8 }; + | ----------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:84:41 + | +LL | const STR_U16_UNION: u16 = unsafe { Nonsense { stringy: "3" }.uint_16 }; + | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:88:41 + | +LL | const STR_U32_UNION: u32 = unsafe { Nonsense { stringy: "3" }.uint_32 }; + | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:95:43 + | +LL | const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_128 }; + | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:99:39 + | +LL | const STR_I8_UNION: i8 = unsafe { Nonsense { stringy: "3" }.int_8 }; + | ----------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:103:41 + | +LL | const STR_I16_UNION: i16 = unsafe { Nonsense { stringy: "3" }.int_16 }; + | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:107:41 + | +LL | const STR_I32_UNION: i32 = unsafe { Nonsense { stringy: "3" }.int_32 }; + | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:114:43 + | +LL | const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128 }; + | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:118:41 + | +LL | const STR_F32_UNION: f32 = unsafe { Nonsense { stringy: "3" }.float_32 }; + | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:125:43 + | +LL | const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_falsey }; + | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:129:43 + | +LL | const STR_CHAR_UNION: char = unsafe { Nonsense { stringy: "3" }.character }; + | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr index c17166263ba09..daf3d8927c19a 100644 --- a/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr +++ b/src/test/ui/consts/const-eval/const_fn_ptr_fail2.stderr @@ -21,3 +21,79 @@ LL | x(y) error: aborting due to 2 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +warning: any use of this value will cause an error + --> $DIR/const_fn_ptr_fail2.rs:12:5 + | +LL | x(y) + | ^^^^ + | | + | calling non-const function `double` + | inside `bar` at $DIR/const_fn_ptr_fail2.rs:12:5 + | inside `Y` at $DIR/const_fn_ptr_fail2.rs:15:18 +... +LL | const Y: usize = bar(X, 2); // FIXME: should fail to typeck someday + | --------------------------- + | +note: the lint level is defined here + --> $DIR/const_fn_ptr_fail2.rs:4:10 + | +LL | #![allow(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +warning: any use of this value will cause an error + --> $DIR/const_fn_ptr_fail2.rs:12:5 + | +LL | x(y) + | ^^^^ + | | + | calling non-const function `double` + | inside `bar` at $DIR/const_fn_ptr_fail2.rs:12:5 + | inside `Z` at $DIR/const_fn_ptr_fail2.rs:16:18 +... +LL | const Z: usize = bar(double, 2); // FIXME: should fail to typeck someday + | -------------------------------- + | +note: the lint level is defined here + --> $DIR/const_fn_ptr_fail2.rs:4:10 + | +LL | #![allow(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +warning: erroneous constant used + --> $DIR/const_fn_ptr_fail2.rs:19:5 + | +LL | assert_eq!(Y, 4); + | ^^^^^^^^^^^^^^^^ referenced constant has errors + | +note: the lint level is defined here + --> $DIR/const_fn_ptr_fail2.rs:4:10 + | +LL | #![allow(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + = note: this warning originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) + +Future breakage diagnostic: +warning: erroneous constant used + --> $DIR/const_fn_ptr_fail2.rs:21:5 + | +LL | assert_eq!(Z, 4); + | ^^^^^^^^^^^^^^^^ referenced constant has errors + | +note: the lint level is defined here + --> $DIR/const_fn_ptr_fail2.rs:4:10 + | +LL | #![allow(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + = note: this warning originates in the macro `assert_eq` (in Nightly builds, run with -Z macro-backtrace for more info) + diff --git a/src/test/ui/consts/const-eval/erroneous-const.stderr b/src/test/ui/consts/const-eval/erroneous-const.stderr index 7e2a60929c73d..9057b58ded9da 100644 --- a/src/test/ui/consts/const-eval/erroneous-const.stderr +++ b/src/test/ui/consts/const-eval/erroneous-const.stderr @@ -41,3 +41,20 @@ LL | pub static FOO: () = no_codegen::(); error: aborting due to previous error; 2 warnings emitted For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +warning: any use of this value will cause an error + --> $DIR/erroneous-const.rs:6:22 + | +LL | const VOID: () = [()][2]; + | -----------------^^^^^^^- + | | + | index out of bounds: the length is 1 but the index is 2 + | +note: the lint level is defined here + --> $DIR/erroneous-const.rs:2:9 + | +LL | #![warn(const_err, unconditional_panic)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-eval/erroneous-const2.stderr b/src/test/ui/consts/const-eval/erroneous-const2.stderr index 813d3ee249fb2..bf6cc8410a7ee 100644 --- a/src/test/ui/consts/const-eval/erroneous-const2.stderr +++ b/src/test/ui/consts/const-eval/erroneous-const2.stderr @@ -35,3 +35,20 @@ LL | let _ = PrintName::::VOID; error: aborting due to previous error; 2 warnings emitted For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +warning: any use of this value will cause an error + --> $DIR/erroneous-const2.rs:6:22 + | +LL | const VOID: () = [()][2]; + | -----------------^^^^^^^- + | | + | index out of bounds: the length is 1 but the index is 2 + | +note: the lint level is defined here + --> $DIR/erroneous-const2.rs:2:9 + | +LL | #![warn(const_err, unconditional_panic)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.stderr b/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.stderr index 73664fa49d189..7b3e46fccca7b 100644 --- a/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.stderr +++ b/src/test/ui/consts/const-eval/index-out-of-bounds-never-type.stderr @@ -22,3 +22,20 @@ LL | let _ = PrintName::::VOID; error: aborting due to previous error; 1 warning emitted +Future incompatibility report: Future breakage diagnostic: +warning: any use of this value will cause an error + --> $DIR/index-out-of-bounds-never-type.rs:10:61 + | +LL | const VOID: ! = { let x = 0 * std::mem::size_of::(); [][x] }; + | --------------------------------------------------------^^^^^--- + | | + | index out of bounds: the length is 0 but the index is 0 + | +note: the lint level is defined here + --> $DIR/index-out-of-bounds-never-type.rs:4:9 + | +LL | #![warn(const_err, unconditional_panic)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-eval/issue-43197.stderr b/src/test/ui/consts/const-eval/issue-43197.stderr index 32ab7c74b891f..53ed32638ced2 100644 --- a/src/test/ui/consts/const-eval/issue-43197.stderr +++ b/src/test/ui/consts/const-eval/issue-43197.stderr @@ -60,3 +60,69 @@ LL | println!("{} {}", X, Y); error: aborting due to 2 previous errors; 4 warnings emitted For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +warning: any use of this value will cause an error + --> $DIR/issue-43197.rs:10:20 + | +LL | const X: u32 = 0 - 1; + | ---------------^^^^^- + | | + | attempt to compute `0_u32 - 1_u32`, which would overflow + | +note: the lint level is defined here + --> $DIR/issue-43197.rs:3:9 + | +LL | #![warn(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +warning: any use of this value will cause an error + --> $DIR/issue-43197.rs:13:24 + | +LL | const Y: u32 = foo(0 - 1); + | -------------------^^^^^-- + | | + | attempt to compute `0_u32 - 1_u32`, which would overflow + | +note: the lint level is defined here + --> $DIR/issue-43197.rs:3:9 + | +LL | #![warn(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +warning: erroneous constant used + --> $DIR/issue-43197.rs:16:23 + | +LL | println!("{} {}", X, Y); + | ^ referenced constant has errors + | +note: the lint level is defined here + --> $DIR/issue-43197.rs:3:9 + | +LL | #![warn(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + = note: this warning originates in the macro `$crate::format_args_nl` (in Nightly builds, run with -Z macro-backtrace for more info) + +Future breakage diagnostic: +warning: erroneous constant used + --> $DIR/issue-43197.rs:16:26 + | +LL | println!("{} {}", X, Y); + | ^ referenced constant has errors + | +note: the lint level is defined here + --> $DIR/issue-43197.rs:3:9 + | +LL | #![warn(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + = note: this warning 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/consts/const-eval/issue-44578.stderr b/src/test/ui/consts/const-eval/issue-44578.stderr index bff9f40f82b35..5ecdb7ef5568b 100644 --- a/src/test/ui/consts/const-eval/issue-44578.stderr +++ b/src/test/ui/consts/const-eval/issue-44578.stderr @@ -7,3 +7,36 @@ LL | println!("{}", as Foo>::AMT); error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +warning: any use of this value will cause an error + --> $DIR/issue-44578.rs:15:24 + | +LL | const AMT: usize = [A::AMT][(A::AMT > B::AMT) as usize]; + | -------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- + | | + | index out of bounds: the length is 1 but the index is 1 + | +note: the lint level is defined here + --> $DIR/issue-44578.rs:3:10 + | +LL | #![allow(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +warning: erroneous constant used + --> $DIR/issue-44578.rs:27:20 + | +LL | println!("{}", as Foo>::AMT); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors + | +note: the lint level is defined here + --> $DIR/issue-44578.rs:3:10 + | +LL | #![allow(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + = note: this warning 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/consts/const-eval/issue-50814-2.stderr b/src/test/ui/consts/const-eval/issue-50814-2.stderr index 298f0a4a446dd..67af3b2b1d3ae 100644 --- a/src/test/ui/consts/const-eval/issue-50814-2.stderr +++ b/src/test/ui/consts/const-eval/issue-50814-2.stderr @@ -25,3 +25,16 @@ LL | println!("{:x}", foo::<()>() as *const usize as usize); error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/issue-50814-2.rs:14:24 + | +LL | const BAR: usize = [5, 6, 7][T::BOO]; + | -------------------^^^^^^^^^^^^^^^^^- + | | + | index out of bounds: the length is 3 but the index is 42 + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-eval/issue-50814.stderr b/src/test/ui/consts/const-eval/issue-50814.stderr index 87bea28e76325..b82bc9ca2f81a 100644 --- a/src/test/ui/consts/const-eval/issue-50814.stderr +++ b/src/test/ui/consts/const-eval/issue-50814.stderr @@ -25,3 +25,16 @@ LL | foo(0); error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/issue-50814.rs:15:21 + | +LL | const MAX: u8 = A::MAX + B::MAX; + | ----------------^^^^^^^^^^^^^^^- + | | + | attempt to compute `u8::MAX + u8::MAX`, which would overflow + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-eval/partial_ptr_overwrite.stderr b/src/test/ui/consts/const-eval/partial_ptr_overwrite.stderr index a18c7e78d95af..1a7d386142097 100644 --- a/src/test/ui/consts/const-eval/partial_ptr_overwrite.stderr +++ b/src/test/ui/consts/const-eval/partial_ptr_overwrite.stderr @@ -18,3 +18,22 @@ LL | | }; error: aborting due to previous error +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/partial_ptr_overwrite.rs:8:9 + | +LL | / const PARTIAL_OVERWRITE: () = { +LL | | let mut p = &42; +LL | | unsafe { +LL | | let ptr: *mut _ = &mut p; +LL | | *(ptr as *mut u8) = 123; + | | ^^^^^^^^^^^^^^^^^^^^^^^ unable to overwrite parts of a pointer in memory at alloc4 +... | +LL | | let x = *p; +LL | | }; + | |__- + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-eval/promoted_errors.noopt.stderr b/src/test/ui/consts/const-eval/promoted_errors.noopt.stderr index 5bfd4ef92a975..be845339dfe67 100644 --- a/src/test/ui/consts/const-eval/promoted_errors.noopt.stderr +++ b/src/test/ui/consts/const-eval/promoted_errors.noopt.stderr @@ -85,3 +85,53 @@ LL | | }; warning: 7 warnings emitted +Future incompatibility report: Future breakage diagnostic: +warning: any use of this value will cause an error + --> $DIR/promoted_errors.rs:15:5 + | +LL | 0 - 1 + | ^^^^^ + | | + | attempt to compute `0_u32 - 1_u32`, which would overflow + | inside `overflow` at $DIR/promoted_errors.rs:15:5 + | inside `X` at $DIR/promoted_errors.rs:43:29 +... +LL | / const X: () = { +LL | | let _x: &'static u32 = &overflow(); +LL | | +LL | | +... | +LL | | let _x: &'static i32 = &oob(); +LL | | }; + | |__- + | +note: the lint level is defined here + --> $DIR/promoted_errors.rs:11:9 + | +LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +warning: any use of this value will cause an error + --> $DIR/promoted_errors.rs:43:28 + | +LL | / const X: () = { +LL | | let _x: &'static u32 = &overflow(); + | | ^^^^^^^^^^^ referenced constant has errors +LL | | +LL | | +... | +LL | | let _x: &'static i32 = &oob(); +LL | | }; + | |__- + | +note: the lint level is defined here + --> $DIR/promoted_errors.rs:11:9 + | +LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-eval/promoted_errors.opt.stderr b/src/test/ui/consts/const-eval/promoted_errors.opt.stderr index 0a8a8aef3cf8f..c91d52336c36d 100644 --- a/src/test/ui/consts/const-eval/promoted_errors.opt.stderr +++ b/src/test/ui/consts/const-eval/promoted_errors.opt.stderr @@ -86,3 +86,54 @@ LL | | }; warning: 7 warnings emitted +Future incompatibility report: Future breakage diagnostic: +warning: any use of this value will cause an error + --> $DIR/promoted_errors.rs:21:5 + | +LL | 1 / 0 + | ^^^^^ + | | + | attempt to divide `1_i32` by zero + | inside `div_by_zero1` at $DIR/promoted_errors.rs:21:5 + | inside `X` at $DIR/promoted_errors.rs:46:29 +... +LL | / const X: () = { +LL | | let _x: &'static u32 = &overflow(); +LL | | +LL | | +... | +LL | | let _x: &'static i32 = &oob(); +LL | | }; + | |__- + | +note: the lint level is defined here + --> $DIR/promoted_errors.rs:11:9 + | +LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +warning: any use of this value will cause an error + --> $DIR/promoted_errors.rs:46:28 + | +LL | / const X: () = { +LL | | let _x: &'static u32 = &overflow(); +LL | | +LL | | +LL | | let _x: &'static i32 = &div_by_zero1(); + | | ^^^^^^^^^^^^^^^ referenced constant has errors +... | +LL | | let _x: &'static i32 = &oob(); +LL | | }; + | |__- + | +note: the lint level is defined here + --> $DIR/promoted_errors.rs:11:9 + | +LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-eval/promoted_errors.opt_with_overflow_checks.stderr b/src/test/ui/consts/const-eval/promoted_errors.opt_with_overflow_checks.stderr index 5bfd4ef92a975..be845339dfe67 100644 --- a/src/test/ui/consts/const-eval/promoted_errors.opt_with_overflow_checks.stderr +++ b/src/test/ui/consts/const-eval/promoted_errors.opt_with_overflow_checks.stderr @@ -85,3 +85,53 @@ LL | | }; warning: 7 warnings emitted +Future incompatibility report: Future breakage diagnostic: +warning: any use of this value will cause an error + --> $DIR/promoted_errors.rs:15:5 + | +LL | 0 - 1 + | ^^^^^ + | | + | attempt to compute `0_u32 - 1_u32`, which would overflow + | inside `overflow` at $DIR/promoted_errors.rs:15:5 + | inside `X` at $DIR/promoted_errors.rs:43:29 +... +LL | / const X: () = { +LL | | let _x: &'static u32 = &overflow(); +LL | | +LL | | +... | +LL | | let _x: &'static i32 = &oob(); +LL | | }; + | |__- + | +note: the lint level is defined here + --> $DIR/promoted_errors.rs:11:9 + | +LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +warning: any use of this value will cause an error + --> $DIR/promoted_errors.rs:43:28 + | +LL | / const X: () = { +LL | | let _x: &'static u32 = &overflow(); + | | ^^^^^^^^^^^ referenced constant has errors +LL | | +LL | | +... | +LL | | let _x: &'static i32 = &oob(); +LL | | }; + | |__- + | +note: the lint level is defined here + --> $DIR/promoted_errors.rs:11:9 + | +LL | #![warn(const_err, arithmetic_overflow, unconditional_panic)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-eval/pub_const_err.stderr b/src/test/ui/consts/const-eval/pub_const_err.stderr index dd47dca2b2e40..56d66827626b9 100644 --- a/src/test/ui/consts/const-eval/pub_const_err.stderr +++ b/src/test/ui/consts/const-eval/pub_const_err.stderr @@ -16,3 +16,20 @@ LL | #![warn(const_err)] warning: 1 warning emitted +Future incompatibility report: Future breakage diagnostic: +warning: any use of this value will cause an error + --> $DIR/pub_const_err.rs:6:20 + | +LL | pub const Z: u32 = 0 - 1; + | -------------------^^^^^- + | | + | attempt to compute `0_u32 - 1_u32`, which would overflow + | +note: the lint level is defined here + --> $DIR/pub_const_err.rs:2:9 + | +LL | #![warn(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-eval/pub_const_err_bin.stderr b/src/test/ui/consts/const-eval/pub_const_err_bin.stderr index 9f413fb8fd770..202ea781e975d 100644 --- a/src/test/ui/consts/const-eval/pub_const_err_bin.stderr +++ b/src/test/ui/consts/const-eval/pub_const_err_bin.stderr @@ -16,3 +16,20 @@ LL | #![warn(const_err)] warning: 1 warning emitted +Future incompatibility report: Future breakage diagnostic: +warning: any use of this value will cause an error + --> $DIR/pub_const_err_bin.rs:4:20 + | +LL | pub const Z: u32 = 0 - 1; + | -------------------^^^^^- + | | + | attempt to compute `0_u32 - 1_u32`, which would overflow + | +note: the lint level is defined here + --> $DIR/pub_const_err_bin.rs:2:9 + | +LL | #![warn(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-eval/unused-broken-const.stderr b/src/test/ui/consts/const-eval/unused-broken-const.stderr index 2ce60ec16a33f..bfc076aa5e64f 100644 --- a/src/test/ui/consts/const-eval/unused-broken-const.stderr +++ b/src/test/ui/consts/const-eval/unused-broken-const.stderr @@ -12,3 +12,16 @@ LL | const FOO: i32 = [][0]; error: aborting due to previous error +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/unused-broken-const.rs:5:18 + | +LL | const FOO: i32 = [][0]; + | -----------------^^^^^- + | | + | index out of bounds: the length is 0 but the index is 0 + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-external-macro-const-err.stderr b/src/test/ui/consts/const-external-macro-const-err.stderr index a66d79a16160c..205ee92dfd7cf 100644 --- a/src/test/ui/consts/const-external-macro-const-err.stderr +++ b/src/test/ui/consts/const-external-macro-const-err.stderr @@ -11,3 +11,15 @@ LL | static_assert!(2 + 2 == 5); error: aborting due to previous error +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-external-macro-const-err.rs:12:5 + | +LL | static_assert!(2 + 2 == 5); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^ index out of bounds: the length is 1 but the index is 1 + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + = note: this error originates in the macro `static_assert` (in Nightly builds, run with -Z macro-backtrace for more info) + diff --git a/src/test/ui/consts/const-len-underflow-separate-spans.stderr b/src/test/ui/consts/const-len-underflow-separate-spans.stderr index 70f645a6c40e8..0c10783476abc 100644 --- a/src/test/ui/consts/const-len-underflow-separate-spans.stderr +++ b/src/test/ui/consts/const-len-underflow-separate-spans.stderr @@ -19,3 +19,16 @@ LL | let a: [i8; LEN] = unimplemented!(); error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-len-underflow-separate-spans.rs:7:20 + | +LL | const LEN: usize = ONE - TWO; + | -------------------^^^^^^^^^- + | | + | attempt to compute `1_usize - 2_usize`, which would overflow + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-prop-read-static-in-const.stderr b/src/test/ui/consts/const-prop-read-static-in-const.stderr index 94d3f1c614544..a60cd16f05a18 100644 --- a/src/test/ui/consts/const-prop-read-static-in-const.stderr +++ b/src/test/ui/consts/const-prop-read-static-in-const.stderr @@ -20,3 +20,16 @@ LL | const TEST: u8 = MY_STATIC; error: aborting due to previous error; 1 warning emitted +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-prop-read-static-in-const.rs:5:18 + | +LL | const TEST: u8 = MY_STATIC; + | -----------------^^^^^^^^^- + | | + | constant accesses static + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-size_of_val-align_of_val-extern-type.stderr b/src/test/ui/consts/const-size_of_val-align_of_val-extern-type.stderr index a9211c17a6bc0..c6e0b321124b1 100644 --- a/src/test/ui/consts/const-size_of_val-align_of_val-extern-type.stderr +++ b/src/test/ui/consts/const-size_of_val-align_of_val-extern-type.stderr @@ -23,3 +23,29 @@ LL | const _ALIGN: usize = unsafe { min_align_of_val(&4 as *const i32 as *const error: aborting due to 2 previous errors +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-size_of_val-align_of_val-extern-type.rs:11:31 + | +LL | const _SIZE: usize = unsafe { size_of_val(&4 as *const i32 as *const Opaque) }; + | ------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | `extern type` does not have known layout + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-size_of_val-align_of_val-extern-type.rs:13:32 + | +LL | const _ALIGN: usize = unsafe { min_align_of_val(&4 as *const i32 as *const Opaque) }; + | -------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | `extern type` does not have known layout + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-slice-oob.stderr b/src/test/ui/consts/const-slice-oob.stderr index 6d2c79034d391..c9f949727bc63 100644 --- a/src/test/ui/consts/const-slice-oob.stderr +++ b/src/test/ui/consts/const-slice-oob.stderr @@ -12,3 +12,16 @@ LL | const BAR: u32 = FOO[5]; error: aborting due to previous error +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-slice-oob.rs:4:18 + | +LL | const BAR: u32 = FOO[5]; + | -----------------^^^^^^- + | | + | index out of bounds: the length is 3 but the index is 5 + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const_limit/const_eval_limit_reached.stderr b/src/test/ui/consts/const_limit/const_eval_limit_reached.stderr index 5e706a4466ea1..ee95b0d518050 100644 --- a/src/test/ui/consts/const_limit/const_eval_limit_reached.stderr +++ b/src/test/ui/consts/const_limit/const_eval_limit_reached.stderr @@ -17,3 +17,21 @@ LL | | }; error: aborting due to previous error +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const_eval_limit_reached.rs:6:11 + | +LL | / const X: usize = { +LL | | let mut x = 0; +LL | | while x != 1000 { + | | ^^^^^^^^^ exceeded interpreter step limit (see `#[const_eval_limit]`) +LL | | +... | +LL | | x +LL | | }; + | |__- + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/invalid-union.64bit.stderr b/src/test/ui/consts/invalid-union.64bit.stderr index 6bfa97a2fded7..0d8b8ffcc161b 100644 --- a/src/test/ui/consts/invalid-union.64bit.stderr +++ b/src/test/ui/consts/invalid-union.64bit.stderr @@ -22,3 +22,14 @@ LL | let _: &'static _ = &C; error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +error: erroneous constant used + --> $DIR/invalid-union.rs:41:25 + | +LL | let _: &'static _ = &C; + | ^^ referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/issue-56164.stderr b/src/test/ui/consts/issue-56164.stderr index 3b80b3486a822..73a0f8ec0d04f 100644 --- a/src/test/ui/consts/issue-56164.stderr +++ b/src/test/ui/consts/issue-56164.stderr @@ -26,3 +26,14 @@ LL | const fn foo() { (||{})() } error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0015`. +Future incompatibility report: Future breakage diagnostic: +error: erroneous constant used + --> $DIR/issue-56164.rs:1:18 + | +LL | const fn foo() { (||{})() } + | ^^^^^^ referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/issue-66693.stderr b/src/test/ui/consts/issue-66693.stderr index b825768498386..929f905ae918b 100644 --- a/src/test/ui/consts/issue-66693.stderr +++ b/src/test/ui/consts/issue-66693.stderr @@ -34,3 +34,14 @@ LL | panic!(&1); error: aborting due to 4 previous errors +Future incompatibility report: Future breakage diagnostic: +error: erroneous constant used + --> $DIR/issue-66693.rs:11:12 + | +LL | panic!(&1); + | ^^ referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/issue-miri-1910.stderr b/src/test/ui/consts/issue-miri-1910.stderr index 87882449c7342..e76a1f96b46a5 100644 --- a/src/test/ui/consts/issue-miri-1910.stderr +++ b/src/test/ui/consts/issue-miri-1910.stderr @@ -24,3 +24,28 @@ LL | | }; error: aborting due to previous error +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL + | +LL | copy_nonoverlapping(src, tmp.as_mut_ptr(), 1); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | unable to turn pointer into raw bytes + | inside `std::ptr::read::` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + | inside `ptr::const_ptr::::read` at $SRC_DIR/core/src/ptr/const_ptr.rs:LL:COL + | inside `C` at $DIR/issue-miri-1910.rs:7:5 + | + ::: $DIR/issue-miri-1910.rs:4:1 + | +LL | / const C: () = unsafe { +LL | | let foo = Some(&42 as *const i32); +LL | | let one_and_a_half_pointers = std::mem::size_of::<*const i32>()/2*3; +LL | | (&foo as *const _ as *const u8).add(one_and_a_half_pointers).read(); +LL | | }; + | |__- + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/miri_unleashed/assoc_const.stderr b/src/test/ui/consts/miri_unleashed/assoc_const.stderr index 193a49bb2666f..1765c9ed10a30 100644 --- a/src/test/ui/consts/miri_unleashed/assoc_const.stderr +++ b/src/test/ui/consts/miri_unleashed/assoc_const.stderr @@ -15,3 +15,28 @@ LL | const F: u32 = (U::X, 42).1; error: aborting due to previous error; 1 warning emitted For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +warning: any use of this value will cause an error + --> $SRC_DIR/core/src/ptr/mod.rs:LL:COL + | +LL | pub unsafe fn drop_in_place(to_drop: *mut T) { + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | | + | calling non-const function ` as Drop>::drop` + | inside `std::ptr::drop_in_place::> - shim(Some(Vec))` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + | inside `std::ptr::drop_in_place::<(Vec, u32)> - shim(Some((Vec, u32)))` at $SRC_DIR/core/src/ptr/mod.rs:LL:COL + | inside `, String>>::F` at $DIR/assoc_const.rs:14:31 + | + ::: $DIR/assoc_const.rs:14:5 + | +LL | const F: u32 = (U::X, 42).1; + | ---------------------------- + | +note: the lint level is defined here + --> $DIR/assoc_const.rs:4:10 + | +LL | #![allow(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/miri_unleashed/assoc_const_2.stderr b/src/test/ui/consts/miri_unleashed/assoc_const_2.stderr index e15717979c5cb..f7be42de03fd6 100644 --- a/src/test/ui/consts/miri_unleashed/assoc_const_2.stderr +++ b/src/test/ui/consts/miri_unleashed/assoc_const_2.stderr @@ -7,3 +7,20 @@ LL | let y = >::F; error: aborting due to previous error For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +warning: any use of this value will cause an error + --> $DIR/assoc_const_2.rs:12:20 + | +LL | const F: u32 = 100 / U::X; + | ---------------^^^^^^^^^^- + | | + | attempt to divide `100_u32` by zero + | +note: the lint level is defined here + --> $DIR/assoc_const_2.rs:3:10 + | +LL | #![allow(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr index c48f59fe84890..98d4dff648a5f 100644 --- a/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr +++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static.stderr @@ -47,3 +47,58 @@ LL | const READ_MUT: u32 = unsafe { MUTABLE }; error: aborting due to 3 previous errors; 1 warning emitted For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +warning: any use of this value will cause an error + --> $DIR/const_refers_to_static.rs:13:5 + | +LL | / const MUTATE_INTERIOR_MUT: usize = { +LL | | static FOO: AtomicUsize = AtomicUsize::new(0); +LL | | FOO.fetch_add(1, Ordering::Relaxed) + | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ calling non-const function `AtomicUsize::fetch_add` +LL | | }; + | |__- + | +note: the lint level is defined here + --> $DIR/const_refers_to_static.rs:3:10 + | +LL | #![allow(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +warning: any use of this value will cause an error + --> $DIR/const_refers_to_static.rs:18:14 + | +LL | / const READ_INTERIOR_MUT: usize = { +LL | | static FOO: AtomicUsize = AtomicUsize::new(0); +LL | | unsafe { *(&FOO as *const _ as *const usize) } + | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static +LL | | }; + | |__- + | +note: the lint level is defined here + --> $DIR/const_refers_to_static.rs:3:10 + | +LL | #![allow(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +warning: any use of this value will cause an error + --> $DIR/const_refers_to_static.rs:22:32 + | +LL | const READ_MUT: u32 = unsafe { MUTABLE }; + | -------------------------------^^^^^^^--- + | | + | constant accesses static + | +note: the lint level is defined here + --> $DIR/const_refers_to_static.rs:3:10 + | +LL | #![allow(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr index 7a64abd7b9cb8..2d4f038d91490 100644 --- a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr +++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr @@ -170,3 +170,45 @@ LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => error: aborting due to 10 previous errors; 3 warnings emitted For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +warning: any use of this value will cause an error + --> $DIR/const_refers_to_static_cross_crate.rs:25:15 + | +LL | / const U8_MUT2: &u8 = { +LL | | unsafe { &(*static_cross_crate::ZERO_REF)[0] } + | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static +LL | | +LL | | +LL | | +LL | | }; + | |__- + | +note: the lint level is defined here + --> $DIR/const_refers_to_static_cross_crate.rs:23:8 + | +LL | #[warn(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +warning: any use of this value will cause an error + --> $DIR/const_refers_to_static_cross_crate.rs:32:20 + | +LL | / const U8_MUT3: &u8 = { +LL | | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } } + | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static +LL | | +LL | | +LL | | +LL | | }; + | |__- + | +note: the lint level is defined here + --> $DIR/const_refers_to_static_cross_crate.rs:30:8 + | +LL | #[warn(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/ptr_comparisons.stderr b/src/test/ui/consts/ptr_comparisons.stderr index 12f6ca0b51a53..7ff3faead6aa3 100644 --- a/src/test/ui/consts/ptr_comparisons.stderr +++ b/src/test/ui/consts/ptr_comparisons.stderr @@ -44,3 +44,29 @@ LL | const _: usize = unsafe { *std::mem::transmute::<&&usize, &usize>(&FOO) + 4 error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ptr_comparisons.rs:65:27 + | +LL | const _: usize = unsafe { std::mem::transmute::<*const usize, usize>(FOO) + 4 }; + | --------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ptr_comparisons.rs:70:27 + | +LL | const _: usize = unsafe { *std::mem::transmute::<&&usize, &usize>(&FOO) + 4 }; + | --------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/recursive.stderr b/src/test/ui/consts/recursive.stderr index 31ac1fff4e84e..8d1e10d4176ff 100644 --- a/src/test/ui/consts/recursive.stderr +++ b/src/test/ui/consts/recursive.stderr @@ -29,3 +29,22 @@ LL | const X: () = f(1); error: aborting due to previous error; 1 warning emitted +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/recursive.rs:4:5 + | +LL | f(x); + | ^^^^ + | | + | reached the configured maximum number of stack frames + | inside `f::` at $DIR/recursive.rs:4:5 + | [... 126 additional calls inside `f::` at $DIR/recursive.rs:4:5 ...] + | inside `X` at $DIR/recursive.rs:9:15 +... +LL | const X: () = f(1); + | ------------------- + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/uninhabited-const-issue-61744.stderr b/src/test/ui/consts/uninhabited-const-issue-61744.stderr index e98eefc11c3c8..17dd6131436c3 100644 --- a/src/test/ui/consts/uninhabited-const-issue-61744.stderr +++ b/src/test/ui/consts/uninhabited-const-issue-61744.stderr @@ -150,3 +150,147 @@ LL | dbg!(i32::CONSTANT); error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/uninhabited-const-issue-61744.rs:4:5 + | +LL | hint_unreachable() + | ^^^^^^^^^^^^^^^^^^ + | | + | reached the configured maximum number of stack frames + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `hint_unreachable` at $DIR/uninhabited-const-issue-61744.rs:9:5 + | inside `fake_type::` at $DIR/uninhabited-const-issue-61744.rs:4:5 + | inside `::CONSTANT` at $DIR/uninhabited-const-issue-61744.rs:13:36 +... +LL | const CONSTANT: i32 = unsafe { fake_type() }; + | --------------------------------------------- + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + From af58692ad10d402612a80fec782cc8e5dce2a75a Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 4 Jun 2022 19:25:43 -0400 Subject: [PATCH 15/21] bless remaining tests --- src/test/ui/consts/invalid-union.32bit.stderr | 11 +++++ ..._refers_to_static_cross_crate.32bit.stderr | 42 +++++++++++++++++++ src/test/ui/limits/issue-55878.stderr | 12 ++++++ .../allowed-cli-deny-by-default-lint.stderr | 13 ++++++ .../allowed-deny-by-default-lint.stderr | 13 ++++++ .../force-warn/deny-by-default-lint.stderr | 13 ++++++ 6 files changed, 104 insertions(+) diff --git a/src/test/ui/consts/invalid-union.32bit.stderr b/src/test/ui/consts/invalid-union.32bit.stderr index 38c38d1ae6732..bd7c95342f7f9 100644 --- a/src/test/ui/consts/invalid-union.32bit.stderr +++ b/src/test/ui/consts/invalid-union.32bit.stderr @@ -22,3 +22,14 @@ LL | let _: &'static _ = &C; error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +error: erroneous constant used + --> $DIR/invalid-union.rs:41:25 + | +LL | let _: &'static _ = &C; + | ^^ referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr index 186c5b1856baa..2a0766294d3e0 100644 --- a/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr +++ b/src/test/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr @@ -170,3 +170,45 @@ LL | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => error: aborting due to 10 previous errors; 3 warnings emitted For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +warning: any use of this value will cause an error + --> $DIR/const_refers_to_static_cross_crate.rs:25:15 + | +LL | / const U8_MUT2: &u8 = { +LL | | unsafe { &(*static_cross_crate::ZERO_REF)[0] } + | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static +LL | | +LL | | +LL | | +LL | | }; + | |__- + | +note: the lint level is defined here + --> $DIR/const_refers_to_static_cross_crate.rs:23:8 + | +LL | #[warn(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +warning: any use of this value will cause an error + --> $DIR/const_refers_to_static_cross_crate.rs:32:20 + | +LL | / const U8_MUT3: &u8 = { +LL | | unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } } + | | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ constant accesses static +LL | | +LL | | +LL | | +LL | | }; + | |__- + | +note: the lint level is defined here + --> $DIR/const_refers_to_static_cross_crate.rs:30:8 + | +LL | #[warn(const_err)] + | ^^^^^^^^^ + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/limits/issue-55878.stderr b/src/test/ui/limits/issue-55878.stderr index 90411353f0825..1402d1387037e 100644 --- a/src/test/ui/limits/issue-55878.stderr +++ b/src/test/ui/limits/issue-55878.stderr @@ -23,3 +23,15 @@ LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>()); error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +error: erroneous constant used + --> $DIR/issue-55878.rs:7:26 + | +LL | println!("Size: {}", std::mem::size_of::<[u8; u64::MAX as usize]>()); + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + = 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/lint/force-warn/allowed-cli-deny-by-default-lint.stderr b/src/test/ui/lint/force-warn/allowed-cli-deny-by-default-lint.stderr index af6308f0d1b4f..c14529a7d090a 100644 --- a/src/test/ui/lint/force-warn/allowed-cli-deny-by-default-lint.stderr +++ b/src/test/ui/lint/force-warn/allowed-cli-deny-by-default-lint.stderr @@ -12,3 +12,16 @@ LL | const C: i32 = 1 / 0; warning: 1 warning emitted +Future incompatibility report: Future breakage diagnostic: +warning: any use of this value will cause an error + --> $DIR/allowed-cli-deny-by-default-lint.rs:6:16 + | +LL | const C: i32 = 1 / 0; + | ---------------^^^^^- + | | + | attempt to divide `1_i32` by zero + | + = note: requested on the command line with `--force-warn const-err` + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/lint/force-warn/allowed-deny-by-default-lint.stderr b/src/test/ui/lint/force-warn/allowed-deny-by-default-lint.stderr index 05656afd22d88..dd71a168960ab 100644 --- a/src/test/ui/lint/force-warn/allowed-deny-by-default-lint.stderr +++ b/src/test/ui/lint/force-warn/allowed-deny-by-default-lint.stderr @@ -12,3 +12,16 @@ LL | const C: i32 = 1 / 0; warning: 1 warning emitted +Future incompatibility report: Future breakage diagnostic: +warning: any use of this value will cause an error + --> $DIR/allowed-deny-by-default-lint.rs:7:16 + | +LL | const C: i32 = 1 / 0; + | ---------------^^^^^- + | | + | attempt to divide `1_i32` by zero + | + = note: requested on the command line with `--force-warn const-err` + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/lint/force-warn/deny-by-default-lint.stderr b/src/test/ui/lint/force-warn/deny-by-default-lint.stderr index ef295f99e649c..d4e80584669ae 100644 --- a/src/test/ui/lint/force-warn/deny-by-default-lint.stderr +++ b/src/test/ui/lint/force-warn/deny-by-default-lint.stderr @@ -12,3 +12,16 @@ LL | const C: i32 = 1 / 0; warning: 1 warning emitted +Future incompatibility report: Future breakage diagnostic: +warning: any use of this value will cause an error + --> $DIR/deny-by-default-lint.rs:5:16 + | +LL | const C: i32 = 1 / 0; + | ---------------^^^^^- + | | + | attempt to divide `1_i32` by zero + | + = note: requested on the command line with `--force-warn const-err` + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + From 24b66da8998eb657998ead4bda734079ceacef83 Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Sat, 18 Jun 2022 20:00:21 -0700 Subject: [PATCH 16/21] Support setting file accessed/modified timestamps Add `struct FileTimes` to contain the relevant file timestamps, since most platforms require setting all of them at once. (This also allows for future platform-specific extensions such as setting creation time.) Add `File::set_file_time` to set the timestamps for a `File`. Implement the `sys` backends for UNIX, macOS (which needs to fall back to `futimes` before macOS 10.13 because it lacks `futimens`), Windows, and WASI. --- library/std/src/fs.rs | 72 +++++++++++++++++++++++++++ library/std/src/sys/unix/fs.rs | 64 ++++++++++++++++++++++++ library/std/src/sys/unsupported/fs.rs | 12 +++++ library/std/src/sys/wasi/fs.rs | 25 ++++++++++ library/std/src/sys/wasi/time.rs | 4 ++ library/std/src/sys/windows/c.rs | 8 ++- library/std/src/sys/windows/fs.rs | 24 +++++++++ library/std/src/sys/windows/time.rs | 7 +++ library/std/src/time.rs | 8 ++- 9 files changed, 222 insertions(+), 2 deletions(-) diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 55bd2c59406df..0500e826768af 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -184,6 +184,11 @@ pub struct DirEntry(fs_imp::DirEntry); #[stable(feature = "rust1", since = "1.0.0")] pub struct OpenOptions(fs_imp::OpenOptions); +/// Representation of the various timestamps on a file. +#[derive(Copy, Clone, Debug, Default)] +#[unstable(feature = "file_set_times", issue = "98245")] +pub struct FileTimes(fs_imp::FileTimes); + /// Representation of the various permissions on a file. /// /// This module only currently provides one bit of information, @@ -590,6 +595,49 @@ impl File { pub fn set_permissions(&self, perm: Permissions) -> io::Result<()> { self.inner.set_permissions(perm.0) } + + /// Changes the timestamps of the underlying file. + /// + /// # Platform-specific behavior + /// + /// This function currently corresponds to the `futimens` function on Unix (falling back to + /// `futimes` on macOS before 10.13) and the `SetFileTime` function on Windows. Note that this + /// [may change in the future][changes]. + /// + /// [changes]: io#platform-specific-behavior + /// + /// # Errors + /// + /// This function will return an error if the user lacks permission to change timestamps on the + /// underlying file. It may also return an error in other os-specific unspecified cases. + /// + /// This function may return an error if the operating system lacks support to change one or + /// more of the timestamps set in the `FileTimes` structure. + /// + /// # Examples + /// + /// ```no_run + /// #![feature(file_set_times)] + /// + /// fn main() -> std::io::Result<()> { + /// use std::fs::{self, File, FileTimes}; + /// + /// let src = fs::metadata("src")?; + /// let dest = File::options().write(true).open("dest")?; + /// let times = FileTimes::new() + /// .set_accessed(src.accessed()?) + /// .set_modified(src.modified()?); + /// dest.set_times(times)?; + /// Ok(()) + /// } + /// ``` + #[unstable(feature = "file_set_times", issue = "98245")] + #[doc(alias = "futimens")] + #[doc(alias = "futimes")] + #[doc(alias = "SetFileTime")] + pub fn set_times(&self, times: FileTimes) -> io::Result<()> { + self.inner.set_times(times.0) + } } // In addition to the `impl`s here, `File` also has `impl`s for @@ -1246,6 +1294,30 @@ impl FromInner for Metadata { } } +impl FileTimes { + /// Create a new `FileTimes` with no times set. + /// + /// Using the resulting `FileTimes` in [`File::set_times`] will not modify any timestamps. + #[unstable(feature = "file_set_times", issue = "98245")] + pub fn new() -> Self { + Self::default() + } + + /// Set the last access time of a file. + #[unstable(feature = "file_set_times", issue = "98245")] + pub fn set_accessed(mut self, t: SystemTime) -> Self { + self.0.set_accessed(t.into_inner()); + self + } + + /// Set the last modified time of a file. + #[unstable(feature = "file_set_times", issue = "98245")] + pub fn set_modified(mut self, t: SystemTime) -> Self { + self.0.set_modified(t.into_inner()); + self + } +} + impl Permissions { /// Returns `true` if these permissions describe a readonly (unwritable) file. /// diff --git a/library/std/src/sys/unix/fs.rs b/library/std/src/sys/unix/fs.rs index 8b0bbd6a55c6b..f33ab3a3e14b2 100644 --- a/library/std/src/sys/unix/fs.rs +++ b/library/std/src/sys/unix/fs.rs @@ -311,6 +311,9 @@ pub struct FilePermissions { mode: mode_t, } +#[derive(Copy, Clone)] +pub struct FileTimes([libc::timespec; 2]); + #[derive(Copy, Clone, PartialEq, Eq, Hash, Debug)] pub struct FileType { mode: mode_t, @@ -503,6 +506,43 @@ impl FilePermissions { } } +impl FileTimes { + pub fn set_accessed(&mut self, t: SystemTime) { + self.0[0] = t.t.to_timespec().expect("Invalid system time"); + } + + pub fn set_modified(&mut self, t: SystemTime) { + self.0[1] = t.t.to_timespec().expect("Invalid system time"); + } +} + +struct TimespecDebugAdapter<'a>(&'a libc::timespec); + +impl fmt::Debug for TimespecDebugAdapter<'_> { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("timespec") + .field("tv_sec", &self.0.tv_sec) + .field("tv_nsec", &self.0.tv_nsec) + .finish() + } +} + +impl fmt::Debug for FileTimes { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_struct("FileTimes") + .field("accessed", &TimespecDebugAdapter(&self.0[0])) + .field("modified", &TimespecDebugAdapter(&self.0[1])) + .finish() + } +} + +impl Default for FileTimes { + fn default() -> Self { + let omit = libc::timespec { tv_sec: 0, tv_nsec: libc::UTIME_OMIT }; + Self([omit; 2]) + } +} + impl FileType { pub fn is_dir(&self) -> bool { self.is(libc::S_IFDIR) @@ -1021,6 +1061,30 @@ impl File { cvt_r(|| unsafe { libc::fchmod(self.as_raw_fd(), perm.mode) })?; Ok(()) } + + pub fn set_times(&self, times: FileTimes) -> io::Result<()> { + cfg_if::cfg_if! { + // futimens requires macOS 10.13 + if #[cfg(target_os = "macos")] { + fn ts_to_tv(ts: &libc::timespec) -> libc::timeval { + libc::timeval { tv_sec: ts.tv_sec, tv_usec: (ts.tv_nsec / 1000) as _ } + } + cvt(unsafe { + weak!(fn futimens(c_int, *const libc::timespec) -> c_int); + futimens.get() + .map(|futimens| futimens(self.as_raw_fd(), times.0.as_ptr())) + .unwrap_or_else(|| { + let timevals = [ts_to_tv(×.0[0]), ts_to_tv(×.0[1])]; + libc::futimes(self.as_raw_fd(), timevals.as_ptr()) + }) + })?; + } else { + cvt(unsafe { libc::futimens(self.as_raw_fd(), times.0.as_ptr()) })?; + } + } + + Ok(()) + } } impl DirBuilder { diff --git a/library/std/src/sys/unsupported/fs.rs b/library/std/src/sys/unsupported/fs.rs index d1d2847cd33be..0e1a6257ed763 100644 --- a/library/std/src/sys/unsupported/fs.rs +++ b/library/std/src/sys/unsupported/fs.rs @@ -17,6 +17,9 @@ pub struct DirEntry(!); #[derive(Clone, Debug)] pub struct OpenOptions {} +#[derive(Copy, Clone, Debug, Default)] +pub struct FileTimes {} + pub struct FilePermissions(!); pub struct FileType(!); @@ -86,6 +89,11 @@ impl fmt::Debug for FilePermissions { } } +impl FileTimes { + pub fn set_accessed(&mut self, _t: SystemTime) {} + pub fn set_modified(&mut self, _t: SystemTime) {} +} + impl FileType { pub fn is_dir(&self) -> bool { self.0 @@ -237,6 +245,10 @@ impl File { pub fn set_permissions(&self, _perm: FilePermissions) -> io::Result<()> { self.0 } + + pub fn set_times(&self, _times: FileTimes) -> io::Result<()> { + self.0 + } } impl DirBuilder { diff --git a/library/std/src/sys/wasi/fs.rs b/library/std/src/sys/wasi/fs.rs index cd6815bfc2136..6614ae397b57f 100644 --- a/library/std/src/sys/wasi/fs.rs +++ b/library/std/src/sys/wasi/fs.rs @@ -63,6 +63,12 @@ pub struct FilePermissions { readonly: bool, } +#[derive(Copy, Clone, Debug, Default)] +pub struct FileTimes { + accessed: Option, + modified: Option, +} + #[derive(PartialEq, Eq, Hash, Debug, Copy, Clone)] pub struct FileType { bits: wasi::Filetype, @@ -112,6 +118,16 @@ impl FilePermissions { } } +impl FileTimes { + pub fn set_accessed(&mut self, t: SystemTime) { + self.accessed = Some(t.to_wasi_timestamp_or_panic()); + } + + pub fn set_modified(&mut self, t: SystemTime) { + self.modified = Some(t.to_wasi_timestamp_or_panic()); + } +} + impl FileType { pub fn is_dir(&self) -> bool { self.bits == wasi::FILETYPE_DIRECTORY @@ -459,6 +475,15 @@ impl File { unsupported() } + pub fn set_times(&self, times: FileTimes) -> io::Result<()> { + self.fd.filestat_set_times( + times.accessed.unwrap_or(0), + times.modified.unwrap_or(0), + times.accessed.map_or(0, |_| wasi::FSTFLAGS_ATIM) + | times.modified.map_or(0, |_| wasi::FSTFLAGS_MTIM), + ) + } + pub fn read_link(&self, file: &Path) -> io::Result { read_link(&self.fd, file) } diff --git a/library/std/src/sys/wasi/time.rs b/library/std/src/sys/wasi/time.rs index 088585654b948..3d326e49106ca 100644 --- a/library/std/src/sys/wasi/time.rs +++ b/library/std/src/sys/wasi/time.rs @@ -47,6 +47,10 @@ impl SystemTime { SystemTime(Duration::from_nanos(ts)) } + pub fn to_wasi_timestamp_or_panic(&self) -> wasi::Timestamp { + self.0.as_nanos().try_into().expect("time does not fit in WASI timestamp") + } + pub fn sub_time(&self, other: &SystemTime) -> Result { self.0.checked_sub(other.0).ok_or_else(|| other.0 - self.0) } diff --git a/library/std/src/sys/windows/c.rs b/library/std/src/sys/windows/c.rs index 5469487df1eed..abb471213d251 100644 --- a/library/std/src/sys/windows/c.rs +++ b/library/std/src/sys/windows/c.rs @@ -607,7 +607,7 @@ pub struct SOCKADDR { } #[repr(C)] -#[derive(Copy, Clone)] +#[derive(Copy, Clone, Debug, Default)] pub struct FILETIME { pub dwLowDateTime: DWORD, pub dwHighDateTime: DWORD, @@ -875,6 +875,12 @@ extern "system" { pub fn GetSystemDirectoryW(lpBuffer: LPWSTR, uSize: UINT) -> UINT; pub fn RemoveDirectoryW(lpPathName: LPCWSTR) -> BOOL; pub fn SetFileAttributesW(lpFileName: LPCWSTR, dwFileAttributes: DWORD) -> BOOL; + pub fn SetFileTime( + hFile: BorrowedHandle<'_>, + lpCreationTime: Option<&FILETIME>, + lpLastAccessTime: Option<&FILETIME>, + lpLastWriteTime: Option<&FILETIME>, + ) -> BOOL; pub fn SetLastError(dwErrCode: DWORD); pub fn GetCommandLineW() -> LPWSTR; pub fn GetTempPathW(nBufferLength: DWORD, lpBuffer: LPCWSTR) -> DWORD; diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs index 157d8a044d3cd..e3809f3579dfd 100644 --- a/library/std/src/sys/windows/fs.rs +++ b/library/std/src/sys/windows/fs.rs @@ -82,6 +82,12 @@ pub struct FilePermissions { attrs: c::DWORD, } +#[derive(Copy, Clone, Debug, Default)] +pub struct FileTimes { + accessed: c::FILETIME, + modified: c::FILETIME, +} + #[derive(Debug)] pub struct DirBuilder; @@ -550,6 +556,14 @@ impl File { })?; Ok(()) } + + pub fn set_times(&self, times: FileTimes) -> io::Result<()> { + cvt(unsafe { + c::SetFileTime(self.as_handle(), None, Some(×.accessed), Some(×.modified)) + })?; + Ok(()) + } + /// Get only basic file information such as attributes and file times. fn basic_info(&self) -> io::Result { unsafe { @@ -895,6 +909,16 @@ impl FilePermissions { } } +impl FileTimes { + pub fn set_accessed(&mut self, t: SystemTime) { + self.accessed = t.into_inner(); + } + + pub fn set_modified(&mut self, t: SystemTime) { + self.modified = t.into_inner(); + } +} + impl FileType { fn new(attrs: c::DWORD, reparse_tag: c::DWORD) -> FileType { FileType { attributes: attrs, reparse_tag } diff --git a/library/std/src/sys/windows/time.rs b/library/std/src/sys/windows/time.rs index 8f46781c75340..b8209a8544585 100644 --- a/library/std/src/sys/windows/time.rs +++ b/library/std/src/sys/windows/time.rs @@ -2,6 +2,7 @@ use crate::cmp::Ordering; use crate::fmt; use crate::mem; use crate::sys::c; +use crate::sys_common::IntoInner; use crate::time::Duration; use core::hash::{Hash, Hasher}; @@ -136,6 +137,12 @@ impl From for SystemTime { } } +impl IntoInner for SystemTime { + fn into_inner(self) -> c::FILETIME { + self.t + } +} + impl Hash for SystemTime { fn hash(&self, state: &mut H) { self.intervals().hash(state) diff --git a/library/std/src/time.rs b/library/std/src/time.rs index b2014f462bd34..759a59e1f98d2 100644 --- a/library/std/src/time.rs +++ b/library/std/src/time.rs @@ -38,7 +38,7 @@ use crate::error::Error; use crate::fmt; use crate::ops::{Add, AddAssign, Sub, SubAssign}; use crate::sys::time; -use crate::sys_common::FromInner; +use crate::sys_common::{FromInner, IntoInner}; #[stable(feature = "time", since = "1.3.0")] pub use core::time::Duration; @@ -686,3 +686,9 @@ impl FromInner for SystemTime { SystemTime(time) } } + +impl IntoInner for SystemTime { + fn into_inner(self) -> time::SystemTime { + self.0 + } +} From e2b5729fdd089389e679cc76853988fd8167d62f Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Mon, 20 Jun 2022 14:37:38 -0700 Subject: [PATCH 17/21] Add alias `File::set_modified` as shorthand --- library/std/src/fs.rs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/library/std/src/fs.rs b/library/std/src/fs.rs index 0500e826768af..4f321cdeeea00 100644 --- a/library/std/src/fs.rs +++ b/library/std/src/fs.rs @@ -638,6 +638,15 @@ impl File { pub fn set_times(&self, times: FileTimes) -> io::Result<()> { self.inner.set_times(times.0) } + + /// Changes the modification time of the underlying file. + /// + /// This is an alias for `set_times(FileTimes::new().set_modified(time))`. + #[unstable(feature = "file_set_times", issue = "98245")] + #[inline] + pub fn set_modified(&self, time: SystemTime) -> io::Result<()> { + self.set_times(FileTimes::new().set_modified(time)) + } } // In addition to the `impl`s here, `File` also has `impl`s for From 3899914131053cafb46f61ba3c7d6846673ebd22 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sat, 25 Jun 2022 09:31:36 -0400 Subject: [PATCH 18/21] bless after rebase --- src/test/ui/borrowck/issue-81899.stderr | 13 ++ .../issue-88434-minimal-example.stderr | 13 ++ ...-88434-removal-index-should-be-less.stderr | 13 ++ .../const-eval/const-eval-query-stack.stderr | 15 +- ...inter-values-in-various-types.64bit.stderr | 131 +++++++++++++++--- src/test/ui/consts/const-eval/format.stderr | 46 ++++++ .../const-eval/ref_to_int_match.32bit.stderr | 13 ++ .../const-eval/ref_to_int_match.64bit.stderr | 13 ++ .../ui/consts/const-eval/ub-enum.32bit.stderr | 55 ++++++++ .../ui/consts/const-eval/ub-enum.64bit.stderr | 55 ++++++++ .../consts/const-eval/ub-ref-ptr.32bit.stderr | 63 +++++++++ .../consts/const-eval/ub-ref-ptr.64bit.stderr | 63 +++++++++ .../const-eval/ub-wide-ptr.32bit.stderr | 83 +++++++++++ .../const-eval/ub-wide-ptr.64bit.stderr | 83 +++++++++++ .../const-float-bits-reject-conv.stderr | 112 +++++++++++++++ src/test/ui/consts/ptr_comparisons.stderr | 2 +- 16 files changed, 750 insertions(+), 23 deletions(-) diff --git a/src/test/ui/borrowck/issue-81899.stderr b/src/test/ui/borrowck/issue-81899.stderr index 92ebd5a220d90..e7345ff3f9a64 100644 --- a/src/test/ui/borrowck/issue-81899.stderr +++ b/src/test/ui/borrowck/issue-81899.stderr @@ -27,3 +27,16 @@ LL | const _CONST: &[u8] = &f(&[], |_| {}); error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/issue-81899.rs:4:23 + | +LL | const _CONST: &[u8] = &f(&[], |_| {}); + | ----------------------^^^^^^^^^^^^^^^- + | | + | referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/borrowck/issue-88434-minimal-example.stderr b/src/test/ui/borrowck/issue-88434-minimal-example.stderr index d46cd862e34aa..47d83c6535583 100644 --- a/src/test/ui/borrowck/issue-88434-minimal-example.stderr +++ b/src/test/ui/borrowck/issue-88434-minimal-example.stderr @@ -27,3 +27,16 @@ LL | const _CONST: &() = &f(&|_| {}); error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/issue-88434-minimal-example.rs:3:21 + | +LL | const _CONST: &() = &f(&|_| {}); + | --------------------^^^^^^^^^^^- + | | + | referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr b/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr index e6b07aba74d42..b08a7cfc7fe1a 100644 --- a/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr +++ b/src/test/ui/borrowck/issue-88434-removal-index-should-be-less.stderr @@ -27,3 +27,16 @@ LL | const _CONST: &[u8] = &f(&[], |_| {}); error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/issue-88434-removal-index-should-be-less.rs:3:23 + | +LL | const _CONST: &[u8] = &f(&[], |_| {}); + | ----------------------^^^^^^^^^^^^^^^- + | | + | referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-eval/const-eval-query-stack.stderr b/src/test/ui/consts/const-eval/const-eval-query-stack.stderr index fb4c92861cb74..bbec2a830e64b 100644 --- a/src/test/ui/consts/const-eval/const-eval-query-stack.stderr +++ b/src/test/ui/consts/const-eval/const-eval-query-stack.stderr @@ -37,7 +37,7 @@ query stack during panic: end of query stack Future incompatibility report: Future breakage diagnostic: warning: any use of this value will cause an error - --> $DIR/const-eval-query-stack.rs:20:16 + --> $DIR/const-eval-query-stack.rs:19:16 | LL | const X: i32 = 1 / 0; | ---------------^^^^^- @@ -45,10 +45,21 @@ LL | const X: i32 = 1 / 0; | attempt to divide `1_i32` by zero | note: the lint level is defined here - --> $DIR/const-eval-query-stack.rs:19:8 + --> $DIR/const-eval-query-stack.rs:18:8 | LL | #[warn(const_err)] | ^^^^^^^^^ = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! = note: for more information, see issue #71800 +Future breakage diagnostic: +error: erroneous constant used + --> $DIR/const-eval-query-stack.rs:23:27 + | +LL | let x: &'static i32 = &X; + | ^^ referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr index 9fcb27f04ab99..b004637fd8300 100644 --- a/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr +++ b/src/test/ui/consts/const-eval/const-pointer-values-in-various-types.64bit.stderr @@ -323,7 +323,20 @@ error: aborting due to 29 previous errors For more information about this error, try `rustc --explain E0080`. Future incompatibility report: Future breakage diagnostic: error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:29:43 + --> $DIR/const-pointer-values-in-various-types.rs:26:49 + | +LL | const I32_REF_USIZE_UNION: usize = unsafe { Nonsense { int_32_ref: &3 }.u }; + | --------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:30:43 | LL | const I32_REF_U8_UNION: u8 = unsafe { Nonsense { int_32_ref: &3 }.uint_8 }; | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -336,7 +349,7 @@ LL | const I32_REF_U8_UNION: u8 = unsafe { Nonsense { int_32_ref: &3 }.uint_ Future breakage diagnostic: error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:33:45 + --> $DIR/const-pointer-values-in-various-types.rs:34:45 | LL | const I32_REF_U16_UNION: u16 = unsafe { Nonsense { int_32_ref: &3 }.uint_16 }; | ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -349,7 +362,7 @@ LL | const I32_REF_U16_UNION: u16 = unsafe { Nonsense { int_32_ref: &3 }.uin Future breakage diagnostic: error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:37:45 + --> $DIR/const-pointer-values-in-various-types.rs:38:45 | LL | const I32_REF_U32_UNION: u32 = unsafe { Nonsense { int_32_ref: &3 }.uint_32 }; | ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -362,7 +375,20 @@ LL | const I32_REF_U32_UNION: u32 = unsafe { Nonsense { int_32_ref: &3 }.uin Future breakage diagnostic: error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:47:43 + --> $DIR/const-pointer-values-in-various-types.rs:42:45 + | +LL | const I32_REF_U64_UNION: u64 = unsafe { Nonsense { int_32_ref: &3 }.uint_64 }; + | ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:49:43 | LL | const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8 }; | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -375,7 +401,7 @@ LL | const I32_REF_I8_UNION: i8 = unsafe { Nonsense { int_32_ref: &3 }.int_8 Future breakage diagnostic: error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:51:45 + --> $DIR/const-pointer-values-in-various-types.rs:53:45 | LL | const I32_REF_I16_UNION: i16 = unsafe { Nonsense { int_32_ref: &3 }.int_16 }; | ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -388,7 +414,7 @@ LL | const I32_REF_I16_UNION: i16 = unsafe { Nonsense { int_32_ref: &3 }.int Future breakage diagnostic: error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:55:45 + --> $DIR/const-pointer-values-in-various-types.rs:57:45 | LL | const I32_REF_I32_UNION: i32 = unsafe { Nonsense { int_32_ref: &3 }.int_32 }; | ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -401,7 +427,20 @@ LL | const I32_REF_I32_UNION: i32 = unsafe { Nonsense { int_32_ref: &3 }.int Future breakage diagnostic: error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:65:45 + --> $DIR/const-pointer-values-in-various-types.rs:61:45 + | +LL | const I32_REF_I64_UNION: i64 = unsafe { Nonsense { int_32_ref: &3 }.int_64 }; + | ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:68:45 | LL | const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.float_32 }; | ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -414,7 +453,20 @@ LL | const I32_REF_F32_UNION: f32 = unsafe { Nonsense { int_32_ref: &3 }.flo Future breakage diagnostic: error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:72:47 + --> $DIR/const-pointer-values-in-various-types.rs:72:45 + | +LL | const I32_REF_F64_UNION: f64 = unsafe { Nonsense { int_32_ref: &3 }.float_64 }; + | ----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:76:47 | LL | const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.truthy_falsey }; | ------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -427,7 +479,7 @@ LL | const I32_REF_BOOL_UNION: bool = unsafe { Nonsense { int_32_ref: &3 }.t Future breakage diagnostic: error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:76:47 + --> $DIR/const-pointer-values-in-various-types.rs:80:47 | LL | const I32_REF_CHAR_UNION: char = unsafe { Nonsense { int_32_ref: &3 }.character }; | ------------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -440,7 +492,7 @@ LL | const I32_REF_CHAR_UNION: char = unsafe { Nonsense { int_32_ref: &3 }.c Future breakage diagnostic: error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:80:39 + --> $DIR/const-pointer-values-in-various-types.rs:84:39 | LL | const STR_U8_UNION: u8 = unsafe { Nonsense { stringy: "3" }.uint_8 }; | ----------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -453,7 +505,7 @@ LL | const STR_U8_UNION: u8 = unsafe { Nonsense { stringy: "3" }.uint_8 }; Future breakage diagnostic: error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:84:41 + --> $DIR/const-pointer-values-in-various-types.rs:88:41 | LL | const STR_U16_UNION: u16 = unsafe { Nonsense { stringy: "3" }.uint_16 }; | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -466,7 +518,7 @@ LL | const STR_U16_UNION: u16 = unsafe { Nonsense { stringy: "3" }.uint_16 } Future breakage diagnostic: error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:88:41 + --> $DIR/const-pointer-values-in-various-types.rs:92:41 | LL | const STR_U32_UNION: u32 = unsafe { Nonsense { stringy: "3" }.uint_32 }; | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -479,7 +531,20 @@ LL | const STR_U32_UNION: u32 = unsafe { Nonsense { stringy: "3" }.uint_32 } Future breakage diagnostic: error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:95:43 + --> $DIR/const-pointer-values-in-various-types.rs:96:41 + | +LL | const STR_U64_UNION: u64 = unsafe { Nonsense { stringy: "3" }.uint_64 }; + | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:100:43 | LL | const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_128 }; | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -492,7 +557,7 @@ LL | const STR_U128_UNION: u128 = unsafe { Nonsense { stringy: "3" }.uint_12 Future breakage diagnostic: error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:99:39 + --> $DIR/const-pointer-values-in-various-types.rs:104:39 | LL | const STR_I8_UNION: i8 = unsafe { Nonsense { stringy: "3" }.int_8 }; | ----------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -505,7 +570,7 @@ LL | const STR_I8_UNION: i8 = unsafe { Nonsense { stringy: "3" }.int_8 }; Future breakage diagnostic: error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:103:41 + --> $DIR/const-pointer-values-in-various-types.rs:108:41 | LL | const STR_I16_UNION: i16 = unsafe { Nonsense { stringy: "3" }.int_16 }; | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -518,7 +583,7 @@ LL | const STR_I16_UNION: i16 = unsafe { Nonsense { stringy: "3" }.int_16 }; Future breakage diagnostic: error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:107:41 + --> $DIR/const-pointer-values-in-various-types.rs:112:41 | LL | const STR_I32_UNION: i32 = unsafe { Nonsense { stringy: "3" }.int_32 }; | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -531,7 +596,20 @@ LL | const STR_I32_UNION: i32 = unsafe { Nonsense { stringy: "3" }.int_32 }; Future breakage diagnostic: error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:114:43 + --> $DIR/const-pointer-values-in-various-types.rs:116:41 + | +LL | const STR_I64_UNION: i64 = unsafe { Nonsense { stringy: "3" }.int_64 }; + | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:120:43 | LL | const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128 }; | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -544,7 +622,7 @@ LL | const STR_I128_UNION: i128 = unsafe { Nonsense { stringy: "3" }.int_128 Future breakage diagnostic: error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:118:41 + --> $DIR/const-pointer-values-in-various-types.rs:124:41 | LL | const STR_F32_UNION: f32 = unsafe { Nonsense { stringy: "3" }.float_32 }; | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -557,7 +635,20 @@ LL | const STR_F32_UNION: f32 = unsafe { Nonsense { stringy: "3" }.float_32 Future breakage diagnostic: error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:125:43 + --> $DIR/const-pointer-values-in-various-types.rs:128:41 + | +LL | const STR_F64_UNION: f64 = unsafe { Nonsense { stringy: "3" }.float_64 }; + | ------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-pointer-values-in-various-types.rs:132:43 | LL | const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_falsey }; | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- @@ -570,7 +661,7 @@ LL | const STR_BOOL_UNION: bool = unsafe { Nonsense { stringy: "3" }.truthy_ Future breakage diagnostic: error: any use of this value will cause an error - --> $DIR/const-pointer-values-in-various-types.rs:129:43 + --> $DIR/const-pointer-values-in-various-types.rs:136:43 | LL | const STR_CHAR_UNION: char = unsafe { Nonsense { stringy: "3" }.character }; | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- diff --git a/src/test/ui/consts/const-eval/format.stderr b/src/test/ui/consts/const-eval/format.stderr index 44f436ae4e3a9..b00cadcea991f 100644 --- a/src/test/ui/consts/const-eval/format.stderr +++ b/src/test/ui/consts/const-eval/format.stderr @@ -76,3 +76,49 @@ LL | println!("{:?}", 0); error: aborting due to 8 previous errors For more information about this error, try `rustc --explain E0015`. +Future incompatibility report: Future breakage diagnostic: +error: erroneous constant used + --> $DIR/format.rs:2:12 + | +LL | panic!("{:?}", 0); + | ^^^^^^ referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: erroneous constant used + --> $DIR/format.rs:2:20 + | +LL | panic!("{:?}", 0); + | ^ referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + = note: this error originates in the macro `$crate::const_format_args` (in Nightly builds, run with -Z macro-backtrace for more info) + +Future breakage diagnostic: +error: erroneous constant used + --> $DIR/format.rs:11:14 + | +LL | println!("{:?}", 0); + | ^^^^^^ referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: erroneous constant used + --> $DIR/format.rs:11:22 + | +LL | println!("{:?}", 0); + | ^ referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + = 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/consts/const-eval/ref_to_int_match.32bit.stderr b/src/test/ui/consts/const-eval/ref_to_int_match.32bit.stderr index 83ac6c90a43a8..a55fd8c156e07 100644 --- a/src/test/ui/consts/const-eval/ref_to_int_match.32bit.stderr +++ b/src/test/ui/consts/const-eval/ref_to_int_match.32bit.stderr @@ -24,3 +24,16 @@ LL | 10..=BAR => {}, error: aborting due to 3 previous errors +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ref_to_int_match.rs:25:27 + | +LL | const BAR: Int = unsafe { Foo { r: &42 }.f }; + | --------------------------^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-eval/ref_to_int_match.64bit.stderr b/src/test/ui/consts/const-eval/ref_to_int_match.64bit.stderr index 83ac6c90a43a8..a55fd8c156e07 100644 --- a/src/test/ui/consts/const-eval/ref_to_int_match.64bit.stderr +++ b/src/test/ui/consts/const-eval/ref_to_int_match.64bit.stderr @@ -24,3 +24,16 @@ LL | 10..=BAR => {}, error: aborting due to 3 previous errors +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ref_to_int_match.rs:25:27 + | +LL | const BAR: Int = unsafe { Foo { r: &42 }.f }; + | --------------------------^^^^^^^^^^^^^^^^--- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-eval/ub-enum.32bit.stderr b/src/test/ui/consts/const-eval/ub-enum.32bit.stderr index c6fa14d0534f4..2440cd2272c6c 100644 --- a/src/test/ui/consts/const-eval/ub-enum.32bit.stderr +++ b/src/test/ui/consts/const-eval/ub-enum.32bit.stderr @@ -125,3 +125,58 @@ LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { error: aborting due to 13 previous errors For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-enum.rs:26:1 + | +LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-enum.rs:30:1 + | +LL | const BAD_ENUM_WRAPPED: Wrap = unsafe { mem::transmute(&1) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-enum.rs:45:1 + | +LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-enum.rs:49:1 + | +LL | const BAD_ENUM2_WRAPPED: Wrap = unsafe { mem::transmute(&0) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-enum.rs:63:1 + | +LL | const BAD_ENUM2_OPTION_PTR: Option = unsafe { mem::transmute(&0) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-eval/ub-enum.64bit.stderr b/src/test/ui/consts/const-eval/ub-enum.64bit.stderr index 25be593ab83b0..e9b4023068e94 100644 --- a/src/test/ui/consts/const-eval/ub-enum.64bit.stderr +++ b/src/test/ui/consts/const-eval/ub-enum.64bit.stderr @@ -125,3 +125,58 @@ LL | const BAD_UNINHABITED_WITH_DATA2: Result<(i32, !), (i32, Never)> = unsafe { error: aborting due to 13 previous errors For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-enum.rs:26:1 + | +LL | const BAD_ENUM_PTR: Enum = unsafe { mem::transmute(&1) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-enum.rs:30:1 + | +LL | const BAD_ENUM_WRAPPED: Wrap = unsafe { mem::transmute(&1) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-enum.rs:45:1 + | +LL | const BAD_ENUM2_PTR: Enum2 = unsafe { mem::transmute(&0) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-enum.rs:49:1 + | +LL | const BAD_ENUM2_WRAPPED: Wrap = unsafe { mem::transmute(&0) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-enum.rs:63:1 + | +LL | const BAD_ENUM2_OPTION_PTR: Option = unsafe { mem::transmute(&0) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr b/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr index 8a4f23c033e89..10a0ccd552b6d 100644 --- a/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr +++ b/src/test/ui/consts/const-eval/ub-ref-ptr.32bit.stderr @@ -176,3 +176,66 @@ LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; error: aborting due to 16 previous errors For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-ref-ptr.rs:31:1 + | +LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-ref-ptr.rs:35:39 + | +LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; + | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-ref-ptr.rs:35:38 + | +LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; + | -------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- + | | + | referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-ref-ptr.rs:41:86 + | +LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; + | -------------------------------------------------------------------------------------^^^^^^^^^^^^^^^^^^^^---- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-ref-ptr.rs:41:85 + | +LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; + | ------------------------------------------------------------------------------------^^^^^^^^^^^^^^^^^^^^^---- + | | + | referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr b/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr index da1c6d1a07f84..e9fcefe12c7d9 100644 --- a/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr +++ b/src/test/ui/consts/const-eval/ub-ref-ptr.64bit.stderr @@ -176,3 +176,66 @@ LL | const DATA_FN_PTR: fn() = unsafe { mem::transmute(&13) }; error: aborting due to 16 previous errors For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-ref-ptr.rs:31:1 + | +LL | const REF_AS_USIZE: usize = unsafe { mem::transmute(&0) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-ref-ptr.rs:35:39 + | +LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; + | --------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-ref-ptr.rs:35:38 + | +LL | const REF_AS_USIZE_SLICE: &[usize] = &[unsafe { mem::transmute(&0) }]; + | -------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- + | | + | referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-ref-ptr.rs:41:86 + | +LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; + | -------------------------------------------------------------------------------------^^^^^^^^^^^^^^^^^^^^---- + | | + | unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-ref-ptr.rs:41:85 + | +LL | const REF_AS_USIZE_BOX_SLICE: Box<[usize]> = unsafe { mem::transmute::<&[usize], _>(&[mem::transmute(&0)]) }; + | ------------------------------------------------------------------------------------^^^^^^^^^^^^^^^^^^^^^---- + | | + | referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr index a78cff11589fd..0c398f5bfd45e 100644 --- a/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr +++ b/src/test/ui/consts/const-eval/ub-wide-ptr.32bit.stderr @@ -344,3 +344,86 @@ LL | mem::transmute::<_, &dyn Trait>((&92u8, &3u64)) error: aborting due to 32 previous errors For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-wide-ptr.rs:42:1 + | +LL | const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-wide-ptr.rs:46:1 + | +LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-wide-ptr.rs:75:1 + | +LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-wide-ptr.rs:82:1 + | +LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-wide-ptr.rs:87:40 + | +LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; + | ---------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- + | | + | referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-wide-ptr.rs:95:42 + | +LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); + | -----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- + | | + | referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-wide-ptr.rs:100:42 + | +LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); + | -----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- + | | + | referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr b/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr index 69a61d9caede6..bf53995d956c5 100644 --- a/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr +++ b/src/test/ui/consts/const-eval/ub-wide-ptr.64bit.stderr @@ -344,3 +344,86 @@ LL | mem::transmute::<_, &dyn Trait>((&92u8, &3u64)) error: aborting due to 32 previous errors For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-wide-ptr.rs:42:1 + | +LL | const STR_LENGTH_PTR: &str = unsafe { mem::transmute((&42u8, &3)) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-wide-ptr.rs:46:1 + | +LL | const MY_STR_LENGTH_PTR: &MyStr = unsafe { mem::transmute((&42u8, &3)) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-wide-ptr.rs:75:1 + | +LL | const SLICE_LENGTH_PTR: &[u8] = unsafe { mem::transmute((&42u8, &3)) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-wide-ptr.rs:82:1 + | +LL | const SLICE_LENGTH_PTR_BOX: Box<[u8]> = unsafe { mem::transmute((&42u8, &3)) }; + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unable to turn pointer into raw bytes + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-wide-ptr.rs:87:40 + | +LL | const SLICE_CONTENT_INVALID: &[bool] = &[unsafe { mem::transmute(3u8) }]; + | ---------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- + | | + | referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-wide-ptr.rs:95:42 + | +LL | const MYSLICE_PREFIX_BAD: &MySliceBool = &MySlice(unsafe { mem::transmute(3u8) }, [false]); + | -----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- + | | + | referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/ub-wide-ptr.rs:100:42 + | +LL | const MYSLICE_SUFFIX_BAD: &MySliceBool = &MySlice(true, [unsafe { mem::transmute(3u8) }]); + | -----------------------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^- + | | + | referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/const-float-bits-reject-conv.stderr b/src/test/ui/consts/const-float-bits-reject-conv.stderr index f3fd098e848a2..d822171df7234 100644 --- a/src/test/ui/consts/const-float-bits-reject-conv.stderr +++ b/src/test/ui/consts/const-float-bits-reject-conv.stderr @@ -214,3 +214,115 @@ LL | const_assert!(f64::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2); error: aborting due to 12 previous errors For more information about this error, try `rustc --explain E0080`. +Future incompatibility report: Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-float-bits-reject-conv.rs:30:34 + | +LL | const _: () = assert!($a); + | -------------------------- +... +LL | const_assert!(f32::from_bits(MASKED_NAN1).is_nan()); + | ^^^^^^^^^^^ referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-float-bits-reject-conv.rs:33:34 + | +LL | const _: () = assert!($a); + | -------------------------- +... +LL | const_assert!(f32::from_bits(MASKED_NAN1).is_nan()); + | ^^^^^^^^^^^ referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-float-bits-reject-conv.rs:41:38 + | +LL | const _: () = assert!($a == $b); + | -------------------------------- +... +LL | const_assert!(f32::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1); + | ^^^^^^^^^^^ referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-float-bits-reject-conv.rs:44:38 + | +LL | const _: () = assert!($a == $b); + | -------------------------------- +... +LL | const_assert!(f32::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2); + | ^^^^^^^^^^^ referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-float-bits-reject-conv.rs:57:34 + | +LL | const _: () = assert!($a); + | -------------------------- +... +LL | const_assert!(f64::from_bits(MASKED_NAN1).is_nan()); + | ^^^^^^^^^^^ referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-float-bits-reject-conv.rs:60:34 + | +LL | const _: () = assert!($a); + | -------------------------- +... +LL | const_assert!(f64::from_bits(MASKED_NAN1).is_nan()); + | ^^^^^^^^^^^ referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-float-bits-reject-conv.rs:66:38 + | +LL | const _: () = assert!($a == $b); + | -------------------------------- +... +LL | const_assert!(f64::from_bits(MASKED_NAN1).to_bits(), MASKED_NAN1); + | ^^^^^^^^^^^ referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + +Future breakage diagnostic: +error: any use of this value will cause an error + --> $DIR/const-float-bits-reject-conv.rs:69:38 + | +LL | const _: () = assert!($a == $b); + | -------------------------------- +... +LL | const_assert!(f64::from_bits(MASKED_NAN2).to_bits(), MASKED_NAN2); + | ^^^^^^^^^^^ referenced constant has errors + | + = note: `#[deny(const_err)]` on by default + = warning: this was previously accepted by the compiler but is being phased out; it will become a hard error in a future release! + = note: for more information, see issue #71800 + diff --git a/src/test/ui/consts/ptr_comparisons.stderr b/src/test/ui/consts/ptr_comparisons.stderr index 7ff3faead6aa3..594576fe2cf3d 100644 --- a/src/test/ui/consts/ptr_comparisons.stderr +++ b/src/test/ui/consts/ptr_comparisons.stderr @@ -62,7 +62,7 @@ error: any use of this value will cause an error --> $DIR/ptr_comparisons.rs:70:27 | LL | const _: usize = unsafe { *std::mem::transmute::<&&usize, &usize>(&FOO) + 4 }; - | --------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^--- + | --------------------------^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^------- | | | unable to turn pointer into raw bytes | From 1d32fed68586b2b2075b4e033d301e48705b311a Mon Sep 17 00:00:00 2001 From: Josh Triplett Date: Sat, 25 Jun 2022 12:04:13 -0700 Subject: [PATCH 19/21] Return an error if trying to set a file timestamp to 0 on Windows This would otherwise silently ignore the attempt, since 0 serves as a flag to not set a timestamp. --- library/std/src/sys/windows/fs.rs | 17 ++++++++++++----- 1 file changed, 12 insertions(+), 5 deletions(-) diff --git a/library/std/src/sys/windows/fs.rs b/library/std/src/sys/windows/fs.rs index e3809f3579dfd..39aabadcf15fc 100644 --- a/library/std/src/sys/windows/fs.rs +++ b/library/std/src/sys/windows/fs.rs @@ -84,8 +84,8 @@ pub struct FilePermissions { #[derive(Copy, Clone, Debug, Default)] pub struct FileTimes { - accessed: c::FILETIME, - modified: c::FILETIME, + accessed: Option, + modified: Option, } #[derive(Debug)] @@ -558,8 +558,15 @@ impl File { } pub fn set_times(&self, times: FileTimes) -> io::Result<()> { + let is_zero = |t: c::FILETIME| t.dwLowDateTime == 0 && t.dwHighDateTime == 0; + if times.accessed.map_or(false, is_zero) || times.modified.map_or(false, is_zero) { + return Err(io::const_io_error!( + io::ErrorKind::InvalidInput, + "Cannot set file timestamp to 0", + )); + } cvt(unsafe { - c::SetFileTime(self.as_handle(), None, Some(×.accessed), Some(×.modified)) + c::SetFileTime(self.as_handle(), None, times.accessed.as_ref(), times.modified.as_ref()) })?; Ok(()) } @@ -911,11 +918,11 @@ impl FilePermissions { impl FileTimes { pub fn set_accessed(&mut self, t: SystemTime) { - self.accessed = t.into_inner(); + self.accessed = Some(t.into_inner()); } pub fn set_modified(&mut self, t: SystemTime) { - self.modified = t.into_inner(); + self.modified = Some(t.into_inner()); } } From 2339bb20a6ae120abf1d5ea5e7aff40f263e92f1 Mon Sep 17 00:00:00 2001 From: scottmcm Date: Sun, 26 Jun 2022 08:45:53 +0000 Subject: [PATCH 20/21] Update `since` to 1.64 (since we're after 1.63) --- library/core/src/num/nonzero.rs | 52 ++++++++++++++++----------------- 1 file changed, 26 insertions(+), 26 deletions(-) diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index 5e95edaee19ff..e570d831cc607 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -330,8 +330,8 @@ macro_rules! nonzero_unsigned_operations { /// # Some(()) /// # } /// ``` - #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] - #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.63.0")] + #[stable(feature = "nonzero_checked_ops", since = "1.64.0")] + #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -365,8 +365,8 @@ macro_rules! nonzero_unsigned_operations { /// # Some(()) /// # } /// ``` - #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] - #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.63.0")] + #[stable(feature = "nonzero_checked_ops", since = "1.64.0")] + #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -431,8 +431,8 @@ macro_rules! nonzero_unsigned_operations { /// # Some(()) /// # } /// ``` - #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] - #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.63.0")] + #[stable(feature = "nonzero_checked_ops", since = "1.64.0")] + #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -533,8 +533,8 @@ macro_rules! nonzero_signed_operations { /// # Some(()) /// # } /// ``` - #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] - #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.63.0")] + #[stable(feature = "nonzero_checked_ops", since = "1.64.0")] + #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -565,8 +565,8 @@ macro_rules! nonzero_signed_operations { /// # Some(()) /// # } /// ``` - #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] - #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.63.0")] + #[stable(feature = "nonzero_checked_ops", since = "1.64.0")] + #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -601,8 +601,8 @@ macro_rules! nonzero_signed_operations { /// # Some(()) /// # } /// ``` - #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] - #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.63.0")] + #[stable(feature = "nonzero_checked_ops", since = "1.64.0")] + #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -641,8 +641,8 @@ macro_rules! nonzero_signed_operations { /// # Some(()) /// # } /// ``` - #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] - #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.63.0")] + #[stable(feature = "nonzero_checked_ops", since = "1.64.0")] + #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -676,8 +676,8 @@ macro_rules! nonzero_signed_operations { /// # Some(()) /// # } /// ``` - #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] - #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.63.0")] + #[stable(feature = "nonzero_checked_ops", since = "1.64.0")] + #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -711,8 +711,8 @@ macro_rules! nonzero_signed_operations { /// # Some(()) /// # } /// ``` - #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] - #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.63.0")] + #[stable(feature = "nonzero_checked_ops", since = "1.64.0")] + #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -760,8 +760,8 @@ macro_rules! nonzero_unsigned_signed_operations { /// # Some(()) /// # } /// ``` - #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] - #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.63.0")] + #[stable(feature = "nonzero_checked_ops", since = "1.64.0")] + #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -796,8 +796,8 @@ macro_rules! nonzero_unsigned_signed_operations { /// # Some(()) /// # } /// ``` - #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] - #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.63.0")] + #[stable(feature = "nonzero_checked_ops", since = "1.64.0")] + #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -869,8 +869,8 @@ macro_rules! nonzero_unsigned_signed_operations { /// # Some(()) /// # } /// ``` - #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] - #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.63.0")] + #[stable(feature = "nonzero_checked_ops", since = "1.64.0")] + #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] @@ -913,8 +913,8 @@ macro_rules! nonzero_unsigned_signed_operations { /// # Some(()) /// # } /// ``` - #[stable(feature = "nonzero_checked_ops", since = "1.63.0")] - #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.63.0")] + #[stable(feature = "nonzero_checked_ops", since = "1.64.0")] + #[rustc_const_stable(feature = "const_nonzero_checked_ops", since = "1.64.0")] #[must_use = "this returns the result of the operation, \ without modifying the original"] #[inline] From 0398aa8ccb6db06e5fc277a31be139fc2c6b19f9 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Sun, 26 Jun 2022 14:01:00 +0200 Subject: [PATCH 21/21] Add regression test for #92859 --- src/test/rustdoc/generic_const_exprs.rs | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 src/test/rustdoc/generic_const_exprs.rs diff --git a/src/test/rustdoc/generic_const_exprs.rs b/src/test/rustdoc/generic_const_exprs.rs new file mode 100644 index 0000000000000..6ff5916397546 --- /dev/null +++ b/src/test/rustdoc/generic_const_exprs.rs @@ -0,0 +1,24 @@ +// Regression test for . + +#![allow(incomplete_features)] +#![feature(generic_const_exprs)] + +#![crate_name = "foo"] + +// @has 'foo/trait.Foo.html' + +pub trait Foo: Sized { + const WIDTH: usize; + + fn arrayify(self) -> [Self; Self::WIDTH]; +} + +impl Foo for T { + const WIDTH: usize = 1; + + // @has - '//*[@id="tymethod.arrayify"]/*[@class="code-header"]' \ + // 'fn arrayify(self) -> [Self; Self::WIDTH]' + fn arrayify(self) -> [Self; Self::WIDTH] { + [self] + } +}