From a2c74b8445001b7f6cfd1e333b29f21637ab2282 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Tue, 19 Mar 2024 14:54:54 +0100 Subject: [PATCH 01/27] SeqCst->Relaxed in doc examples. SeqCst is unnecessary here. --- library/alloc/src/sync.rs | 2 +- library/core/src/alloc/global.rs | 9 +++------ 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/library/alloc/src/sync.rs b/library/alloc/src/sync.rs index 80f0f2acc99a2..7e3e2fb38b13e 100644 --- a/library/alloc/src/sync.rs +++ b/library/alloc/src/sync.rs @@ -233,7 +233,7 @@ macro_rules! acquire { /// let val = Arc::clone(&val); /// /// thread::spawn(move || { -/// let v = val.fetch_add(1, Ordering::SeqCst); +/// let v = val.fetch_add(1, Ordering::Relaxed); /// println!("{v:?}"); /// }); /// } diff --git a/library/core/src/alloc/global.rs b/library/core/src/alloc/global.rs index a1fff6707bd0f..8df3ace54ffe1 100644 --- a/library/core/src/alloc/global.rs +++ b/library/core/src/alloc/global.rs @@ -24,10 +24,7 @@ use crate::ptr; /// use std::alloc::{GlobalAlloc, Layout}; /// use std::cell::UnsafeCell; /// use std::ptr::null_mut; -/// use std::sync::atomic::{ -/// AtomicUsize, -/// Ordering::{Acquire, SeqCst}, -/// }; +/// use std::sync::atomic::{AtomicUsize, Ordering::Relaxed}; /// /// const ARENA_SIZE: usize = 128 * 1024; /// const MAX_SUPPORTED_ALIGN: usize = 4096; @@ -61,7 +58,7 @@ use crate::ptr; /// let mut allocated = 0; /// if self /// .remaining -/// .fetch_update(SeqCst, SeqCst, |mut remaining| { +/// .fetch_update(Relaxed, Relaxed, |mut remaining| { /// if size > remaining { /// return None; /// } @@ -81,7 +78,7 @@ use crate::ptr; /// /// fn main() { /// let _s = format!("allocating a string!"); -/// let currently = ALLOCATOR.remaining.load(Acquire); +/// let currently = ALLOCATOR.remaining.load(Relaxed); /// println!("allocated so far: {}", ARENA_SIZE - currently); /// } /// ``` From 5e4cc6f69475320b6d917ff4a54a063401d17f5b Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Tue, 19 Mar 2024 14:56:48 +0100 Subject: [PATCH 02/27] SeqCst->Relaxed in panic_unwind/emcc. SeqCst is unnecessary here. --- library/panic_unwind/src/emcc.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/panic_unwind/src/emcc.rs b/library/panic_unwind/src/emcc.rs index af18e19337c7a..fed4c52e83c5f 100644 --- a/library/panic_unwind/src/emcc.rs +++ b/library/panic_unwind/src/emcc.rs @@ -84,7 +84,7 @@ pub unsafe fn cleanup(ptr: *mut u8) -> Box { super::__rust_foreign_exception(); } - let was_caught = (*adjusted_ptr).caught.swap(true, Ordering::SeqCst); + let was_caught = (*adjusted_ptr).caught.swap(true, Ordering::Relaxed); if was_caught { // Since cleanup() isn't allowed to panic, we just abort instead. intrinsics::abort(); From bf3debe9d776a6eeda48e4c063ab6798d066fc4e Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Tue, 19 Mar 2024 14:57:19 +0100 Subject: [PATCH 03/27] SeqCst->Relaxed for proc_macro bridge counter. Relaxed is enough here. --- library/proc_macro/src/bridge/handle.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/proc_macro/src/bridge/handle.rs b/library/proc_macro/src/bridge/handle.rs index 894acae217e44..8c53bb609f60c 100644 --- a/library/proc_macro/src/bridge/handle.rs +++ b/library/proc_macro/src/bridge/handle.rs @@ -21,7 +21,7 @@ impl OwnedStore { pub(super) fn new(counter: &'static AtomicU32) -> Self { // Ensure the handle counter isn't 0, which would panic later, // when `NonZero::new` (aka `Handle::new`) is called in `alloc`. - assert_ne!(counter.load(Ordering::SeqCst), 0); + assert_ne!(counter.load(Ordering::Relaxed), 0); OwnedStore { counter, data: BTreeMap::new() } } @@ -29,7 +29,7 @@ impl OwnedStore { impl OwnedStore { pub(super) fn alloc(&mut self, x: T) -> Handle { - let counter = self.counter.fetch_add(1, Ordering::SeqCst); + let counter = self.counter.fetch_add(1, Ordering::Relaxed); let handle = Handle::new(counter).expect("`proc_macro` handle counter overflowed"); assert!(self.data.insert(handle, x).is_none()); handle From 904fef0e24c8b7f7ff0a33c1b7f3ecbb59ade249 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Tue, 19 Mar 2024 14:57:59 +0100 Subject: [PATCH 04/27] SeqCst->{Release,Acquire} for alloc error hook. SeqCst is unnecessary. --- library/std/src/alloc.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/std/src/alloc.rs b/library/std/src/alloc.rs index a834b36697c00..dc0e302a81088 100644 --- a/library/std/src/alloc.rs +++ b/library/std/src/alloc.rs @@ -329,7 +329,7 @@ static HOOK: AtomicPtr<()> = AtomicPtr::new(ptr::null_mut()); /// ``` #[unstable(feature = "alloc_error_hook", issue = "51245")] pub fn set_alloc_error_hook(hook: fn(Layout)) { - HOOK.store(hook as *mut (), Ordering::SeqCst); + HOOK.store(hook as *mut (), Ordering::Release); } /// Unregisters the current allocation error hook, returning it. @@ -339,7 +339,7 @@ pub fn set_alloc_error_hook(hook: fn(Layout)) { /// If no custom hook is registered, the default hook will be returned. #[unstable(feature = "alloc_error_hook", issue = "51245")] pub fn take_alloc_error_hook() -> fn(Layout) { - let hook = HOOK.swap(ptr::null_mut(), Ordering::SeqCst); + let hook = HOOK.swap(ptr::null_mut(), Ordering::Acquire); if hook.is_null() { default_alloc_error_hook } else { unsafe { mem::transmute(hook) } } } @@ -362,7 +362,7 @@ fn default_alloc_error_hook(layout: Layout) { #[alloc_error_handler] #[unstable(feature = "alloc_internals", issue = "none")] pub fn rust_oom(layout: Layout) -> ! { - let hook = HOOK.load(Ordering::SeqCst); + let hook = HOOK.load(Ordering::Acquire); let hook: fn(Layout) = if hook.is_null() { default_alloc_error_hook } else { unsafe { mem::transmute(hook) } }; hook(layout); From 9f25a04498fbe30dcf6a9c764953704c333a0137 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Tue, 19 Mar 2024 14:58:40 +0100 Subject: [PATCH 05/27] SeqCst->Relaxed for FIRST_PANIC. Relaxed is enough to make sure this `swap` results in `true` only once. --- library/std/src/panicking.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/panicking.rs b/library/std/src/panicking.rs index 464a46264cbdd..b0bcab7994c76 100644 --- a/library/std/src/panicking.rs +++ b/library/std/src/panicking.rs @@ -272,7 +272,7 @@ fn default_hook(info: &PanicInfo<'_>) { drop(backtrace::print(err, crate::backtrace_rs::PrintFmt::Full)) } Some(BacktraceStyle::Off) => { - if FIRST_PANIC.swap(false, Ordering::SeqCst) { + if FIRST_PANIC.swap(false, Ordering::Relaxed) { let _ = writeln!( err, "note: run with `RUST_BACKTRACE=1` environment variable to display a \ From eb966983f2814b80d6bb526b53557dd32b1621c0 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Tue, 19 Mar 2024 15:00:09 +0100 Subject: [PATCH 06/27] SeqCst->{Release,Acquire} in xous mutex. No need for SeqCst. Release+Acquire is the right memory ordering for a mutex. --- library/std/src/sys/sync/mutex/xous.rs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/library/std/src/sys/sync/mutex/xous.rs b/library/std/src/sys/sync/mutex/xous.rs index a8c9518ff0bcf..1426e48f8b7af 100644 --- a/library/std/src/sys/sync/mutex/xous.rs +++ b/library/std/src/sys/sync/mutex/xous.rs @@ -1,6 +1,9 @@ use crate::os::xous::ffi::{blocking_scalar, do_yield}; use crate::os::xous::services::{ticktimer_server, TicktimerScalar}; -use crate::sync::atomic::{AtomicBool, AtomicUsize, Ordering::Relaxed, Ordering::SeqCst}; +use crate::sync::atomic::{ + AtomicBool, AtomicUsize, + Ordering::{Acquire, Relaxed, Release}, +}; pub struct Mutex { /// The "locked" value indicates how many threads are waiting on this @@ -68,7 +71,7 @@ impl Mutex { #[inline] pub unsafe fn unlock(&self) { - let prev = self.locked.fetch_sub(1, SeqCst); + let prev = self.locked.fetch_sub(1, Release); // If the previous value was 1, then this was a "fast path" unlock, so no // need to involve the Ticktimer server @@ -89,12 +92,12 @@ impl Mutex { #[inline] pub unsafe fn try_lock(&self) -> bool { - self.locked.compare_exchange(0, 1, SeqCst, SeqCst).is_ok() + self.locked.compare_exchange(0, 1, Acquire, Relaxed).is_ok() } #[inline] pub unsafe fn try_lock_or_poison(&self) -> bool { - self.locked.fetch_add(1, SeqCst) == 0 + self.locked.fetch_add(1, Acquire) == 0 } } From 516684c22ec3819c6ef772407bd6d50d8387dafb Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Tue, 19 Mar 2024 15:01:24 +0100 Subject: [PATCH 07/27] Use less restricted memory ordering in thread_parking::pthread. SeqCst is unnecessary here. --- .../sys/pal/unix/thread_parking/pthread.rs | 22 ++++++++++--------- 1 file changed, 12 insertions(+), 10 deletions(-) diff --git a/library/std/src/sys/pal/unix/thread_parking/pthread.rs b/library/std/src/sys/pal/unix/thread_parking/pthread.rs index ae805d8439945..bb79cf9548e68 100644 --- a/library/std/src/sys/pal/unix/thread_parking/pthread.rs +++ b/library/std/src/sys/pal/unix/thread_parking/pthread.rs @@ -5,7 +5,7 @@ use crate::marker::PhantomPinned; use crate::pin::Pin; use crate::ptr::addr_of_mut; use crate::sync::atomic::AtomicUsize; -use crate::sync::atomic::Ordering::SeqCst; +use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release}; #[cfg(not(target_os = "nto"))] use crate::sys::time::TIMESPEC_MAX; #[cfg(target_os = "nto")] @@ -150,16 +150,18 @@ impl Parker { // This implementation doesn't require `unsafe`, but other implementations // may assume this is only called by the thread that owns the Parker. + // + // For memory ordering, see std/src/sys_common/thread_parking/futex.rs pub unsafe fn park(self: Pin<&Self>) { // If we were previously notified then we consume this notification and // return quickly. - if self.state.compare_exchange(NOTIFIED, EMPTY, SeqCst, SeqCst).is_ok() { + if self.state.compare_exchange(NOTIFIED, EMPTY, Acquire, Relaxed).is_ok() { return; } // Otherwise we need to coordinate going to sleep lock(self.lock.get()); - match self.state.compare_exchange(EMPTY, PARKED, SeqCst, SeqCst) { + match self.state.compare_exchange(EMPTY, PARKED, Relaxed, Relaxed) { Ok(_) => {} Err(NOTIFIED) => { // We must read here, even though we know it will be `NOTIFIED`. @@ -168,7 +170,7 @@ impl Parker { // acquire operation that synchronizes with that `unpark` to observe // any writes it made before the call to unpark. To do that we must // read from the write it made to `state`. - let old = self.state.swap(EMPTY, SeqCst); + let old = self.state.swap(EMPTY, Acquire); unlock(self.lock.get()); @@ -185,7 +187,7 @@ impl Parker { loop { wait(self.cvar.get(), self.lock.get()); - match self.state.compare_exchange(NOTIFIED, EMPTY, SeqCst, SeqCst) { + match self.state.compare_exchange(NOTIFIED, EMPTY, Acquire, Relaxed) { Ok(_) => break, // got a notification Err(_) => {} // spurious wakeup, go back to sleep } @@ -201,16 +203,16 @@ impl Parker { // Like `park` above we have a fast path for an already-notified thread, and // afterwards we start coordinating for a sleep. // return quickly. - if self.state.compare_exchange(NOTIFIED, EMPTY, SeqCst, SeqCst).is_ok() { + if self.state.compare_exchange(NOTIFIED, EMPTY, Acquire, Relaxed).is_ok() { return; } lock(self.lock.get()); - match self.state.compare_exchange(EMPTY, PARKED, SeqCst, SeqCst) { + match self.state.compare_exchange(EMPTY, PARKED, Relaxed, Relaxed) { Ok(_) => {} Err(NOTIFIED) => { // We must read again here, see `park`. - let old = self.state.swap(EMPTY, SeqCst); + let old = self.state.swap(EMPTY, Acquire); unlock(self.lock.get()); assert_eq!(old, NOTIFIED, "park state changed unexpectedly"); @@ -228,7 +230,7 @@ impl Parker { // parked. wait_timeout(self.cvar.get(), self.lock.get(), dur); - match self.state.swap(EMPTY, SeqCst) { + match self.state.swap(EMPTY, Acquire) { NOTIFIED => unlock(self.lock.get()), // got a notification, hurray! PARKED => unlock(self.lock.get()), // no notification, alas n => { @@ -245,7 +247,7 @@ impl Parker { // `state` is already `NOTIFIED`. That is why this must be a swap // rather than a compare-and-swap that returns if it reads `NOTIFIED` // on failure. - match self.state.swap(NOTIFIED, SeqCst) { + match self.state.swap(NOTIFIED, Release) { EMPTY => return, // no one was waiting NOTIFIED => return, // already unparked PARKED => {} // gotta go wake someone up From e43aef0ef9cc9d2d12c138b36fd817f7c41d0152 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Tue, 19 Mar 2024 15:03:29 +0100 Subject: [PATCH 08/27] SeqCst->{Release,Acquire} in sys_common::thread_local_key. SeqCst is unnecessary here. --- library/std/src/sys_common/thread_local_key.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/std/src/sys_common/thread_local_key.rs b/library/std/src/sys_common/thread_local_key.rs index 204834984a227..7dcc114109958 100644 --- a/library/std/src/sys_common/thread_local_key.rs +++ b/library/std/src/sys_common/thread_local_key.rs @@ -128,7 +128,7 @@ impl StaticKey { #[inline] unsafe fn key(&self) -> imp::Key { - match self.key.load(Ordering::Relaxed) { + match self.key.load(Ordering::Acquire) { KEY_SENTVAL => self.lazy_init() as imp::Key, n => n as imp::Key, } @@ -156,8 +156,8 @@ impl StaticKey { match self.key.compare_exchange( KEY_SENTVAL, key as usize, - Ordering::SeqCst, - Ordering::SeqCst, + Ordering::Release, + Ordering::Acquire, ) { // The CAS succeeded, so we've created the actual key Ok(_) => key as usize, From 46bb0734235bd25be5beb0c11e73c61905f5044b Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Tue, 19 Mar 2024 15:03:58 +0100 Subject: [PATCH 09/27] SeqCst->{Release,Acquire} for wasm DropLock. SeqCst is unnecessary. Release+Acquire is the right ordering for a mutex. --- library/std/src/sys/pal/wasm/alloc.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/library/std/src/sys/pal/wasm/alloc.rs b/library/std/src/sys/pal/wasm/alloc.rs index 6dceb1689a8b7..b74ce0d47425a 100644 --- a/library/std/src/sys/pal/wasm/alloc.rs +++ b/library/std/src/sys/pal/wasm/alloc.rs @@ -57,7 +57,10 @@ unsafe impl GlobalAlloc for System { #[cfg(target_feature = "atomics")] mod lock { - use crate::sync::atomic::{AtomicI32, Ordering::SeqCst}; + use crate::sync::atomic::{ + AtomicI32, + Ordering::{Acquire, Release}, + }; static LOCKED: AtomicI32 = AtomicI32::new(0); @@ -65,7 +68,7 @@ mod lock { pub fn lock() -> DropLock { loop { - if LOCKED.swap(1, SeqCst) == 0 { + if LOCKED.swap(1, Acquire) == 0 { return DropLock; } // Ok so here's where things get a little depressing. At this point @@ -143,7 +146,7 @@ mod lock { impl Drop for DropLock { fn drop(&mut self) { - let r = LOCKED.swap(0, SeqCst); + let r = LOCKED.swap(0, Release); debug_assert_eq!(r, 1); // Note that due to the above logic we don't actually need to wake From 60ad49005a4383abe68f6b0137c6ff0d795a1513 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Tue, 19 Mar 2024 15:05:46 +0100 Subject: [PATCH 10/27] SeqCst->Relaxed in pal::windows::pipe. Relaxed is enough to ensure fetch_add(1) returns each integer exactly once. --- library/std/src/sys/pal/windows/pipe.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/library/std/src/sys/pal/windows/pipe.rs b/library/std/src/sys/pal/windows/pipe.rs index 013f588676ae8..dfa938d4d5769 100644 --- a/library/std/src/sys/pal/windows/pipe.rs +++ b/library/std/src/sys/pal/windows/pipe.rs @@ -7,7 +7,7 @@ use crate::path::Path; use crate::ptr; use crate::slice; use crate::sync::atomic::AtomicUsize; -use crate::sync::atomic::Ordering::SeqCst; +use crate::sync::atomic::Ordering::Relaxed; use crate::sys::c; use crate::sys::fs::{File, OpenOptions}; use crate::sys::handle::Handle; @@ -214,11 +214,11 @@ pub fn spawn_pipe_relay( fn random_number() -> usize { static N: AtomicUsize = AtomicUsize::new(0); loop { - if N.load(SeqCst) != 0 { - return N.fetch_add(1, SeqCst); + if N.load(Relaxed) != 0 { + return N.fetch_add(1, Relaxed); } - N.store(hashmap_random_keys().0 as usize, SeqCst); + N.store(hashmap_random_keys().0 as usize, Relaxed); } } From 69a4d77d67cc3b2833726e1a87013697902950a7 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Tue, 19 Mar 2024 15:03:58 +0100 Subject: [PATCH 11/27] SeqCst->{Release,Acquire} for xous DropLock. SeqCst is unnecessary. Release+Acquire is the right ordering for a mutex. --- library/std/src/sys/pal/xous/alloc.rs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/library/std/src/sys/pal/xous/alloc.rs b/library/std/src/sys/pal/xous/alloc.rs index 0d540e9552072..601411173aacb 100644 --- a/library/std/src/sys/pal/xous/alloc.rs +++ b/library/std/src/sys/pal/xous/alloc.rs @@ -46,7 +46,10 @@ unsafe impl GlobalAlloc for System { } mod lock { - use crate::sync::atomic::{AtomicI32, Ordering::SeqCst}; + use crate::sync::atomic::{ + AtomicI32, + Ordering::{Acquire, Release}, + }; static LOCKED: AtomicI32 = AtomicI32::new(0); @@ -54,7 +57,7 @@ mod lock { pub fn lock() -> DropLock { loop { - if LOCKED.swap(1, SeqCst) == 0 { + if LOCKED.swap(1, Acquire) == 0 { return DropLock; } crate::os::xous::ffi::do_yield(); @@ -63,7 +66,7 @@ mod lock { impl Drop for DropLock { fn drop(&mut self) { - let r = LOCKED.swap(0, SeqCst); + let r = LOCKED.swap(0, Release); debug_assert_eq!(r, 1); } } From 5a594f7bcd29cc3d839986b031166aeca1d3745b Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Tue, 19 Mar 2024 15:08:04 +0100 Subject: [PATCH 12/27] SeqCst->Relaxed for xous set_nonblocking. The SeqCst wasn't synchronizing with anything. Relaxed is enough. --- library/std/src/sys/pal/xous/net/tcpstream.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys/pal/xous/net/tcpstream.rs b/library/std/src/sys/pal/xous/net/tcpstream.rs index 7149678118ab6..aebef02acdad5 100644 --- a/library/std/src/sys/pal/xous/net/tcpstream.rs +++ b/library/std/src/sys/pal/xous/net/tcpstream.rs @@ -406,7 +406,7 @@ impl TcpStream { } pub fn set_nonblocking(&self, nonblocking: bool) -> io::Result<()> { - self.nonblocking.store(nonblocking, Ordering::SeqCst); + self.nonblocking.store(nonblocking, Ordering::Relaxed); Ok(()) } } From 75a5196490fc1d8e0e39b406ce99a30d115bcfc5 Mon Sep 17 00:00:00 2001 From: Tshepang Mbambo Date: Tue, 19 Mar 2024 20:32:55 +0200 Subject: [PATCH 13/27] use more accurate terminology rustc is just one tool/executable, even if at the center of the toolchain --- config.example.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/config.example.toml b/config.example.toml index f94553dd63f72..b8cdc2ec84804 100644 --- a/config.example.toml +++ b/config.example.toml @@ -915,6 +915,6 @@ # Available options: fast, balanced, best #compression-profile = "fast" -# Copy the linker, DLLs, and various libraries from MinGW into the rustc toolchain. +# Copy the linker, DLLs, and various libraries from MinGW into the Rust toolchain. # Only applies when the host or target is pc-windows-gnu. #include-mingw-linker = true From 70206f06ca5cff08d3b84240074ec89e705ab61b Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 20 Mar 2024 18:00:12 +1100 Subject: [PATCH 14/27] coverage: Regression test for ICE triggered by self-loops --- tests/coverage/let_else_loop.cov-map | 30 +++++++++++++++++++++++ tests/coverage/let_else_loop.coverage | 35 +++++++++++++++++++++++++++ tests/coverage/let_else_loop.rs | 33 +++++++++++++++++++++++++ 3 files changed, 98 insertions(+) create mode 100644 tests/coverage/let_else_loop.cov-map create mode 100644 tests/coverage/let_else_loop.coverage create mode 100644 tests/coverage/let_else_loop.rs diff --git a/tests/coverage/let_else_loop.cov-map b/tests/coverage/let_else_loop.cov-map new file mode 100644 index 0000000000000..b0cee30052200 --- /dev/null +++ b/tests/coverage/let_else_loop.cov-map @@ -0,0 +1,30 @@ +Function name: let_else_loop::_if (unused) +Raw bytes (19): 0x[01, 01, 00, 03, 00, 16, 01, 01, 0c, 00, 02, 09, 00, 10, 00, 02, 09, 00, 10] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 0 +Number of file 0 mappings: 3 +- Code(Zero) at (prev + 22, 1) to (start + 1, 12) +- Code(Zero) at (prev + 2, 9) to (start + 0, 16) +- Code(Zero) at (prev + 2, 9) to (start + 0, 16) + +Function name: let_else_loop::_loop_either_way (unused) +Raw bytes (19): 0x[01, 01, 00, 03, 00, 0f, 01, 01, 14, 00, 01, 1c, 00, 23, 00, 01, 05, 00, 0c] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 0 +Number of file 0 mappings: 3 +- Code(Zero) at (prev + 15, 1) to (start + 1, 20) +- Code(Zero) at (prev + 1, 28) to (start + 0, 35) +- Code(Zero) at (prev + 1, 5) to (start + 0, 12) + +Function name: let_else_loop::loopy +Raw bytes (19): 0x[01, 01, 00, 03, 01, 09, 01, 01, 14, 00, 01, 1c, 00, 23, 05, 01, 01, 00, 02] +Number of files: 1 +- file 0 => global file 1 +Number of expressions: 0 +Number of file 0 mappings: 3 +- Code(Counter(0)) at (prev + 9, 1) to (start + 1, 20) +- Code(Zero) at (prev + 1, 28) to (start + 0, 35) +- Code(Counter(1)) at (prev + 1, 1) to (start + 0, 2) + diff --git a/tests/coverage/let_else_loop.coverage b/tests/coverage/let_else_loop.coverage new file mode 100644 index 0000000000000..3b3c39ff30180 --- /dev/null +++ b/tests/coverage/let_else_loop.coverage @@ -0,0 +1,35 @@ + LL| |#![feature(coverage_attribute)] + LL| |//@ edition: 2021 + LL| |//@ ignore-test + LL| |// Regression test for . + LL| |// These code patterns should not trigger an ICE when allocating a physical + LL| |// counter to a node and also one of its in-edges, because that is allowed + LL| |// when the node contains a tight loop to itself. + LL| | + LL| 1|fn loopy(cond: bool) { + LL| 1| let true = cond else { loop {} }; + ^0 + LL| 1|} + LL| | + LL| |// Variant that also has `loop {}` on the success path. + LL| |// This isn't needed to catch the original ICE, but might help detect regressions. + LL| 0|fn _loop_either_way(cond: bool) { + LL| 0| let true = cond else { loop {} }; + LL| 0| loop {} + LL| |} + LL| | + LL| |// Variant using regular `if` instead of let-else. + LL| |// This doesn't trigger the original ICE, but might help detect regressions. + LL| 0|fn _if(cond: bool) { + LL| 0| if cond { + LL| 0| loop {} + LL| | } else { + LL| 0| loop {} + LL| | } + LL| |} + LL| | + LL| |#[coverage(off)] + LL| |fn main() { + LL| | loopy(true); + LL| |} + diff --git a/tests/coverage/let_else_loop.rs b/tests/coverage/let_else_loop.rs new file mode 100644 index 0000000000000..92a252cbbdc99 --- /dev/null +++ b/tests/coverage/let_else_loop.rs @@ -0,0 +1,33 @@ +#![feature(coverage_attribute)] +//@ edition: 2021 +//@ ignore-test +// Regression test for . +// These code patterns should not trigger an ICE when allocating a physical +// counter to a node and also one of its in-edges, because that is allowed +// when the node contains a tight loop to itself. + +fn loopy(cond: bool) { + let true = cond else { loop {} }; +} + +// Variant that also has `loop {}` on the success path. +// This isn't needed to catch the original ICE, but might help detect regressions. +fn _loop_either_way(cond: bool) { + let true = cond else { loop {} }; + loop {} +} + +// Variant using regular `if` instead of let-else. +// This doesn't trigger the original ICE, but might help detect regressions. +fn _if(cond: bool) { + if cond { + loop {} + } else { + loop {} + } +} + +#[coverage(off)] +fn main() { + loopy(true); +} From 85bec7a50c9a8ab466f8fbafa7b0c4eb05e6c721 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 20 Mar 2024 18:17:23 +1100 Subject: [PATCH 15/27] coverage: Remove incorrect assertions from counter allocation These assertions detect situations where a BCB node would have both a physical counter and one or more in-edge counters/expressions. For most BCBs that situation would indicate an implementation bug. However, it's perfectly fine in the case of a BCB having an edge that loops back to itself. Given the complexity and risk involved in fixing the assertions, and the fact that nothing relies on them actually being true, this patch just removes them instead. --- .../src/coverage/counters.rs | 31 ------------------- tests/coverage/let_else_loop.coverage | 2 +- tests/coverage/let_else_loop.rs | 2 +- 3 files changed, 2 insertions(+), 33 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coverage/counters.rs b/compiler/rustc_mir_transform/src/coverage/counters.rs index 9a1d8bae6b410..402ce6ba8d9a9 100644 --- a/compiler/rustc_mir_transform/src/coverage/counters.rs +++ b/compiler/rustc_mir_transform/src/coverage/counters.rs @@ -1,7 +1,6 @@ use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::graph::WithNumNodes; -use rustc_index::bit_set::BitSet; use rustc_index::IndexVec; use rustc_middle::mir::coverage::*; @@ -18,10 +17,6 @@ pub(super) enum BcbCounter { } impl BcbCounter { - fn is_expression(&self) -> bool { - matches!(self, Self::Expression { .. }) - } - pub(super) fn as_term(&self) -> CovTerm { match *self { BcbCounter::Counter { id, .. } => CovTerm::Counter(id), @@ -60,10 +55,6 @@ pub(super) struct CoverageCounters { /// We currently don't iterate over this map, but if we do in the future, /// switch it back to `FxIndexMap` to avoid query stability hazards. bcb_edge_counters: FxHashMap<(BasicCoverageBlock, BasicCoverageBlock), BcbCounter>, - /// Tracks which BCBs have a counter associated with some incoming edge. - /// Only used by assertions, to verify that BCBs with incoming edge - /// counters do not have their own physical counters (expressions are allowed). - bcb_has_incoming_edge_counters: BitSet, /// Table of expression data, associating each expression ID with its /// corresponding operator (+ or -) and its LHS/RHS operands. expressions: IndexVec, @@ -83,7 +74,6 @@ impl CoverageCounters { counter_increment_sites: IndexVec::new(), bcb_counters: IndexVec::from_elem_n(None, num_bcbs), bcb_edge_counters: FxHashMap::default(), - bcb_has_incoming_edge_counters: BitSet::new_empty(num_bcbs), expressions: IndexVec::new(), }; @@ -122,14 +112,6 @@ impl CoverageCounters { } fn set_bcb_counter(&mut self, bcb: BasicCoverageBlock, counter_kind: BcbCounter) -> BcbCounter { - assert!( - // If the BCB has an edge counter (to be injected into a new `BasicBlock`), it can also - // have an expression (to be injected into an existing `BasicBlock` represented by this - // `BasicCoverageBlock`). - counter_kind.is_expression() || !self.bcb_has_incoming_edge_counters.contains(bcb), - "attempt to add a `Counter` to a BCB target with existing incoming edge counters" - ); - if let Some(replaced) = self.bcb_counters[bcb].replace(counter_kind) { bug!( "attempt to set a BasicCoverageBlock coverage counter more than once; \ @@ -146,19 +128,6 @@ impl CoverageCounters { to_bcb: BasicCoverageBlock, counter_kind: BcbCounter, ) -> BcbCounter { - // If the BCB has an edge counter (to be injected into a new `BasicBlock`), it can also - // have an expression (to be injected into an existing `BasicBlock` represented by this - // `BasicCoverageBlock`). - if let Some(node_counter) = self.bcb_counter(to_bcb) - && !node_counter.is_expression() - { - bug!( - "attempt to add an incoming edge counter from {from_bcb:?} \ - when the target BCB already has {node_counter:?}" - ); - } - - self.bcb_has_incoming_edge_counters.insert(to_bcb); if let Some(replaced) = self.bcb_edge_counters.insert((from_bcb, to_bcb), counter_kind) { bug!( "attempt to set an edge counter more than once; from_bcb: \ diff --git a/tests/coverage/let_else_loop.coverage b/tests/coverage/let_else_loop.coverage index 3b3c39ff30180..d193c8ca1b514 100644 --- a/tests/coverage/let_else_loop.coverage +++ b/tests/coverage/let_else_loop.coverage @@ -1,6 +1,6 @@ LL| |#![feature(coverage_attribute)] LL| |//@ edition: 2021 - LL| |//@ ignore-test + LL| | LL| |// Regression test for . LL| |// These code patterns should not trigger an ICE when allocating a physical LL| |// counter to a node and also one of its in-edges, because that is allowed diff --git a/tests/coverage/let_else_loop.rs b/tests/coverage/let_else_loop.rs index 92a252cbbdc99..12e0aeabcab95 100644 --- a/tests/coverage/let_else_loop.rs +++ b/tests/coverage/let_else_loop.rs @@ -1,6 +1,6 @@ #![feature(coverage_attribute)] //@ edition: 2021 -//@ ignore-test + // Regression test for . // These code patterns should not trigger an ICE when allocating a physical // counter to a node and also one of its in-edges, because that is allowed From 2f21e4f8bb86e1877d20bf74289272ecbe2bf103 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 20 Mar 2024 18:25:06 +1100 Subject: [PATCH 16/27] coverage: Tidy imports in `rustc_mir_transform::coverage::counters` --- compiler/rustc_mir_transform/src/coverage/counters.rs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/compiler/rustc_mir_transform/src/coverage/counters.rs b/compiler/rustc_mir_transform/src/coverage/counters.rs index 402ce6ba8d9a9..69dc4f2ddea71 100644 --- a/compiler/rustc_mir_transform/src/coverage/counters.rs +++ b/compiler/rustc_mir_transform/src/coverage/counters.rs @@ -1,12 +1,12 @@ +use std::fmt::{self, Debug}; + use rustc_data_structures::captures::Captures; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::graph::WithNumNodes; use rustc_index::IndexVec; -use rustc_middle::mir::coverage::*; +use rustc_middle::mir::coverage::{CounterId, CovTerm, Expression, ExpressionId, Op}; -use super::graph::{BasicCoverageBlock, CoverageGraph, TraverseCoverageGraphWithLoops}; - -use std::fmt::{self, Debug}; +use crate::coverage::graph::{BasicCoverageBlock, CoverageGraph, TraverseCoverageGraphWithLoops}; /// The coverage counter or counter expression associated with a particular /// BCB node or BCB edge. From 92f668c20b155736ef8278cb02456340097f0840 Mon Sep 17 00:00:00 2001 From: Jubilee Young Date: Wed, 20 Mar 2024 01:17:18 -0700 Subject: [PATCH 17/27] Add usize::MAX arg tests for Vec --- library/alloc/tests/vec.rs | 41 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+) diff --git a/library/alloc/tests/vec.rs b/library/alloc/tests/vec.rs index aa95b4e977081..f1f841fe190f0 100644 --- a/library/alloc/tests/vec.rs +++ b/library/alloc/tests/vec.rs @@ -2643,3 +2643,44 @@ fn test_vec_from_array_ref() { fn test_vec_from_array_mut_ref() { assert_eq!(Vec::from(&mut [1, 2, 3]), vec![1, 2, 3]); } + +/// This assortment of tests, in combination with miri, verifies we handle UB on fishy arguments +/// in the stdlib. Draining and extending the allocation are fairly well-tested earlier, but +/// `vec.insert(usize::MAX, val)` once slipped by! +/// +/// All code that manipulates the collection types should be tested with "trivially wrong" args. +#[test] +fn max_dont_panic() { + let mut v = vec![0]; + let _ = v.get(usize::MAX); + v.shrink_to(usize::MAX); + v.truncate(usize::MAX); +} + +#[test] +#[should_panic] +fn max_insert() { + let mut v = vec![0]; + v.insert(usize::MAX, 1); +} + +#[test] +#[should_panic] +fn max_remove() { + let mut v = vec![0]; + v.remove(usize::MAX); +} + +#[test] +#[should_panic] +fn max_splice() { + let mut v = vec![0]; + v.splice(usize::MAX.., core::iter::once(1)); +} + +#[test] +#[should_panic] +fn max_swap_remove() { + let mut v = vec![0]; + v.swap_remove(usize::MAX); +} From 8b519f98e26539a6f6f3bbd4164b8a0b653c2b68 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Tue, 19 Mar 2024 15:10:35 +0100 Subject: [PATCH 18/27] Use less restricted memory ordering in xous::thread_local_key. SeqCst isn't necessary in any of these cases. --- library/std/src/sys/pal/xous/thread_local_key.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/library/std/src/sys/pal/xous/thread_local_key.rs b/library/std/src/sys/pal/xous/thread_local_key.rs index 59a668c3df6ff..2aaf46d0244a7 100644 --- a/library/std/src/sys/pal/xous/thread_local_key.rs +++ b/library/std/src/sys/pal/xous/thread_local_key.rs @@ -2,7 +2,7 @@ use crate::mem::ManuallyDrop; use crate::ptr; use crate::sync::atomic::AtomicPtr; use crate::sync::atomic::AtomicUsize; -use crate::sync::atomic::Ordering::SeqCst; +use crate::sync::atomic::Ordering::{Acquire, Relaxed, Release}; use core::arch::asm; use crate::os::xous::ffi::{map_memory, unmap_memory, MemoryFlags}; @@ -92,7 +92,7 @@ fn tls_table() -> &'static mut [*mut u8] { pub unsafe fn create(dtor: Option) -> Key { // Allocate a new TLS key. These keys are shared among all threads. #[allow(unused_unsafe)] - let key = unsafe { TLS_KEY_INDEX.fetch_add(1, SeqCst) }; + let key = unsafe { TLS_KEY_INDEX.fetch_add(1, Relaxed) }; if let Some(f) = dtor { unsafe { register_dtor(key, f) }; } @@ -154,11 +154,11 @@ unsafe fn register_dtor(key: Key, dtor: Dtor) { let mut node = ManuallyDrop::new(Box::new(Node { key, dtor, next: ptr::null_mut() })); #[allow(unused_unsafe)] - let mut head = unsafe { DTORS.load(SeqCst) }; + let mut head = unsafe { DTORS.load(Acquire) }; loop { node.next = head; #[allow(unused_unsafe)] - match unsafe { DTORS.compare_exchange(head, &mut **node, SeqCst, SeqCst) } { + match unsafe { DTORS.compare_exchange(head, &mut **node, Release, Acquire) } { Ok(_) => return, // nothing to drop, we successfully added the node to the list Err(cur) => head = cur, } @@ -199,7 +199,7 @@ unsafe fn run_dtors() { } any_run = false; #[allow(unused_unsafe)] - let mut cur = unsafe { DTORS.load(SeqCst) }; + let mut cur = unsafe { DTORS.load(Acquire) }; while !cur.is_null() { let ptr = unsafe { get((*cur).key) }; From b45a725cbcac8ff8196d0c4ad5e4c4edc1929591 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Tue, 19 Mar 2024 15:12:38 +0100 Subject: [PATCH 19/27] SeqCst->Relaxed in std::net::test. Relaxed is enough to have fetch_add(1) return each value only once (until it wraps around). --- library/std/src/net/test.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/net/test.rs b/library/std/src/net/test.rs index 37937b5ea9541..d318d457f3569 100644 --- a/library/std/src/net/test.rs +++ b/library/std/src/net/test.rs @@ -7,12 +7,12 @@ use crate::sync::atomic::{AtomicUsize, Ordering}; static PORT: AtomicUsize = AtomicUsize::new(0); pub fn next_test_ip4() -> SocketAddr { - let port = PORT.fetch_add(1, Ordering::SeqCst) as u16 + base_port(); + let port = PORT.fetch_add(1, Ordering::Relaxed) as u16 + base_port(); SocketAddr::V4(SocketAddrV4::new(Ipv4Addr::new(127, 0, 0, 1), port)) } pub fn next_test_ip6() -> SocketAddr { - let port = PORT.fetch_add(1, Ordering::SeqCst) as u16 + base_port(); + let port = PORT.fetch_add(1, Ordering::Relaxed) as u16 + base_port(); SocketAddr::V6(SocketAddrV6::new(Ipv6Addr::new(0, 0, 0, 0, 0, 0, 0, 1), port, 0, 0)) } From acddc55748d16559531965785a175e48530cdecd Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Tue, 19 Mar 2024 15:14:09 +0100 Subject: [PATCH 20/27] SeqCst->Relaxed in thread local test. Relaxed memory ordering is fine because spawn()/join() already provides all the synchronization we need. --- library/std/src/thread/local/tests.rs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/library/std/src/thread/local/tests.rs b/library/std/src/thread/local/tests.rs index 964c7fc5b0ca2..25019b554bb6a 100644 --- a/library/std/src/thread/local/tests.rs +++ b/library/std/src/thread/local/tests.rs @@ -255,6 +255,9 @@ fn join_orders_after_tls_destructors() { // observe the channel in the `THREAD1_WAITING` state. If this does occur, // we switch to the “poison” state `THREAD2_JOINED` and panic all around. // (This is equivalent to “sending” from an alternate producer thread.) + // + // Relaxed memory ordering is fine because and spawn()/join() already provide all the + // synchronization we need here. const FRESH: u8 = 0; const THREAD2_LAUNCHED: u8 = 1; const THREAD1_WAITING: u8 = 2; @@ -263,7 +266,7 @@ fn join_orders_after_tls_destructors() { static SYNC_STATE: AtomicU8 = AtomicU8::new(FRESH); for _ in 0..10 { - SYNC_STATE.store(FRESH, Ordering::SeqCst); + SYNC_STATE.store(FRESH, Ordering::Relaxed); let jh = thread::Builder::new() .name("thread1".into()) @@ -272,7 +275,7 @@ fn join_orders_after_tls_destructors() { impl Drop for TlDrop { fn drop(&mut self) { - let mut sync_state = SYNC_STATE.swap(THREAD1_WAITING, Ordering::SeqCst); + let mut sync_state = SYNC_STATE.swap(THREAD1_WAITING, Ordering::Relaxed); loop { match sync_state { THREAD2_LAUNCHED | THREAD1_WAITING => thread::yield_now(), @@ -282,7 +285,7 @@ fn join_orders_after_tls_destructors() { ), v => unreachable!("sync state: {}", v), } - sync_state = SYNC_STATE.load(Ordering::SeqCst); + sync_state = SYNC_STATE.load(Ordering::Relaxed); } } } @@ -294,7 +297,7 @@ fn join_orders_after_tls_destructors() { TL_DROP.with(|_| {}); loop { - match SYNC_STATE.load(Ordering::SeqCst) { + match SYNC_STATE.load(Ordering::Relaxed) { FRESH => thread::yield_now(), THREAD2_LAUNCHED => break, v => unreachable!("sync state: {}", v), @@ -306,9 +309,9 @@ fn join_orders_after_tls_destructors() { let jh2 = thread::Builder::new() .name("thread2".into()) .spawn(move || { - assert_eq!(SYNC_STATE.swap(THREAD2_LAUNCHED, Ordering::SeqCst), FRESH); + assert_eq!(SYNC_STATE.swap(THREAD2_LAUNCHED, Ordering::Relaxed), FRESH); jh.join().unwrap(); - match SYNC_STATE.swap(THREAD2_JOINED, Ordering::SeqCst) { + match SYNC_STATE.swap(THREAD2_JOINED, Ordering::Relaxed) { MAIN_THREAD_RENDEZVOUS => return, THREAD2_LAUNCHED | THREAD1_WAITING => { panic!("Thread 2 running after thread 1 join before main thread rendezvous") @@ -322,8 +325,8 @@ fn join_orders_after_tls_destructors() { match SYNC_STATE.compare_exchange( THREAD1_WAITING, MAIN_THREAD_RENDEZVOUS, - Ordering::SeqCst, - Ordering::SeqCst, + Ordering::Relaxed, + Ordering::Relaxed, ) { Ok(_) => break, Err(FRESH) => thread::yield_now(), From 34621757ea9437994ef717ac4f1928933a6e1b24 Mon Sep 17 00:00:00 2001 From: Mara Bos Date: Tue, 19 Mar 2024 15:17:40 +0100 Subject: [PATCH 21/27] SeqCst->Relaxed in condvar test. Relaxed is enough here. Synchronization is done by the mutex. --- library/std/src/sync/condvar/tests.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/sync/condvar/tests.rs b/library/std/src/sync/condvar/tests.rs index 24f467f0b03d7..12d13a6b20be3 100644 --- a/library/std/src/sync/condvar/tests.rs +++ b/library/std/src/sync/condvar/tests.rs @@ -170,14 +170,14 @@ fn wait_timeout_wake() { let t = thread::spawn(move || { let _g = m2.lock().unwrap(); thread::sleep(Duration::from_millis(1)); - notified_copy.store(true, Ordering::SeqCst); + notified_copy.store(true, Ordering::Relaxed); c2.notify_one(); }); let (g, timeout_res) = c.wait_timeout(g, Duration::from_millis(u64::MAX)).unwrap(); assert!(!timeout_res.timed_out()); // spurious wakeups mean this isn't necessarily true // so execute test again, if not notified - if !notified.load(Ordering::SeqCst) { + if !notified.load(Ordering::Relaxed) { t.join().unwrap(); continue; } From 98e66553a607ad9cfc492a6def69b404507becf4 Mon Sep 17 00:00:00 2001 From: Guillaume Gomez Date: Wed, 20 Mar 2024 16:47:11 +0100 Subject: [PATCH 22/27] Rename `hir::Let` into `hir::LetExpr` --- compiler/rustc_ast_lowering/src/expr.rs | 2 +- compiler/rustc_hir/src/hir.rs | 4 ++-- compiler/rustc_hir/src/intravisit.rs | 2 +- compiler/rustc_hir_pretty/src/lib.rs | 2 +- compiler/rustc_hir_typeck/src/_match.rs | 2 +- compiler/rustc_hir_typeck/src/expr.rs | 6 +++++- compiler/rustc_hir_typeck/src/expr_use_visitor.rs | 2 +- compiler/rustc_hir_typeck/src/gather_locals.rs | 8 ++++---- .../clippy/clippy_lints/src/pattern_type_mismatch.rs | 4 ++-- src/tools/clippy/clippy_lints/src/shadow.rs | 4 ++-- src/tools/clippy/clippy_lints/src/unused_io_amount.rs | 2 +- src/tools/clippy/clippy_utils/src/higher.rs | 4 ++-- src/tools/clippy/clippy_utils/src/hir_utils.rs | 4 ++-- src/tools/clippy/clippy_utils/src/visitors.rs | 4 ++-- 14 files changed, 27 insertions(+), 23 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 41f7418ddde42..d802dbbcb9e67 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -157,7 +157,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir::ExprKind::AddrOf(*k, *m, ohs) } ExprKind::Let(pat, scrutinee, span, is_recovered) => { - hir::ExprKind::Let(self.arena.alloc(hir::Let { + hir::ExprKind::Let(self.arena.alloc(hir::LetExpr { span: self.lower_span(*span), pat: self.lower_pat(pat), ty: None, diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index ca5d2930e82c4..d0446785e4ed2 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -1259,7 +1259,7 @@ pub struct Arm<'hir> { /// In an `if let`, imagine it as `if (let = ) { ... }`; in a let-else, it is part of /// the desugaring to if-let. Only let-else supports the type annotation at present. #[derive(Debug, Clone, Copy, HashStable_Generic)] -pub struct Let<'hir> { +pub struct LetExpr<'hir> { pub span: Span, pub pat: &'hir Pat<'hir>, pub ty: Option<&'hir Ty<'hir>>, @@ -1852,7 +1852,7 @@ pub enum ExprKind<'hir> { /// /// These are not `Local` and only occur as expressions. /// The `let Some(x) = foo()` in `if let Some(x) = foo()` is an example of `Let(..)`. - Let(&'hir Let<'hir>), + Let(&'hir LetExpr<'hir>), /// An `if` block, with an optional else block. /// /// I.e., `if { } else { }`. diff --git a/compiler/rustc_hir/src/intravisit.rs b/compiler/rustc_hir/src/intravisit.rs index 186bb234a450b..3cf1093eeec72 100644 --- a/compiler/rustc_hir/src/intravisit.rs +++ b/compiler/rustc_hir/src/intravisit.rs @@ -753,7 +753,7 @@ pub fn walk_expr<'v, V: Visitor<'v>>(visitor: &mut V, expression: &'v Expr<'v>) ExprKind::DropTemps(ref subexpression) => { try_visit!(visitor.visit_expr(subexpression)); } - ExprKind::Let(Let { span: _, pat, ty, init, is_recovered: _ }) => { + ExprKind::Let(LetExpr { span: _, pat, ty, init, is_recovered: _ }) => { // match the visit order in walk_local try_visit!(visitor.visit_expr(init)); try_visit!(visitor.visit_pat(pat)); diff --git a/compiler/rustc_hir_pretty/src/lib.rs b/compiler/rustc_hir_pretty/src/lib.rs index 34c245839478f..c7651cf3264a5 100644 --- a/compiler/rustc_hir_pretty/src/lib.rs +++ b/compiler/rustc_hir_pretty/src/lib.rs @@ -1387,7 +1387,7 @@ impl<'a> State<'a> { // Print `}`: self.bclose_maybe_open(expr.span, true); } - hir::ExprKind::Let(&hir::Let { pat, ty, init, .. }) => { + hir::ExprKind::Let(&hir::LetExpr { pat, ty, init, .. }) => { self.print_let(pat, ty, init); } hir::ExprKind::If(test, blk, elseopt) => { diff --git a/compiler/rustc_hir_typeck/src/_match.rs b/compiler/rustc_hir_typeck/src/_match.rs index 4b3359858f15d..b6421a10e133d 100644 --- a/compiler/rustc_hir_typeck/src/_match.rs +++ b/compiler/rustc_hir_typeck/src/_match.rs @@ -317,7 +317,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { err.note("`if` expressions without `else` evaluate to `()`"); err.help("consider adding an `else` block that evaluates to the expected type"); *error = true; - if let ExprKind::Let(hir::Let { span, pat, init, .. }) = cond_expr.kind + if let ExprKind::Let(hir::LetExpr { span, pat, init, .. }) = cond_expr.kind && let ExprKind::Block(block, _) = then_expr.kind // Refutability checks occur on the MIR, so we approximate it here by checking // if we have an enum with a single variant or a struct in the pattern. diff --git a/compiler/rustc_hir_typeck/src/expr.rs b/compiler/rustc_hir_typeck/src/expr.rs index 1a142f27809e1..4c01c201ad238 100644 --- a/compiler/rustc_hir_typeck/src/expr.rs +++ b/compiler/rustc_hir_typeck/src/expr.rs @@ -1261,7 +1261,11 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { } } - pub(super) fn check_expr_let(&self, let_expr: &'tcx hir::Let<'tcx>, hir_id: HirId) -> Ty<'tcx> { + pub(super) fn check_expr_let( + &self, + let_expr: &'tcx hir::LetExpr<'tcx>, + hir_id: HirId, + ) -> Ty<'tcx> { // for let statements, this is done in check_stmt let init = let_expr.init; self.warn_if_unreachable(init.hir_id, init.span, "block in `let` expression"); diff --git a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs index 43e9554459439..2dc355b72f61a 100644 --- a/compiler/rustc_hir_typeck/src/expr_use_visitor.rs +++ b/compiler/rustc_hir_typeck/src/expr_use_visitor.rs @@ -245,7 +245,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> { } } - hir::ExprKind::Let(hir::Let { pat, init, .. }) => { + hir::ExprKind::Let(hir::LetExpr { pat, init, .. }) => { self.walk_local(init, pat, None, |t| t.borrow_expr(init, ty::ImmBorrow)) } diff --git a/compiler/rustc_hir_typeck/src/gather_locals.rs b/compiler/rustc_hir_typeck/src/gather_locals.rs index 4d37f725c9400..6dae1fab6dcde 100644 --- a/compiler/rustc_hir_typeck/src/gather_locals.rs +++ b/compiler/rustc_hir_typeck/src/gather_locals.rs @@ -29,7 +29,7 @@ impl<'a> DeclOrigin<'a> { } } -/// A declaration is an abstraction of [hir::Local] and [hir::Let]. +/// A declaration is an abstraction of [hir::Local] and [hir::LetExpr]. /// /// It must have a hir_id, as this is how we connect gather_locals to the check functions. pub(super) struct Declaration<'a> { @@ -48,9 +48,9 @@ impl<'a> From<&'a hir::Local<'a>> for Declaration<'a> { } } -impl<'a> From<(&'a hir::Let<'a>, hir::HirId)> for Declaration<'a> { - fn from((let_expr, hir_id): (&'a hir::Let<'a>, hir::HirId)) -> Self { - let hir::Let { pat, ty, span, init, is_recovered: _ } = *let_expr; +impl<'a> From<(&'a hir::LetExpr<'a>, hir::HirId)> for Declaration<'a> { + fn from((let_expr, hir_id): (&'a hir::LetExpr<'a>, hir::HirId)) -> Self { + let hir::LetExpr { pat, ty, span, init, is_recovered: _ } = *let_expr; Declaration { hir_id, pat, ty, span, init: Some(init), origin: DeclOrigin::LetExpr } } } diff --git a/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs b/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs index fbca4329342a9..127801de7defa 100644 --- a/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs +++ b/src/tools/clippy/clippy_lints/src/pattern_type_mismatch.rs @@ -1,5 +1,5 @@ use clippy_utils::diagnostics::span_lint_and_help; -use rustc_hir::{intravisit, Body, Expr, ExprKind, FnDecl, Let, LocalSource, Mutability, Pat, PatKind, Stmt, StmtKind}; +use rustc_hir::{intravisit, Body, Expr, ExprKind, FnDecl, LetExpr, LocalSource, Mutability, Pat, PatKind, Stmt, StmtKind}; use rustc_lint::{LateContext, LateLintPass, LintContext}; use rustc_middle::lint::in_external_macro; use rustc_middle::ty; @@ -103,7 +103,7 @@ impl<'tcx> LateLintPass<'tcx> for PatternTypeMismatch { } } } - if let ExprKind::Let(Let { pat, .. }) = expr.kind { + if let ExprKind::Let(LetExpr { pat, .. }) = expr.kind { apply_lint(cx, pat, DerefPossible::Possible); } } diff --git a/src/tools/clippy/clippy_lints/src/shadow.rs b/src/tools/clippy/clippy_lints/src/shadow.rs index c74364d89d61b..df7bd4c8d1d39 100644 --- a/src/tools/clippy/clippy_lints/src/shadow.rs +++ b/src/tools/clippy/clippy_lints/src/shadow.rs @@ -5,7 +5,7 @@ use rustc_data_structures::fx::FxHashMap; use rustc_hir::def::Res; use rustc_hir::def_id::LocalDefId; use rustc_hir::hir_id::ItemLocalId; -use rustc_hir::{Block, Body, BodyOwnerKind, Expr, ExprKind, HirId, Let, Node, Pat, PatKind, QPath, UnOp}; +use rustc_hir::{Block, Body, BodyOwnerKind, Expr, ExprKind, HirId, LetExpr, Node, Pat, PatKind, QPath, UnOp}; use rustc_lint::{LateContext, LateLintPass}; use rustc_session::impl_lint_pass; use rustc_span::{Span, Symbol}; @@ -238,7 +238,7 @@ fn find_init<'tcx>(cx: &LateContext<'tcx>, hir_id: HirId) -> Option<&'tcx Expr<' let init = match node { Node::Arm(_) | Node::Pat(_) => continue, Node::Expr(expr) => match expr.kind { - ExprKind::Match(e, _, _) | ExprKind::Let(&Let { init: e, .. }) => Some(e), + ExprKind::Match(e, _, _) | ExprKind::Let(&LetExpr { init: e, .. }) => Some(e), _ => None, }, Node::Local(local) => local.init, diff --git a/src/tools/clippy/clippy_lints/src/unused_io_amount.rs b/src/tools/clippy/clippy_lints/src/unused_io_amount.rs index eb64dd633f606..1497d883dfc48 100644 --- a/src/tools/clippy/clippy_lints/src/unused_io_amount.rs +++ b/src/tools/clippy/clippy_lints/src/unused_io_amount.rs @@ -131,7 +131,7 @@ fn non_consuming_ok_arm<'a>(cx: &LateContext<'a>, arm: &hir::Arm<'a>) -> bool { fn check_expr<'a>(cx: &LateContext<'a>, expr: &'a hir::Expr<'a>) { match expr.kind { hir::ExprKind::If(cond, _, _) - if let ExprKind::Let(hir::Let { pat, init, .. }) = cond.kind + if let ExprKind::Let(hir::LetExpr { pat, init, .. }) = cond.kind && is_ok_wild_or_dotdot_pattern(cx, pat) && let Some(op) = should_lint(cx, init) => { diff --git a/src/tools/clippy/clippy_utils/src/higher.rs b/src/tools/clippy/clippy_utils/src/higher.rs index ba682813dadf8..8ce19998a0828 100644 --- a/src/tools/clippy/clippy_utils/src/higher.rs +++ b/src/tools/clippy/clippy_utils/src/higher.rs @@ -102,7 +102,7 @@ impl<'hir> IfLet<'hir> { if let ExprKind::If( Expr { kind: - ExprKind::Let(&hir::Let { + ExprKind::Let(&hir::LetExpr { pat: let_pat, init: let_expr, span: let_span, @@ -379,7 +379,7 @@ impl<'hir> WhileLet<'hir> { ExprKind::If( Expr { kind: - ExprKind::Let(&hir::Let { + ExprKind::Let(&hir::LetExpr { pat: let_pat, init: let_expr, span: let_span, diff --git a/src/tools/clippy/clippy_utils/src/hir_utils.rs b/src/tools/clippy/clippy_utils/src/hir_utils.rs index 106d1d0d77f01..162bf24d85d29 100644 --- a/src/tools/clippy/clippy_utils/src/hir_utils.rs +++ b/src/tools/clippy/clippy_utils/src/hir_utils.rs @@ -8,7 +8,7 @@ use rustc_hir::def::Res; use rustc_hir::MatchSource::TryDesugar; use rustc_hir::{ ArrayLen, BinOpKind, BindingAnnotation, Block, BodyId, Closure, Expr, ExprField, ExprKind, FnRetTy, GenericArg, - GenericArgs, HirId, HirIdMap, InlineAsmOperand, Let, Lifetime, LifetimeName, Pat, PatField, PatKind, Path, + GenericArgs, HirId, HirIdMap, InlineAsmOperand, LetExpr, Lifetime, LifetimeName, Pat, PatField, PatKind, Path, PathSegment, PrimTy, QPath, Stmt, StmtKind, Ty, TyKind, TypeBinding, }; use rustc_lexer::{tokenize, TokenKind}; @@ -837,7 +837,7 @@ impl<'a, 'tcx> SpanlessHash<'a, 'tcx> { } } }, - ExprKind::Let(Let { pat, init, ty, .. }) => { + ExprKind::Let(LetExpr { pat, init, ty, .. }) => { self.hash_expr(init); if let Some(ty) = ty { self.hash_ty(ty); diff --git a/src/tools/clippy/clippy_utils/src/visitors.rs b/src/tools/clippy/clippy_utils/src/visitors.rs index ebc38e531fe6e..0a05ac029eae5 100644 --- a/src/tools/clippy/clippy_utils/src/visitors.rs +++ b/src/tools/clippy/clippy_utils/src/visitors.rs @@ -5,7 +5,7 @@ use rustc_hir as hir; use rustc_hir::def::{CtorKind, DefKind, Res}; use rustc_hir::intravisit::{self, walk_block, walk_expr, Visitor}; use rustc_hir::{ - AnonConst, Arm, Block, BlockCheckMode, Body, BodyId, Expr, ExprKind, HirId, ItemId, ItemKind, Let, Pat, QPath, + AnonConst, Arm, Block, BlockCheckMode, Body, BodyId, Expr, ExprKind, HirId, ItemId, ItemKind, LetExpr, Pat, QPath, Stmt, UnOp, UnsafeSource, Unsafety, }; use rustc_lint::LateContext; @@ -624,7 +624,7 @@ pub fn for_each_unconsumed_temporary<'tcx, B>( | ExprKind::Field(e, _) | ExprKind::Unary(UnOp::Deref, e) | ExprKind::Match(e, ..) - | ExprKind::Let(&Let { init: e, .. }) => { + | ExprKind::Let(&LetExpr { init: e, .. }) => { helper(typeck, false, e, f)?; }, ExprKind::Block(&Block { expr: Some(e), .. }, _) | ExprKind::Cast(e, _) | ExprKind::Unary(_, e) => { From a8452461dcfb789e4d4f557bad648016ed2ad954 Mon Sep 17 00:00:00 2001 From: Alex Macleod Date: Fri, 15 Mar 2024 14:00:08 +0000 Subject: [PATCH 23/27] Ignore paths from expansion in `unused_qualifications` --- compiler/rustc_resolve/src/late.rs | 4 +++- tests/ui/lint/lint-qualification.fixed | 1 + tests/ui/lint/lint-qualification.rs | 1 + 3 files changed, 5 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index c661be3587e92..fc0374048294f 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -4672,7 +4672,9 @@ impl<'a: 'ast, 'b, 'ast, 'tcx> LateResolutionVisitor<'a, 'b, 'ast, 'tcx> { return; } - if path.iter().any(|seg| seg.ident.span.from_expansion()) { + if finalize.path_span.from_expansion() + || path.iter().any(|seg| seg.ident.span.from_expansion()) + { return; } diff --git a/tests/ui/lint/lint-qualification.fixed b/tests/ui/lint/lint-qualification.fixed index 2070bbcef5269..7c8fd5236e608 100644 --- a/tests/ui/lint/lint-qualification.fixed +++ b/tests/ui/lint/lint-qualification.fixed @@ -35,6 +35,7 @@ fn main() { foo::bar(); foo::$b(); // issue #96698 $a::bar(); + $a::$b(); } } m!(foo, bar); } diff --git a/tests/ui/lint/lint-qualification.rs b/tests/ui/lint/lint-qualification.rs index 41b7e17c6ed45..009b3080d5c79 100644 --- a/tests/ui/lint/lint-qualification.rs +++ b/tests/ui/lint/lint-qualification.rs @@ -35,6 +35,7 @@ fn main() { foo::bar(); foo::$b(); // issue #96698 $a::bar(); + $a::$b(); } } m!(foo, bar); } From 19e0ea4a6d4266eeae6fc05c42b2e4ba78e19b6b Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Tue, 19 Mar 2024 20:58:37 +0000 Subject: [PATCH 24/27] make `type_flags(ReError) & HAS_ERROR` --- .../src/region_infer/opaque_types.rs | 4 - compiler/rustc_middle/src/ty/region.rs | 1 + compiler/rustc_type_ir/src/flags.rs | 2 +- .../in-trait/return-not-existing-pair.rs | 3 +- .../in-trait/return-not-existing-pair.stderr | 15 +- .../in-trait/unconstrained-impl-region.rs | 1 + .../in-trait/unconstrained-impl-region.stderr | 21 +- .../late-bound-in-return-issue-77357.stderr | 43 +--- tests/ui/error-codes/E0637.rs | 4 +- tests/ui/error-codes/E0637.stderr | 20 +- .../generic-associated-types/issue-80433.rs | 2 +- .../issue-80433.stderr | 17 +- tests/ui/impl-trait/impl-fn-hrtb-bounds.rs | 3 - .../ui/impl-trait/impl-fn-hrtb-bounds.stderr | 39 +-- .../impl-trait/impl-fn-parsing-ambiguities.rs | 1 - .../impl-fn-parsing-ambiguities.stderr | 13 +- tests/ui/impl-trait/nested-rpit-hrtb.rs | 2 - tests/ui/impl-trait/nested-rpit-hrtb.stderr | 36 +-- tests/ui/inference/issue-107090.rs | 2 +- tests/ui/inference/issue-107090.stderr | 17 +- tests/ui/issues/issue-10412.rs | 1 - tests/ui/issues/issue-10412.stderr | 26 +- .../could-not-resolve-issue-121503.rs | 3 +- .../could-not-resolve-issue-121503.stderr | 18 +- tests/ui/lifetimes/issue-26638.rs | 1 - tests/ui/lifetimes/issue-26638.stderr | 25 +- .../ex1b-return-no-names-if-else.rs | 2 - .../ex1b-return-no-names-if-else.stderr | 18 +- .../region-error-ice-109072.rs | 1 + .../region-error-ice-109072.stderr | 11 +- ...lifetime-default-dyn-binding-nonstatic3.rs | 1 - ...time-default-dyn-binding-nonstatic3.stderr | 18 +- tests/ui/suggestions/issue-86667.rs | 2 - tests/ui/suggestions/issue-86667.stderr | 22 +- .../suggestions/missing-lifetime-specifier.rs | 10 - .../missing-lifetime-specifier.stderr | 228 +----------------- tests/ui/traits/span-bug-issue-121414.rs | 3 +- tests/ui/traits/span-bug-issue-121414.stderr | 21 +- .../escaping-bound-var.rs | 1 + .../escaping-bound-var.stderr | 10 +- tests/ui/typeck/escaping_bound_vars.rs | 3 - tests/ui/typeck/escaping_bound_vars.stderr | 47 +--- .../unboxed-closure-sugar-region.rs | 1 - .../unboxed-closure-sugar-region.stderr | 20 +- .../underscore-lifetime-binders.rs | 1 - .../underscore-lifetime-binders.stderr | 10 +- .../wf/wf-in-foreign-fn-decls-issue-80468.rs | 1 + .../wf-in-foreign-fn-decls-issue-80468.stderr | 17 +- 48 files changed, 140 insertions(+), 628 deletions(-) diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs index bea9be240283f..193b6d3e3d97a 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types.rs @@ -434,10 +434,6 @@ fn check_opaque_type_parameter_valid( // Only check the parent generics, which will ignore any of the // duplicated lifetime args that come from reifying late-bounds. for (i, arg) in opaque_type_key.args.iter().take(parent_generics.count()).enumerate() { - if let Err(guar) = arg.error_reported() { - return Err(guar); - } - let arg_is_param = match arg.unpack() { GenericArgKind::Type(ty) => matches!(ty.kind(), ty::Param(_)), GenericArgKind::Lifetime(lt) if is_ty_alias => { diff --git a/compiler/rustc_middle/src/ty/region.rs b/compiler/rustc_middle/src/ty/region.rs index d21f0e6385c59..c66b9864e4623 100644 --- a/compiler/rustc_middle/src/ty/region.rs +++ b/compiler/rustc_middle/src/ty/region.rs @@ -251,6 +251,7 @@ impl<'tcx> Region<'tcx> { } ty::ReError(_) => { flags = flags | TypeFlags::HAS_FREE_REGIONS; + flags = flags | TypeFlags::HAS_ERROR; } } diff --git a/compiler/rustc_type_ir/src/flags.rs b/compiler/rustc_type_ir/src/flags.rs index b38ef2ad84d48..cd199222d900a 100644 --- a/compiler/rustc_type_ir/src/flags.rs +++ b/compiler/rustc_type_ir/src/flags.rs @@ -85,7 +85,7 @@ bitflags! { | TypeFlags::HAS_TY_INHERENT.bits() | TypeFlags::HAS_CT_PROJECTION.bits(); - /// Is an error type/const reachable? + /// Is an error type/lifetime/const reachable? const HAS_ERROR = 1 << 15; /// Does this have any region that "appears free" in the type? diff --git a/tests/ui/async-await/in-trait/return-not-existing-pair.rs b/tests/ui/async-await/in-trait/return-not-existing-pair.rs index 68be1358f812b..3889efe1f2a3c 100644 --- a/tests/ui/async-await/in-trait/return-not-existing-pair.rs +++ b/tests/ui/async-await/in-trait/return-not-existing-pair.rs @@ -9,8 +9,7 @@ trait MyTrait<'a, 'b, T> { impl<'a, 'b, T, U> MyTrait for U { //~^ ERROR: implicit elided lifetime not allowed here [E0726] async fn foo(_: T) -> (&'a U, &'b T) {} - //~^ ERROR: method `foo` has a `&self` declaration in the trait, but not in the impl [E0186] - //~| ERROR: mismatched types [E0308] + //~^ ERROR: mismatched types [E0308] } fn main() {} diff --git a/tests/ui/async-await/in-trait/return-not-existing-pair.stderr b/tests/ui/async-await/in-trait/return-not-existing-pair.stderr index 4694e608097e2..13d3606abba78 100644 --- a/tests/ui/async-await/in-trait/return-not-existing-pair.stderr +++ b/tests/ui/async-await/in-trait/return-not-existing-pair.stderr @@ -15,15 +15,6 @@ error[E0412]: cannot find type `ConnImpl` in this scope LL | async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T); | ^^^^^^^^ not found in this scope -error[E0186]: method `foo` has a `&self` declaration in the trait, but not in the impl - --> $DIR/return-not-existing-pair.rs:11:5 - | -LL | async fn foo(&'a self, key: &'b T) -> (&'a ConnImpl, &'b T); - | ------------------------------------------------------------ `&self` used in trait -... -LL | async fn foo(_: T) -> (&'a U, &'b T) {} - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `&self` in impl - error[E0308]: mismatched types --> $DIR/return-not-existing-pair.rs:11:42 | @@ -33,7 +24,7 @@ LL | async fn foo(_: T) -> (&'a U, &'b T) {} = note: expected tuple `(&'a U, &'b T)` found unit type `()` -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0186, E0308, E0412, E0726. -For more information about an error, try `rustc --explain E0186`. +Some errors have detailed explanations: E0308, E0412, E0726. +For more information about an error, try `rustc --explain E0308`. diff --git a/tests/ui/async-await/in-trait/unconstrained-impl-region.rs b/tests/ui/async-await/in-trait/unconstrained-impl-region.rs index 9382c2323643b..95ba1f3f27708 100644 --- a/tests/ui/async-await/in-trait/unconstrained-impl-region.rs +++ b/tests/ui/async-await/in-trait/unconstrained-impl-region.rs @@ -14,6 +14,7 @@ impl<'a> Actor for () { //~^ ERROR the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates type Message = &'a (); async fn on_mount(self, _: impl Inbox<&'a ()>) {} + //~^ ERROR the trait bound `impl Inbox<&'a ()>: Inbox<&'a ()>` is not satisfied } fn main() {} diff --git a/tests/ui/async-await/in-trait/unconstrained-impl-region.stderr b/tests/ui/async-await/in-trait/unconstrained-impl-region.stderr index ef7e4ef0eb85f..66819d1fcf7db 100644 --- a/tests/ui/async-await/in-trait/unconstrained-impl-region.stderr +++ b/tests/ui/async-await/in-trait/unconstrained-impl-region.stderr @@ -1,9 +1,26 @@ +error[E0277]: the trait bound `impl Inbox<&'a ()>: Inbox<&'a ()>` is not satisfied + --> $DIR/unconstrained-impl-region.rs:16:5 + | +LL | async fn on_mount(self, _: impl Inbox<&'a ()>) {} + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Inbox<&'a ()>` is not implemented for `impl Inbox<&'a ()>` + | +note: required by a bound in `<() as Actor>::on_mount` + --> $DIR/unconstrained-impl-region.rs:16:37 + | +LL | async fn on_mount(self, _: impl Inbox<&'a ()>) {} + | ^^^^^^^^^^^^^ required by this bound in `<() as Actor>::on_mount` +help: consider further restricting this bound + | +LL | async fn on_mount(self, _: impl Inbox<&'a ()> + Inbox<&'a ()>) {} + | +++++++++++++++ + error[E0207]: the lifetime parameter `'a` is not constrained by the impl trait, self type, or predicates --> $DIR/unconstrained-impl-region.rs:13:6 | LL | impl<'a> Actor for () { | ^^ unconstrained lifetime parameter -error: aborting due to 1 previous error +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0207`. +Some errors have detailed explanations: E0207, E0277. +For more information about an error, try `rustc --explain E0207`. diff --git a/tests/ui/const-generics/late-bound-vars/late-bound-in-return-issue-77357.stderr b/tests/ui/const-generics/late-bound-vars/late-bound-in-return-issue-77357.stderr index e42bb6e8cc561..7bef98b1d5d2f 100644 --- a/tests/ui/const-generics/late-bound-vars/late-bound-in-return-issue-77357.stderr +++ b/tests/ui/const-generics/late-bound-vars/late-bound-in-return-issue-77357.stderr @@ -4,46 +4,5 @@ error: cannot capture late-bound lifetime in constant LL | fn bug<'a, T>() -> &'static dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]> { | -- lifetime defined here ^^ -error: overly complex generic constant - --> $DIR/late-bound-in-return-issue-77357.rs:9:46 - | -LL | fn bug<'a, T>() -> &'static dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ blocks are not supported in generic constants - | - = help: consider moving this anonymous constant into a `const` function - = note: this operation may be supported in the future - -error[E0391]: cycle detected when evaluating type-level constant - --> $DIR/late-bound-in-return-issue-77357.rs:9:46 - | -LL | fn bug<'a, T>() -> &'static dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - | -note: ...which requires const-evaluating + checking `bug::{constant#0}`... - --> $DIR/late-bound-in-return-issue-77357.rs:9:46 - | -LL | fn bug<'a, T>() -> &'static dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires caching mir of `bug::{constant#0}` for CTFE... - --> $DIR/late-bound-in-return-issue-77357.rs:9:46 - | -LL | fn bug<'a, T>() -> &'static dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires elaborating drops for `bug::{constant#0}`... - --> $DIR/late-bound-in-return-issue-77357.rs:9:46 - | -LL | fn bug<'a, T>() -> &'static dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ -note: ...which requires borrow-checking `bug::{constant#0}`... - --> $DIR/late-bound-in-return-issue-77357.rs:9:46 - | -LL | fn bug<'a, T>() -> &'static dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]> { - | ^^^^^^^^^^^^^^^^^^^^^^^^^ - = note: ...which requires normalizing `Binder { value: ConstEvaluatable(UnevaluatedConst { def: DefId(0:8 ~ late_bound_in_return_issue_77357[9394]::bug::{constant#0}), args: [T/#0] }: usize), bound_vars: [] }`... - = note: ...which again requires evaluating type-level constant, completing the cycle - = note: cycle used when normalizing `&dyn MyTrait<[(); { |x: &'a u32| { x }; 4 }]>` - = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error -For more information about this error, try `rustc --explain E0391`. diff --git a/tests/ui/error-codes/E0637.rs b/tests/ui/error-codes/E0637.rs index e107ea9521b62..382ce3ed01f34 100644 --- a/tests/ui/error-codes/E0637.rs +++ b/tests/ui/error-codes/E0637.rs @@ -2,9 +2,9 @@ fn underscore_lifetime<'_>(str1: &'_ str, str2: &'_ str) -> &'_ str { //~^ ERROR: `'_` cannot be used here [E0637] //~| ERROR: missing lifetime specifier if str1.len() > str2.len() { - str1 //~ ERROR: lifetime may not live long enough + str1 } else { - str2 //~ ERROR: lifetime may not live long enough + str2 } } diff --git a/tests/ui/error-codes/E0637.stderr b/tests/ui/error-codes/E0637.stderr index 217881b8e7c0e..d9db89ddb0c97 100644 --- a/tests/ui/error-codes/E0637.stderr +++ b/tests/ui/error-codes/E0637.stderr @@ -27,25 +27,7 @@ help: consider introducing a higher-ranked lifetime here LL | T: for<'a> Into<&'a u32>, | +++++++ ++ -error: lifetime may not live long enough - --> $DIR/E0637.rs:5:9 - | -LL | fn underscore_lifetime<'_>(str1: &'_ str, str2: &'_ str) -> &'_ str { - | - let's call the lifetime of this reference `'1` -... -LL | str1 - | ^^^^ returning this value requires that `'1` must outlive `'static` - -error: lifetime may not live long enough - --> $DIR/E0637.rs:7:9 - | -LL | fn underscore_lifetime<'_>(str1: &'_ str, str2: &'_ str) -> &'_ str { - | - let's call the lifetime of this reference `'2` -... -LL | str2 - | ^^^^ returning this value requires that `'2` must outlive `'static` - -error: aborting due to 5 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0106, E0637. For more information about an error, try `rustc --explain E0106`. diff --git a/tests/ui/generic-associated-types/issue-80433.rs b/tests/ui/generic-associated-types/issue-80433.rs index 6d23427f16f8c..5305754244025 100644 --- a/tests/ui/generic-associated-types/issue-80433.rs +++ b/tests/ui/generic-associated-types/issue-80433.rs @@ -29,5 +29,5 @@ fn test_simpler<'a>(dst: &'a mut impl TestMut) fn main() { let mut t1: E = Default::default(); - test_simpler(&mut t1); //~ ERROR does not live long enough + test_simpler(&mut t1); } diff --git a/tests/ui/generic-associated-types/issue-80433.stderr b/tests/ui/generic-associated-types/issue-80433.stderr index 1ca080f5df26b..a9a14d3f51ced 100644 --- a/tests/ui/generic-associated-types/issue-80433.stderr +++ b/tests/ui/generic-associated-types/issue-80433.stderr @@ -48,20 +48,7 @@ LL | *dst.test_mut() = n.into(); | `dst` escapes the function body here | argument requires that `'a` must outlive `'static` -error[E0597]: `t1` does not live long enough - --> $DIR/issue-80433.rs:32:18 - | -LL | let mut t1: E = Default::default(); - | ------ binding `t1` declared here -LL | test_simpler(&mut t1); - | -------------^^^^^^^- - | | | - | | borrowed value does not live long enough - | argument requires that `t1` is borrowed for `'static` -LL | } - | - `t1` dropped here while still borrowed - -error: aborting due to 5 previous errors +error: aborting due to 4 previous errors -Some errors have detailed explanations: E0107, E0499, E0521, E0597. +Some errors have detailed explanations: E0107, E0499, E0521. For more information about an error, try `rustc --explain E0107`. diff --git a/tests/ui/impl-trait/impl-fn-hrtb-bounds.rs b/tests/ui/impl-trait/impl-fn-hrtb-bounds.rs index a9ea657f10e2c..da7530b4e7a8c 100644 --- a/tests/ui/impl-trait/impl-fn-hrtb-bounds.rs +++ b/tests/ui/impl-trait/impl-fn-hrtb-bounds.rs @@ -4,19 +4,16 @@ use std::fmt::Debug; fn a() -> impl Fn(&u8) -> (impl Debug + '_) { //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` |x| x - //~^ ERROR lifetime may not live long enough } fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) { //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` |x| x - //~^ ERROR lifetime may not live long enough } fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) { //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` |x| x - //~^ ERROR lifetime may not live long enough } fn d() -> impl Fn() -> (impl Debug + '_) { diff --git a/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr b/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr index bdb099619b76f..7d108b30b76ed 100644 --- a/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr +++ b/tests/ui/impl-trait/impl-fn-hrtb-bounds.stderr @@ -1,5 +1,5 @@ error[E0106]: missing lifetime specifier - --> $DIR/impl-fn-hrtb-bounds.rs:22:38 + --> $DIR/impl-fn-hrtb-bounds.rs:19:38 | LL | fn d() -> impl Fn() -> (impl Debug + '_) { | ^^ expected named lifetime parameter @@ -22,58 +22,31 @@ note: lifetime declared here LL | fn a() -> impl Fn(&u8) -> (impl Debug + '_) { | ^ -error: lifetime may not live long enough - --> $DIR/impl-fn-hrtb-bounds.rs:6:9 - | -LL | |x| x - | -- ^ returning this value requires that `'1` must outlive `'2` - | || - | |return type of closure is impl Debug + '2 - | has type `&'1 u8` - error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/impl-fn-hrtb-bounds.rs:10:52 + --> $DIR/impl-fn-hrtb-bounds.rs:9:52 | LL | fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) { | ^^ | note: lifetime declared here - --> $DIR/impl-fn-hrtb-bounds.rs:10:20 + --> $DIR/impl-fn-hrtb-bounds.rs:9:20 | LL | fn b() -> impl for<'a> Fn(&'a u8) -> (impl Debug + 'a) { | ^^ -error: lifetime may not live long enough - --> $DIR/impl-fn-hrtb-bounds.rs:12:9 - | -LL | |x| x - | -- ^ returning this value requires that `'1` must outlive `'2` - | || - | |return type of closure is impl Debug + '2 - | has type `&'1 u8` - error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/impl-fn-hrtb-bounds.rs:16:52 + --> $DIR/impl-fn-hrtb-bounds.rs:14:52 | LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) { | ^^ | note: lifetime declared here - --> $DIR/impl-fn-hrtb-bounds.rs:16:20 + --> $DIR/impl-fn-hrtb-bounds.rs:14:20 | LL | fn c() -> impl for<'a> Fn(&'a u8) -> (impl Debug + '_) { | ^^ -error: lifetime may not live long enough - --> $DIR/impl-fn-hrtb-bounds.rs:18:9 - | -LL | |x| x - | -- ^ returning this value requires that `'1` must outlive `'2` - | || - | |return type of closure is impl Debug + '2 - | has type `&'1 u8` - -error: aborting due to 7 previous errors +error: aborting due to 4 previous errors Some errors have detailed explanations: E0106, E0657. For more information about an error, try `rustc --explain E0106`. diff --git a/tests/ui/impl-trait/impl-fn-parsing-ambiguities.rs b/tests/ui/impl-trait/impl-fn-parsing-ambiguities.rs index ef9d87335097f..7679b7ec478f9 100644 --- a/tests/ui/impl-trait/impl-fn-parsing-ambiguities.rs +++ b/tests/ui/impl-trait/impl-fn-parsing-ambiguities.rs @@ -5,7 +5,6 @@ fn a() -> impl Fn(&u8) -> impl Debug + '_ { //~^ ERROR ambiguous `+` in a type //~| ERROR cannot capture higher-ranked lifetime from outer `impl Trait` |x| x - //~^ ERROR lifetime may not live long enough } fn b() -> impl Fn() -> impl Debug + Send { diff --git a/tests/ui/impl-trait/impl-fn-parsing-ambiguities.stderr b/tests/ui/impl-trait/impl-fn-parsing-ambiguities.stderr index 3881b37a0cbf4..e0955faac7ca0 100644 --- a/tests/ui/impl-trait/impl-fn-parsing-ambiguities.stderr +++ b/tests/ui/impl-trait/impl-fn-parsing-ambiguities.stderr @@ -5,7 +5,7 @@ LL | fn a() -> impl Fn(&u8) -> impl Debug + '_ { | ^^^^^^^^^^^^^^^ help: use parentheses to disambiguate: `(impl Debug + '_)` error: ambiguous `+` in a type - --> $DIR/impl-fn-parsing-ambiguities.rs:11:24 + --> $DIR/impl-fn-parsing-ambiguities.rs:10:24 | LL | fn b() -> impl Fn() -> impl Debug + Send { | ^^^^^^^^^^^^^^^^^ help: use parentheses to disambiguate: `(impl Debug + Send)` @@ -22,15 +22,6 @@ note: lifetime declared here LL | fn a() -> impl Fn(&u8) -> impl Debug + '_ { | ^ -error: lifetime may not live long enough - --> $DIR/impl-fn-parsing-ambiguities.rs:7:9 - | -LL | |x| x - | -- ^ returning this value requires that `'1` must outlive `'2` - | || - | |return type of closure is impl Debug + '2 - | has type `&'1 u8` - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0657`. diff --git a/tests/ui/impl-trait/nested-rpit-hrtb.rs b/tests/ui/impl-trait/nested-rpit-hrtb.rs index c10bfbfe4dc1a..aa9aa011f61ab 100644 --- a/tests/ui/impl-trait/nested-rpit-hrtb.rs +++ b/tests/ui/impl-trait/nested-rpit-hrtb.rs @@ -31,11 +31,9 @@ fn one_hrtb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl Qux<'a>> {} fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {} //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` -//~| ERROR implementation of `Bar` is not general enough fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {} //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` -//~| ERROR: the trait bound `for<'a> &'a (): Qux<'_>` is not satisfied // This should resolve. fn one_hrtb_mention_fn_trait_param<'b>() -> impl for<'a> Foo<'a, Assoc = impl Qux<'b>> {} diff --git a/tests/ui/impl-trait/nested-rpit-hrtb.stderr b/tests/ui/impl-trait/nested-rpit-hrtb.stderr index 2779694a51711..b6fa81a23afcb 100644 --- a/tests/ui/impl-trait/nested-rpit-hrtb.stderr +++ b/tests/ui/impl-trait/nested-rpit-hrtb.stderr @@ -1,5 +1,5 @@ error[E0261]: use of undeclared lifetime name `'b` - --> $DIR/nested-rpit-hrtb.rs:58:77 + --> $DIR/nested-rpit-hrtb.rs:56:77 | LL | fn two_htrb_outlives() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Sized + 'b> {} | ^^ undeclared lifetime @@ -15,7 +15,7 @@ LL | fn two_htrb_outlives<'b>() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Siz | ++++ error[E0261]: use of undeclared lifetime name `'b` - --> $DIR/nested-rpit-hrtb.rs:66:82 + --> $DIR/nested-rpit-hrtb.rs:64:82 | LL | fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {} | ^^ undeclared lifetime @@ -65,38 +65,20 @@ note: lifetime declared here LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {} | ^^ -error: implementation of `Bar` is not general enough - --> $DIR/nested-rpit-hrtb.rs:32:78 - | -LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {} - | ^^ implementation of `Bar` is not general enough - | - = note: `()` must implement `Bar<'a>` - = note: ...but it actually implements `Bar<'0>`, for some specific lifetime `'0` - error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/nested-rpit-hrtb.rs:36:73 + --> $DIR/nested-rpit-hrtb.rs:35:73 | LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {} | ^^ | note: lifetime declared here - --> $DIR/nested-rpit-hrtb.rs:36:44 + --> $DIR/nested-rpit-hrtb.rs:35:44 | LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {} | ^^ -error[E0277]: the trait bound `for<'a> &'a (): Qux<'_>` is not satisfied - --> $DIR/nested-rpit-hrtb.rs:36:64 - | -LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {} - | ^^^^^^^^^^^^ the trait `for<'a> Qux<'_>` is not implemented for `&'a ()` - | - = help: the trait `Qux<'_>` is implemented for `()` - = help: for that trait implementation, expected `()`, found `&'a ()` - error[E0277]: the trait bound `for<'a> &'a (): Qux<'b>` is not satisfied - --> $DIR/nested-rpit-hrtb.rs:47:79 + --> $DIR/nested-rpit-hrtb.rs:45:79 | LL | fn one_hrtb_mention_fn_trait_param_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Qux<'b>> {} | ^^^^^^^^^^^^ the trait `for<'a> Qux<'b>` is not implemented for `&'a ()` @@ -105,7 +87,7 @@ LL | fn one_hrtb_mention_fn_trait_param_uses<'b>() -> impl for<'a> Bar<'a, Assoc = help: for that trait implementation, expected `()`, found `&'a ()` error: implementation of `Bar` is not general enough - --> $DIR/nested-rpit-hrtb.rs:51:93 + --> $DIR/nested-rpit-hrtb.rs:49:93 | LL | fn one_hrtb_mention_fn_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'b> {} | ^^ implementation of `Bar` is not general enough @@ -114,7 +96,7 @@ LL | fn one_hrtb_mention_fn_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = = note: ...but it actually implements `Bar<'0>`, for some specific lifetime `'0` error[E0277]: the trait bound `for<'a, 'b> &'a (): Qux<'b>` is not satisfied - --> $DIR/nested-rpit-hrtb.rs:62:64 + --> $DIR/nested-rpit-hrtb.rs:60:64 | LL | fn two_htrb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Qux<'b>> {} | ^^^^^^^^^^^^^^^^^^^^ the trait `for<'a, 'b> Qux<'b>` is not implemented for `&'a ()` @@ -123,7 +105,7 @@ LL | fn two_htrb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> = help: for that trait implementation, expected `()`, found `&'a ()` error: implementation of `Bar` is not general enough - --> $DIR/nested-rpit-hrtb.rs:66:86 + --> $DIR/nested-rpit-hrtb.rs:64:86 | LL | fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {} | ^^ implementation of `Bar` is not general enough @@ -131,7 +113,7 @@ LL | fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Si = note: `()` must implement `Bar<'a>` = note: ...but it actually implements `Bar<'0>`, for some specific lifetime `'0` -error: aborting due to 12 previous errors +error: aborting due to 10 previous errors Some errors have detailed explanations: E0261, E0277, E0657. For more information about an error, try `rustc --explain E0261`. diff --git a/tests/ui/inference/issue-107090.rs b/tests/ui/inference/issue-107090.rs index d1c86fb03d78e..799c3641833b6 100644 --- a/tests/ui/inference/issue-107090.rs +++ b/tests/ui/inference/issue-107090.rs @@ -19,7 +19,7 @@ impl<'long: 'short, 'short, T> Convert<'long, 'b> for Foo<'short, 'out, T> { fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ Foo<'short, 'out, T>) -> &'out T { //~^ ERROR use of undeclared lifetime name - sadness.cast() //~ ERROR: mismatched types + sadness.cast() } fn main() {} diff --git a/tests/ui/inference/issue-107090.stderr b/tests/ui/inference/issue-107090.stderr index 55825f7765bb4..e509e262fb1bd 100644 --- a/tests/ui/inference/issue-107090.stderr +++ b/tests/ui/inference/issue-107090.stderr @@ -66,19 +66,6 @@ LL | fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ Foo<'short, | | | help: consider introducing lifetime `'short` here: `'short,` -error[E0308]: mismatched types - --> $DIR/issue-107090.rs:22:5 - | -LL | fn badboi<'in_, 'out, T>(x: Foo<'in_, 'out, T>, sadness: &'in_ Foo<'short, 'out, T>) -> &'out T { - | - expected this type parameter ------- expected `&'out T` because of return type -LL | -LL | sadness.cast() - | ^^^^^^^^^^^^^^ expected `&T`, found `&Foo<'_, '_, T>` - | - = note: expected reference `&'out T` - found reference `&Foo<'_, '_, T>` - -error: aborting due to 7 previous errors +error: aborting due to 6 previous errors -Some errors have detailed explanations: E0261, E0308. -For more information about an error, try `rustc --explain E0261`. +For more information about this error, try `rustc --explain E0261`. diff --git a/tests/ui/issues/issue-10412.rs b/tests/ui/issues/issue-10412.rs index 0de170161b514..68ce0c2ea3cb7 100644 --- a/tests/ui/issues/issue-10412.rs +++ b/tests/ui/issues/issue-10412.rs @@ -8,7 +8,6 @@ impl<'self> Serializable for &'self str { //~^ ERROR lifetimes cannot use keyword names //~| ERROR lifetimes cannot use keyword names //~| ERROR implicit elided lifetime not allowed here - //~| ERROR the size for values of type `str` cannot be known at compilation time [E0277] fn serialize(val: &'self str) -> Vec { //~^ ERROR lifetimes cannot use keyword names vec![1] diff --git a/tests/ui/issues/issue-10412.stderr b/tests/ui/issues/issue-10412.stderr index 02a26034f9aa7..c74ba1306cc48 100644 --- a/tests/ui/issues/issue-10412.stderr +++ b/tests/ui/issues/issue-10412.stderr @@ -29,13 +29,13 @@ LL | impl<'self> Serializable for &'self str { | ^^^^^ error: lifetimes cannot use keyword names - --> $DIR/issue-10412.rs:12:24 + --> $DIR/issue-10412.rs:11:24 | LL | fn serialize(val: &'self str) -> Vec { | ^^^^^ error: lifetimes cannot use keyword names - --> $DIR/issue-10412.rs:16:37 + --> $DIR/issue-10412.rs:15:37 | LL | fn deserialize(repr: &[u8]) -> &'self str { | ^^^^^ @@ -51,24 +51,6 @@ help: indicate the anonymous lifetime LL | impl<'self> Serializable<'_, str> for &'self str { | +++ -error[E0277]: the size for values of type `str` cannot be known at compilation time - --> $DIR/issue-10412.rs:7:13 - | -LL | impl<'self> Serializable for &'self str { - | ^^^^^^^^^^^^^^^^^ doesn't have a size known at compile-time - | - = help: the trait `Sized` is not implemented for `str` -note: required by an implicit `Sized` bound in `Serializable` - --> $DIR/issue-10412.rs:1:27 - | -LL | trait Serializable<'self, T> { - | ^ required by the implicit `Sized` requirement on this type parameter in `Serializable` -help: consider relaxing the implicit `Sized` restriction - | -LL | trait Serializable<'self, T: ?Sized> { - | ++++++++ - -error: aborting due to 9 previous errors +error: aborting due to 8 previous errors -Some errors have detailed explanations: E0277, E0726. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0726`. diff --git a/tests/ui/lifetimes/could-not-resolve-issue-121503.rs b/tests/ui/lifetimes/could-not-resolve-issue-121503.rs index 6bc70a907d9e9..363162370f21b 100644 --- a/tests/ui/lifetimes/could-not-resolve-issue-121503.rs +++ b/tests/ui/lifetimes/could-not-resolve-issue-121503.rs @@ -4,8 +4,7 @@ struct Struct; impl Struct { async fn box_ref_Struct(self: Box) -> &u32 { - //~^ ERROR the trait bound `impl FnMut(&mut Self): Allocator` is not satisfied - //~| ERROR Box` cannot be used as the type of `self` without + //~^ ERROR Box` cannot be used as the type of `self` without &1 } } diff --git a/tests/ui/lifetimes/could-not-resolve-issue-121503.stderr b/tests/ui/lifetimes/could-not-resolve-issue-121503.stderr index a5d8239a2df05..3babf63347c35 100644 --- a/tests/ui/lifetimes/could-not-resolve-issue-121503.stderr +++ b/tests/ui/lifetimes/could-not-resolve-issue-121503.stderr @@ -1,16 +1,3 @@ -error[E0277]: the trait bound `impl FnMut(&mut Self): Allocator` is not satisfied - --> $DIR/could-not-resolve-issue-121503.rs:6:5 - | -LL | async fn box_ref_Struct(self: Box) -> &u32 { - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ the trait `Allocator` is not implemented for `impl FnMut(&mut Self)` - | -note: required by a bound in `Box` - --> $SRC_DIR/alloc/src/boxed.rs:LL:COL -help: consider further restricting this bound - | -LL | async fn box_ref_Struct(self: Box) -> &u32 { - | +++++++++++++++++++++++ - error[E0658]: `Box` cannot be used as the type of `self` without the `arbitrary_self_types` feature --> $DIR/could-not-resolve-issue-121503.rs:6:35 | @@ -22,7 +9,6 @@ LL | async fn box_ref_Struct(self: Box) -> &u32 = note: this compiler was built on YYYY-MM-DD; consider upgrading it if it is out of date = help: consider changing to `self`, `&self`, `&mut self`, `self: Box`, `self: Rc`, `self: Arc`, or `self: Pin

` (where P is one of the previous types except `Self`) -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0277, E0658. -For more information about an error, try `rustc --explain E0277`. +For more information about this error, try `rustc --explain E0658`. diff --git a/tests/ui/lifetimes/issue-26638.rs b/tests/ui/lifetimes/issue-26638.rs index 4bec3b3415bbc..11c730165f228 100644 --- a/tests/ui/lifetimes/issue-26638.rs +++ b/tests/ui/lifetimes/issue-26638.rs @@ -1,6 +1,5 @@ fn parse_type(iter: Box+'static>) -> &str { iter.next() } //~^ ERROR missing lifetime specifier [E0106] -//~| ERROR mismatched types fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() } //~^ ERROR missing lifetime specifier [E0106] diff --git a/tests/ui/lifetimes/issue-26638.stderr b/tests/ui/lifetimes/issue-26638.stderr index ee958686259aa..403a8c67ccb34 100644 --- a/tests/ui/lifetimes/issue-26638.stderr +++ b/tests/ui/lifetimes/issue-26638.stderr @@ -11,7 +11,7 @@ LL | fn parse_type<'a>(iter: Box+'static>) -> &'a str | ++++ ++ ++ error[E0106]: missing lifetime specifier - --> $DIR/issue-26638.rs:5:40 + --> $DIR/issue-26638.rs:4:40 | LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() } | ^ expected named lifetime parameter @@ -31,7 +31,7 @@ LL | fn parse_type_2(iter: fn(&u8)->&u8) -> String { iter() } | ~~~~~~ error[E0106]: missing lifetime specifier - --> $DIR/issue-26638.rs:10:22 + --> $DIR/issue-26638.rs:9:22 | LL | fn parse_type_3() -> &str { unimplemented!() } | ^ expected named lifetime parameter @@ -46,23 +46,8 @@ help: instead, you are more likely to want to return an owned value LL | fn parse_type_3() -> String { unimplemented!() } | ~~~~~~ -error[E0308]: mismatched types - --> $DIR/issue-26638.rs:1:69 - | -LL | fn parse_type(iter: Box+'static>) -> &str { iter.next() } - | ---- ^^^^^^^^^^^ expected `&str`, found `Option<&str>` - | | - | expected `&str` because of return type - | - = note: expected reference `&str` - found enum `Option<&str>` -help: consider using `Option::expect` to unwrap the `Option<&str>` value, panicking if the value is an `Option::None` - | -LL | fn parse_type(iter: Box+'static>) -> &str { iter.next().expect("REASON") } - | +++++++++++++++++ - error[E0061]: this function takes 1 argument but 0 arguments were supplied - --> $DIR/issue-26638.rs:5:47 + --> $DIR/issue-26638.rs:4:47 | LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() } | ^^^^-- an argument of type `&u8` is missing @@ -73,7 +58,7 @@ LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter(/* &u8 */) } | ~~~~~~~~~~~ error[E0308]: mismatched types - --> $DIR/issue-26638.rs:5:47 + --> $DIR/issue-26638.rs:4:47 | LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() } | ---- ^^^^^^ expected `&str`, found `&u8` @@ -83,7 +68,7 @@ LL | fn parse_type_2(iter: fn(&u8)->&u8) -> &str { iter() } = note: expected reference `&'static str` found reference `&u8` -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors Some errors have detailed explanations: E0061, E0106, E0308. For more information about an error, try `rustc --explain E0061`. diff --git a/tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.rs b/tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.rs index 56f89b7041085..d6c918843c700 100644 --- a/tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.rs +++ b/tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.rs @@ -1,7 +1,5 @@ fn foo(x: &i32, y: &i32) -> &i32 { //~ ERROR missing lifetime if x > y { x } else { y } - //~^ ERROR: lifetime may not live long enough - //~| ERROR: lifetime may not live long enough } fn main() {} diff --git a/tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr b/tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr index db5b039d1c2f0..62b0a8a04bf79 100644 --- a/tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr +++ b/tests/ui/lifetimes/lifetime-errors/ex1b-return-no-names-if-else.stderr @@ -10,22 +10,6 @@ help: consider introducing a named lifetime parameter LL | fn foo<'a>(x: &'a i32, y: &'a i32) -> &'a i32 { | ++++ ++ ++ ++ -error: lifetime may not live long enough - --> $DIR/ex1b-return-no-names-if-else.rs:2:16 - | -LL | fn foo(x: &i32, y: &i32) -> &i32 { - | - let's call the lifetime of this reference `'1` -LL | if x > y { x } else { y } - | ^ returning this value requires that `'1` must outlive `'static` - -error: lifetime may not live long enough - --> $DIR/ex1b-return-no-names-if-else.rs:2:27 - | -LL | fn foo(x: &i32, y: &i32) -> &i32 { - | - let's call the lifetime of this reference `'2` -LL | if x > y { x } else { y } - | ^ returning this value requires that `'2` must outlive `'static` - -error: aborting due to 3 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0106`. diff --git a/tests/ui/nll/user-annotations/region-error-ice-109072.rs b/tests/ui/nll/user-annotations/region-error-ice-109072.rs index 3f2ad3ccbf582..bcdc6651cf5bb 100644 --- a/tests/ui/nll/user-annotations/region-error-ice-109072.rs +++ b/tests/ui/nll/user-annotations/region-error-ice-109072.rs @@ -11,4 +11,5 @@ impl Lt<'missing> for () { //~ ERROR undeclared lifetime fn main() { let _: <() as Lt<'_>>::T = &(); + //~^ ERROR the trait bound `(): Lt<'_>` is not satisfied } diff --git a/tests/ui/nll/user-annotations/region-error-ice-109072.stderr b/tests/ui/nll/user-annotations/region-error-ice-109072.stderr index d90971bed25ba..c187c17d98c68 100644 --- a/tests/ui/nll/user-annotations/region-error-ice-109072.stderr +++ b/tests/ui/nll/user-annotations/region-error-ice-109072.stderr @@ -21,6 +21,13 @@ help: consider introducing lifetime `'missing` here LL | impl<'missing> Lt<'missing> for () { | ++++++++++ -error: aborting due to 2 previous errors +error[E0277]: the trait bound `(): Lt<'_>` is not satisfied + --> $DIR/region-error-ice-109072.rs:13:13 + | +LL | let _: <() as Lt<'_>>::T = &(); + | ^^ the trait `Lt<'_>` is not implemented for `()` + +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0261`. +Some errors have detailed explanations: E0261, E0277. +For more information about an error, try `rustc --explain E0261`. diff --git a/tests/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic3.rs b/tests/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic3.rs index 345c8a25f79f1..51be999a6329d 100644 --- a/tests/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic3.rs +++ b/tests/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic3.rs @@ -15,7 +15,6 @@ fn is_static(_: T) where T: 'static { } // code forces us into a conservative, hacky path. fn bar(x: &str) -> &dyn Foo { &() } //~^ ERROR please supply an explicit bound -//~| ERROR `(): Foo<'_>` is not satisfied fn main() { let s = format!("foo"); diff --git a/tests/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic3.stderr b/tests/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic3.stderr index d227c8778fe58..688f8af0822b4 100644 --- a/tests/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic3.stderr +++ b/tests/ui/object-lifetime/object-lifetime-default-dyn-binding-nonstatic3.stderr @@ -4,20 +4,6 @@ error[E0228]: the lifetime bound for this object type cannot be deduced from con LL | fn bar(x: &str) -> &dyn Foo { &() } | ^^^^^^^ -error[E0277]: the trait bound `(): Foo<'_>` is not satisfied - --> $DIR/object-lifetime-default-dyn-binding-nonstatic3.rs:16:47 - | -LL | fn bar(x: &str) -> &dyn Foo { &() } - | ^^^ the trait `Foo<'_>` is not implemented for `()` - | -help: this trait has no implementations, consider adding one - --> $DIR/object-lifetime-default-dyn-binding-nonstatic3.rs:4:1 - | -LL | trait Foo<'a> { - | ^^^^^^^^^^^^^ - = note: required for the cast from `&()` to `&dyn Foo<'_, Item = dyn Bar>` - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error -Some errors have detailed explanations: E0228, E0277. -For more information about an error, try `rustc --explain E0228`. +For more information about this error, try `rustc --explain E0228`. diff --git a/tests/ui/suggestions/issue-86667.rs b/tests/ui/suggestions/issue-86667.rs index 8c18a87923894..1f37e9a5f6de3 100644 --- a/tests/ui/suggestions/issue-86667.rs +++ b/tests/ui/suggestions/issue-86667.rs @@ -6,13 +6,11 @@ async fn a(s1: &str, s2: &str) -> &str { //~^ ERROR: missing lifetime specifier [E0106] s1 - //~^ ERROR: lifetime may not live long enough } fn b(s1: &str, s2: &str) -> &str { //~^ ERROR: missing lifetime specifier [E0106] s1 - //~^ ERROR lifetime may not live long enough } fn main() {} diff --git a/tests/ui/suggestions/issue-86667.stderr b/tests/ui/suggestions/issue-86667.stderr index e3d673ff23318..14dbbfffb0e62 100644 --- a/tests/ui/suggestions/issue-86667.stderr +++ b/tests/ui/suggestions/issue-86667.stderr @@ -11,7 +11,7 @@ LL | async fn a<'a>(s1: &'a str, s2: &'a str) -> &'a str { | ++++ ++ ++ ++ error[E0106]: missing lifetime specifier - --> $DIR/issue-86667.rs:12:29 + --> $DIR/issue-86667.rs:11:29 | LL | fn b(s1: &str, s2: &str) -> &str { | ---- ---- ^ expected named lifetime parameter @@ -22,24 +22,6 @@ help: consider introducing a named lifetime parameter LL | fn b<'a>(s1: &'a str, s2: &'a str) -> &'a str { | ++++ ++ ++ ++ -error: lifetime may not live long enough - --> $DIR/issue-86667.rs:8:5 - | -LL | async fn a(s1: &str, s2: &str) -> &str { - | - let's call the lifetime of this reference `'1` -LL | -LL | s1 - | ^^ returning this value requires that `'1` must outlive `'static` - -error: lifetime may not live long enough - --> $DIR/issue-86667.rs:14:5 - | -LL | fn b(s1: &str, s2: &str) -> &str { - | - let's call the lifetime of this reference `'1` -LL | -LL | s1 - | ^^ returning this value requires that `'1` must outlive `'static` - -error: aborting due to 4 previous errors +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0106`. diff --git a/tests/ui/suggestions/missing-lifetime-specifier.rs b/tests/ui/suggestions/missing-lifetime-specifier.rs index 3fa7f75f86219..cd7fa0c1d8562 100644 --- a/tests/ui/suggestions/missing-lifetime-specifier.rs +++ b/tests/ui/suggestions/missing-lifetime-specifier.rs @@ -20,31 +20,21 @@ pub union Qux<'t, 'k, I> { trait Tar<'t, 'k, I> {} thread_local! { - //~^ ERROR lifetime may not live long enough - //~| ERROR lifetime may not live long enough static a: RefCell>>> = RefCell::new(HashMap::new()); //~^ ERROR missing lifetime specifiers //~| ERROR missing lifetime specifiers } thread_local! { - //~^ ERROR lifetime may not live long enough - //~| ERROR lifetime may not live long enough - //~| ERROR lifetime may not live long enough static b: RefCell>>> = RefCell::new(HashMap::new()); //~^ ERROR missing lifetime specifiers //~| ERROR missing lifetime specifiers } thread_local! { - //~^ ERROR lifetime may not live long enough - //~| ERROR lifetime may not live long enough static c: RefCell>>>> = RefCell::new(HashMap::new()); //~^ ERROR missing lifetime specifiers //~| ERROR missing lifetime specifiers } thread_local! { - //~^ ERROR lifetime may not live long enough - //~| ERROR lifetime may not live long enough - //~| ERROR lifetime may not live long enough static d: RefCell>>>> = RefCell::new(HashMap::new()); //~^ ERROR missing lifetime specifiers //~| ERROR missing lifetime specifiers diff --git a/tests/ui/suggestions/missing-lifetime-specifier.stderr b/tests/ui/suggestions/missing-lifetime-specifier.stderr index 62eca16214871..2b85cfde7b64b 100644 --- a/tests/ui/suggestions/missing-lifetime-specifier.stderr +++ b/tests/ui/suggestions/missing-lifetime-specifier.stderr @@ -1,5 +1,5 @@ error[E0106]: missing lifetime specifiers - --> $DIR/missing-lifetime-specifier.rs:25:44 + --> $DIR/missing-lifetime-specifier.rs:23:44 | LL | static a: RefCell>>> = RefCell::new(HashMap::new()); | ^^^ expected 2 lifetime parameters @@ -11,11 +11,9 @@ LL | static a: RefCell>>>> = RefC | ++++++++++++++++++ error[E0106]: missing lifetime specifiers - --> $DIR/missing-lifetime-specifier.rs:25:44 + --> $DIR/missing-lifetime-specifier.rs:23:44 | LL | / thread_local! { -LL | | -LL | | LL | | static a: RefCell>>> = RefCell::new(HashMap::new()); | | ^^^ expected 2 lifetime parameters LL | | @@ -26,7 +24,7 @@ LL | | } = help: this function's return type contains a borrowed value, but the signature does not say which one of `init`'s 3 lifetimes it is borrowed from error[E0106]: missing lifetime specifiers - --> $DIR/missing-lifetime-specifier.rs:33:44 + --> $DIR/missing-lifetime-specifier.rs:28:44 | LL | static b: RefCell>>> = RefCell::new(HashMap::new()); | ^^^^ expected 2 lifetime parameters @@ -40,12 +38,9 @@ LL | static b: RefCell>> | +++++++ ++++++++++++++++++ error[E0106]: missing lifetime specifiers - --> $DIR/missing-lifetime-specifier.rs:33:44 + --> $DIR/missing-lifetime-specifier.rs:28:44 | LL | / thread_local! { -LL | | -LL | | -LL | | LL | | static b: RefCell>>> = RefCell::new(HashMap::new()); | | ^^^^ expected 2 lifetime parameters | | | @@ -58,7 +53,7 @@ LL | | } = help: this function's return type contains a borrowed value, but the signature does not say which one of `init`'s 4 lifetimes it is borrowed from error[E0106]: missing lifetime specifiers - --> $DIR/missing-lifetime-specifier.rs:40:47 + --> $DIR/missing-lifetime-specifier.rs:33:47 | LL | static c: RefCell>>>> = RefCell::new(HashMap::new()); | ^ expected 2 lifetime parameters @@ -70,11 +65,9 @@ LL | static c: RefCell>>>> = | +++++++++++++++++ error[E0106]: missing lifetime specifiers - --> $DIR/missing-lifetime-specifier.rs:40:47 + --> $DIR/missing-lifetime-specifier.rs:33:47 | LL | / thread_local! { -LL | | -LL | | LL | | static c: RefCell>>>> = RefCell::new(HashMap::new()); | | ^ expected 2 lifetime parameters LL | | @@ -85,7 +78,7 @@ LL | | } = help: this function's return type contains a borrowed value, but the signature does not say which one of `init`'s 3 lifetimes it is borrowed from error[E0106]: missing lifetime specifiers - --> $DIR/missing-lifetime-specifier.rs:48:44 + --> $DIR/missing-lifetime-specifier.rs:38:44 | LL | static d: RefCell>>>> = RefCell::new(HashMap::new()); | ^ ^ expected 2 lifetime parameters @@ -99,12 +92,9 @@ LL | static d: RefCell $DIR/missing-lifetime-specifier.rs:48:44 + --> $DIR/missing-lifetime-specifier.rs:38:44 | LL | / thread_local! { -LL | | -LL | | -LL | | LL | | static d: RefCell>>>> = RefCell::new(HashMap::new()); | | ^ ^ expected 2 lifetime parameters | | | @@ -117,7 +107,7 @@ LL | | } = help: this function's return type contains a borrowed value, but the signature does not say which one of `init`'s 4 lifetimes it is borrowed from error[E0106]: missing lifetime specifier - --> $DIR/missing-lifetime-specifier.rs:58:44 + --> $DIR/missing-lifetime-specifier.rs:48:44 | LL | static f: RefCell>>>> = RefCell::new(HashMap::new()); | ^ expected named lifetime parameter @@ -129,7 +119,7 @@ LL | static f: RefCell>>>> = | +++++++ error[E0106]: missing lifetime specifier - --> $DIR/missing-lifetime-specifier.rs:58:44 + --> $DIR/missing-lifetime-specifier.rs:48:44 | LL | / thread_local! { LL | | static f: RefCell>>>> = RefCell::new(HashMap::new()); @@ -143,7 +133,7 @@ LL | | } = help: this function's return type contains a borrowed value, but the signature does not say which one of `init`'s 3 lifetimes it is borrowed from error[E0107]: union takes 2 lifetime arguments but 1 lifetime argument was supplied - --> $DIR/missing-lifetime-specifier.rs:54:44 + --> $DIR/missing-lifetime-specifier.rs:44:44 | LL | static e: RefCell>>>> = RefCell::new(HashMap::new()); | ^^^ ------- supplied 1 lifetime argument @@ -161,7 +151,7 @@ LL | static e: RefCell>>>> = | +++++++++ error[E0107]: trait takes 2 lifetime arguments but 1 lifetime argument was supplied - --> $DIR/missing-lifetime-specifier.rs:58:45 + --> $DIR/missing-lifetime-specifier.rs:48:45 | LL | static f: RefCell>>>> = RefCell::new(HashMap::new()); | ^^^ ------- supplied 1 lifetime argument @@ -178,199 +168,7 @@ help: add missing lifetime argument LL | static f: RefCell>>>> = RefCell::new(HashMap::new()); | +++++++++ -error: lifetime may not live long enough - --> $DIR/missing-lifetime-specifier.rs:22:1 - | -LL | / thread_local! { -LL | | -LL | | -LL | | static a: RefCell>>> = RefCell::new(HashMap::new()); -LL | | -LL | | -LL | | } - | | ^ - | | | - | |_has type `Option<&mut Option>>>>>>` - | returning this value requires that `'1` must outlive `'static` - | - = note: this error originates in the macro `$crate::thread::local_impl::thread_local_inner` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: lifetime may not live long enough - --> $DIR/missing-lifetime-specifier.rs:22:1 - | -LL | / thread_local! { -LL | | -LL | | -LL | | static a: RefCell>>> = RefCell::new(HashMap::new()); -LL | | -LL | | -LL | | } - | | ^ - | | | - | |_has type `Option<&mut Option>>>>>>` - | returning this value requires that `'2` must outlive `'static` - | - = note: this error originates in the macro `$crate::thread::local_impl::thread_local_inner` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: lifetime may not live long enough - --> $DIR/missing-lifetime-specifier.rs:29:1 - | -LL | / thread_local! { -LL | | -LL | | -LL | | -LL | | static b: RefCell>>> = RefCell::new(HashMap::new()); - | | - let's call the lifetime of this reference `'1` -LL | | -LL | | -LL | | } - | |_^ returning this value requires that `'1` must outlive `'static` - | - = note: this error originates in the macro `$crate::thread::local_impl::thread_local_inner` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info) -help: to declare that the trait object captures data from argument `init`, you can add an explicit `'_` lifetime bound - | -LL | static b: RefCell>>> = RefCell::new(HashMap::new()); - | ++++ - -error: lifetime may not live long enough - --> $DIR/missing-lifetime-specifier.rs:29:1 - | -LL | / thread_local! { -LL | | -LL | | -LL | | -... | -LL | | -LL | | } - | | ^ - | | | - | |_has type `Option<&mut Option>>>>>>` - | returning this value requires that `'2` must outlive `'static` - | - = note: this error originates in the macro `$crate::thread::local_impl::thread_local_inner` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info) -help: to declare that the trait object captures data from argument `init`, you can add an explicit `'_` lifetime bound - | -LL | static b: RefCell>>> = RefCell::new(HashMap::new()); - | ++++ - -error: lifetime may not live long enough - --> $DIR/missing-lifetime-specifier.rs:29:1 - | -LL | / thread_local! { -LL | | -LL | | -LL | | -... | -LL | | -LL | | } - | | ^ - | | | - | |_has type `Option<&mut Option>>>>>>` - | returning this value requires that `'3` must outlive `'static` - | - = note: this error originates in the macro `$crate::thread::local_impl::thread_local_inner` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info) -help: to declare that the trait object captures data from argument `init`, you can add an explicit `'_` lifetime bound - | -LL | static b: RefCell>>> = RefCell::new(HashMap::new()); - | ++++ - -error: lifetime may not live long enough - --> $DIR/missing-lifetime-specifier.rs:37:1 - | -LL | / thread_local! { -LL | | -LL | | -LL | | static c: RefCell>>>> = RefCell::new(HashMap::new()); -LL | | -LL | | -LL | | } - | | ^ - | | | - | |_has type `Option<&mut Option>>>>>>` - | returning this value requires that `'1` must outlive `'static` - | - = note: this error originates in the macro `$crate::thread::local_impl::thread_local_inner` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: lifetime may not live long enough - --> $DIR/missing-lifetime-specifier.rs:37:1 - | -LL | / thread_local! { -LL | | -LL | | -LL | | static c: RefCell>>>> = RefCell::new(HashMap::new()); -LL | | -LL | | -LL | | } - | | ^ - | | | - | |_has type `Option<&mut Option>>>>>>` - | returning this value requires that `'2` must outlive `'static` - | - = note: this error originates in the macro `$crate::thread::local_impl::thread_local_inner` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info) - -error: lifetime may not live long enough - --> $DIR/missing-lifetime-specifier.rs:44:1 - | -LL | / thread_local! { -LL | | -LL | | -LL | | -LL | | static d: RefCell>>>> = RefCell::new(HashMap::new()); - | | - let's call the lifetime of this reference `'1` -LL | | -LL | | -LL | | } - | |_^ returning this value requires that `'1` must outlive `'static` - | - = note: this error originates in the macro `$crate::thread::local_impl::thread_local_inner` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info) -help: to declare that the trait object captures data from argument `init`, you can add an explicit `'_` lifetime bound - | -LL | static d: RefCell + '_>>>> = RefCell::new(HashMap::new()); - | ++++ - -error: lifetime may not live long enough - --> $DIR/missing-lifetime-specifier.rs:44:1 - | -LL | / thread_local! { -LL | | -LL | | -LL | | -... | -LL | | -LL | | } - | | ^ - | | | - | |_has type `Option<&mut Option>>>>>>` - | returning this value requires that `'2` must outlive `'static` - | - = note: this error originates in the macro `$crate::thread::local_impl::thread_local_inner` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info) -help: to declare that the trait object captures data from argument `init`, you can add an explicit `'_` lifetime bound - | -LL | static d: RefCell + '_>>>> = RefCell::new(HashMap::new()); - | ++++ - -error: lifetime may not live long enough - --> $DIR/missing-lifetime-specifier.rs:44:1 - | -LL | / thread_local! { -LL | | -LL | | -LL | | -... | -LL | | -LL | | } - | | ^ - | | | - | |_has type `Option<&mut Option>>>>>>` - | returning this value requires that `'3` must outlive `'static` - | - = note: this error originates in the macro `$crate::thread::local_impl::thread_local_inner` which comes from the expansion of the macro `thread_local` (in Nightly builds, run with -Z macro-backtrace for more info) -help: to declare that the trait object captures data from argument `init`, you can add an explicit `'_` lifetime bound - | -LL | static d: RefCell + '_>>>> = RefCell::new(HashMap::new()); - | ++++ - -error: aborting due to 22 previous errors +error: aborting due to 12 previous errors Some errors have detailed explanations: E0106, E0107. For more information about an error, try `rustc --explain E0106`. diff --git a/tests/ui/traits/span-bug-issue-121414.rs b/tests/ui/traits/span-bug-issue-121414.rs index 6fbe2c179c652..ec38d8c2de6a6 100644 --- a/tests/ui/traits/span-bug-issue-121414.rs +++ b/tests/ui/traits/span-bug-issue-121414.rs @@ -6,7 +6,8 @@ impl<'a> Bar for Foo<'f> { //~ ERROR undeclared lifetime type Type = u32; } -fn test() //~ ERROR implementation of `Bar` is not general enough +fn test() //~ ERROR the trait bound `for<'a> Foo<'a>: Bar` is not satisfied + //~| ERROR the trait bound `for<'a> Foo<'a>: Bar` is not satisfied where for<'a> as Bar>::Type: Sized, { diff --git a/tests/ui/traits/span-bug-issue-121414.stderr b/tests/ui/traits/span-bug-issue-121414.stderr index 3c97f64e781e3..e2ef6672cd57a 100644 --- a/tests/ui/traits/span-bug-issue-121414.stderr +++ b/tests/ui/traits/span-bug-issue-121414.stderr @@ -6,15 +6,22 @@ LL | impl<'a> Bar for Foo<'f> { | | | help: consider introducing lifetime `'f` here: `'f,` -error: implementation of `Bar` is not general enough +error[E0277]: the trait bound `for<'a> Foo<'a>: Bar` is not satisfied + --> $DIR/span-bug-issue-121414.rs:9:1 + | +LL | / fn test() +LL | | +LL | | where +LL | | for<'a> as Bar>::Type: Sized, + | |__________________________________________^ the trait `for<'a> Bar` is not implemented for `Foo<'a>` + +error[E0277]: the trait bound `for<'a> Foo<'a>: Bar` is not satisfied --> $DIR/span-bug-issue-121414.rs:9:4 | LL | fn test() - | ^^^^ implementation of `Bar` is not general enough - | - = note: `Bar` would have to be implemented for the type `Foo<'0>`, for any lifetime `'0`... - = note: ...but `Bar` is actually implemented for the type `Foo<'1>`, for some specific lifetime `'1` + | ^^^^ the trait `for<'a> Bar` is not implemented for `Foo<'a>` -error: aborting due to 2 previous errors +error: aborting due to 3 previous errors -For more information about this error, try `rustc --explain E0261`. +Some errors have detailed explanations: E0261, E0277. +For more information about an error, try `rustc --explain E0261`. diff --git a/tests/ui/type-alias-impl-trait/escaping-bound-var.rs b/tests/ui/type-alias-impl-trait/escaping-bound-var.rs index 1ff200680be5e..2883a428d5435 100644 --- a/tests/ui/type-alias-impl-trait/escaping-bound-var.rs +++ b/tests/ui/type-alias-impl-trait/escaping-bound-var.rs @@ -8,6 +8,7 @@ trait Test<'a> {} pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>; //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` +//~| ERROR unconstrained opaque type impl Trait<'_> for () { type Assoc = (); diff --git a/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr b/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr index 09f6fba79cfdf..dd2a9b2ade577 100644 --- a/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr +++ b/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr @@ -10,6 +10,14 @@ note: lifetime declared here LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>; | ^^ -error: aborting due to 1 previous error +error: unconstrained opaque type + --> $DIR/escaping-bound-var.rs:9:47 + | +LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>; + | ^^^^^^^^^^^^^ + | + = note: `Foo` must be used in combination with a concrete type within the same module + +error: aborting due to 2 previous errors For more information about this error, try `rustc --explain E0657`. diff --git a/tests/ui/typeck/escaping_bound_vars.rs b/tests/ui/typeck/escaping_bound_vars.rs index f886388bfbd7d..985a3fdbccf3c 100644 --- a/tests/ui/typeck/escaping_bound_vars.rs +++ b/tests/ui/typeck/escaping_bound_vars.rs @@ -11,9 +11,6 @@ where (): Test<{ 1 + (<() as Elide(&())>::call) }>, //~^ ERROR cannot capture late-bound lifetime in constant //~| ERROR associated type bindings are not allowed here - //~| ERROR the trait bound `(): Elide<(&(),)>` is not satisfied - //~| ERROR the trait bound `(): Elide<(&(),)>` is not satisfied - //~| ERROR cannot add { } diff --git a/tests/ui/typeck/escaping_bound_vars.stderr b/tests/ui/typeck/escaping_bound_vars.stderr index 8c7dcdb7f1618..bd9c95fab979e 100644 --- a/tests/ui/typeck/escaping_bound_vars.stderr +++ b/tests/ui/typeck/escaping_bound_vars.stderr @@ -12,49 +12,6 @@ error[E0229]: associated type bindings are not allowed here LL | (): Test<{ 1 + (<() as Elide(&())>::call) }>, | ^^^^^^^^^^ associated type not allowed here -error[E0277]: the trait bound `(): Elide<(&(),)>` is not satisfied - --> $DIR/escaping_bound_vars.rs:11:22 - | -LL | (): Test<{ 1 + (<() as Elide(&())>::call) }>, - | ^^ the trait `Elide<(&(),)>` is not implemented for `()` - | -help: this trait has no implementations, consider adding one - --> $DIR/escaping_bound_vars.rs:5:1 - | -LL | trait Elide { - | ^^^^^^^^^^^^^^ - -error[E0277]: cannot add `fn() {<() as Elide<(&(),)>>::call}` to `{integer}` - --> $DIR/escaping_bound_vars.rs:11:18 - | -LL | (): Test<{ 1 + (<() as Elide(&())>::call) }>, - | ^ no implementation for `{integer} + fn() {<() as Elide<(&(),)>>::call}` - | - = help: the trait `Add>::call}>` is not implemented for `{integer}` - = help: the following other types implement trait `Add`: - - > - - > - - > - - > - and 48 others - -error[E0277]: the trait bound `(): Elide<(&(),)>` is not satisfied - --> $DIR/escaping_bound_vars.rs:11:18 - | -LL | (): Test<{ 1 + (<() as Elide(&())>::call) }>, - | ^ the trait `Elide<(&(),)>` is not implemented for `()` - | -help: this trait has no implementations, consider adding one - --> $DIR/escaping_bound_vars.rs:5:1 - | -LL | trait Elide { - | ^^^^^^^^^^^^^^ - -error: aborting due to 5 previous errors +error: aborting due to 2 previous errors -Some errors have detailed explanations: E0229, E0277. -For more information about an error, try `rustc --explain E0229`. +For more information about this error, try `rustc --explain E0229`. diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-region.rs b/tests/ui/unboxed-closures/unboxed-closure-sugar-region.rs index 8537eb7177484..ea73b8b3c4a28 100644 --- a/tests/ui/unboxed-closures/unboxed-closure-sugar-region.rs +++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-region.rs @@ -33,7 +33,6 @@ fn test2(x: &dyn Foo<(isize,),Output=()>, y: &dyn Foo(isize)) { //~^ ERROR trait takes 1 lifetime argument but 0 lifetime arguments were supplied // Here, the omitted lifetimes are expanded to distinct things. same_type(x, y) - //~^ ERROR borrowed data escapes outside of function } fn main() { } diff --git a/tests/ui/unboxed-closures/unboxed-closure-sugar-region.stderr b/tests/ui/unboxed-closures/unboxed-closure-sugar-region.stderr index 6e6c649ca3d57..d73aef851fd76 100644 --- a/tests/ui/unboxed-closures/unboxed-closure-sugar-region.stderr +++ b/tests/ui/unboxed-closures/unboxed-closure-sugar-region.stderr @@ -34,22 +34,6 @@ note: trait defined here, with 1 lifetime parameter: `'a` LL | trait Foo<'a,T> { | ^^^ -- -error[E0521]: borrowed data escapes outside of function - --> $DIR/unboxed-closure-sugar-region.rs:35:5 - | -LL | fn test2(x: &dyn Foo<(isize,),Output=()>, y: &dyn Foo(isize)) { - | - - `y` declared here, outside of the function body - | | - | `x` is a reference that is only valid in the function body - | has type `&dyn Foo<'1, (isize,), Output = ()>` -... -LL | same_type(x, y) - | ^^^^^^^^^^^^^^^ - | | - | `x` escapes the function body here - | argument requires that `'1` must outlive `'static` - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0107, E0521. -For more information about an error, try `rustc --explain E0107`. +For more information about this error, try `rustc --explain E0107`. diff --git a/tests/ui/underscore-lifetime/underscore-lifetime-binders.rs b/tests/ui/underscore-lifetime/underscore-lifetime-binders.rs index ebc3879854434..3d049cc5639c0 100644 --- a/tests/ui/underscore-lifetime/underscore-lifetime-binders.rs +++ b/tests/ui/underscore-lifetime/underscore-lifetime-binders.rs @@ -14,7 +14,6 @@ fn meh() -> Box Meh<'_>> //~ ERROR cannot be used here } fn foo2(_: &'_ u8, y: &'_ u8) -> &'_ u8 { y } //~ ERROR missing lifetime specifier -//~^ ERROR lifetime may not live long enough fn main() { let x = 5; diff --git a/tests/ui/underscore-lifetime/underscore-lifetime-binders.stderr b/tests/ui/underscore-lifetime/underscore-lifetime-binders.stderr index 5d2954d1d71e0..cd74d27dcb55f 100644 --- a/tests/ui/underscore-lifetime/underscore-lifetime-binders.stderr +++ b/tests/ui/underscore-lifetime/underscore-lifetime-binders.stderr @@ -45,15 +45,7 @@ help: consider introducing a named lifetime parameter LL | fn foo2<'a>(_: &'a u8, y: &'a u8) -> &'a u8 { y } | ++++ ~~ ~~ ~~ -error: lifetime may not live long enough - --> $DIR/underscore-lifetime-binders.rs:16:43 - | -LL | fn foo2(_: &'_ u8, y: &'_ u8) -> &'_ u8 { y } - | - ^ returning this value requires that `'1` must outlive `'static` - | | - | let's call the lifetime of this reference `'1` - -error: aborting due to 6 previous errors +error: aborting due to 5 previous errors Some errors have detailed explanations: E0106, E0637. For more information about an error, try `rustc --explain E0106`. diff --git a/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs b/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs index 0be5127dcc4da..e6d4e2ee01a27 100644 --- a/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs +++ b/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.rs @@ -14,4 +14,5 @@ impl Trait for Ref {} //~ ERROR: implicit elided lifetime not allowed here extern "C" { pub fn repro(_: Wrapper); + //~^ ERROR the trait bound `Ref<'_>: Trait` is not satisfied } diff --git a/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr b/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr index 0af4ab022e1eb..59b55b2732d30 100644 --- a/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr +++ b/tests/ui/wf/wf-in-foreign-fn-decls-issue-80468.stderr @@ -9,6 +9,19 @@ help: indicate the anonymous lifetime LL | impl Trait for Ref<'_> {} | ++++ -error: aborting due to 1 previous error +error[E0277]: the trait bound `Ref<'_>: Trait` is not satisfied + --> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:16:21 + | +LL | pub fn repro(_: Wrapper); + | ^^^^^^^^^^^^ the trait `Trait` is not implemented for `Ref<'_>` + | +note: required by a bound in `Wrapper` + --> $DIR/wf-in-foreign-fn-decls-issue-80468.rs:8:23 + | +LL | pub struct Wrapper(T); + | ^^^^^ required by this bound in `Wrapper` + +error: aborting due to 2 previous errors -For more information about this error, try `rustc --explain E0726`. +Some errors have detailed explanations: E0277, E0726. +For more information about an error, try `rustc --explain E0277`. From 0dc006b3a8901f8591b65c71f8eaaba14ab39862 Mon Sep 17 00:00:00 2001 From: Ali MJ Al-Nasrawy Date: Wed, 20 Mar 2024 17:24:07 +0000 Subject: [PATCH 25/27] register opaques that reference errors --- .../rustc_infer/src/infer/opaque_types/mod.rs | 3 -- .../generic_const_exprs/issue-109141.rs | 1 + .../generic_const_exprs/issue-109141.stderr | 21 ++++++++++-- tests/ui/impl-trait/nested-rpit-hrtb.rs | 3 +- tests/ui/impl-trait/nested-rpit-hrtb.stderr | 34 ++++++++++++------- .../escaping-bound-var.rs | 1 - .../escaping-bound-var.stderr | 10 +----- 7 files changed, 44 insertions(+), 29 deletions(-) diff --git a/compiler/rustc_infer/src/infer/opaque_types/mod.rs b/compiler/rustc_infer/src/infer/opaque_types/mod.rs index a6f8115c27e2d..02b8ded285f6d 100644 --- a/compiler/rustc_infer/src/infer/opaque_types/mod.rs +++ b/compiler/rustc_infer/src/infer/opaque_types/mod.rs @@ -94,9 +94,6 @@ impl<'tcx> InferCtxt<'tcx> { cause: &ObligationCause<'tcx>, param_env: ty::ParamEnv<'tcx>, ) -> InferResult<'tcx, ()> { - if a.references_error() || b.references_error() { - return Ok(InferOk { value: (), obligations: vec![] }); - } let process = |a: Ty<'tcx>, b: Ty<'tcx>| match *a.kind() { ty::Alias(ty::Opaque, ty::AliasTy { def_id, args, .. }) if def_id.is_local() => { let def_id = def_id.expect_local(); diff --git a/tests/ui/const-generics/generic_const_exprs/issue-109141.rs b/tests/ui/const-generics/generic_const_exprs/issue-109141.rs index 148c3bda8d287..c6dd981cced00 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-109141.rs +++ b/tests/ui/const-generics/generic_const_exprs/issue-109141.rs @@ -4,6 +4,7 @@ impl EntriesBuffer { fn a(&self) -> impl Iterator { self.0.iter_mut() //~ ERROR: cannot borrow `*self.0` as mutable, as it is behind a `&` reference + //~| ERROR captures lifetime that does not appear in bounds } } diff --git a/tests/ui/const-generics/generic_const_exprs/issue-109141.stderr b/tests/ui/const-generics/generic_const_exprs/issue-109141.stderr index 8b8489ac2bc51..7a9572d000d5a 100644 --- a/tests/ui/const-generics/generic_const_exprs/issue-109141.stderr +++ b/tests/ui/const-generics/generic_const_exprs/issue-109141.stderr @@ -1,5 +1,5 @@ error[E0425]: cannot find value `HashesEntryLEN` in this scope - --> $DIR/issue-109141.rs:10:32 + --> $DIR/issue-109141.rs:11:32 | LL | struct EntriesBuffer(Box<[[u8; HashesEntryLEN]; 5]>); | ^^^^^^^^^^^^^^ not found in this scope @@ -20,7 +20,22 @@ help: consider changing this to be a mutable reference LL | fn a(&mut self) -> impl Iterator { | ~~~~~~~~~ -error: aborting due to 2 previous errors +error[E0700]: hidden type for `impl Iterator` captures lifetime that does not appear in bounds + --> $DIR/issue-109141.rs:6:9 + | +LL | fn a(&self) -> impl Iterator { + | ----- ------------- opaque type defined here + | | + | hidden type `std::slice::IterMut<'_, [u8; {const error}]>` captures the anonymous lifetime defined here +LL | self.0.iter_mut() + | ^^^^^^^^^^^^^^^^^ + | +help: to declare that `impl Iterator` captures `'_`, you can add an explicit `'_` lifetime bound + | +LL | fn a(&self) -> impl Iterator + '_ { + | ++++ + +error: aborting due to 3 previous errors -Some errors have detailed explanations: E0425, E0596. +Some errors have detailed explanations: E0425, E0596, E0700. For more information about an error, try `rustc --explain E0425`. diff --git a/tests/ui/impl-trait/nested-rpit-hrtb.rs b/tests/ui/impl-trait/nested-rpit-hrtb.rs index aa9aa011f61ab..a696e1710f065 100644 --- a/tests/ui/impl-trait/nested-rpit-hrtb.rs +++ b/tests/ui/impl-trait/nested-rpit-hrtb.rs @@ -31,6 +31,7 @@ fn one_hrtb_trait_param() -> impl for<'a> Foo<'a, Assoc = impl Qux<'a>> {} fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {} //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` +//~| ERROR implementation of `Bar` is not general enough fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {} //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` @@ -43,7 +44,7 @@ fn one_hrtb_mention_fn_outlives<'b>() -> impl for<'a> Foo<'a, Assoc = impl Sized // This should resolve. fn one_hrtb_mention_fn_trait_param_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Qux<'b>> {} -//~^ ERROR: the trait bound `for<'a> &'a (): Qux<'b>` is not satisfied +//~^ ERROR type annotations needed: cannot satisfy `for<'a> &'a (): Qux<'b>` // This should resolve. fn one_hrtb_mention_fn_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'b> {} diff --git a/tests/ui/impl-trait/nested-rpit-hrtb.stderr b/tests/ui/impl-trait/nested-rpit-hrtb.stderr index b6fa81a23afcb..64f801ea6851f 100644 --- a/tests/ui/impl-trait/nested-rpit-hrtb.stderr +++ b/tests/ui/impl-trait/nested-rpit-hrtb.stderr @@ -1,5 +1,5 @@ error[E0261]: use of undeclared lifetime name `'b` - --> $DIR/nested-rpit-hrtb.rs:56:77 + --> $DIR/nested-rpit-hrtb.rs:57:77 | LL | fn two_htrb_outlives() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Sized + 'b> {} | ^^ undeclared lifetime @@ -15,7 +15,7 @@ LL | fn two_htrb_outlives<'b>() -> impl for<'a> Foo<'a, Assoc = impl for<'b> Siz | ++++ error[E0261]: use of undeclared lifetime name `'b` - --> $DIR/nested-rpit-hrtb.rs:64:82 + --> $DIR/nested-rpit-hrtb.rs:65:82 | LL | fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {} | ^^ undeclared lifetime @@ -65,29 +65,39 @@ note: lifetime declared here LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {} | ^^ +error: implementation of `Bar` is not general enough + --> $DIR/nested-rpit-hrtb.rs:32:78 + | +LL | fn one_hrtb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'a> {} + | ^^ implementation of `Bar` is not general enough + | + = note: `()` must implement `Bar<'a>` + = note: ...but it actually implements `Bar<'0>`, for some specific lifetime `'0` + error[E0657]: `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` - --> $DIR/nested-rpit-hrtb.rs:35:73 + --> $DIR/nested-rpit-hrtb.rs:36:73 | LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {} | ^^ | note: lifetime declared here - --> $DIR/nested-rpit-hrtb.rs:35:44 + --> $DIR/nested-rpit-hrtb.rs:36:44 | LL | fn one_hrtb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl Qux<'a>> {} | ^^ -error[E0277]: the trait bound `for<'a> &'a (): Qux<'b>` is not satisfied - --> $DIR/nested-rpit-hrtb.rs:45:79 +error[E0283]: type annotations needed: cannot satisfy `for<'a> &'a (): Qux<'b>` + --> $DIR/nested-rpit-hrtb.rs:46:79 | LL | fn one_hrtb_mention_fn_trait_param_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Qux<'b>> {} - | ^^^^^^^^^^^^ the trait `for<'a> Qux<'b>` is not implemented for `&'a ()` + | ^^^^^^^^^^^^ | + = note: cannot satisfy `for<'a> &'a (): Qux<'b>` = help: the trait `Qux<'_>` is implemented for `()` = help: for that trait implementation, expected `()`, found `&'a ()` error: implementation of `Bar` is not general enough - --> $DIR/nested-rpit-hrtb.rs:49:93 + --> $DIR/nested-rpit-hrtb.rs:50:93 | LL | fn one_hrtb_mention_fn_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = impl Sized + 'b> {} | ^^ implementation of `Bar` is not general enough @@ -96,7 +106,7 @@ LL | fn one_hrtb_mention_fn_outlives_uses<'b>() -> impl for<'a> Bar<'a, Assoc = = note: ...but it actually implements `Bar<'0>`, for some specific lifetime `'0` error[E0277]: the trait bound `for<'a, 'b> &'a (): Qux<'b>` is not satisfied - --> $DIR/nested-rpit-hrtb.rs:60:64 + --> $DIR/nested-rpit-hrtb.rs:61:64 | LL | fn two_htrb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Qux<'b>> {} | ^^^^^^^^^^^^^^^^^^^^ the trait `for<'a, 'b> Qux<'b>` is not implemented for `&'a ()` @@ -105,7 +115,7 @@ LL | fn two_htrb_trait_param_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> = help: for that trait implementation, expected `()`, found `&'a ()` error: implementation of `Bar` is not general enough - --> $DIR/nested-rpit-hrtb.rs:64:86 + --> $DIR/nested-rpit-hrtb.rs:65:86 | LL | fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Sized + 'b> {} | ^^ implementation of `Bar` is not general enough @@ -113,7 +123,7 @@ LL | fn two_htrb_outlives_uses() -> impl for<'a> Bar<'a, Assoc = impl for<'b> Si = note: `()` must implement `Bar<'a>` = note: ...but it actually implements `Bar<'0>`, for some specific lifetime `'0` -error: aborting due to 10 previous errors +error: aborting due to 11 previous errors -Some errors have detailed explanations: E0261, E0277, E0657. +Some errors have detailed explanations: E0261, E0277, E0283, E0657. For more information about an error, try `rustc --explain E0261`. diff --git a/tests/ui/type-alias-impl-trait/escaping-bound-var.rs b/tests/ui/type-alias-impl-trait/escaping-bound-var.rs index 2883a428d5435..1ff200680be5e 100644 --- a/tests/ui/type-alias-impl-trait/escaping-bound-var.rs +++ b/tests/ui/type-alias-impl-trait/escaping-bound-var.rs @@ -8,7 +8,6 @@ trait Test<'a> {} pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>; //~^ ERROR `impl Trait` cannot capture higher-ranked lifetime from outer `impl Trait` -//~| ERROR unconstrained opaque type impl Trait<'_> for () { type Assoc = (); diff --git a/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr b/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr index dd2a9b2ade577..09f6fba79cfdf 100644 --- a/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr +++ b/tests/ui/type-alias-impl-trait/escaping-bound-var.stderr @@ -10,14 +10,6 @@ note: lifetime declared here LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>; | ^^ -error: unconstrained opaque type - --> $DIR/escaping-bound-var.rs:9:47 - | -LL | pub type Foo = impl for<'a> Trait<'a, Assoc = impl Test<'a>>; - | ^^^^^^^^^^^^^ - | - = note: `Foo` must be used in combination with a concrete type within the same module - -error: aborting due to 2 previous errors +error: aborting due to 1 previous error For more information about this error, try `rustc --explain E0657`. From 352587af44dfbe76fbb8cae6bd2f75ff4b292f16 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Wed, 20 Mar 2024 19:24:18 +0100 Subject: [PATCH 26/27] compiletest: mir_dump_dir.as_path() -> &mir_dump_dir --- src/tools/compiletest/src/runtest.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 63e52df8c040e..1a2d8495dbb0e 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -2470,7 +2470,7 @@ impl<'test> TestCx<'test> { let mir_dump_dir = self.get_mir_dump_dir(); let _ = fs::remove_dir_all(&mir_dump_dir); - create_dir_all(mir_dump_dir.as_path()).unwrap(); + create_dir_all(&mir_dump_dir).unwrap(); let mut dir_opt = "-Zdump-mir-dir=".to_string(); dir_opt.push_str(mir_dump_dir.to_str().unwrap()); debug!("dir_opt: {:?}", dir_opt); From c3cc6c199012094ab3017c07a67e9b37469ebf91 Mon Sep 17 00:00:00 2001 From: Martin Nordholts Date: Wed, 20 Mar 2024 19:29:13 +0100 Subject: [PATCH 27/27] compiletest: Introduce remove_and_create_dir_all() helper The code let _ = fs::remove_dir_all(&dir); create_dir_all(&dir).unwrap(); is duplicated in 7 places. Let's introduce a helper. --- src/tools/compiletest/src/runtest.rs | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/src/tools/compiletest/src/runtest.rs b/src/tools/compiletest/src/runtest.rs index 1a2d8495dbb0e..85f3aa006f205 100644 --- a/src/tools/compiletest/src/runtest.rs +++ b/src/tools/compiletest/src/runtest.rs @@ -198,6 +198,11 @@ pub fn compute_stamp_hash(config: &Config) -> String { format!("{:x}", hash.finish()) } +fn remove_and_create_dir_all(path: &Path) { + let _ = fs::remove_dir_all(path); + fs::create_dir_all(path).unwrap(); +} + #[derive(Copy, Clone)] struct TestCx<'test> { config: &'test Config, @@ -998,8 +1003,7 @@ impl<'test> TestCx<'test> { let mut rustc = Command::new(&self.config.rustc_path); let out_dir = self.output_base_name().with_extension("pretty-out"); - let _ = fs::remove_dir_all(&out_dir); - create_dir_all(&out_dir).unwrap(); + remove_and_create_dir_all(&out_dir); let target = if self.props.force_host { &*self.config.host } else { &*self.config.target }; @@ -2094,14 +2098,12 @@ impl<'test> TestCx<'test> { let aux_dir = self.aux_output_dir_name(); if !self.props.aux_builds.is_empty() { - let _ = fs::remove_dir_all(&aux_dir); - create_dir_all(&aux_dir).unwrap(); + remove_and_create_dir_all(&aux_dir); } if !self.props.aux_bins.is_empty() { let aux_bin_dir = self.aux_bin_output_dir_name(); - let _ = fs::remove_dir_all(&aux_bin_dir); - create_dir_all(&aux_bin_dir).unwrap(); + remove_and_create_dir_all(&aux_bin_dir); } aux_dir @@ -2469,8 +2471,7 @@ impl<'test> TestCx<'test> { } let mir_dump_dir = self.get_mir_dump_dir(); - let _ = fs::remove_dir_all(&mir_dump_dir); - create_dir_all(&mir_dump_dir).unwrap(); + remove_and_create_dir_all(&mir_dump_dir); let mut dir_opt = "-Zdump-mir-dir=".to_string(); dir_opt.push_str(mir_dump_dir.to_str().unwrap()); debug!("dir_opt: {:?}", dir_opt); @@ -2951,8 +2952,7 @@ impl<'test> TestCx<'test> { assert!(self.revision.is_none(), "revisions not relevant here"); let out_dir = self.output_base_dir(); - let _ = fs::remove_dir_all(&out_dir); - create_dir_all(&out_dir).unwrap(); + remove_and_create_dir_all(&out_dir); let proc_res = self.document(&out_dir); if !proc_res.status.success() { @@ -2986,9 +2986,7 @@ impl<'test> TestCx<'test> { let suffix = self.safe_revision().map_or("nightly".into(), |path| path.to_owned() + "-nightly"); let compare_dir = output_base_dir(self.config, self.testpaths, Some(&suffix)); - // Don't give an error if the directory didn't already exist - let _ = fs::remove_dir_all(&compare_dir); - create_dir_all(&compare_dir).unwrap(); + remove_and_create_dir_all(&compare_dir); // We need to create a new struct for the lifetimes on `config` to work. let new_rustdoc = TestCx { @@ -3137,8 +3135,7 @@ impl<'test> TestCx<'test> { assert!(self.revision.is_none(), "revisions not relevant here"); let out_dir = self.output_base_dir(); - let _ = fs::remove_dir_all(&out_dir); - create_dir_all(&out_dir).unwrap(); + remove_and_create_dir_all(&out_dir); let proc_res = self.document(&out_dir); if !proc_res.status.success() {