From f7ae92c6bd9b50e3d1cd7ce123ffa15d0e1ecd97 Mon Sep 17 00:00:00 2001 From: joboet Date: Thu, 30 Jun 2022 11:48:54 +0200 Subject: [PATCH 01/14] std: use futex-based locks on Fuchsia --- library/std/src/sys/unix/futex.rs | 25 ++- .../std/src/sys/unix/locks/fuchsia_mutex.rs | 158 ++++++++++++++++++ .../std/src/sys/unix/locks/futex_condvar.rs | 58 +++++++ .../unix/locks/{futex.rs => futex_mutex.rs} | 56 +------ library/std/src/sys/unix/locks/mod.rs | 13 +- 5 files changed, 246 insertions(+), 64 deletions(-) create mode 100644 library/std/src/sys/unix/locks/fuchsia_mutex.rs create mode 100644 library/std/src/sys/unix/locks/futex_condvar.rs rename library/std/src/sys/unix/locks/{futex.rs => futex_mutex.rs} (62%) diff --git a/library/std/src/sys/unix/futex.rs b/library/std/src/sys/unix/futex.rs index ab516a7f76dd0..9480451fc5c86 100644 --- a/library/std/src/sys/unix/futex.rs +++ b/library/std/src/sys/unix/futex.rs @@ -240,17 +240,22 @@ pub fn futex_wake_all(futex: &AtomicU32) { } #[cfg(target_os = "fuchsia")] -mod zircon { - type zx_time_t = i64; - type zx_futex_t = crate::sync::atomic::AtomicU32; - type zx_handle_t = u32; - type zx_status_t = i32; +pub mod zircon { + pub type zx_futex_t = crate::sync::atomic::AtomicU32; + pub type zx_handle_t = u32; + pub type zx_status_t = i32; + pub type zx_time_t = i64; pub const ZX_HANDLE_INVALID: zx_handle_t = 0; - pub const ZX_ERR_TIMED_OUT: zx_status_t = -21; + pub const ZX_TIME_INFINITE: zx_time_t = zx_time_t::MAX; + pub const ZX_OK: zx_status_t = 0; + pub const ZX_ERR_BAD_STATE: zx_status_t = -20; + pub const ZX_ERR_TIMED_OUT: zx_status_t = -21; + extern "C" { + pub fn zx_clock_get_monotonic() -> zx_time_t; pub fn zx_futex_wait( value_ptr: *const zx_futex_t, current_value: zx_futex_t, @@ -258,7 +263,8 @@ mod zircon { deadline: zx_time_t, ) -> zx_status_t; pub fn zx_futex_wake(value_ptr: *const zx_futex_t, wake_count: u32) -> zx_status_t; - pub fn zx_clock_get_monotonic() -> zx_time_t; + pub fn zx_futex_wake_single_owner(value_ptr: *const zx_futex_t) -> zx_status_t; + pub fn zx_thread_self() -> zx_handle_t; } } @@ -287,3 +293,8 @@ pub fn futex_wake(futex: &AtomicU32) -> bool { unsafe { zircon::zx_futex_wake(futex, 1) }; false } + +#[cfg(target_os = "fuchsia")] +pub fn futex_wake_all(futex: &AtomicU32) { + unsafe { zircon::zx_futex_wake(futex, u32::MAX) }; +} diff --git a/library/std/src/sys/unix/locks/fuchsia_mutex.rs b/library/std/src/sys/unix/locks/fuchsia_mutex.rs new file mode 100644 index 0000000000000..412e7e0018b48 --- /dev/null +++ b/library/std/src/sys/unix/locks/fuchsia_mutex.rs @@ -0,0 +1,158 @@ +//! A priority inheriting mutex for Fuchsia. +//! +//! This is a port of the [mutex in Fuchsia's libsync]. Contrary to the original, +//! it does not abort the process when reentrant locking is detected, but deadlocks. +//! +//! Priority inheritance is achieved by storing the owning thread's handle in an +//! atomic variable. Fuchsia's futex operations support setting an owner thread +//! for a futex, which can boost that thread's priority while the futex is waited +//! upon. +//! +//! libsync is licenced under the following BSD-style licence: +//! +//! Copyright 2016 The Fuchsia Authors. +//! +//! Redistribution and use in source and binary forms, with or without +//! modification, are permitted provided that the following conditions are +//! met: +//! +//! * Redistributions of source code must retain the above copyright +//! notice, this list of conditions and the following disclaimer. +//! * Redistributions in binary form must reproduce the above +//! copyright notice, this list of conditions and the following +//! disclaimer in the documentation and/or other materials provided +//! with the distribution. +//! +//! THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS +//! "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT +//! LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR +//! A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT +//! OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, +//! SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT +//! LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, +//! DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY +//! THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT +//! (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +//! OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +//! +//! [mutex in Fuchsia's libsync]: https://cs.opensource.google/fuchsia/fuchsia/+/main:zircon/system/ulib/sync/mutex.c + +use crate::sync::atomic::{ + AtomicU32, + Ordering::{Acquire, Relaxed, Release}, +}; +use crate::sys::futex::zircon::{ + zx_futex_wait, zx_futex_wake_single_owner, zx_handle_t, zx_thread_self, ZX_ERR_BAD_STATE, + ZX_OK, ZX_TIME_INFINITE, +}; + +// The lowest two bits of a `zx_handle_t` are always set, so the lowest bit is used to mark the +// mutex as contested by clearing it. +const CONTESTED_BIT: u32 = 1; +// This can never be a valid `zx_handle_t`. +const UNLOCKED: u32 = 0; + +pub type MovableMutex = Mutex; + +pub struct Mutex { + futex: AtomicU32, +} + +#[inline] +fn to_state(owner: zx_handle_t) -> u32 { + owner +} + +#[inline] +fn to_owner(state: u32) -> zx_handle_t { + state | CONTESTED_BIT +} + +#[inline] +fn is_contested(state: u32) -> bool { + state & CONTESTED_BIT == 0 +} + +#[inline] +fn mark_contested(state: u32) -> u32 { + state & !CONTESTED_BIT +} + +impl Mutex { + #[inline] + pub const fn new() -> Mutex { + Mutex { futex: AtomicU32::new(UNLOCKED) } + } + + #[inline] + pub unsafe fn init(&mut self) {} + + #[inline] + pub unsafe fn try_lock(&self) -> bool { + let thread_self = zx_thread_self(); + self.futex.compare_exchange(UNLOCKED, to_state(thread_self), Acquire, Relaxed).is_ok() + } + + #[inline] + pub unsafe fn lock(&self) { + let thread_self = zx_thread_self(); + if let Err(state) = + self.futex.compare_exchange(UNLOCKED, to_state(thread_self), Acquire, Relaxed) + { + self.lock_contested(state, thread_self); + } + } + + #[cold] + fn lock_contested(&self, mut state: u32, thread_self: zx_handle_t) { + let owned_state = mark_contested(to_state(thread_self)); + loop { + // Mark the mutex as contested if it is not already. + let contested = mark_contested(state); + if is_contested(state) + || self.futex.compare_exchange(state, contested, Relaxed, Relaxed).is_ok() + { + // The mutex has been marked as contested, wait for the state to change. + unsafe { + match zx_futex_wait( + &self.futex, + AtomicU32::new(contested), + to_owner(state), + ZX_TIME_INFINITE, + ) { + ZX_OK | ZX_ERR_BAD_STATE => (), + // Deadlock even in the case of reentrant locking, as leaking a guard + // could lead to the same condition if the thread id is reused, but + // panicking is not expected in that situation. This makes things + // quite a bit harder to debug, but encourages portable programming. + _ if to_owner(state) == thread_self => loop {}, + error => panic!("futex operation failed with error code {error}"), + } + } + } + + // The state has changed or a wakeup occured, try to lock the mutex. + match self.futex.compare_exchange(UNLOCKED, owned_state, Acquire, Relaxed) { + Ok(_) => return, + Err(updated) => state = updated, + } + } + } + + #[inline] + pub unsafe fn unlock(&self) { + if is_contested(self.futex.swap(UNLOCKED, Release)) { + // The woken thread will mark the mutex as contested again, + // and return here, waking until there are no waiters left, + // in which case this is a noop. + self.wake(); + } + } + + #[cold] + fn wake(&self) { + unsafe { + zx_futex_wake_single_owner(&self.futex); + } + } +} diff --git a/library/std/src/sys/unix/locks/futex_condvar.rs b/library/std/src/sys/unix/locks/futex_condvar.rs new file mode 100644 index 0000000000000..c0576c17880e1 --- /dev/null +++ b/library/std/src/sys/unix/locks/futex_condvar.rs @@ -0,0 +1,58 @@ +use super::Mutex; +use crate::sync::atomic::{AtomicU32, Ordering::Relaxed}; +use crate::sys::futex::{futex_wait, futex_wake, futex_wake_all}; +use crate::time::Duration; + +pub type MovableCondvar = Condvar; + +pub struct Condvar { + // The value of this atomic is simply incremented on every notification. + // This is used by `.wait()` to not miss any notifications after + // unlocking the mutex and before waiting for notifications. + futex: AtomicU32, +} + +impl Condvar { + #[inline] + pub const fn new() -> Self { + Self { futex: AtomicU32::new(0) } + } + + // All the memory orderings here are `Relaxed`, + // because synchronization is done by unlocking and locking the mutex. + + pub unsafe fn notify_one(&self) { + self.futex.fetch_add(1, Relaxed); + futex_wake(&self.futex); + } + + pub unsafe fn notify_all(&self) { + self.futex.fetch_add(1, Relaxed); + futex_wake_all(&self.futex); + } + + pub unsafe fn wait(&self, mutex: &Mutex) { + self.wait_optional_timeout(mutex, None); + } + + pub unsafe fn wait_timeout(&self, mutex: &Mutex, timeout: Duration) -> bool { + self.wait_optional_timeout(mutex, Some(timeout)) + } + + unsafe fn wait_optional_timeout(&self, mutex: &Mutex, timeout: Option) -> bool { + // Examine the notification counter _before_ we unlock the mutex. + let futex_value = self.futex.load(Relaxed); + + // Unlock the mutex before going to sleep. + mutex.unlock(); + + // Wait, but only if there hasn't been any + // notification since we unlocked the mutex. + let r = futex_wait(&self.futex, futex_value, timeout); + + // Lock the mutex again. + mutex.lock(); + + r + } +} diff --git a/library/std/src/sys/unix/locks/futex.rs b/library/std/src/sys/unix/locks/futex_mutex.rs similarity index 62% rename from library/std/src/sys/unix/locks/futex.rs rename to library/std/src/sys/unix/locks/futex_mutex.rs index a9a1a32c5afb0..99ba86e5f996d 100644 --- a/library/std/src/sys/unix/locks/futex.rs +++ b/library/std/src/sys/unix/locks/futex_mutex.rs @@ -2,11 +2,9 @@ use crate::sync::atomic::{ AtomicU32, Ordering::{Acquire, Relaxed, Release}, }; -use crate::sys::futex::{futex_wait, futex_wake, futex_wake_all}; -use crate::time::Duration; +use crate::sys::futex::{futex_wait, futex_wake}; pub type MovableMutex = Mutex; -pub type MovableCondvar = Condvar; pub struct Mutex { /// 0: unlocked @@ -101,55 +99,3 @@ impl Mutex { futex_wake(&self.futex); } } - -pub struct Condvar { - // The value of this atomic is simply incremented on every notification. - // This is used by `.wait()` to not miss any notifications after - // unlocking the mutex and before waiting for notifications. - futex: AtomicU32, -} - -impl Condvar { - #[inline] - pub const fn new() -> Self { - Self { futex: AtomicU32::new(0) } - } - - // All the memory orderings here are `Relaxed`, - // because synchronization is done by unlocking and locking the mutex. - - pub unsafe fn notify_one(&self) { - self.futex.fetch_add(1, Relaxed); - futex_wake(&self.futex); - } - - pub unsafe fn notify_all(&self) { - self.futex.fetch_add(1, Relaxed); - futex_wake_all(&self.futex); - } - - pub unsafe fn wait(&self, mutex: &Mutex) { - self.wait_optional_timeout(mutex, None); - } - - pub unsafe fn wait_timeout(&self, mutex: &Mutex, timeout: Duration) -> bool { - self.wait_optional_timeout(mutex, Some(timeout)) - } - - unsafe fn wait_optional_timeout(&self, mutex: &Mutex, timeout: Option) -> bool { - // Examine the notification counter _before_ we unlock the mutex. - let futex_value = self.futex.load(Relaxed); - - // Unlock the mutex before going to sleep. - mutex.unlock(); - - // Wait, but only if there hasn't been any - // notification since we unlocked the mutex. - let r = futex_wait(&self.futex, futex_value, timeout); - - // Lock the mutex again. - mutex.lock(); - - r - } -} diff --git a/library/std/src/sys/unix/locks/mod.rs b/library/std/src/sys/unix/locks/mod.rs index 03400efa3c9aa..f5f92f6935830 100644 --- a/library/std/src/sys/unix/locks/mod.rs +++ b/library/std/src/sys/unix/locks/mod.rs @@ -7,10 +7,19 @@ cfg_if::cfg_if! { target_os = "openbsd", target_os = "dragonfly", ))] { - mod futex; + mod futex_mutex; mod futex_rwlock; - pub(crate) use futex::{Mutex, MovableMutex, MovableCondvar}; + mod futex_condvar; + pub(crate) use futex_mutex::{Mutex, MovableMutex}; pub(crate) use futex_rwlock::{RwLock, MovableRwLock}; + pub(crate) use futex_condvar::MovableCondvar; + } else if #[cfg(target_os = "fuchsia")] { + mod fuchsia_mutex; + mod futex_rwlock; + mod futex_condvar; + pub(crate) use fuchsia_mutex::{Mutex, MovableMutex}; + pub(crate) use futex_rwlock::{RwLock, MovableRwLock}; + pub(crate) use futex_condvar::MovableCondvar; } else { mod pthread_mutex; mod pthread_rwlock; From 0d91b08970301ae586031b1b2437a44115074efc Mon Sep 17 00:00:00 2001 From: joboet Date: Tue, 12 Jul 2022 12:25:43 +0200 Subject: [PATCH 02/14] std: fix issue with perma-locked mutexes on Fuchsia --- library/std/src/sys/unix/futex.rs | 4 +++ .../std/src/sys/unix/locks/fuchsia_mutex.rs | 25 ++++++++++++------- 2 files changed, 20 insertions(+), 9 deletions(-) diff --git a/library/std/src/sys/unix/futex.rs b/library/std/src/sys/unix/futex.rs index 9480451fc5c86..96b07b510a777 100644 --- a/library/std/src/sys/unix/futex.rs +++ b/library/std/src/sys/unix/futex.rs @@ -251,6 +251,9 @@ pub mod zircon { pub const ZX_TIME_INFINITE: zx_time_t = zx_time_t::MAX; pub const ZX_OK: zx_status_t = 0; + pub const ZX_ERR_INVALID_ARGS: zx_status_t = -10; + pub const ZX_ERR_BAD_HANDLE: zx_status_t = -11; + pub const ZX_ERR_WRONG_TYPE: zx_status_t = -12; pub const ZX_ERR_BAD_STATE: zx_status_t = -20; pub const ZX_ERR_TIMED_OUT: zx_status_t = -21; @@ -264,6 +267,7 @@ pub mod zircon { ) -> zx_status_t; pub fn zx_futex_wake(value_ptr: *const zx_futex_t, wake_count: u32) -> zx_status_t; pub fn zx_futex_wake_single_owner(value_ptr: *const zx_futex_t) -> zx_status_t; + pub fn zx_nanosleep(deadline: zx_time_t) -> zx_status_t; pub fn zx_thread_self() -> zx_handle_t; } } diff --git a/library/std/src/sys/unix/locks/fuchsia_mutex.rs b/library/std/src/sys/unix/locks/fuchsia_mutex.rs index 412e7e0018b48..65d7c4eefd99a 100644 --- a/library/std/src/sys/unix/locks/fuchsia_mutex.rs +++ b/library/std/src/sys/unix/locks/fuchsia_mutex.rs @@ -42,8 +42,9 @@ use crate::sync::atomic::{ Ordering::{Acquire, Relaxed, Release}, }; use crate::sys::futex::zircon::{ - zx_futex_wait, zx_futex_wake_single_owner, zx_handle_t, zx_thread_self, ZX_ERR_BAD_STATE, - ZX_OK, ZX_TIME_INFINITE, + zx_futex_wait, zx_futex_wake_single_owner, zx_handle_t, zx_nanosleep, zx_thread_self, + ZX_ERR_BAD_HANDLE, ZX_ERR_BAD_STATE, ZX_ERR_INVALID_ARGS, ZX_ERR_TIMED_OUT, ZX_ERR_WRONG_TYPE, + ZX_OK, ZX_TIME_INFINITE, ZX_TIME_INFINITE, }; // The lowest two bits of a `zx_handle_t` are always set, so the lowest bit is used to mark the @@ -120,13 +121,19 @@ impl Mutex { to_owner(state), ZX_TIME_INFINITE, ) { - ZX_OK | ZX_ERR_BAD_STATE => (), - // Deadlock even in the case of reentrant locking, as leaking a guard - // could lead to the same condition if the thread id is reused, but - // panicking is not expected in that situation. This makes things - // quite a bit harder to debug, but encourages portable programming. - _ if to_owner(state) == thread_self => loop {}, - error => panic!("futex operation failed with error code {error}"), + ZX_OK | ZX_ERR_BAD_STATE | ZX_ERR_TIMED_OUT => (), + // Either the current thread is trying to lock a mutex it has already locked, + // or the previous owner did not unlock the mutex before exiting. Since it is + // not possible to reliably detect which is the case, the current thread is + // deadlocked. This makes debugging these cases quite a bit harder, but encourages + // portable programming, since all other platforms do the same. + // + // Note that if the thread handle is reused, an arbitrary thread's priority could + // be boosted by the wait, but there is currently no way to prevent that. + ZX_ERR_INVALID_ARGS | ZX_ERR_BAD_HANDLE | ZX_ERR_WRONG_TYPE => loop { + zx_nanosleep(ZX_TIME_INFINITE); + }, + error => unreachable!("unexpected error code in futex wait: {error}"), } } } From c8165c5775966ba639e1a062bb807917e3fa3631 Mon Sep 17 00:00:00 2001 From: Michael Goulet Date: Fri, 15 Jul 2022 05:37:32 +0000 Subject: [PATCH 03/14] Do not resolve associated const when there is no provided value --- .../src/traits/const_evaluatable.rs | 15 ++++++++++++--- compiler/rustc_ty_utils/src/instance.rs | 5 +++++ .../ui/const-generics/issues/issue-86530.rs | 1 - .../const-generics/issues/issue-86530.stderr | 18 +----------------- .../ui/const-generics/issues/issue-98629.rs | 15 +++++++++++++++ .../const-generics/issues/issue-98629.stderr | 12 ++++++++++++ src/test/ui/issues/issue-77919.rs | 1 - src/test/ui/issues/issue-77919.stderr | 16 ++++------------ 8 files changed, 49 insertions(+), 34 deletions(-) create mode 100644 src/test/ui/const-generics/issues/issue-98629.rs create mode 100644 src/test/ui/const-generics/issues/issue-98629.stderr diff --git a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs index e6284b1c4ace0..decbf0133114f 100644 --- a/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs +++ b/compiler/rustc_trait_selection/src/traits/const_evaluatable.rs @@ -185,14 +185,20 @@ pub fn is_const_evaluatable<'cx, 'tcx>( } let concrete = infcx.const_eval_resolve(param_env, uv.expand(), Some(span)); match concrete { - Err(ErrorHandled::TooGeneric) => Err(if !uv.has_infer_types_or_consts() { + Err(ErrorHandled::TooGeneric) => Err(if uv.has_infer_types_or_consts() { + NotConstEvaluatable::MentionsInfer + } else if uv.has_param_types_or_consts() { infcx .tcx .sess .delay_span_bug(span, &format!("unexpected `TooGeneric` for {:?}", uv)); NotConstEvaluatable::MentionsParam } else { - NotConstEvaluatable::MentionsInfer + let guar = infcx.tcx.sess.delay_span_bug( + span, + format!("Missing value for constant, but no error reported?"), + ); + NotConstEvaluatable::Error(guar) }), Err(ErrorHandled::Linted) => { let reported = infcx @@ -240,8 +246,11 @@ pub fn is_const_evaluatable<'cx, 'tcx>( Err(ErrorHandled::TooGeneric) => Err(if uv.has_infer_types_or_consts() { NotConstEvaluatable::MentionsInfer - } else { + } else if uv.has_param_types_or_consts() { NotConstEvaluatable::MentionsParam + } else { + let guar = infcx.tcx.sess.delay_span_bug(span, format!("Missing value for constant, but no error reported?")); + NotConstEvaluatable::Error(guar) }), Err(ErrorHandled::Linted) => { let reported = diff --git a/compiler/rustc_ty_utils/src/instance.rs b/compiler/rustc_ty_utils/src/instance.rs index 5e58f2379827e..979e997f24491 100644 --- a/compiler/rustc_ty_utils/src/instance.rs +++ b/compiler/rustc_ty_utils/src/instance.rs @@ -280,6 +280,11 @@ fn resolve_associated_item<'tcx>( return Ok(None); } + // If the item does not have a value, then we cannot return an instance. + if !leaf_def.item.defaultness.has_value() { + return Ok(None); + } + let substs = tcx.erase_regions(substs); // Check if we just resolved an associated `const` declaration from diff --git a/src/test/ui/const-generics/issues/issue-86530.rs b/src/test/ui/const-generics/issues/issue-86530.rs index 4a6ffd1f3008e..b024decd4e11c 100644 --- a/src/test/ui/const-generics/issues/issue-86530.rs +++ b/src/test/ui/const-generics/issues/issue-86530.rs @@ -15,7 +15,6 @@ where fn unit_literals() { z(" "); //~^ ERROR: the trait bound `&str: X` is not satisfied - //~| ERROR: unconstrained generic constant } fn main() {} diff --git a/src/test/ui/const-generics/issues/issue-86530.stderr b/src/test/ui/const-generics/issues/issue-86530.stderr index c688f838dab47..c63857b2314e9 100644 --- a/src/test/ui/const-generics/issues/issue-86530.stderr +++ b/src/test/ui/const-generics/issues/issue-86530.stderr @@ -15,22 +15,6 @@ LL | where LL | T: X, | ^ required by this bound in `z` -error: unconstrained generic constant - --> $DIR/issue-86530.rs:16:5 - | -LL | z(" "); - | ^ - | - = help: try adding a `where` bound using this expression: `where [(); T::Y]:` -note: required by a bound in `z` - --> $DIR/issue-86530.rs:11:10 - | -LL | fn z(t: T) - | - required by a bound in this -... -LL | [(); T::Y]: , - | ^^^^ required by this bound in `z` - -error: aborting due to 2 previous errors +error: aborting due to previous error For more information about this error, try `rustc --explain E0277`. diff --git a/src/test/ui/const-generics/issues/issue-98629.rs b/src/test/ui/const-generics/issues/issue-98629.rs new file mode 100644 index 0000000000000..fc8666bbcdb79 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-98629.rs @@ -0,0 +1,15 @@ +#![feature(const_trait_impl)] + +trait Trait { + const N: usize; +} + +impl const Trait for i32 {} +//~^ ERROR not all trait items implemented, missing: `N` + +fn f() +where + [(); ::N]:, +{} + +fn main() {} diff --git a/src/test/ui/const-generics/issues/issue-98629.stderr b/src/test/ui/const-generics/issues/issue-98629.stderr new file mode 100644 index 0000000000000..53570220882c3 --- /dev/null +++ b/src/test/ui/const-generics/issues/issue-98629.stderr @@ -0,0 +1,12 @@ +error[E0046]: not all trait items implemented, missing: `N` + --> $DIR/issue-98629.rs:7:1 + | +LL | const N: usize; + | -------------- `N` from trait +... +LL | impl const Trait for i32 {} + | ^^^^^^^^^^^^^^^^^^^^^^^^ missing `N` in implementation + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0046`. diff --git a/src/test/ui/issues/issue-77919.rs b/src/test/ui/issues/issue-77919.rs index 1d5d593073117..966d76d148af3 100644 --- a/src/test/ui/issues/issue-77919.rs +++ b/src/test/ui/issues/issue-77919.rs @@ -1,6 +1,5 @@ fn main() { [1; >::VAL]; - //~^ ERROR: constant expression depends on a generic parameter } trait TypeVal { const VAL: T; diff --git a/src/test/ui/issues/issue-77919.stderr b/src/test/ui/issues/issue-77919.stderr index b4c877a2d74a4..ca256847b1f3b 100644 --- a/src/test/ui/issues/issue-77919.stderr +++ b/src/test/ui/issues/issue-77919.stderr @@ -1,5 +1,5 @@ error[E0412]: cannot find type `PhantomData` in this scope - --> $DIR/issue-77919.rs:10:9 + --> $DIR/issue-77919.rs:9:9 | LL | _n: PhantomData, | ^^^^^^^^^^^ not found in this scope @@ -10,7 +10,7 @@ LL | use std::marker::PhantomData; | error[E0412]: cannot find type `VAL` in this scope - --> $DIR/issue-77919.rs:12:63 + --> $DIR/issue-77919.rs:11:63 | LL | impl TypeVal for Multiply where N: TypeVal {} | - ^^^ not found in this scope @@ -18,7 +18,7 @@ LL | impl TypeVal for Multiply where N: TypeVal {} | help: you might be missing a type parameter: `, VAL` error[E0046]: not all trait items implemented, missing: `VAL` - --> $DIR/issue-77919.rs:12:1 + --> $DIR/issue-77919.rs:11:1 | LL | const VAL: T; | ------------ `VAL` from trait @@ -26,15 +26,7 @@ LL | const VAL: T; LL | impl TypeVal for Multiply where N: TypeVal {} | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ missing `VAL` in implementation -error: constant expression depends on a generic parameter - --> $DIR/issue-77919.rs:2:9 - | -LL | [1; >::VAL]; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ - | - = note: this may fail depending on what value the parameter takes - -error: aborting due to 4 previous errors +error: aborting due to 3 previous errors Some errors have detailed explanations: E0046, E0412. For more information about an error, try `rustc --explain E0046`. From f3579268372723bc4ff7b76090c090aa7b9e6a3a Mon Sep 17 00:00:00 2001 From: joboet Date: Mon, 18 Jul 2022 10:56:10 +0200 Subject: [PATCH 04/14] std: panic instead of deadlocking in mutex implementation on Fuchsia --- library/std/src/sys/unix/futex.rs | 1 - .../std/src/sys/unix/locks/fuchsia_mutex.rs | 30 +++++++++---------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/library/std/src/sys/unix/futex.rs b/library/std/src/sys/unix/futex.rs index 96b07b510a777..8d5b540212a17 100644 --- a/library/std/src/sys/unix/futex.rs +++ b/library/std/src/sys/unix/futex.rs @@ -267,7 +267,6 @@ pub mod zircon { ) -> zx_status_t; pub fn zx_futex_wake(value_ptr: *const zx_futex_t, wake_count: u32) -> zx_status_t; pub fn zx_futex_wake_single_owner(value_ptr: *const zx_futex_t) -> zx_status_t; - pub fn zx_nanosleep(deadline: zx_time_t) -> zx_status_t; pub fn zx_thread_self() -> zx_handle_t; } } diff --git a/library/std/src/sys/unix/locks/fuchsia_mutex.rs b/library/std/src/sys/unix/locks/fuchsia_mutex.rs index 65d7c4eefd99a..7372406b32fac 100644 --- a/library/std/src/sys/unix/locks/fuchsia_mutex.rs +++ b/library/std/src/sys/unix/locks/fuchsia_mutex.rs @@ -42,9 +42,9 @@ use crate::sync::atomic::{ Ordering::{Acquire, Relaxed, Release}, }; use crate::sys::futex::zircon::{ - zx_futex_wait, zx_futex_wake_single_owner, zx_handle_t, zx_nanosleep, zx_thread_self, - ZX_ERR_BAD_HANDLE, ZX_ERR_BAD_STATE, ZX_ERR_INVALID_ARGS, ZX_ERR_TIMED_OUT, ZX_ERR_WRONG_TYPE, - ZX_OK, ZX_TIME_INFINITE, ZX_TIME_INFINITE, + zx_futex_wait, zx_futex_wake_single_owner, zx_handle_t, zx_thread_self, ZX_ERR_BAD_HANDLE, + ZX_ERR_BAD_STATE, ZX_ERR_INVALID_ARGS, ZX_ERR_TIMED_OUT, ZX_ERR_WRONG_TYPE, ZX_OK, + ZX_TIME_INFINITE, ZX_TIME_INFINITE, }; // The lowest two bits of a `zx_handle_t` are always set, so the lowest bit is used to mark the @@ -122,18 +122,18 @@ impl Mutex { ZX_TIME_INFINITE, ) { ZX_OK | ZX_ERR_BAD_STATE | ZX_ERR_TIMED_OUT => (), - // Either the current thread is trying to lock a mutex it has already locked, - // or the previous owner did not unlock the mutex before exiting. Since it is - // not possible to reliably detect which is the case, the current thread is - // deadlocked. This makes debugging these cases quite a bit harder, but encourages - // portable programming, since all other platforms do the same. - // - // Note that if the thread handle is reused, an arbitrary thread's priority could - // be boosted by the wait, but there is currently no way to prevent that. - ZX_ERR_INVALID_ARGS | ZX_ERR_BAD_HANDLE | ZX_ERR_WRONG_TYPE => loop { - zx_nanosleep(ZX_TIME_INFINITE); - }, - error => unreachable!("unexpected error code in futex wait: {error}"), + // Note that if a thread handle is reused after its associated thread + // exits without unlocking the mutex, an arbitrary thread's priority + // could be boosted by the wait, but there is currently no way to + // prevent that. + ZX_ERR_INVALID_ARGS | ZX_ERR_BAD_HANDLE | ZX_ERR_WRONG_TYPE => { + panic!( + "either the current thread is trying to lock a mutex it has + already locked, or the previous uowner did not unlock the mutex + before exiting" + ) + } + error => panic!("unexpected error in zx_futex_wait: {error}"), } } } From c39826e3fac3a3d63a75355d87b6a62ff3cbb8cb Mon Sep 17 00:00:00 2001 From: Artur Sinila Date: Tue, 19 Jul 2022 02:25:14 +0300 Subject: [PATCH 05/14] feat: omit suffixes in const generics (e.g. `1_i32`) Closes #99255 --- compiler/rustc_middle/src/ty/print/pretty.rs | 2 +- .../match_arr_unknown_len.stderr | 2 +- .../associated-type-bound-fail.stderr | 2 +- .../generic-expr-default-concrete.stderr | 6 ++-- .../ui/const-generics/defaults/mismatch.rs | 22 ++++++------ .../const-generics/defaults/mismatch.stderr | 34 +++++++++---------- .../defaults/rp_impl_trait_fail.rs | 5 ++- .../defaults/rp_impl_trait_fail.stderr | 18 +++++----- .../defaults/trait_objects_fail.rs | 4 +-- .../defaults/trait_objects_fail.stderr | 10 +++--- src/test/ui/const-generics/defaults/wfness.rs | 12 ++++--- .../ui/const-generics/defaults/wfness.stderr | 27 ++++++++------- .../different_generic_args.full.stderr | 6 ++-- .../different_generic_args.min.stderr | 6 ++-- .../different_generic_args_array.stderr | 6 ++-- .../ui/const-generics/exhaustive-value.stderr | 16 ++++----- .../generic_arg_infer/in-signature.stderr | 12 +++---- .../abstract-const-as-cast-3.stderr | 24 ++++++------- .../generic_const_exprs/from-sig-fail.rs | 2 +- .../generic_const_exprs/from-sig-fail.stderr | 2 +- .../generic_const_exprs/issue-69654.stderr | 4 +-- .../issue-72787.min.stderr | 8 ++--- .../generic_const_exprs/simple_fail.rs | 9 +++-- .../generic_const_exprs/simple_fail.stderr | 10 +++--- .../infer/one-param-uninferred.stderr | 4 +-- src/test/ui/const-generics/issue-66451.stderr | 6 ++-- .../ui/const-generics/nested-type.full.stderr | 2 +- .../occurs-check/unused-substs-1.stderr | 6 ++-- .../types-mismatch-const-args.full.stderr | 10 +++--- .../types-mismatch-const-args.min.stderr | 10 +++--- .../ui/consts/const-eval/issue-85155.stderr | 4 +-- .../reject-specialized-drops-8142.stderr | 2 +- .../const-expr-generic-err.stderr | 4 +-- .../ui/lint/function-item-references.stderr | 4 +-- .../method-not-found-generic-arg-elision.rs | 14 ++++---- ...ethod-not-found-generic-arg-elision.stderr | 8 ++--- .../ui/simd/intrinsic/generic-shuffle.stderr | 4 +-- .../ui/simd/libm_no_std_cant_float.stderr | 12 +++---- .../type-generic-monomorphisation-empty.rs | 2 +- ...type-generic-monomorphisation-empty.stderr | 2 +- ...type-generic-monomorphisation-oversized.rs | 2 +- ...-generic-monomorphisation-oversized.stderr | 2 +- .../generic_nondefining_use.stderr | 2 +- 43 files changed, 179 insertions(+), 170 deletions(-) diff --git a/compiler/rustc_middle/src/ty/print/pretty.rs b/compiler/rustc_middle/src/ty/print/pretty.rs index 96e84bc8f0acf..5378c63a87da0 100644 --- a/compiler/rustc_middle/src/ty/print/pretty.rs +++ b/compiler/rustc_middle/src/ty/print/pretty.rs @@ -1727,7 +1727,7 @@ impl<'tcx> Printer<'tcx> for FmtPrinter<'_, 'tcx> { } fn print_const(self, ct: ty::Const<'tcx>) -> Result { - self.pretty_print_const(ct, true) + self.pretty_print_const(ct, false) } fn path_crate(mut self, cnum: CrateNum) -> Result { diff --git a/src/test/ui/array-slice-vec/match_arr_unknown_len.stderr b/src/test/ui/array-slice-vec/match_arr_unknown_len.stderr index 1a14ab40b1f86..5e531a993c62c 100644 --- a/src/test/ui/array-slice-vec/match_arr_unknown_len.stderr +++ b/src/test/ui/array-slice-vec/match_arr_unknown_len.stderr @@ -2,7 +2,7 @@ error[E0308]: mismatched types --> $DIR/match_arr_unknown_len.rs:3:9 | LL | [1, 2] => true, - | ^^^^^^ expected `2_usize`, found `N` + | ^^^^^^ expected `2`, found `N` | = note: expected array `[u32; 2]` found array `[u32; N]` diff --git a/src/test/ui/const-generics/associated-type-bound-fail.stderr b/src/test/ui/const-generics/associated-type-bound-fail.stderr index da2558229a758..e5e7ee26e44bc 100644 --- a/src/test/ui/const-generics/associated-type-bound-fail.stderr +++ b/src/test/ui/const-generics/associated-type-bound-fail.stderr @@ -4,7 +4,7 @@ error[E0277]: the trait bound `u16: Bar` is not satisfied LL | type Assoc = u16; | ^^^ the trait `Bar` is not implemented for `u16` | - = help: the trait `Bar<3_usize>` is implemented for `u16` + = help: the trait `Bar<3>` is implemented for `u16` note: required by a bound in `Foo::Assoc` --> $DIR/associated-type-bound-fail.rs:4:17 | diff --git a/src/test/ui/const-generics/defaults/generic-expr-default-concrete.stderr b/src/test/ui/const-generics/defaults/generic-expr-default-concrete.stderr index 905a285370a0d..e8826ce4335e7 100644 --- a/src/test/ui/const-generics/defaults/generic-expr-default-concrete.stderr +++ b/src/test/ui/const-generics/defaults/generic-expr-default-concrete.stderr @@ -2,10 +2,10 @@ error[E0308]: mismatched types --> $DIR/generic-expr-default-concrete.rs:10:5 | LL | Foo::<10, 12> - | ^^^^^^^^^^^^^ expected `11_usize`, found `12_usize` + | ^^^^^^^^^^^^^ expected `11`, found `12` | - = note: expected type `11_usize` - found type `12_usize` + = note: expected type `11` + found type `12` error: aborting due to previous error diff --git a/src/test/ui/const-generics/defaults/mismatch.rs b/src/test/ui/const-generics/defaults/mismatch.rs index fce4ec4edda08..ec131505ed755 100644 --- a/src/test/ui/const-generics/defaults/mismatch.rs +++ b/src/test/ui/const-generics/defaults/mismatch.rs @@ -1,22 +1,22 @@ -pub struct Example; -pub struct Example2(T); -pub struct Example3(T); -pub struct Example4; +pub struct Example; +pub struct Example2(T); +pub struct Example3(T); +pub struct Example4; fn main() { - let e: Example::<13> = (); + let e: Example<13> = (); //~^ Error: mismatched types //~| expected struct `Example` - let e: Example2:: = (); + let e: Example2 = (); //~^ Error: mismatched types //~| expected struct `Example2` - let e: Example3::<13, u32> = (); + let e: Example3<13, u32> = (); //~^ Error: mismatched types //~| expected struct `Example3` - let e: Example3::<7> = (); + let e: Example3<7> = (); //~^ Error: mismatched types - //~| expected struct `Example3<7_usize>` - let e: Example4::<7> = (); + //~| expected struct `Example3<7>` + let e: Example4<7> = (); //~^ Error: mismatched types - //~| expected struct `Example4<7_usize>` + //~| expected struct `Example4<7>` } diff --git a/src/test/ui/const-generics/defaults/mismatch.stderr b/src/test/ui/const-generics/defaults/mismatch.stderr index 369768191951b..52c54aace5f16 100644 --- a/src/test/ui/const-generics/defaults/mismatch.stderr +++ b/src/test/ui/const-generics/defaults/mismatch.stderr @@ -1,8 +1,8 @@ error[E0308]: mismatched types - --> $DIR/mismatch.rs:7:28 + --> $DIR/mismatch.rs:7:26 | -LL | let e: Example::<13> = (); - | ------------- ^^ expected struct `Example`, found `()` +LL | let e: Example<13> = (); + | ----------- ^^ expected struct `Example`, found `()` | | | expected due to this | @@ -10,10 +10,10 @@ LL | let e: Example::<13> = (); found unit type `()` error[E0308]: mismatched types - --> $DIR/mismatch.rs:10:34 + --> $DIR/mismatch.rs:10:32 | -LL | let e: Example2:: = (); - | ------------------- ^^ expected struct `Example2`, found `()` +LL | let e: Example2 = (); + | ----------------- ^^ expected struct `Example2`, found `()` | | | expected due to this | @@ -21,10 +21,10 @@ LL | let e: Example2:: = (); found unit type `()` error[E0308]: mismatched types - --> $DIR/mismatch.rs:13:34 + --> $DIR/mismatch.rs:13:32 | -LL | let e: Example3::<13, u32> = (); - | ------------------- ^^ expected struct `Example3`, found `()` +LL | let e: Example3<13, u32> = (); + | ----------------- ^^ expected struct `Example3`, found `()` | | | expected due to this | @@ -32,25 +32,25 @@ LL | let e: Example3::<13, u32> = (); found unit type `()` error[E0308]: mismatched types - --> $DIR/mismatch.rs:16:28 + --> $DIR/mismatch.rs:16:26 | -LL | let e: Example3::<7> = (); - | ------------- ^^ expected struct `Example3`, found `()` +LL | let e: Example3<7> = (); + | ----------- ^^ expected struct `Example3`, found `()` | | | expected due to this | - = note: expected struct `Example3<7_usize>` + = note: expected struct `Example3<7>` found unit type `()` error[E0308]: mismatched types - --> $DIR/mismatch.rs:19:28 + --> $DIR/mismatch.rs:19:26 | -LL | let e: Example4::<7> = (); - | ------------- ^^ expected struct `Example4`, found `()` +LL | let e: Example4<7> = (); + | ----------- ^^ expected struct `Example4`, found `()` | | | expected due to this | - = note: expected struct `Example4<7_usize>` + = note: expected struct `Example4<7>` found unit type `()` error: aborting due to 5 previous errors diff --git a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs index f633e56b0ec1d..80013e7b4b230 100644 --- a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs +++ b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.rs @@ -4,16 +4,15 @@ trait Trait {} impl Trait for Uwu {} fn rawr() -> impl Trait { - //~^ error: the trait bound `Uwu<10_u32, 12_u32>: Trait` is not satisfied + //~^ error: the trait bound `Uwu<10, 12>: Trait` is not satisfied Uwu::<10, 12> } -trait Traitor { } +trait Traitor {} impl Traitor for u32 {} impl Traitor<1, 2> for u64 {} - fn uwu() -> impl Traitor { //~^ error: the trait bound `u32: Traitor` is not satisfied 1_u32 diff --git a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr index cbc7b93f3a925..f2e7777ce6814 100644 --- a/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr +++ b/src/test/ui/const-generics/defaults/rp_impl_trait_fail.stderr @@ -1,16 +1,16 @@ -error[E0277]: the trait bound `Uwu<10_u32, 12_u32>: Trait` is not satisfied +error[E0277]: the trait bound `Uwu<10, 12>: Trait` is not satisfied --> $DIR/rp_impl_trait_fail.rs:6:14 | LL | fn rawr() -> impl Trait { - | ^^^^^^^^^^ the trait `Trait` is not implemented for `Uwu<10_u32, 12_u32>` + | ^^^^^^^^^^ the trait `Trait` is not implemented for `Uwu<10, 12>` LL | LL | Uwu::<10, 12> - | ------------- return type was inferred to be `Uwu<10_u32, 12_u32>` here + | ------------- return type was inferred to be `Uwu<10, 12>` here | = help: the trait `Trait` is implemented for `Uwu` error[E0277]: the trait bound `u32: Traitor` is not satisfied - --> $DIR/rp_impl_trait_fail.rs:17:26 + --> $DIR/rp_impl_trait_fail.rs:16:26 | LL | fn uwu() -> impl Traitor { | ^^^^^^^^^^^^^^^ the trait `Traitor` is not implemented for `u32` @@ -19,11 +19,11 @@ LL | 1_u32 | ----- return type was inferred to be `u32` here | = help: the following other types implement trait `Traitor`: - > - > + > + > error[E0277]: the trait bound `u64: Traitor` is not satisfied - --> $DIR/rp_impl_trait_fail.rs:22:13 + --> $DIR/rp_impl_trait_fail.rs:21:13 | LL | fn owo() -> impl Traitor { | ^^^^^^^^^^^^ the trait `Traitor` is not implemented for `u64` @@ -32,8 +32,8 @@ LL | 1_u64 | ----- return type was inferred to be `u64` here | = help: the following other types implement trait `Traitor`: - > - > + > + > error: aborting due to 3 previous errors diff --git a/src/test/ui/const-generics/defaults/trait_objects_fail.rs b/src/test/ui/const-generics/defaults/trait_objects_fail.rs index 5e779d2e8de59..6ab803f990920 100644 --- a/src/test/ui/const-generics/defaults/trait_objects_fail.rs +++ b/src/test/ui/const-generics/defaults/trait_objects_fail.rs @@ -16,7 +16,7 @@ trait Traitor { } } -impl Traitor<2, 3> for bool { } +impl Traitor<2, 3> for bool {} fn bar(arg: &dyn Traitor) -> u8 { arg.owo() @@ -26,5 +26,5 @@ fn main() { foo(&10_u32); //~^ error: the trait bound `u32: Trait` is not satisfied bar(&true); - //~^ error: the trait bound `bool: Traitor<{_: u8}>` is not satisfied + //~^ error: the trait bound `bool: Traitor<_>` is not satisfied } diff --git a/src/test/ui/const-generics/defaults/trait_objects_fail.stderr b/src/test/ui/const-generics/defaults/trait_objects_fail.stderr index da85b2059f0a3..a9c185e5fcbd1 100644 --- a/src/test/ui/const-generics/defaults/trait_objects_fail.stderr +++ b/src/test/ui/const-generics/defaults/trait_objects_fail.stderr @@ -6,19 +6,19 @@ LL | foo(&10_u32); | | | required by a bound introduced by this call | - = help: the trait `Trait<2_u8>` is implemented for `u32` + = help: the trait `Trait<2>` is implemented for `u32` = note: required for the cast from `u32` to the object type `dyn Trait` -error[E0277]: the trait bound `bool: Traitor<{_: u8}>` is not satisfied +error[E0277]: the trait bound `bool: Traitor<_>` is not satisfied --> $DIR/trait_objects_fail.rs:28:9 | LL | bar(&true); - | --- ^^^^^ the trait `Traitor<{_: u8}>` is not implemented for `bool` + | --- ^^^^^ the trait `Traitor<_>` is not implemented for `bool` | | | required by a bound introduced by this call | - = help: the trait `Traitor<2_u8, 3_u8>` is implemented for `bool` - = note: required for the cast from `bool` to the object type `dyn Traitor<{_: u8}>` + = help: the trait `Traitor<2, 3>` is implemented for `bool` + = note: required for the cast from `bool` to the object type `dyn Traitor<_>` error: aborting due to 2 previous errors diff --git a/src/test/ui/const-generics/defaults/wfness.rs b/src/test/ui/const-generics/defaults/wfness.rs index d366040ba3ea6..a93f670815a03 100644 --- a/src/test/ui/const-generics/defaults/wfness.rs +++ b/src/test/ui/const-generics/defaults/wfness.rs @@ -3,16 +3,20 @@ struct Ooopsies; trait Trait {} impl Trait<3> for () {} -struct WhereClause where (): Trait; -//~^ error: the trait bound `(): Trait<2_u8>` is not satisfied +struct WhereClause +where + (): Trait; +//~^ error: the trait bound `(): Trait<2>` is not satisfied trait Traitor {} -struct WhereClauseTooGeneric(T) where (): Traitor; +struct WhereClauseTooGeneric(T) +where + (): Traitor; // no error on struct def struct DependentDefaultWfness>(T); fn foo() -> DependentDefaultWfness { - //~^ error: the trait bound `(): Trait<1_u8>` is not satisfied + //~^ error: the trait bound `(): Trait<1>` is not satisfied loop {} } diff --git a/src/test/ui/const-generics/defaults/wfness.stderr b/src/test/ui/const-generics/defaults/wfness.stderr index 8b405d6753e56..25038f830befc 100644 --- a/src/test/ui/const-generics/defaults/wfness.stderr +++ b/src/test/ui/const-generics/defaults/wfness.stderr @@ -4,26 +4,29 @@ error[E0080]: evaluation of constant value failed LL | struct Ooopsies; | ^^^^^^^^^^^ attempt to compute `u8::MAX + 1_u8`, which would overflow -error[E0277]: the trait bound `(): Trait<2_u8>` is not satisfied - --> $DIR/wfness.rs:6:47 +error[E0277]: the trait bound `(): Trait<2>` is not satisfied + --> $DIR/wfness.rs:8:9 | -LL | struct WhereClause where (): Trait; - | ^^^^^^^^ the trait `Trait<2_u8>` is not implemented for `()` +LL | (): Trait; + | ^^^^^^^^ the trait `Trait<2>` is not implemented for `()` | - = help: the trait `Trait<3_u8>` is implemented for `()` + = help: the trait `Trait<3>` is implemented for `()` -error[E0277]: the trait bound `(): Trait<1_u8>` is not satisfied - --> $DIR/wfness.rs:14:13 +error[E0277]: the trait bound `(): Trait<1>` is not satisfied + --> $DIR/wfness.rs:18:13 | LL | fn foo() -> DependentDefaultWfness { - | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<1_u8>` is not implemented for `()` + | ^^^^^^^^^^^^^^^^^^^^^^ the trait `Trait<1>` is not implemented for `()` | - = help: the trait `Trait<3_u8>` is implemented for `()` + = help: the trait `Trait<3>` is implemented for `()` note: required by a bound in `WhereClause` - --> $DIR/wfness.rs:6:47 + --> $DIR/wfness.rs:8:9 | -LL | struct WhereClause where (): Trait; - | ^^^^^^^^ required by this bound in `WhereClause` +LL | struct WhereClause + | ----------- required by a bound in this +LL | where +LL | (): Trait; + | ^^^^^^^^ required by this bound in `WhereClause` error: aborting due to 3 previous errors diff --git a/src/test/ui/const-generics/different_generic_args.full.stderr b/src/test/ui/const-generics/different_generic_args.full.stderr index a2dcc033627c6..eba1768f7dda3 100644 --- a/src/test/ui/const-generics/different_generic_args.full.stderr +++ b/src/test/ui/const-generics/different_generic_args.full.stderr @@ -2,10 +2,10 @@ error[E0308]: mismatched types --> $DIR/different_generic_args.rs:11:9 | LL | u = ConstUsize::<4> {}; - | ^^^^^^^^^^^^^^^^^^ expected `3_usize`, found `4_usize` + | ^^^^^^^^^^^^^^^^^^ expected `3`, found `4` | - = note: expected struct `ConstUsize<3_usize>` - found struct `ConstUsize<4_usize>` + = note: expected struct `ConstUsize<3>` + found struct `ConstUsize<4>` error: aborting due to previous error diff --git a/src/test/ui/const-generics/different_generic_args.min.stderr b/src/test/ui/const-generics/different_generic_args.min.stderr index a2dcc033627c6..eba1768f7dda3 100644 --- a/src/test/ui/const-generics/different_generic_args.min.stderr +++ b/src/test/ui/const-generics/different_generic_args.min.stderr @@ -2,10 +2,10 @@ error[E0308]: mismatched types --> $DIR/different_generic_args.rs:11:9 | LL | u = ConstUsize::<4> {}; - | ^^^^^^^^^^^^^^^^^^ expected `3_usize`, found `4_usize` + | ^^^^^^^^^^^^^^^^^^ expected `3`, found `4` | - = note: expected struct `ConstUsize<3_usize>` - found struct `ConstUsize<4_usize>` + = note: expected struct `ConstUsize<3>` + found struct `ConstUsize<4>` error: aborting due to previous error diff --git a/src/test/ui/const-generics/different_generic_args_array.stderr b/src/test/ui/const-generics/different_generic_args_array.stderr index f0b9035357d82..4c5b5ada4f132 100644 --- a/src/test/ui/const-generics/different_generic_args_array.stderr +++ b/src/test/ui/const-generics/different_generic_args_array.stderr @@ -2,10 +2,10 @@ error[E0308]: mismatched types --> $DIR/different_generic_args_array.rs:9:9 | LL | x = Const::<{ [4] }> {}; - | ^^^^^^^^^^^^^^^^^^^ expected `[3_usize]`, found `[4_usize]` + | ^^^^^^^^^^^^^^^^^^^ expected `[3]`, found `[4]` | - = note: expected struct `Const<[3_usize]>` - found struct `Const<[4_usize]>` + = note: expected struct `Const<[3]>` + found struct `Const<[4]>` error: aborting due to previous error diff --git a/src/test/ui/const-generics/exhaustive-value.stderr b/src/test/ui/const-generics/exhaustive-value.stderr index 9c1b086f4da9a..76a83ba67ce79 100644 --- a/src/test/ui/const-generics/exhaustive-value.stderr +++ b/src/test/ui/const-generics/exhaustive-value.stderr @@ -5,14 +5,14 @@ LL | <() as Foo>::test() | ^^^^^^^^^^^^^^^^^^^^ the trait `Foo` is not implemented for `()` | = help: the following other types implement trait `Foo`: - <() as Foo<0_u8>> - <() as Foo<100_u8>> - <() as Foo<101_u8>> - <() as Foo<102_u8>> - <() as Foo<103_u8>> - <() as Foo<104_u8>> - <() as Foo<105_u8>> - <() as Foo<106_u8>> + <() as Foo<0>> + <() as Foo<100>> + <() as Foo<101>> + <() as Foo<102>> + <() as Foo<103>> + <() as Foo<104>> + <() as Foo<105>> + <() as Foo<106>> and 248 others error: aborting due to previous error diff --git a/src/test/ui/const-generics/generic_arg_infer/in-signature.stderr b/src/test/ui/const-generics/generic_arg_infer/in-signature.stderr index 7581cf4120ecf..52d1b29f93222 100644 --- a/src/test/ui/const-generics/generic_arg_infer/in-signature.stderr +++ b/src/test/ui/const-generics/generic_arg_infer/in-signature.stderr @@ -14,7 +14,7 @@ LL | fn ty_fn() -> Bar { | ---------^- | | | | | not allowed in type signatures - | help: replace with the correct return type: `Bar` + | help: replace with the correct return type: `Bar` error[E0121]: the placeholder `_` is not allowed within types on item signatures for return types --> $DIR/in-signature.rs:17:25 @@ -24,7 +24,7 @@ LL | fn ty_fn_mixed() -> Bar<_, _> { | | | | | | | not allowed in type signatures | | not allowed in type signatures - | help: replace with the correct return type: `Bar` + | help: replace with the correct return type: `Bar` error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants --> $DIR/in-signature.rs:22:15 @@ -45,7 +45,7 @@ LL | const TY_CT: Bar = Bar::(0); | ^^^^^^^^^^^ | | | not allowed in type signatures - | help: replace with the correct type: `Bar` + | help: replace with the correct type: `Bar` error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables --> $DIR/in-signature.rs:28:19 @@ -54,7 +54,7 @@ LL | static TY_STATIC: Bar = Bar::(0); | ^^^^^^^^^^^ | | | not allowed in type signatures - | help: replace with the correct type: `Bar` + | help: replace with the correct type: `Bar` error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants --> $DIR/in-signature.rs:30:20 @@ -63,7 +63,7 @@ LL | const TY_CT_MIXED: Bar<_, _> = Bar::(0); | ^^^^^^^^^ | | | not allowed in type signatures - | help: replace with the correct type: `Bar` + | help: replace with the correct type: `Bar` error[E0121]: the placeholder `_` is not allowed within types on item signatures for static variables --> $DIR/in-signature.rs:32:25 @@ -72,7 +72,7 @@ LL | static TY_STATIC_MIXED: Bar<_, _> = Bar::(0); | ^^^^^^^^^ | | | not allowed in type signatures - | help: replace with the correct type: `Bar` + | help: replace with the correct type: `Bar` error[E0121]: the placeholder `_` is not allowed within types on item signatures for constants --> $DIR/in-signature.rs:35:21 diff --git a/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr b/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr index f235eb443b829..ababb27a869d6 100644 --- a/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/abstract-const-as-cast-3.stderr @@ -56,19 +56,19 @@ error[E0308]: mismatched types --> $DIR/abstract-const-as-cast-3.rs:23:5 | LL | assert_impl::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `12_u128`, found `13_u128` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `12`, found `13` | - = note: expected type `12_u128` - found type `13_u128` + = note: expected type `12` + found type `13` error[E0308]: mismatched types --> $DIR/abstract-const-as-cast-3.rs:25:5 | LL | assert_impl::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `13_u128`, found `14_u128` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `13`, found `14` | - = note: expected type `13_u128` - found type `14_u128` + = note: expected type `13` + found type `14` error: unconstrained generic constant --> $DIR/abstract-const-as-cast-3.rs:35:5 @@ -128,19 +128,19 @@ error[E0308]: mismatched types --> $DIR/abstract-const-as-cast-3.rs:41:5 | LL | assert_impl::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `12_u128`, found `13_u128` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `12`, found `13` | - = note: expected type `12_u128` - found type `13_u128` + = note: expected type `12` + found type `13` error[E0308]: mismatched types --> $DIR/abstract-const-as-cast-3.rs:43:5 | LL | assert_impl::>(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `13_u128`, found `14_u128` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `13`, found `14` | - = note: expected type `13_u128` - found type `14_u128` + = note: expected type `13` + found type `14` error: aborting due to 12 previous errors diff --git a/src/test/ui/const-generics/generic_const_exprs/from-sig-fail.rs b/src/test/ui/const-generics/generic_const_exprs/from-sig-fail.rs index 90953145944fe..b8f9827ec9187 100644 --- a/src/test/ui/const-generics/generic_const_exprs/from-sig-fail.rs +++ b/src/test/ui/const-generics/generic_const_exprs/from-sig-fail.rs @@ -2,7 +2,7 @@ #![allow(incomplete_features)] fn test() -> [u8; N - 1] { - //~^ ERROR evaluation of `test::<0_usize>::{constant#0}` failed + //~^ ERROR evaluation of `test::<0>::{constant#0}` failed todo!() } diff --git a/src/test/ui/const-generics/generic_const_exprs/from-sig-fail.stderr b/src/test/ui/const-generics/generic_const_exprs/from-sig-fail.stderr index 31ccf97969472..bd71b49ee238b 100644 --- a/src/test/ui/const-generics/generic_const_exprs/from-sig-fail.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/from-sig-fail.stderr @@ -1,4 +1,4 @@ -error[E0080]: evaluation of `test::<0_usize>::{constant#0}` failed +error[E0080]: evaluation of `test::<0>::{constant#0}` failed --> $DIR/from-sig-fail.rs:4:35 | LL | fn test() -> [u8; N - 1] { diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-69654.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-69654.stderr index 77a3b77ad428b..7a083733a2cd1 100644 --- a/src/test/ui/const-generics/generic_const_exprs/issue-69654.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/issue-69654.stderr @@ -4,14 +4,14 @@ error[E0423]: expected value, found type parameter `T` LL | impl Bar for [u8; T] {} | ^ not a value -error[E0599]: the function or associated item `foo` exists for struct `Foo<{_: usize}>`, but its trait bounds were not satisfied +error[E0599]: the function or associated item `foo` exists for struct `Foo<_>`, but its trait bounds were not satisfied --> $DIR/issue-69654.rs:17:10 | LL | struct Foo {} | -------------------------- function or associated item `foo` not found for this struct ... LL | Foo::foo(); - | ^^^ function or associated item cannot be called on `Foo<{_: usize}>` due to unsatisfied trait bounds + | ^^^ function or associated item cannot be called on `Foo<_>` due to unsatisfied trait bounds | = note: the following trait bounds were not satisfied: `[u8; _]: Bar<[(); _]>` diff --git a/src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr b/src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr index 41afaec86b6e4..4d0d0253f1b6d 100644 --- a/src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/issue-72787.min.stderr @@ -34,21 +34,21 @@ LL | IsLessOrEqual<{ 8 - I }, { 8 - J }>: True, = help: const parameters may only be used as standalone arguments, i.e. `J` = help: use `#![feature(generic_const_exprs)]` to allow generic const expressions -error[E0283]: type annotations needed: cannot satisfy `IsLessOrEqual: True` +error[E0283]: type annotations needed: cannot satisfy `IsLessOrEqual: True` --> $DIR/issue-72787.rs:21:26 | LL | IsLessOrEqual: True, | ^^^^ | - = note: cannot satisfy `IsLessOrEqual: True` + = note: cannot satisfy `IsLessOrEqual: True` -error[E0283]: type annotations needed: cannot satisfy `IsLessOrEqual: True` +error[E0283]: type annotations needed: cannot satisfy `IsLessOrEqual: True` --> $DIR/issue-72787.rs:21:26 | LL | IsLessOrEqual: True, | ^^^^ | - = note: cannot satisfy `IsLessOrEqual: True` + = note: cannot satisfy `IsLessOrEqual: True` error: aborting due to 6 previous errors diff --git a/src/test/ui/const-generics/generic_const_exprs/simple_fail.rs b/src/test/ui/const-generics/generic_const_exprs/simple_fail.rs index c47a350c7fb43..cae54df4c1210 100644 --- a/src/test/ui/const-generics/generic_const_exprs/simple_fail.rs +++ b/src/test/ui/const-generics/generic_const_exprs/simple_fail.rs @@ -2,10 +2,13 @@ #![allow(incomplete_features)] type Arr = [u8; N - 1]; -//~^ ERROR evaluation of `Arr::<0_usize>::{constant#0}` failed +//~^ ERROR evaluation of `Arr::<0>::{constant#0}` failed -fn test() -> Arr where [u8; N - 1]: Sized { -//~^ ERROR evaluation of `test::<0_usize>::{constant#0}` failed +fn test() -> Arr +where + [u8; N - 1]: Sized, + //~^ ERROR evaluation of `test::<0>::{constant#0}` failed +{ todo!() } diff --git a/src/test/ui/const-generics/generic_const_exprs/simple_fail.stderr b/src/test/ui/const-generics/generic_const_exprs/simple_fail.stderr index 99fc92fb4f0ad..a25fa56b7d498 100644 --- a/src/test/ui/const-generics/generic_const_exprs/simple_fail.stderr +++ b/src/test/ui/const-generics/generic_const_exprs/simple_fail.stderr @@ -1,10 +1,10 @@ -error[E0080]: evaluation of `test::<0_usize>::{constant#0}` failed - --> $DIR/simple_fail.rs:7:48 +error[E0080]: evaluation of `test::<0>::{constant#0}` failed + --> $DIR/simple_fail.rs:9:10 | -LL | fn test() -> Arr where [u8; N - 1]: Sized { - | ^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow +LL | [u8; N - 1]: Sized, + | ^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow -error[E0080]: evaluation of `Arr::<0_usize>::{constant#0}` failed +error[E0080]: evaluation of `Arr::<0>::{constant#0}` failed --> $DIR/simple_fail.rs:4:33 | LL | type Arr = [u8; N - 1]; diff --git a/src/test/ui/const-generics/infer/one-param-uninferred.stderr b/src/test/ui/const-generics/infer/one-param-uninferred.stderr index 98ea8df825265..cf70c21813950 100644 --- a/src/test/ui/const-generics/infer/one-param-uninferred.stderr +++ b/src/test/ui/const-generics/infer/one-param-uninferred.stderr @@ -6,8 +6,8 @@ LL | let _: [u8; 17] = foo(); | help: consider specifying the generic arguments | -LL | let _: [u8; 17] = foo::<17_usize, M>(); - | +++++++++++++++ +LL | let _: [u8; 17] = foo::<17, M>(); + | +++++++++ error: aborting due to previous error diff --git a/src/test/ui/const-generics/issue-66451.stderr b/src/test/ui/const-generics/issue-66451.stderr index b691eac4f2d0e..e0cb0b661ff65 100644 --- a/src/test/ui/const-generics/issue-66451.stderr +++ b/src/test/ui/const-generics/issue-66451.stderr @@ -8,12 +8,12 @@ LL | | value: 3, LL | | nested: &Bar(5), LL | | } LL | | }> = x; - | | - ^ expected `Foo { value: 3_i32, nested: &Bar::(5_i32) }`, found `Foo { value: 3_i32, nested: &Bar::(4_i32) }` + | | - ^ expected `Foo { value: 3, nested: &Bar::(5) }`, found `Foo { value: 3, nested: &Bar::(4) }` | |______| | expected due to this | - = note: expected struct `Test(5_i32) }>` - found struct `Test(4_i32) }>` + = note: expected struct `Test(5) }>` + found struct `Test(4) }>` error: aborting due to previous error diff --git a/src/test/ui/const-generics/nested-type.full.stderr b/src/test/ui/const-generics/nested-type.full.stderr index 52f1c58825823..6d9f4406504ee 100644 --- a/src/test/ui/const-generics/nested-type.full.stderr +++ b/src/test/ui/const-generics/nested-type.full.stderr @@ -1,4 +1,4 @@ -error[E0015]: cannot call non-const fn `Foo::{constant#0}::Foo::<17_usize>::value` in constants +error[E0015]: cannot call non-const fn `Foo::{constant#0}::Foo::<17>::value` in constants --> $DIR/nested-type.rs:15:5 | LL | Foo::<17>::value() diff --git a/src/test/ui/const-generics/occurs-check/unused-substs-1.stderr b/src/test/ui/const-generics/occurs-check/unused-substs-1.stderr index 48e12e903b86a..a3c011d927b5a 100644 --- a/src/test/ui/const-generics/occurs-check/unused-substs-1.stderr +++ b/src/test/ui/const-generics/occurs-check/unused-substs-1.stderr @@ -1,10 +1,10 @@ -error[E0277]: the trait bound `A<{_: usize}>: Bar<{_: usize}>` is not satisfied +error[E0277]: the trait bound `A<_>: Bar<_>` is not satisfied --> $DIR/unused-substs-1.rs:12:13 | LL | let _ = A; - | ^ the trait `Bar<{_: usize}>` is not implemented for `A<{_: usize}>` + | ^ the trait `Bar<_>` is not implemented for `A<_>` | - = help: the trait `Bar` is implemented for `A<7_usize>` + = help: the trait `Bar` is implemented for `A<7>` note: required by a bound in `A` --> $DIR/unused-substs-1.rs:9:11 | diff --git a/src/test/ui/const-generics/types-mismatch-const-args.full.stderr b/src/test/ui/const-generics/types-mismatch-const-args.full.stderr index 4d6b752867f1b..486506239ddfd 100644 --- a/src/test/ui/const-generics/types-mismatch-const-args.full.stderr +++ b/src/test/ui/const-generics/types-mismatch-const-args.full.stderr @@ -2,10 +2,10 @@ error[E0308]: mismatched types --> $DIR/types-mismatch-const-args.rs:14:41 | LL | let _: A<'a, u32, {2u32}, {3u32}> = A::<'a, u32, {2u32 + 2u32}, {3u32}> { data: PhantomData }; - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `2_u32`, found `4_u32` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `2`, found `4` | - = note: expected type `2_u32` - found type `4_u32` + = note: expected type `2` + found type `4` error[E0308]: mismatched types --> $DIR/types-mismatch-const-args.rs:16:41 @@ -26,8 +26,8 @@ LL | let _: A<'a, u16, {4u32}, {3u32}> = A::<'b, u32, {2u32}, {3u32}> { data | | | expected due to this | - = note: expected struct `A<'a, u16, 4_u32, _>` - found struct `A<'b, u32, 2_u32, _>` + = note: expected struct `A<'a, u16, 4, _>` + found struct `A<'b, u32, 2, _>` error: aborting due to 3 previous errors diff --git a/src/test/ui/const-generics/types-mismatch-const-args.min.stderr b/src/test/ui/const-generics/types-mismatch-const-args.min.stderr index 8b60238cb0c03..6ac93a08d5d68 100644 --- a/src/test/ui/const-generics/types-mismatch-const-args.min.stderr +++ b/src/test/ui/const-generics/types-mismatch-const-args.min.stderr @@ -2,12 +2,12 @@ error[E0308]: mismatched types --> $DIR/types-mismatch-const-args.rs:14:41 | LL | let _: A<'a, u32, {2u32}, {3u32}> = A::<'a, u32, {2u32 + 2u32}, {3u32}> { data: PhantomData }; - | -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `2_u32`, found `4_u32` + | -------------------------- ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ expected `2`, found `4` | | | expected due to this | - = note: expected struct `A<'_, _, 2_u32, _>` - found struct `A<'_, _, 4_u32, _>` + = note: expected struct `A<'_, _, 2, _>` + found struct `A<'_, _, 4, _>` error[E0308]: mismatched types --> $DIR/types-mismatch-const-args.rs:16:41 @@ -28,8 +28,8 @@ LL | let _: A<'a, u16, {4u32}, {3u32}> = A::<'b, u32, {2u32}, {3u32}> { data | | | expected due to this | - = note: expected struct `A<'a, u16, 4_u32, _>` - found struct `A<'b, u32, 2_u32, _>` + = note: expected struct `A<'a, u16, 4, _>` + found struct `A<'b, u32, 2, _>` error: aborting due to 3 previous errors diff --git a/src/test/ui/consts/const-eval/issue-85155.stderr b/src/test/ui/consts/const-eval/issue-85155.stderr index c36d7c1721526..3d2c76b7ed040 100644 --- a/src/test/ui/consts/const-eval/issue-85155.stderr +++ b/src/test/ui/consts/const-eval/issue-85155.stderr @@ -1,10 +1,10 @@ -error[E0080]: evaluation of `post_monomorphization_error::ValidateConstImm::<2_i32, 0_i32, 1_i32>::VALID` failed +error[E0080]: evaluation of `post_monomorphization_error::ValidateConstImm::<2, 0, 1>::VALID` failed --> $DIR/auxiliary/post_monomorphization_error.rs:7:17 | LL | let _ = 1 / ((IMM >= MIN && IMM <= MAX) as usize); | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ attempt to divide `1_usize` by zero -note: the above error was encountered while instantiating `fn post_monomorphization_error::stdarch_intrinsic::<2_i32>` +note: the above error was encountered while instantiating `fn post_monomorphization_error::stdarch_intrinsic::<2>` --> $DIR/issue-85155.rs:19:5 | LL | post_monomorphization_error::stdarch_intrinsic::<2>(); diff --git a/src/test/ui/dropck/reject-specialized-drops-8142.stderr b/src/test/ui/dropck/reject-specialized-drops-8142.stderr index ebd484b880001..cb48221c67a82 100644 --- a/src/test/ui/dropck/reject-specialized-drops-8142.stderr +++ b/src/test/ui/dropck/reject-specialized-drops-8142.stderr @@ -104,7 +104,7 @@ error[E0366]: `Drop` impls cannot be specialized LL | impl Drop for X<3> { fn drop(&mut self) { } } // REJECT | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ | - = note: `3_usize` is not a generic parameter + = note: `3` is not a generic parameter note: use the same sequence of generic lifetime, type and const parameters as the struct definition --> $DIR/reject-specialized-drops-8142.rs:17:1 | diff --git a/src/test/ui/inline-const/const-expr-generic-err.stderr b/src/test/ui/inline-const/const-expr-generic-err.stderr index db0d85a2d4e74..fc0b6cc445164 100644 --- a/src/test/ui/inline-const/const-expr-generic-err.stderr +++ b/src/test/ui/inline-const/const-expr-generic-err.stderr @@ -12,13 +12,13 @@ note: the above error was encountered while instantiating `fn foo::` LL | foo::(); | ^^^^^^^^^^^^ -error[E0080]: evaluation of `bar::<0_usize>::{constant#0}` failed +error[E0080]: evaluation of `bar::<0>::{constant#0}` failed --> $DIR/const-expr-generic-err.rs:9:13 | LL | const { N - 1 } | ^^^^^ attempt to compute `0_usize - 1_usize`, which would overflow -note: the above error was encountered while instantiating `fn bar::<0_usize>` +note: the above error was encountered while instantiating `fn bar::<0>` --> $DIR/const-expr-generic-err.rs:14:5 | LL | bar::<0>(); diff --git a/src/test/ui/lint/function-item-references.stderr b/src/test/ui/lint/function-item-references.stderr index 33db687df31d2..a9d18bb6a4743 100644 --- a/src/test/ui/lint/function-item-references.stderr +++ b/src/test/ui/lint/function-item-references.stderr @@ -116,7 +116,7 @@ warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:118:22 | LL | println!("{:p}", &take_generic_array::); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: cast `take_generic_array` to obtain a function pointer: `take_generic_array:: as fn(_)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: cast `take_generic_array` to obtain a function pointer: `take_generic_array:: as fn(_)` warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:120:22 @@ -128,7 +128,7 @@ warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:122:22 | LL | println!("{:p}", &multiple_generic_arrays::); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: cast `multiple_generic_arrays` to obtain a function pointer: `multiple_generic_arrays:: as fn(_, _)` + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ help: cast `multiple_generic_arrays` to obtain a function pointer: `multiple_generic_arrays:: as fn(_, _)` warning: taking a reference to a function item does not give a function pointer --> $DIR/function-item-references.rs:124:22 diff --git a/src/test/ui/methods/method-not-found-generic-arg-elision.rs b/src/test/ui/methods/method-not-found-generic-arg-elision.rs index 3df928b5d804d..799ced5e9c460 100644 --- a/src/test/ui/methods/method-not-found-generic-arg-elision.rs +++ b/src/test/ui/methods/method-not-found-generic-arg-elision.rs @@ -61,13 +61,13 @@ impl Other { fn other(&self) {} } -struct Struct{ - _phatom: PhantomData +struct Struct { + _phatom: PhantomData, } impl Default for Struct { fn default() -> Self { - Self{ _phatom: PhantomData } + Self { _phatom: PhantomData } } } @@ -76,9 +76,9 @@ impl Struct { } fn main() { - let point_f64 = Point{ x: 1_f64, y: 1_f64}; + let point_f64 = Point { x: 1_f64, y: 1_f64 }; let d = point_f64.distance(); - let point_i32 = Point{ x: 1_i32, y: 1_i32}; + let point_i32 = Point { x: 1_i32, y: 1_i32 }; let d = point_i32.distance(); //~^ ERROR no method named `distance` found for struct `Point let d = point_i32.other(); @@ -92,9 +92,9 @@ fn main() { wrapper.other(); //~^ ERROR no method named `other` found for struct `Wrapper let boolean = true; - let wrapper = Wrapper2::<'_, _, 3> {x: &boolean}; + let wrapper = Wrapper2::<'_, _, 3> { x: &boolean }; wrapper.method(); - //~^ ERROR no method named `method` found for struct `Wrapper2<'_, bool, 3_usize> + //~^ ERROR no method named `method` found for struct `Wrapper2<'_, bool, 3> wrapper.other(); //~^ ERROR no method named `other` found for struct `Wrapper2 let a = vec![1, 2, 3]; diff --git a/src/test/ui/methods/method-not-found-generic-arg-elision.stderr b/src/test/ui/methods/method-not-found-generic-arg-elision.stderr index 56e1b5a0f4473..fc42d1a4dcd08 100644 --- a/src/test/ui/methods/method-not-found-generic-arg-elision.stderr +++ b/src/test/ui/methods/method-not-found-generic-arg-elision.stderr @@ -50,14 +50,14 @@ LL | struct Wrapper(T); LL | wrapper.other(); | ^^^^^ method not found in `Wrapper` -error[E0599]: no method named `method` found for struct `Wrapper2<'_, bool, 3_usize>` in the current scope +error[E0599]: no method named `method` found for struct `Wrapper2<'_, bool, 3>` in the current scope --> $DIR/method-not-found-generic-arg-elision.rs:96:13 | LL | struct Wrapper2<'a, T, const C: usize> { | -------------------------------------- method `method` not found for this struct ... LL | wrapper.method(); - | ^^^^^^ method not found in `Wrapper2<'_, bool, 3_usize>` + | ^^^^^^ method not found in `Wrapper2<'_, bool, 3>` | = note: the method was found for - `Wrapper2<'a, i8, C>` @@ -71,7 +71,7 @@ LL | struct Wrapper2<'a, T, const C: usize> { | -------------------------------------- method `other` not found for this struct ... LL | wrapper.other(); - | ^^^^^ method not found in `Wrapper2<'_, bool, 3_usize>` + | ^^^^^ method not found in `Wrapper2<'_, bool, 3>` error[E0599]: no method named `not_found` found for struct `Vec<{integer}>` in the current scope --> $DIR/method-not-found-generic-arg-elision.rs:101:7 @@ -82,7 +82,7 @@ LL | a.not_found(); error[E0599]: the method `method` exists for struct `Struct`, but its trait bounds were not satisfied --> $DIR/method-not-found-generic-arg-elision.rs:104:7 | -LL | struct Struct{ +LL | struct Struct { | ---------------- method `method` not found for this struct ... LL | s.method(); diff --git a/src/test/ui/simd/intrinsic/generic-shuffle.stderr b/src/test/ui/simd/intrinsic/generic-shuffle.stderr index 44c57cd7c47bc..81e641612ce00 100644 --- a/src/test/ui/simd/intrinsic/generic-shuffle.stderr +++ b/src/test/ui/simd/intrinsic/generic-shuffle.stderr @@ -1,10 +1,10 @@ -error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 2, found `Simd` with length 4 +error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return type of length 2, found `Simd` with length 4 --> $DIR/generic-shuffle.rs:24:31 | LL | let _: Simd = simd_shuffle(v, v, I); | ^^^^^^^^^^^^^^^^^^^^^ -error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `u32` (element of input `Simd`), found `Simd` with element type `f32` +error[E0511]: invalid monomorphization of `simd_shuffle` intrinsic: expected return element type `u32` (element of input `Simd`), found `Simd` with element type `f32` --> $DIR/generic-shuffle.rs:27:31 | LL | let _: Simd = simd_shuffle(v, v, I); diff --git a/src/test/ui/simd/libm_no_std_cant_float.stderr b/src/test/ui/simd/libm_no_std_cant_float.stderr index dc8638f6ab72d..7249914256cd9 100644 --- a/src/test/ui/simd/libm_no_std_cant_float.stderr +++ b/src/test/ui/simd/libm_no_std_cant_float.stderr @@ -2,37 +2,37 @@ error[E0599]: no method named `ceil` found for struct `Simd` in the current scop --> $DIR/libm_no_std_cant_float.rs:14:17 | LL | let _xc = x.ceil(); - | ^^^^ method not found in `Simd` + | ^^^^ method not found in `Simd` error[E0599]: no method named `floor` found for struct `Simd` in the current scope --> $DIR/libm_no_std_cant_float.rs:15:17 | LL | let _xf = x.floor(); - | ^^^^^ method not found in `Simd` + | ^^^^^ method not found in `Simd` error[E0599]: no method named `round` found for struct `Simd` in the current scope --> $DIR/libm_no_std_cant_float.rs:16:17 | LL | let _xr = x.round(); - | ^^^^^ method not found in `Simd` + | ^^^^^ method not found in `Simd` error[E0599]: no method named `trunc` found for struct `Simd` in the current scope --> $DIR/libm_no_std_cant_float.rs:17:17 | LL | let _xt = x.trunc(); - | ^^^^^ method not found in `Simd` + | ^^^^^ method not found in `Simd` error[E0599]: no method named `mul_add` found for struct `Simd` in the current scope --> $DIR/libm_no_std_cant_float.rs:18:19 | LL | let _xfma = x.mul_add(x, x); - | ^^^^^^^ method not found in `Simd` + | ^^^^^^^ method not found in `Simd` error[E0599]: no method named `sqrt` found for struct `Simd` in the current scope --> $DIR/libm_no_std_cant_float.rs:19:20 | LL | let _xsqrt = x.sqrt(); - | ^^^^ method not found in `Simd` + | ^^^^ method not found in `Simd` error: aborting due to 6 previous errors diff --git a/src/test/ui/simd/type-generic-monomorphisation-empty.rs b/src/test/ui/simd/type-generic-monomorphisation-empty.rs index 0121404c74935..2bf6641e9c91c 100644 --- a/src/test/ui/simd/type-generic-monomorphisation-empty.rs +++ b/src/test/ui/simd/type-generic-monomorphisation-empty.rs @@ -2,7 +2,7 @@ #![feature(repr_simd, platform_intrinsics)] -// error-pattern:monomorphising SIMD type `Simd<0_usize>` of zero length +// error-pattern:monomorphising SIMD type `Simd<0>` of zero length #[repr(simd)] struct Simd([f32; N]); diff --git a/src/test/ui/simd/type-generic-monomorphisation-empty.stderr b/src/test/ui/simd/type-generic-monomorphisation-empty.stderr index 00fde199b12a2..b334b1f4b5893 100644 --- a/src/test/ui/simd/type-generic-monomorphisation-empty.stderr +++ b/src/test/ui/simd/type-generic-monomorphisation-empty.stderr @@ -1,4 +1,4 @@ -error: monomorphising SIMD type `Simd<0_usize>` of zero length +error: monomorphising SIMD type `Simd<0>` of zero length error: aborting due to previous error diff --git a/src/test/ui/simd/type-generic-monomorphisation-oversized.rs b/src/test/ui/simd/type-generic-monomorphisation-oversized.rs index bd0d457b35e27..a7dc482f3cb1d 100644 --- a/src/test/ui/simd/type-generic-monomorphisation-oversized.rs +++ b/src/test/ui/simd/type-generic-monomorphisation-oversized.rs @@ -2,7 +2,7 @@ #![feature(repr_simd, platform_intrinsics)] -// error-pattern:monomorphising SIMD type `Simd<65536_usize>` of length greater than 32768 +// error-pattern:monomorphising SIMD type `Simd<65536>` of length greater than 32768 #[repr(simd)] struct Simd([f32; N]); diff --git a/src/test/ui/simd/type-generic-monomorphisation-oversized.stderr b/src/test/ui/simd/type-generic-monomorphisation-oversized.stderr index f441835011532..a2dba1222eecd 100644 --- a/src/test/ui/simd/type-generic-monomorphisation-oversized.stderr +++ b/src/test/ui/simd/type-generic-monomorphisation-oversized.stderr @@ -1,4 +1,4 @@ -error: monomorphising SIMD type `Simd<65536_usize>` of length greater than 32768 +error: monomorphising SIMD type `Simd<65536>` of length greater than 32768 error: aborting due to previous error diff --git a/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr index 6c82d31e18d8b..e7565525ad338 100644 --- a/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr +++ b/src/test/ui/type-alias-impl-trait/generic_nondefining_use.stderr @@ -25,7 +25,7 @@ error: non-defining opaque type use in defining scope LL | 7u32 | ^^^^ | -note: used non-generic constant `123_usize` for generic parameter +note: used non-generic constant `123` for generic parameter --> $DIR/generic_nondefining_use.rs:11:15 | LL | type OneConst = impl Debug; From c6454a8d654aed1ab08aaf8a5038c40819e9a48a Mon Sep 17 00:00:00 2001 From: Artur Sinila Date: Tue, 19 Jul 2022 02:54:13 +0300 Subject: [PATCH 06/14] tests: fix `rustc-pass-by-value-self` --- .../ui-fulldeps/internal-lints/rustc_pass_by_value_self.rs | 4 ++-- .../internal-lints/rustc_pass_by_value_self.stderr | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.rs b/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.rs index 2868517774d46..6ce67dcaf1d9b 100644 --- a/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.rs +++ b/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.rs @@ -44,11 +44,11 @@ struct WithParameters { } impl WithParameters { - fn with_ref(&self) {} //~ ERROR passing `WithParameters` by reference + fn with_ref(&self) {} //~ ERROR passing `WithParameters` by reference } impl WithParameters { - fn with_ref(&self) {} //~ ERROR passing `WithParameters` by reference + fn with_ref(&self) {} //~ ERROR passing `WithParameters` by reference } fn main() {} diff --git a/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.stderr b/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.stderr index 54a7cf7cab757..9cc97c0d16500 100644 --- a/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.stderr +++ b/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.stderr @@ -26,13 +26,13 @@ error: passing `WithParameters` by reference --> $DIR/rustc_pass_by_value_self.rs:47:17 | LL | fn with_ref(&self) {} - | ^^^^^ help: try passing by value: `WithParameters` + | ^^^^^ help: try passing by value: `WithParameters` error: passing `WithParameters` by reference --> $DIR/rustc_pass_by_value_self.rs:51:17 | LL | fn with_ref(&self) {} - | ^^^^^ help: try passing by value: `WithParameters` + | ^^^^^ help: try passing by value: `WithParameters` error: aborting due to 5 previous errors From c44fa6e94cbcf5ed570c5ae6a46e5e6f517d5b25 Mon Sep 17 00:00:00 2001 From: Artur Sinila Date: Tue, 19 Jul 2022 03:19:24 +0300 Subject: [PATCH 07/14] tests: fix `rustc-pass-by-value-self` --- .../internal-lints/rustc_pass_by_value_self.stderr | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.stderr b/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.stderr index 9cc97c0d16500..fb39ed60b8235 100644 --- a/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.stderr +++ b/src/test/ui-fulldeps/internal-lints/rustc_pass_by_value_self.stderr @@ -22,13 +22,13 @@ error: passing `Foo` by reference LL | fn with_ref(&self) {} | ^^^^^ help: try passing by value: `Foo` -error: passing `WithParameters` by reference +error: passing `WithParameters` by reference --> $DIR/rustc_pass_by_value_self.rs:47:17 | LL | fn with_ref(&self) {} | ^^^^^ help: try passing by value: `WithParameters` -error: passing `WithParameters` by reference +error: passing `WithParameters` by reference --> $DIR/rustc_pass_by_value_self.rs:51:17 | LL | fn with_ref(&self) {} From 8530407e311dae1f6b735ed09727cc592b29f522 Mon Sep 17 00:00:00 2001 From: Artur Sinila Date: Tue, 19 Jul 2022 03:46:32 +0300 Subject: [PATCH 08/14] tests: fix `rustdoc` tests --- src/test/rustdoc/const-generics/add-impl.rs | 2 +- src/test/rustdoc/const-generics/const-generic-defaults.rs | 2 +- src/test/rustdoc/const-generics/const-generics-docs.rs | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/test/rustdoc/const-generics/add-impl.rs b/src/test/rustdoc/const-generics/add-impl.rs index e54f9a57ae4ee..591139523456e 100644 --- a/src/test/rustdoc/const-generics/add-impl.rs +++ b/src/test/rustdoc/const-generics/add-impl.rs @@ -7,7 +7,7 @@ pub struct Simd { inner: T, } -// @has foo/struct.Simd.html '//div[@id="trait-implementations-list"]//h3[@class="code-header in-band"]' 'impl Add> for Simd' +// @has foo/struct.Simd.html '//div[@id="trait-implementations-list"]//h3[@class="code-header in-band"]' 'impl Add> for Simd' impl Add for Simd { type Output = Self; diff --git a/src/test/rustdoc/const-generics/const-generic-defaults.rs b/src/test/rustdoc/const-generics/const-generic-defaults.rs index 8035f826775ef..2693d9b596993 100644 --- a/src/test/rustdoc/const-generics/const-generic-defaults.rs +++ b/src/test/rustdoc/const-generics/const-generic-defaults.rs @@ -1,5 +1,5 @@ #![crate_name = "foo"] // @has foo/struct.Foo.html '//pre[@class="rust struct"]' \ -// 'pub struct Foo(_);' +// 'pub struct Foo(_);' pub struct Foo(T); diff --git a/src/test/rustdoc/const-generics/const-generics-docs.rs b/src/test/rustdoc/const-generics/const-generics-docs.rs index 61af7de4794a6..352a8e646bb49 100644 --- a/src/test/rustdoc/const-generics/const-generics-docs.rs +++ b/src/test/rustdoc/const-generics/const-generics-docs.rs @@ -19,8 +19,8 @@ pub use extern_crate::WTrait; // @has foo/trait.Trait.html '//pre[@class="rust trait"]' \ // 'pub trait Trait' -// @has - '//*[@id="impl-Trait%3C1_usize%3E-for-u8"]//h3[@class="code-header in-band"]' 'impl Trait<1_usize> for u8' -// @has - '//*[@id="impl-Trait%3C2_usize%3E-for-u8"]//h3[@class="code-header in-band"]' 'impl Trait<2_usize> for u8' +// @has - '//*[@id="impl-Trait%3C1%3E-for-u8"]//h3[@class="code-header in-band"]' 'impl Trait<1> for u8' +// @has - '//*[@id="impl-Trait%3C2%3E-for-u8"]//h3[@class="code-header in-band"]' 'impl Trait<2> for u8' // @has - '//*[@id="impl-Trait%3C{1%20+%202}%3E-for-u8"]//h3[@class="code-header in-band"]' 'impl Trait<{1 + 2}> for u8' // @has - '//*[@id="impl-Trait%3CN%3E-for-%5Bu8%3B%20N%5D"]//h3[@class="code-header in-band"]' \ // 'impl Trait for [u8; N]' From c72a77e093556e0f1e600686adb8de4419fff4c9 Mon Sep 17 00:00:00 2001 From: joboet Date: Wed, 20 Jul 2022 16:11:31 +0200 Subject: [PATCH 09/14] owner is not micro (correct typo) --- library/std/src/sys/unix/locks/fuchsia_mutex.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys/unix/locks/fuchsia_mutex.rs b/library/std/src/sys/unix/locks/fuchsia_mutex.rs index 7372406b32fac..fd3e9d1768b4c 100644 --- a/library/std/src/sys/unix/locks/fuchsia_mutex.rs +++ b/library/std/src/sys/unix/locks/fuchsia_mutex.rs @@ -129,7 +129,7 @@ impl Mutex { ZX_ERR_INVALID_ARGS | ZX_ERR_BAD_HANDLE | ZX_ERR_WRONG_TYPE => { panic!( "either the current thread is trying to lock a mutex it has - already locked, or the previous uowner did not unlock the mutex + already locked, or the previous owner did not unlock the mutex before exiting" ) } From bd0474d24ac6438018f02afbc66b576845c44169 Mon Sep 17 00:00:00 2001 From: Josh Stone Date: Wed, 20 Jul 2022 12:09:49 -0700 Subject: [PATCH 10/14] Fix the stable version of `AsFd for Arc` and `Box` These merged in #97437 for 1.64.0, apart from the main `io_safety` feature that stabilized in 1.63.0. --- library/std/src/os/fd/owned.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/std/src/os/fd/owned.rs b/library/std/src/os/fd/owned.rs index d661a13edc5e5..a463bc41db7aa 100644 --- a/library/std/src/os/fd/owned.rs +++ b/library/std/src/os/fd/owned.rs @@ -356,7 +356,7 @@ impl From for crate::net::UdpSocket { } } -#[stable(feature = "io_safety", since = "1.63.0")] +#[stable(feature = "asfd_ptrs", since = "1.64.0")] /// This impl allows implementing traits that require `AsFd` on Arc. /// ``` /// # #[cfg(any(unix, target_os = "wasi"))] mod group_cfg { @@ -379,7 +379,7 @@ impl AsFd for crate::sync::Arc { } } -#[stable(feature = "io_safety", since = "1.63.0")] +#[stable(feature = "asfd_ptrs", since = "1.64.0")] impl AsFd for Box { #[inline] fn as_fd(&self) -> BorrowedFd<'_> { From 1993a5f7a866f174aa50329a03b2f8b2f589221c Mon Sep 17 00:00:00 2001 From: benluelo Date: Tue, 19 Jul 2022 03:16:07 -0400 Subject: [PATCH 11/14] Add map_continue and continue_value combinators to ControlFlow Fix type error Fix continue_value doc comment --- library/core/src/ops/control_flow.rs | 35 ++++++++++++++++++++++++++++ 1 file changed, 35 insertions(+) diff --git a/library/core/src/ops/control_flow.rs b/library/core/src/ops/control_flow.rs index e34e26746c0a5..b1f5559dcfc17 100644 --- a/library/core/src/ops/control_flow.rs +++ b/library/core/src/ops/control_flow.rs @@ -195,6 +195,41 @@ impl ControlFlow { ControlFlow::Break(x) => ControlFlow::Break(f(x)), } } + + /// Converts the `ControlFlow` into an `Option` which is `Some` if the + /// `ControlFlow` was `Continue` and `None` otherwise. + /// + /// # Examples + /// + /// ``` + /// #![feature(control_flow_enum)] + /// use std::ops::ControlFlow; + /// + /// assert_eq!(ControlFlow::::Break(3).continue_value(), None); + /// assert_eq!(ControlFlow::::Continue(3).continue_value(), Some(3)); + /// ``` + #[inline] + #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")] + pub fn continue_value(self) -> Option { + match self { + ControlFlow::Continue(x) => Some(x), + ControlFlow::Break(..) => None, + } + } + + /// Maps `ControlFlow` to `ControlFlow` by applying a function + /// to the continue value in case it exists. + #[inline] + #[unstable(feature = "control_flow_enum", reason = "new API", issue = "75744")] + pub fn map_continue(self, f: F) -> ControlFlow + where + F: FnOnce(C) -> T, + { + match self { + ControlFlow::Continue(x) => ControlFlow::Continue(f(x)), + ControlFlow::Break(x) => ControlFlow::Break(x), + } + } } /// These are used only as part of implementing the iterator adapters. From 7d0a18239e72fe170818d1cf5ebea8def3830364 Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 21 Jul 2022 10:53:54 +0200 Subject: [PATCH 12/14] orphan check: opaque types are an error --- .../src/traits/coherence.rs | 30 +------------------ .../ui/impl-trait/negative-reasoning.stderr | 2 +- 2 files changed, 2 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 52ca23c4b303e..67ae26b0b3ad1 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -739,34 +739,6 @@ fn ty_is_local_constructor(tcx: TyCtxt<'_>, ty: Ty<'_>, in_crate: InCrate) -> bo ty::Adt(def, _) => def_id_is_local(def.did(), in_crate), ty::Foreign(did) => def_id_is_local(did, in_crate), - ty::Opaque(..) => { - // This merits some explanation. - // Normally, opaque types are not involved when performing - // coherence checking, since it is illegal to directly - // implement a trait on an opaque type. However, we might - // end up looking at an opaque type during coherence checking - // if an opaque type gets used within another type (e.g. as - // a type parameter). This requires us to decide whether or - // not an opaque type should be considered 'local' or not. - // - // We choose to treat all opaque types as non-local, even - // those that appear within the same crate. This seems - // somewhat surprising at first, but makes sense when - // you consider that opaque types are supposed to hide - // the underlying type *within the same crate*. When an - // opaque type is used from outside the module - // where it is declared, it should be impossible to observe - // anything about it other than the traits that it implements. - // - // The alternative would be to look at the underlying type - // to determine whether or not the opaque type itself should - // be considered local. However, this could make it a breaking change - // to switch the underlying ('defining') type from a local type - // to a remote type. This would violate the rule that opaque - // types should be completely opaque apart from the traits - // that they implement, so we don't use this behavior. - false - } ty::Dynamic(ref tt, ..) => { if let Some(principal) = tt.principal() { @@ -786,7 +758,7 @@ fn ty_is_local_constructor(tcx: TyCtxt<'_>, ty: Ty<'_>, in_crate: InCrate) -> bo // // See `test/ui/coherence/coherence-with-closure.rs` for an example where this // could happens. - ty::Closure(..) | ty::Generator(..) | ty::GeneratorWitness(..) => { + ty::Opaque(..) | ty::Closure(..) | ty::Generator(..) | ty::GeneratorWitness(..) => { tcx.sess.delay_span_bug( DUMMY_SP, format!("ty_is_local invoked on closure or generator: {:?}", ty), diff --git a/src/test/ui/impl-trait/negative-reasoning.stderr b/src/test/ui/impl-trait/negative-reasoning.stderr index 479b451855d55..2eea726a19c5a 100644 --- a/src/test/ui/impl-trait/negative-reasoning.stderr +++ b/src/test/ui/impl-trait/negative-reasoning.stderr @@ -7,7 +7,7 @@ LL | impl AnotherTrait for T {} LL | impl AnotherTrait for D { | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ conflicting implementation for `D` | - = note: upstream crates may add a new impl of trait `std::fmt::Debug` for type `OpaqueType` in future versions + = note: downstream crates may implement trait `std::fmt::Debug` for type `OpaqueType` error: cannot implement trait on type alias impl trait --> $DIR/negative-reasoning.rs:19:25 From 84c3fcd2a0285c06a682c9b064640084e4c7271b Mon Sep 17 00:00:00 2001 From: lcnr Date: Thu, 21 Jul 2022 11:51:09 +0200 Subject: [PATCH 13/14] rewrite the orphan check to use a type visitor --- .../src/traits/coherence.rs | 293 ++++++++---------- 1 file changed, 124 insertions(+), 169 deletions(-) diff --git a/compiler/rustc_trait_selection/src/traits/coherence.rs b/compiler/rustc_trait_selection/src/traits/coherence.rs index 67ae26b0b3ad1..9983438233e1e 100644 --- a/compiler/rustc_trait_selection/src/traits/coherence.rs +++ b/compiler/rustc_trait_selection/src/traits/coherence.rs @@ -22,11 +22,12 @@ use rustc_middle::traits::specialization_graph::OverlapMode; use rustc_middle::ty::fast_reject::{DeepRejectCtxt, TreatParams}; use rustc_middle::ty::subst::Subst; use rustc_middle::ty::visit::TypeVisitable; -use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt}; +use rustc_middle::ty::{self, ImplSubject, Ty, TyCtxt, TypeVisitor}; use rustc_span::symbol::sym; use rustc_span::DUMMY_SP; use std::fmt::Debug; use std::iter; +use std::ops::ControlFlow; /// Whether we do the orphan check relative to this crate or /// to some remote crate. @@ -578,192 +579,146 @@ fn orphan_check_trait_ref<'tcx>( ); } - // Given impl Trait for T0, an impl is valid only - // if at least one of the following is true: - // - // - Trait is a local trait - // (already checked in orphan_check prior to calling this function) - // - All of - // - At least one of the types T0..=Tn must be a local type. - // Let Ti be the first such type. - // - No uncovered type parameters P1..=Pn may appear in T0..Ti (excluding Ti) - // - fn uncover_fundamental_ty<'tcx>( - tcx: TyCtxt<'tcx>, - ty: Ty<'tcx>, - in_crate: InCrate, - ) -> Vec> { - // FIXME: this is currently somewhat overly complicated, - // but fixing this requires a more complicated refactor. - if !contained_non_local_types(tcx, ty, in_crate).is_empty() { - if let Some(inner_tys) = fundamental_ty_inner_tys(tcx, ty) { - return inner_tys - .flat_map(|ty| uncover_fundamental_ty(tcx, ty, in_crate)) - .collect(); + let mut checker = OrphanChecker::new(tcx, in_crate); + match trait_ref.visit_with(&mut checker) { + ControlFlow::Continue(()) => Err(OrphanCheckErr::NonLocalInputType(checker.non_local_tys)), + ControlFlow::Break(OrphanCheckEarlyExit::ParamTy(ty)) => { + // Does there exist some local type after the `ParamTy`. + checker.search_first_local_ty = true; + if let Some(OrphanCheckEarlyExit::LocalTy(local_ty)) = + trait_ref.visit_with(&mut checker).break_value() + { + Err(OrphanCheckErr::UncoveredTy(ty, Some(local_ty))) + } else { + Err(OrphanCheckErr::UncoveredTy(ty, None)) } } - - vec![ty] - } - - let mut non_local_spans = vec![]; - for (i, input_ty) in trait_ref - .substs - .types() - .flat_map(|ty| uncover_fundamental_ty(tcx, ty, in_crate)) - .enumerate() - { - debug!("orphan_check_trait_ref: check ty `{:?}`", input_ty); - let non_local_tys = contained_non_local_types(tcx, input_ty, in_crate); - if non_local_tys.is_empty() { - debug!("orphan_check_trait_ref: ty_is_local `{:?}`", input_ty); - return Ok(()); - } else if let ty::Param(_) = input_ty.kind() { - debug!("orphan_check_trait_ref: uncovered ty: `{:?}`", input_ty); - let local_type = trait_ref - .substs - .types() - .flat_map(|ty| uncover_fundamental_ty(tcx, ty, in_crate)) - .find(|&ty| ty_is_local_constructor(tcx, ty, in_crate)); - - debug!("orphan_check_trait_ref: uncovered ty local_type: `{:?}`", local_type); - - return Err(OrphanCheckErr::UncoveredTy(input_ty, local_type)); - } - - non_local_spans.extend(non_local_tys.into_iter().map(|input_ty| (input_ty, i == 0))); + ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(_)) => Ok(()), } - // If we exit above loop, never found a local type. - debug!("orphan_check_trait_ref: no local type"); - Err(OrphanCheckErr::NonLocalInputType(non_local_spans)) } -/// Returns a list of relevant non-local types for `ty`. -/// -/// This is just `ty` itself unless `ty` is `#[fundamental]`, -/// in which case we recursively look into this type. -/// -/// If `ty` is local itself, this method returns an empty `Vec`. -/// -/// # Examples -/// -/// - `u32` is not local, so this returns `[u32]`. -/// - for `Foo`, where `Foo` is a local type, this returns `[]`. -/// - `&mut u32` returns `[u32]`, as `&mut` is a fundamental type, similar to `Box`. -/// - `Box>` returns `[]`, as `Box` is a fundamental type and `Foo` is local. -fn contained_non_local_types<'tcx>( +struct OrphanChecker<'tcx> { tcx: TyCtxt<'tcx>, - ty: Ty<'tcx>, in_crate: InCrate, -) -> Vec> { - if ty_is_local_constructor(tcx, ty, in_crate) { - Vec::new() - } else { - match fundamental_ty_inner_tys(tcx, ty) { - Some(inner_tys) => { - inner_tys.flat_map(|ty| contained_non_local_types(tcx, ty, in_crate)).collect() - } - None => vec![ty], + in_self_ty: bool, + /// Ignore orphan check failures and exclusively search for the first + /// local type. + search_first_local_ty: bool, + non_local_tys: Vec<(Ty<'tcx>, bool)>, +} + +impl<'tcx> OrphanChecker<'tcx> { + fn new(tcx: TyCtxt<'tcx>, in_crate: InCrate) -> Self { + OrphanChecker { + tcx, + in_crate, + in_self_ty: true, + search_first_local_ty: false, + non_local_tys: Vec::new(), } } -} -/// For `#[fundamental]` ADTs and `&T` / `&mut T`, returns `Some` with the -/// type parameters of the ADT, or `T`, respectively. For non-fundamental -/// types, returns `None`. -fn fundamental_ty_inner_tys<'tcx>( - tcx: TyCtxt<'tcx>, - ty: Ty<'tcx>, -) -> Option>> { - let (first_ty, rest_tys) = match *ty.kind() { - ty::Ref(_, ty, _) => (ty, ty::subst::InternalSubsts::empty().types()), - ty::Adt(def, substs) if def.is_fundamental() => { - let mut types = substs.types(); - - // FIXME(eddyb) actually validate `#[fundamental]` up-front. - match types.next() { - None => { - tcx.sess.span_err( - tcx.def_span(def.did()), - "`#[fundamental]` requires at least one type parameter", - ); - - return None; - } + fn found_non_local_ty(&mut self, t: Ty<'tcx>) -> ControlFlow> { + self.non_local_tys.push((t, self.in_self_ty)); + ControlFlow::CONTINUE + } - Some(first_ty) => (first_ty, types), - } + fn found_param_ty(&mut self, t: Ty<'tcx>) -> ControlFlow> { + if self.search_first_local_ty { + ControlFlow::CONTINUE + } else { + ControlFlow::Break(OrphanCheckEarlyExit::ParamTy(t)) } - _ => return None, - }; + } + + fn def_id_is_local(&mut self, def_id: DefId) -> bool { + match self.in_crate { + InCrate::Local => def_id.is_local(), + InCrate::Remote => false, + } + } +} - Some(iter::once(first_ty).chain(rest_tys)) +enum OrphanCheckEarlyExit<'tcx> { + ParamTy(Ty<'tcx>), + LocalTy(Ty<'tcx>), } -fn def_id_is_local(def_id: DefId, in_crate: InCrate) -> bool { - match in_crate { - // The type is local to *this* crate - it will not be - // local in any other crate. - InCrate::Remote => false, - InCrate::Local => def_id.is_local(), +impl<'tcx> TypeVisitor<'tcx> for OrphanChecker<'tcx> { + type BreakTy = OrphanCheckEarlyExit<'tcx>; + fn visit_region(&mut self, _r: ty::Region<'tcx>) -> ControlFlow { + ControlFlow::CONTINUE } -} -fn ty_is_local_constructor(tcx: TyCtxt<'_>, ty: Ty<'_>, in_crate: InCrate) -> bool { - debug!("ty_is_local_constructor({:?})", ty); - - match *ty.kind() { - ty::Bool - | ty::Char - | ty::Int(..) - | ty::Uint(..) - | ty::Float(..) - | ty::Str - | ty::FnDef(..) - | ty::FnPtr(_) - | ty::Array(..) - | ty::Slice(..) - | ty::RawPtr(..) - | ty::Ref(..) - | ty::Never - | ty::Tuple(..) - | ty::Param(..) - | ty::Projection(..) => false, - - ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) => match in_crate { - InCrate::Local => false, - // The inference variable might be unified with a local - // type in that remote crate. - InCrate::Remote => true, - }, - - ty::Adt(def, _) => def_id_is_local(def.did(), in_crate), - ty::Foreign(did) => def_id_is_local(did, in_crate), - - ty::Dynamic(ref tt, ..) => { - if let Some(principal) = tt.principal() { - def_id_is_local(principal.def_id(), in_crate) - } else { - false + fn visit_ty(&mut self, ty: Ty<'tcx>) -> ControlFlow { + let result = match *ty.kind() { + ty::Bool + | ty::Char + | ty::Int(..) + | ty::Uint(..) + | ty::Float(..) + | ty::Str + | ty::FnDef(..) + | ty::FnPtr(_) + | ty::Array(..) + | ty::Slice(..) + | ty::RawPtr(..) + | ty::Never + | ty::Tuple(..) + | ty::Projection(..) => self.found_non_local_ty(ty), + + ty::Param(..) => self.found_param_ty(ty), + + ty::Placeholder(..) | ty::Bound(..) | ty::Infer(..) => match self.in_crate { + InCrate::Local => self.found_non_local_ty(ty), + // The inference variable might be unified with a local + // type in that remote crate. + InCrate::Remote => ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)), + }, + + // For fundamental types, we just look inside of them. + ty::Ref(_, ty, _) => ty.visit_with(self), + ty::Adt(def, substs) => { + if self.def_id_is_local(def.did()) { + ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)) + } else if def.is_fundamental() { + substs.visit_with(self) + } else { + self.found_non_local_ty(ty) + } } - } + ty::Foreign(def_id) => { + if self.def_id_is_local(def_id) { + ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)) + } else { + self.found_non_local_ty(ty) + } + } + ty::Dynamic(tt, ..) => { + let principal = tt.principal().map(|p| p.def_id()); + if principal.map_or(false, |p| self.def_id_is_local(p)) { + ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)) + } else { + self.found_non_local_ty(ty) + } + } + ty::Error(_) => ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)), + ty::Opaque(..) | ty::Closure(..) | ty::Generator(..) | ty::GeneratorWitness(..) => { + self.tcx.sess.delay_span_bug( + DUMMY_SP, + format!("ty_is_local invoked on closure or generator: {:?}", ty), + ); + ControlFlow::Break(OrphanCheckEarlyExit::LocalTy(ty)) + } + }; + // A bit of a hack, the `OrphanChecker` is only used to visit a `TraitRef`, so + // the first type we visit is always the self type. + self.in_self_ty = false; + result + } - ty::Error(_) => true, - - // These variants should never appear during coherence checking because they - // cannot be named directly. - // - // They could be indirectly used through an opaque type. While using opaque types - // in impls causes an error, this path can still be hit afterwards. - // - // See `test/ui/coherence/coherence-with-closure.rs` for an example where this - // could happens. - ty::Opaque(..) | ty::Closure(..) | ty::Generator(..) | ty::GeneratorWitness(..) => { - tcx.sess.delay_span_bug( - DUMMY_SP, - format!("ty_is_local invoked on closure or generator: {:?}", ty), - ); - true - } + // FIXME: Constants should participate in orphan checking. + fn visit_const(&mut self, _c: ty::Const<'tcx>) -> ControlFlow { + ControlFlow::CONTINUE } } From 8ba02f18b813aa8ea2599979567797bbb9dc3ecb Mon Sep 17 00:00:00 2001 From: joboet Date: Thu, 21 Jul 2022 11:51:26 +0200 Subject: [PATCH 14/14] remove unused import --- library/std/src/sys/unix/locks/fuchsia_mutex.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/sys/unix/locks/fuchsia_mutex.rs b/library/std/src/sys/unix/locks/fuchsia_mutex.rs index fd3e9d1768b4c..ce427599c3bdd 100644 --- a/library/std/src/sys/unix/locks/fuchsia_mutex.rs +++ b/library/std/src/sys/unix/locks/fuchsia_mutex.rs @@ -44,7 +44,7 @@ use crate::sync::atomic::{ use crate::sys::futex::zircon::{ zx_futex_wait, zx_futex_wake_single_owner, zx_handle_t, zx_thread_self, ZX_ERR_BAD_HANDLE, ZX_ERR_BAD_STATE, ZX_ERR_INVALID_ARGS, ZX_ERR_TIMED_OUT, ZX_ERR_WRONG_TYPE, ZX_OK, - ZX_TIME_INFINITE, ZX_TIME_INFINITE, + ZX_TIME_INFINITE, }; // The lowest two bits of a `zx_handle_t` are always set, so the lowest bit is used to mark the