From 741d6ef17e7ee4a77c9fbc73ea92878d2a6e58ab Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Wed, 11 Sep 2024 01:26:55 +0300 Subject: [PATCH 01/16] Stabilize `std::io::ErrorKind::CrossesDevices` --- library/std/src/io/error.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index 6ecd9469c1740..d0b20b344ff8a 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -353,7 +353,7 @@ pub enum ErrorKind { #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")] Deadlock, /// Cross-device or cross-filesystem (hard) link or rename. - #[unstable(feature = "io_error_more", issue = "86442")] + #[stable(feature = "io_error_crosses_devices", since = "CURRENT_RUSTC_VERSION")] CrossesDevices, /// Too many (hard) links to the same filesystem object. /// From b2c1c8f13a88be63ebe1907996bf806a91ec5680 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Thu, 12 Sep 2024 02:53:12 +0300 Subject: [PATCH 02/16] Stabilize `std::io::ErrorKind::QuotaExceeded` Also drop "Filesystem" from its name --- library/std/src/io/error.rs | 8 ++++---- library/std/src/io/error/repr_bitpacked.rs | 2 +- library/std/src/sys/pal/teeos/mod.rs | 2 +- library/std/src/sys/pal/unix/mod.rs | 2 +- library/std/src/sys/pal/windows/mod.rs | 4 ++-- src/tools/miri/src/shims/io_error.rs | 2 +- 6 files changed, 10 insertions(+), 10 deletions(-) diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index f20814dd95cc1..4cb0754de9b29 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -327,9 +327,9 @@ pub enum ErrorKind { /// example, on Unix, a named pipe opened with `File::open`. #[stable(feature = "io_error_a_bit_more", since = "CURRENT_RUSTC_VERSION")] NotSeekable, - /// Filesystem quota was exceeded. - #[unstable(feature = "io_error_more", issue = "86442")] - FilesystemQuotaExceeded, + /// Filesystem quota or some other kind of quota was exceeded. + #[stable(feature = "io_error_quota_exceeded", since = "CURRENT_RUSTC_VERSION")] + QuotaExceeded, /// File larger than allowed or supported. /// /// This might arise from a hard limit of the underlying filesystem or file access API, or from @@ -451,7 +451,7 @@ impl ErrorKind { ExecutableFileBusy => "executable file busy", FileTooLarge => "file too large", FilesystemLoop => "filesystem loop or indirection limit (e.g. symlink loop)", - FilesystemQuotaExceeded => "filesystem quota exceeded", + QuotaExceeded => "quota exceeded", HostUnreachable => "host unreachable", Interrupted => "operation interrupted", InProgress => "in progress", diff --git a/library/std/src/io/error/repr_bitpacked.rs b/library/std/src/io/error/repr_bitpacked.rs index a839a2fbac117..f958a93864603 100644 --- a/library/std/src/io/error/repr_bitpacked.rs +++ b/library/std/src/io/error/repr_bitpacked.rs @@ -335,7 +335,7 @@ fn kind_from_prim(ek: u32) -> Option { WriteZero, StorageFull, NotSeekable, - FilesystemQuotaExceeded, + QuotaExceeded, FileTooLarge, ResourceBusy, ExecutableFileBusy, diff --git a/library/std/src/sys/pal/teeos/mod.rs b/library/std/src/sys/pal/teeos/mod.rs index 60a227afb84e3..4253fcb7f5be7 100644 --- a/library/std/src/sys/pal/teeos/mod.rs +++ b/library/std/src/sys/pal/teeos/mod.rs @@ -63,7 +63,7 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind { libc::ECONNREFUSED => ConnectionRefused, libc::ECONNRESET => ConnectionReset, libc::EDEADLK => Deadlock, - libc::EDQUOT => FilesystemQuotaExceeded, + libc::EDQUOT => QuotaExceeded, libc::EEXIST => AlreadyExists, libc::EFBIG => FileTooLarge, libc::EHOSTUNREACH => HostUnreachable, diff --git a/library/std/src/sys/pal/unix/mod.rs b/library/std/src/sys/pal/unix/mod.rs index 4fe18daa2040f..35a6f0ccd74d0 100644 --- a/library/std/src/sys/pal/unix/mod.rs +++ b/library/std/src/sys/pal/unix/mod.rs @@ -253,7 +253,7 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind { libc::ECONNREFUSED => ConnectionRefused, libc::ECONNRESET => ConnectionReset, libc::EDEADLK => Deadlock, - libc::EDQUOT => FilesystemQuotaExceeded, + libc::EDQUOT => QuotaExceeded, libc::EEXIST => AlreadyExists, libc::EFBIG => FileTooLarge, libc::EHOSTUNREACH => HostUnreachable, diff --git a/library/std/src/sys/pal/windows/mod.rs b/library/std/src/sys/pal/windows/mod.rs index 1ea253e5e5263..b3b26eb858d81 100644 --- a/library/std/src/sys/pal/windows/mod.rs +++ b/library/std/src/sys/pal/windows/mod.rs @@ -113,7 +113,7 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind { c::ERROR_WRITE_PROTECT => return ReadOnlyFilesystem, c::ERROR_DISK_FULL | c::ERROR_HANDLE_DISK_FULL => return StorageFull, c::ERROR_SEEK_ON_DEVICE => return NotSeekable, - c::ERROR_DISK_QUOTA_EXCEEDED => return FilesystemQuotaExceeded, + c::ERROR_DISK_QUOTA_EXCEEDED => return QuotaExceeded, c::ERROR_FILE_TOO_LARGE => return FileTooLarge, c::ERROR_BUSY => return ResourceBusy, c::ERROR_POSSIBLE_DEADLOCK => return Deadlock, @@ -138,7 +138,7 @@ pub fn decode_error_kind(errno: i32) -> ErrorKind { c::WSAEHOSTUNREACH => HostUnreachable, c::WSAENETDOWN => NetworkDown, c::WSAENETUNREACH => NetworkUnreachable, - c::WSAEDQUOT => FilesystemQuotaExceeded, + c::WSAEDQUOT => QuotaExceeded, _ => Uncategorized, } diff --git a/src/tools/miri/src/shims/io_error.rs b/src/tools/miri/src/shims/io_error.rs index 38aa181cb4f05..1a95ae1e7d451 100644 --- a/src/tools/miri/src/shims/io_error.rs +++ b/src/tools/miri/src/shims/io_error.rs @@ -43,7 +43,7 @@ const UNIX_IO_ERROR_TABLE: &[(&str, std::io::ErrorKind)] = { ("ECONNREFUSED", ConnectionRefused), ("ECONNRESET", ConnectionReset), ("EDEADLK", Deadlock), - ("EDQUOT", FilesystemQuotaExceeded), + ("EDQUOT", QuotaExceeded), ("EEXIST", AlreadyExists), ("EFBIG", FileTooLarge), ("EHOSTUNREACH", HostUnreachable), From eb5203233a20e15c9f8f0796cd82e9170c6466f9 Mon Sep 17 00:00:00 2001 From: Pavel Grigorenko Date: Thu, 12 Sep 2024 02:58:27 +0300 Subject: [PATCH 03/16] Unbreak tidy --- library/std/src/io/error.rs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/library/std/src/io/error.rs b/library/std/src/io/error.rs index 4cb0754de9b29..0c76ddec99ed5 100644 --- a/library/std/src/io/error.rs +++ b/library/std/src/io/error.rs @@ -435,8 +435,8 @@ pub enum ErrorKind { impl ErrorKind { pub(crate) fn as_str(&self) -> &'static str { use ErrorKind::*; - // tidy-alphabetical-start match *self { + // tidy-alphabetical-start AddrInUse => "address in use", AddrNotAvailable => "address not available", AlreadyExists => "entity already exists", @@ -449,12 +449,11 @@ impl ErrorKind { Deadlock => "deadlock", DirectoryNotEmpty => "directory not empty", ExecutableFileBusy => "executable file busy", - FileTooLarge => "file too large", FilesystemLoop => "filesystem loop or indirection limit (e.g. symlink loop)", - QuotaExceeded => "quota exceeded", + FileTooLarge => "file too large", HostUnreachable => "host unreachable", - Interrupted => "operation interrupted", InProgress => "in progress", + Interrupted => "operation interrupted", InvalidData => "invalid data", InvalidFilename => "invalid filename", InvalidInput => "invalid input parameter", @@ -468,6 +467,7 @@ impl ErrorKind { Other => "other error", OutOfMemory => "out of memory", PermissionDenied => "permission denied", + QuotaExceeded => "quota exceeded", ReadOnlyFilesystem => "read-only filesystem or storage medium", ResourceBusy => "resource busy", StaleNetworkFileHandle => "stale network file handle", @@ -479,8 +479,8 @@ impl ErrorKind { Unsupported => "unsupported", WouldBlock => "operation would block", WriteZero => "write zero", + // tidy-alphabetical-end } - // tidy-alphabetical-end } } From 59be878506d38483b49bbd97a11aaa1047cfd76b Mon Sep 17 00:00:00 2001 From: Sebastian Hahn Date: Sat, 26 Oct 2024 17:25:10 +0200 Subject: [PATCH 04/16] Add Extend impls for tuples of arity 1 through 12 --- library/core/src/iter/traits/collect.rs | 248 +++++++++++++----------- 1 file changed, 138 insertions(+), 110 deletions(-) diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs index 2cf2ea58fd4ee..16211610f0551 100644 --- a/library/core/src/iter/traits/collect.rs +++ b/library/core/src/iter/traits/collect.rs @@ -492,131 +492,159 @@ impl Extend<()> for () { fn extend_one(&mut self, _item: ()) {} } -#[stable(feature = "extend_for_tuple", since = "1.56.0")] -impl Extend<(A, B)> for (ExtendA, ExtendB) -where - ExtendA: Extend, - ExtendB: Extend, -{ - /// Allows to `extend` a tuple of collections that also implement `Extend`. - /// - /// See also: [`Iterator::unzip`] - /// - /// # Examples - /// ``` - /// let mut tuple = (vec![0], vec![1]); - /// tuple.extend([(2, 3), (4, 5), (6, 7)]); - /// assert_eq!(tuple.0, [0, 2, 4, 6]); - /// assert_eq!(tuple.1, [1, 3, 5, 7]); - /// - /// // also allows for arbitrarily nested tuples as elements - /// let mut nested_tuple = (vec![1], (vec![2], vec![3])); - /// nested_tuple.extend([(4, (5, 6)), (7, (8, 9))]); - /// - /// let (a, (b, c)) = nested_tuple; - /// assert_eq!(a, [1, 4, 7]); - /// assert_eq!(b, [2, 5, 8]); - /// assert_eq!(c, [3, 6, 9]); - /// ``` - fn extend>(&mut self, into_iter: T) { - let (a, b) = self; - let iter = into_iter.into_iter(); - SpecTupleExtend::extend(iter, a, b); - } +macro_rules! spec_tuple_impl { + ( ($ty_name:ident, $var_name:ident, $extend_ty_name: ident, $trait_name:ident, $default_fn_name:ident, $cnt:tt), ) => { + spec_tuple_impl!($trait_name, $default_fn_name, #[stable(feature = "extend_for_more_tuples", since = "CURRENT_RUSTC_VERSION")] #[doc(fake_variadic)] #[doc = "This trait is implemented for tuples up to twelve items long."] => ($ty_name, $var_name, $extend_ty_name, $cnt),); + }; + // Special case (A, B) as this was stabilized earlier + ( ($ty_name:ident, $var_name:ident, $extend_ty_name: ident, $trait_name:ident, $default_fn_name:ident, $cnt:tt), + ($ty_names:ident, $var_names:ident, $extend_ty_names: ident, $trait_names:ident, $default_fn_names:ident, $cnts:tt),) => { - fn extend_one(&mut self, item: (A, B)) { - self.0.extend_one(item.0); - self.1.extend_one(item.1); - } + spec_tuple_impl!(($ty_names, $var_names, $extend_ty_names, $trait_names, $default_fn_names, $cnts),); + spec_tuple_impl!($trait_name, $default_fn_name, #[stable(feature = "extend_for_tuple", since = "1.56.0")] => ($ty_name, $var_name, $extend_ty_name, $cnt), ($ty_names, $var_names, $extend_ty_names, $cnts),); + }; + ( ($ty_name:ident, $var_name:ident, $extend_ty_name: ident, $trait_name:ident, $default_fn_name:ident, $cnt:tt), $(($ty_names:ident, $var_names:ident, $extend_ty_names:ident, $trait_names:ident, $default_fn_names:ident, $cnts:tt),)*) => { - fn extend_reserve(&mut self, additional: usize) { - self.0.extend_reserve(additional); - self.1.extend_reserve(additional); - } + spec_tuple_impl!($(($ty_names, $var_names, $extend_ty_names, $trait_names, $default_fn_names, $cnts),)*); + spec_tuple_impl!($trait_name, $default_fn_name, #[stable(feature = "extend_for_more_tuples", since = "CURRENT_RUSTC_VERSION")] #[doc(hidden)] => ($ty_name, $var_name, $extend_ty_name, $cnt), $(($ty_names, $var_names, $extend_ty_names, $cnts),)*); + }; + ($trait_name:ident, $default_fn_name:ident, #[$stable:meta] $(#[$meta:meta] $(#[$doctext:meta])?)? => $(($ty_names:ident, $var_names:ident, $extend_ty_names:ident, $cnts:tt),)*) => { + $(#[$meta] + $(#[$doctext])? + )? + #[$stable] + impl<$($ty_names,)* $($extend_ty_names,)*> Extend<($($ty_names,)*)> for ($($extend_ty_names,)*) + where + $($extend_ty_names: Extend<$ty_names>,)* + { + /// Allows to `extend` a tuple of collections that also implement `Extend`. + /// + /// See also: [`Iterator::unzip`] + /// + /// # Examples + /// ``` + /// // Example given for a 2-tuple, but 1- through 12-tuples are supported + /// let mut tuple = (vec![0], vec![1]); + /// tuple.extend([(2, 3), (4, 5), (6, 7)]); + /// assert_eq!(tuple.0, [0, 2, 4, 6]); + /// assert_eq!(tuple.1, [1, 3, 5, 7]); + /// + /// // also allows for arbitrarily nested tuples as elements + /// let mut nested_tuple = (vec![1], (vec![2], vec![3])); + /// nested_tuple.extend([(4, (5, 6)), (7, (8, 9))]); + /// + /// let (a, (b, c)) = nested_tuple; + /// assert_eq!(a, [1, 4, 7]); + /// assert_eq!(b, [2, 5, 8]); + /// assert_eq!(c, [3, 6, 9]); + /// ``` + fn extend>(&mut self, into_iter: T) { + let ($($var_names,)*) = self; + let iter = into_iter.into_iter(); + $trait_name::extend(iter, $($var_names,)*); + } - unsafe fn extend_one_unchecked(&mut self, item: (A, B)) { - // SAFETY: Those are our safety preconditions, and we correctly forward `extend_reserve`. - unsafe { - self.0.extend_one_unchecked(item.0); - self.1.extend_one_unchecked(item.1); - } - } -} + fn extend_one(&mut self, item: ($($ty_names,)*)) { + $(self.$cnts.extend_one(item.$cnts);)* + } -fn default_extend_tuple( - iter: impl Iterator, - a: &mut ExtendA, - b: &mut ExtendB, -) where - ExtendA: Extend, - ExtendB: Extend, -{ - fn extend<'a, A, B>( - a: &'a mut impl Extend, - b: &'a mut impl Extend, - ) -> impl FnMut((), (A, B)) + 'a { - move |(), (t, u)| { - a.extend_one(t); - b.extend_one(u); + fn extend_reserve(&mut self, additional: usize) { + $(self.$cnts.extend_reserve(additional);)* + } + + unsafe fn extend_one_unchecked(&mut self, item: ($($ty_names,)*)) { + // SAFETY: Those are our safety preconditions, and we correctly forward `extend_reserve`. + unsafe { + $(self.$cnts.extend_one_unchecked(item.$cnts);)* + } + } } - } - let (lower_bound, _) = iter.size_hint(); - if lower_bound > 0 { - a.extend_reserve(lower_bound); - b.extend_reserve(lower_bound); - } + trait $trait_name<$($ty_names),*> { + fn extend(self, $($var_names: &mut $ty_names,)*); + } - iter.fold((), extend(a, b)); -} + fn $default_fn_name<$($ty_names,)* $($extend_ty_names,)*>( + iter: impl Iterator, + $($var_names: &mut $extend_ty_names,)* + ) where + $($extend_ty_names: Extend<$ty_names>,)* + { + fn extend<'a, $($ty_names,)*>( + $($var_names: &'a mut impl Extend<$ty_names>,)* + ) -> impl FnMut((), ($($ty_names,)*)) + 'a { + #[allow(non_snake_case)] + move |(), ($($extend_ty_names,)*)| { + $($var_names.extend_one($extend_ty_names);)* + } + } -trait SpecTupleExtend { - fn extend(self, a: &mut A, b: &mut B); -} + let (lower_bound, _) = iter.size_hint(); + if lower_bound > 0 { + $($var_names.extend_reserve(lower_bound);)* + } -impl SpecTupleExtend for Iter -where - ExtendA: Extend, - ExtendB: Extend, - Iter: Iterator, -{ - default fn extend(self, a: &mut ExtendA, b: &mut ExtendB) { - default_extend_tuple(self, a, b); - } -} + iter.fold((), extend($($var_names,)*)); + } -impl SpecTupleExtend for Iter -where - ExtendA: Extend, - ExtendB: Extend, - Iter: TrustedLen, -{ - fn extend(self, a: &mut ExtendA, b: &mut ExtendB) { - fn extend<'a, A, B>( - a: &'a mut impl Extend, - b: &'a mut impl Extend, - ) -> impl FnMut((), (A, B)) + 'a { - // SAFETY: We reserve enough space for the `size_hint`, and the iterator is `TrustedLen` - // so its `size_hint` is exact. - move |(), (t, u)| unsafe { - a.extend_one_unchecked(t); - b.extend_one_unchecked(u); + impl<$($ty_names,)* $($extend_ty_names,)* Iter> $trait_name<$($extend_ty_names),*> for Iter + where + $($extend_ty_names: Extend<$ty_names>,)* + Iter: Iterator, + { + default fn extend(self, $($var_names: &mut $extend_ty_names),*) { + $default_fn_name(self, $($var_names),*); } } - let (lower_bound, upper_bound) = self.size_hint(); + impl<$($ty_names,)* $($extend_ty_names,)* Iter> $trait_name<$($extend_ty_names),*> for Iter + where + $($extend_ty_names: Extend<$ty_names>,)* + Iter: TrustedLen, + { + fn extend(self, $($var_names: &mut $extend_ty_names,)*) { + fn extend<'a, $($ty_names,)*>( + $($var_names: &'a mut impl Extend<$ty_names>,)* + ) -> impl FnMut((), ($($ty_names,)*)) + 'a { + #[allow(non_snake_case)] + // SAFETY: We reserve enough space for the `size_hint`, and the iterator is `TrustedLen` + // so its `size_hint` is exact. + move |(), ($($extend_ty_names,)*)| unsafe { + $($var_names.extend_one_unchecked($extend_ty_names);)* + } + } - if upper_bound.is_none() { - // We cannot reserve more than `usize::MAX` items, and this is likely to go out of memory anyway. - default_extend_tuple(self, a, b); - return; - } + let (lower_bound, upper_bound) = self.size_hint(); - if lower_bound > 0 { - a.extend_reserve(lower_bound); - b.extend_reserve(lower_bound); - } + if upper_bound.is_none() { + // We cannot reserve more than `usize::MAX` items, and this is likely to go out of memory anyway. + $default_fn_name(self, $($var_names,)*); + return; + } - self.fold((), extend(a, b)); + if lower_bound > 0 { + $($var_names.extend_reserve(lower_bound);)* + } + + self.fold((), extend($($var_names,)*)); + } } + + }; } + +spec_tuple_impl!( + (M, m, EM, TraitM, default_extend_tuple_m, 12), + (L, l, EL, TraitL, default_extend_tuple_l, 11), + (K, k, EK, TraitK, default_extend_tuple_k, 10), + (J, j, EJ, TraitJ, default_extend_tuple_j, 9), + (I, i, EI, TraitI, default_extend_tuple_i, 8), + (H, h, EH, TraitH, default_extend_tuple_h, 7), + (G, g, EG, TraitG, default_extend_tuple_g, 6), + (F, f, EF, TraitF, default_extend_tuple_f, 5), + (E, e, EE, TraitE, default_extend_tuple_e, 4), + (D, d, ED, TraitD, default_extend_tuple_d, 3), + (C, c, EC, TraitC, default_extend_tuple_c, 2), + (B, b, EB, TraitB, default_extend_tuple_b, 1), + (A, a, EA, TraitA, default_extend_tuple_a, 0), +); From be0650272d590f14198d64c6c6f256b1804dcb28 Mon Sep 17 00:00:00 2001 From: Sebastian Hahn Date: Sat, 26 Oct 2024 18:58:05 +0200 Subject: [PATCH 05/16] Simplify documentation for Extend impl for tuples --- library/core/src/iter/traits/collect.rs | 20 ++++++-------------- 1 file changed, 6 insertions(+), 14 deletions(-) diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs index 16211610f0551..8e2d7b9b4a6eb 100644 --- a/library/core/src/iter/traits/collect.rs +++ b/library/core/src/iter/traits/collect.rs @@ -494,25 +494,17 @@ impl Extend<()> for () { macro_rules! spec_tuple_impl { ( ($ty_name:ident, $var_name:ident, $extend_ty_name: ident, $trait_name:ident, $default_fn_name:ident, $cnt:tt), ) => { - spec_tuple_impl!($trait_name, $default_fn_name, #[stable(feature = "extend_for_more_tuples", since = "CURRENT_RUSTC_VERSION")] #[doc(fake_variadic)] #[doc = "This trait is implemented for tuples up to twelve items long."] => ($ty_name, $var_name, $extend_ty_name, $cnt),); - }; - // Special case (A, B) as this was stabilized earlier - ( ($ty_name:ident, $var_name:ident, $extend_ty_name: ident, $trait_name:ident, $default_fn_name:ident, $cnt:tt), - ($ty_names:ident, $var_names:ident, $extend_ty_names: ident, $trait_names:ident, $default_fn_names:ident, $cnts:tt),) => { - - spec_tuple_impl!(($ty_names, $var_names, $extend_ty_names, $trait_names, $default_fn_names, $cnts),); - spec_tuple_impl!($trait_name, $default_fn_name, #[stable(feature = "extend_for_tuple", since = "1.56.0")] => ($ty_name, $var_name, $extend_ty_name, $cnt), ($ty_names, $var_names, $extend_ty_names, $cnts),); + spec_tuple_impl!($trait_name, $default_fn_name, #[doc(fake_variadic)] #[doc = "This trait is implemented for tuples up to twelve items long. The `impl`s for 1- and 3- through 12-ary tuples were stabilized after 2-tuples, in RUSTC_CURRENT_VERSION."] => ($ty_name, $var_name, $extend_ty_name, $cnt),); }; ( ($ty_name:ident, $var_name:ident, $extend_ty_name: ident, $trait_name:ident, $default_fn_name:ident, $cnt:tt), $(($ty_names:ident, $var_names:ident, $extend_ty_names:ident, $trait_names:ident, $default_fn_names:ident, $cnts:tt),)*) => { spec_tuple_impl!($(($ty_names, $var_names, $extend_ty_names, $trait_names, $default_fn_names, $cnts),)*); - spec_tuple_impl!($trait_name, $default_fn_name, #[stable(feature = "extend_for_more_tuples", since = "CURRENT_RUSTC_VERSION")] #[doc(hidden)] => ($ty_name, $var_name, $extend_ty_name, $cnt), $(($ty_names, $var_names, $extend_ty_names, $cnts),)*); + spec_tuple_impl!($trait_name, $default_fn_name, #[doc(hidden)] => ($ty_name, $var_name, $extend_ty_name, $cnt), $(($ty_names, $var_names, $extend_ty_names, $cnts),)*); }; - ($trait_name:ident, $default_fn_name:ident, #[$stable:meta] $(#[$meta:meta] $(#[$doctext:meta])?)? => $(($ty_names:ident, $var_names:ident, $extend_ty_names:ident, $cnts:tt),)*) => { - $(#[$meta] - $(#[$doctext])? - )? - #[$stable] + ($trait_name:ident, $default_fn_name:ident, #[$meta:meta] $(#[$doctext:meta])? => $(($ty_names:ident, $var_names:ident, $extend_ty_names:ident, $cnts:tt),)*) => { + #[$meta] + $(#[$doctext])? + #[stable(feature = "extend_for_tuple", since = "1.56.0")] impl<$($ty_names,)* $($extend_ty_names,)*> Extend<($($ty_names,)*)> for ($($extend_ty_names,)*) where $($extend_ty_names: Extend<$ty_names>,)* From 9cebcbad1846f6b5448e386a6a6647484adf7e8f Mon Sep 17 00:00:00 2001 From: Sebastian Hahn Date: Thu, 31 Oct 2024 01:23:46 +0100 Subject: [PATCH 06/16] Don't impl Extend for 13-tuples --- library/core/src/iter/traits/collect.rs | 1 - 1 file changed, 1 deletion(-) diff --git a/library/core/src/iter/traits/collect.rs b/library/core/src/iter/traits/collect.rs index 8e2d7b9b4a6eb..c3c7288e38990 100644 --- a/library/core/src/iter/traits/collect.rs +++ b/library/core/src/iter/traits/collect.rs @@ -626,7 +626,6 @@ macro_rules! spec_tuple_impl { } spec_tuple_impl!( - (M, m, EM, TraitM, default_extend_tuple_m, 12), (L, l, EL, TraitL, default_extend_tuple_l, 11), (K, k, EK, TraitK, default_extend_tuple_k, 10), (J, j, EJ, TraitJ, default_extend_tuple_j, 9), From 27342cbb1fef4ab2a1b7347b38c09c079f7dc838 Mon Sep 17 00:00:00 2001 From: Sebastian Hahn Date: Thu, 31 Oct 2024 01:48:37 +0100 Subject: [PATCH 07/16] Add a `collect_into` tuple test case --- library/core/tests/iter/traits/iterator.rs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/library/core/tests/iter/traits/iterator.rs b/library/core/tests/iter/traits/iterator.rs index 93ef9c0812b16..76f1e3319d42e 100644 --- a/library/core/tests/iter/traits/iterator.rs +++ b/library/core/tests/iter/traits/iterator.rs @@ -617,6 +617,19 @@ fn test_next_chunk() { assert_eq!(it.next_chunk::<0>().unwrap(), []); } +#[test] +fn test_collect_into_tuples() { + let a = vec![(1, 2, 3), (4, 5, 6), (7, 8, 9)]; + let b = vec![1, 4, 7]; + let c = vec![2, 5, 8]; + let d = vec![3, 6, 9]; + let mut e = (Vec::new(), Vec::new(), Vec::new()); + a.iter().cloned().collect_into(&mut e); + assert!(e.0 == b); + assert!(e.1 == c); + assert!(e.2 == d); +} + // just tests by whether or not this compiles fn _empty_impl_all_auto_traits() { use std::panic::{RefUnwindSafe, UnwindSafe}; From 44019ee33067fba418873f79b684b1d30f2538df Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 5 Dec 2024 08:08:19 +0000 Subject: [PATCH 08/16] Avoid looking at HIR for inline const pattern literals --- .../rustc_mir_build/src/thir/pattern/mod.rs | 24 ------------------- 1 file changed, 24 deletions(-) diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 08c6b4abd3b91..510a79530514b 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -620,32 +620,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { ) -> PatKind<'tcx> { let tcx = self.tcx; let def_id = block.def_id; - let body_id = block.body; - let expr = &tcx.hir().body(body_id).value; let ty = tcx.typeck(def_id).node_type(block.hir_id); - // Special case inline consts that are just literals. This is solely - // a performance optimization, as we could also just go through the regular - // const eval path below. - // FIXME: investigate the performance impact of removing this. - let lit_input = match expr.kind { - hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }), - hir::ExprKind::Unary(hir::UnOp::Neg, expr) => match expr.kind { - hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: true }), - _ => None, - }, - _ => None, - }; - if let Some(lit_input) = lit_input { - match tcx.at(expr.span).lit_to_const(lit_input) { - Ok(c) => return self.const_to_pat(c, ty, id, span).kind, - // If an error occurred, ignore that it's a literal - // and leave reporting the error up to const eval of - // the unevaluated constant below. - Err(_) => {} - } - } - let typeck_root_def_id = tcx.typeck_root_def_id(def_id.to_def_id()); let parent_args = tcx.erase_regions(ty::GenericArgs::identity_for_item(tcx, typeck_root_def_id)); From 83909b6b05b38daaf69af523d4c852a45e252d2b Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Thu, 5 Dec 2024 00:29:29 +0300 Subject: [PATCH 09/16] skip formatting when `--json-output` is used Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/test.rs | 32 ++++++++++++++-------- 1 file changed, 21 insertions(+), 11 deletions(-) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 4fa91c1a57144..98bfc40fd7a9b 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -1070,23 +1070,33 @@ impl Step for Tidy { } if builder.config.channel == "dev" || builder.config.channel == "nightly" { - builder.info("fmt check"); - if builder.initial_rustfmt().is_none() { - let inferred_rustfmt_dir = builder.initial_sysroot.join("bin"); - eprintln!( - "\ + if !builder.config.json_output { + builder.info("fmt check"); + if builder.initial_rustfmt().is_none() { + let inferred_rustfmt_dir = builder.initial_sysroot.join("bin"); + eprintln!( + "\ ERROR: no `rustfmt` binary found in {PATH} INFO: `rust.channel` is currently set to \"{CHAN}\" HELP: if you are testing a beta branch, set `rust.channel` to \"beta\" in the `config.toml` file HELP: to skip test's attempt to check tidiness, pass `--skip src/tools/tidy` to `x.py test`", - PATH = inferred_rustfmt_dir.display(), - CHAN = builder.config.channel, + PATH = inferred_rustfmt_dir.display(), + CHAN = builder.config.channel, + ); + crate::exit!(1); + } + let all = false; + crate::core::build_steps::format::format( + builder, + !builder.config.cmd.bless(), + all, + &[], + ); + } else { + eprintln!( + "WARNING: `--json-output` is not supported on rustfmt, formatting will be skipped" ); - crate::exit!(1); } - let all = false; - crate::core::build_steps::format::format(builder, !builder.config.cmd.bless(), all, &[ - ]); } builder.info("tidy check"); From 31c4057bb8edb92671e632e22eec2c14ef19c556 Mon Sep 17 00:00:00 2001 From: onur-ozkan Date: Thu, 5 Dec 2024 10:17:26 +0000 Subject: [PATCH 10/16] handle `json_output` in `test::run_cargo_test` Signed-off-by: onur-ozkan --- src/bootstrap/src/core/build_steps/test.rs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/bootstrap/src/core/build_steps/test.rs b/src/bootstrap/src/core/build_steps/test.rs index 98bfc40fd7a9b..db246b97515e5 100644 --- a/src/bootstrap/src/core/build_steps/test.rs +++ b/src/bootstrap/src/core/build_steps/test.rs @@ -2634,6 +2634,11 @@ fn prepare_cargo_test( if builder.kind == Kind::Test && !builder.fail_fast { cargo.arg("--no-fail-fast"); } + + if builder.config.json_output { + cargo.arg("--message-format=json"); + } + match builder.doc_tests { DocTests::Only => { cargo.arg("--doc"); From cb72b9bb37c53c495baa726bfafaa893fb81396a Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 5 Dec 2024 16:57:30 +0000 Subject: [PATCH 11/16] Silence follow-up errors from `lit_to_const` --- compiler/rustc_mir_build/src/thir/constant.rs | 6 +- tests/crashes/123809.rs | 4 -- .../assoc-const-eq-ambiguity.stderr | 4 +- ...ce-hir-wf-check-anon-const-issue-122989.rs | 4 -- ...ir-wf-check-anon-const-issue-122989.stderr | 71 ++----------------- 5 files changed, 11 insertions(+), 78 deletions(-) delete mode 100644 tests/crashes/123809.rs diff --git a/compiler/rustc_mir_build/src/thir/constant.rs b/compiler/rustc_mir_build/src/thir/constant.rs index 3fa0e4def82e6..30b6718683b67 100644 --- a/compiler/rustc_mir_build/src/thir/constant.rs +++ b/compiler/rustc_mir_build/src/thir/constant.rs @@ -2,7 +2,7 @@ use rustc_ast as ast; use rustc_hir::LangItem; use rustc_middle::bug; use rustc_middle::mir::interpret::{LitToConstError, LitToConstInput}; -use rustc_middle::ty::{self, ScalarInt, TyCtxt}; +use rustc_middle::ty::{self, ScalarInt, TyCtxt, TypeVisitableExt as _}; use tracing::trace; use crate::build::parse_float_into_scalar; @@ -13,6 +13,10 @@ pub(crate) fn lit_to_const<'tcx>( ) -> Result, LitToConstError> { let LitToConstInput { lit, ty, neg } = lit_input; + if let Err(guar) = ty.error_reported() { + return Ok(ty::Const::new_error(tcx, guar)); + } + let trunc = |n| { let width = match tcx.layout_of(ty::TypingEnv::fully_monomorphized().as_query_input(ty)) { Ok(layout) => layout.size, diff --git a/tests/crashes/123809.rs b/tests/crashes/123809.rs deleted file mode 100644 index 75abe6dc0cd83..0000000000000 --- a/tests/crashes/123809.rs +++ /dev/null @@ -1,4 +0,0 @@ -//@ known-bug: #123809 -type Positive = std::pat::pattern_type!(std::pat is 0..); - -pub fn main() {} diff --git a/tests/ui/associated-consts/assoc-const-eq-ambiguity.stderr b/tests/ui/associated-consts/assoc-const-eq-ambiguity.stderr index ba3a870131606..4517610d8e5d5 100644 --- a/tests/ui/associated-consts/assoc-const-eq-ambiguity.stderr +++ b/tests/ui/associated-consts/assoc-const-eq-ambiguity.stderr @@ -30,8 +30,8 @@ LL | fn take1(_: impl Trait1) {} = help: consider introducing a new type parameter `T` and adding `where` constraints: where T: Trait1, - T: Parent2::C = "?", - T: Parent1::C = "?" + T: Parent2::C = {const error}, + T: Parent1::C = {const error} error: aborting due to 2 previous errors diff --git a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs index a953f1818c580..997bee1e60081 100644 --- a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs +++ b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.rs @@ -3,15 +3,11 @@ trait Foo> { //~^ WARN trait objects without an explicit `dyn` are deprecated //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! //~| ERROR cycle detected when computing type of `Foo::N` - //~| ERROR the trait `Foo` cannot be made into an object - //~| ERROR `(dyn Bar<2> + 'static)` is forbidden as the type of a const generic parameter fn func() {} } trait Bar> {} //~^ WARN trait objects without an explicit `dyn` are deprecated //~| WARN this is accepted in the current edition (Rust 2015) but is a hard error in Rust 2021! -//~| ERROR the trait `Foo` cannot be made into an object -//~| ERROR `(dyn Foo<2> + 'static)` is forbidden as the type of a const generic parameter fn main() {} diff --git a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr index f8905437c6ea6..733b729faf07a 100644 --- a/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr +++ b/tests/ui/wf/ice-hir-wf-check-anon-const-issue-122989.stderr @@ -13,7 +13,7 @@ LL | trait Foo> { | +++ warning: trait objects without an explicit `dyn` are deprecated - --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:11:20 + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:9:20 | LL | trait Bar> {} | ^^^^^^ @@ -32,7 +32,7 @@ LL | trait Foo> { | ^^^^^^^^^^^^^^^ | note: ...which requires computing type of `Bar::M`... - --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:11:11 + --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:9:11 | LL | trait Bar> {} | ^^^^^^^^^^^^^^^ @@ -44,69 +44,6 @@ LL | trait Foo> { | ^^^^^^^^^^^^^^^^^^^^^^^^^^ = note: see https://rustc-dev-guide.rust-lang.org/overview.html#queries and https://rustc-dev-guide.rust-lang.org/query.html for more information -error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:2:24 - | -LL | trait Foo> { - | ^ `Foo` cannot be made into an object - | -note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:8:8 - | -LL | trait Foo> { - | --- this trait cannot be made into an object... -... -LL | fn func() {} - | ^^^^ ...because associated function `func` has no `self` parameter -help: consider turning `func` into a method by giving it a `&self` argument - | -LL | fn func(&self) {} - | +++++ -help: alternatively, consider constraining `func` so it does not apply to trait objects - | -LL | fn func() where Self: Sized {} - | +++++++++++++++++ - -error: `(dyn Bar<2> + 'static)` is forbidden as the type of a const generic parameter - --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:2:20 - | -LL | trait Foo> { - | ^^^^^^ - | - = note: the only supported types are integers, `bool`, and `char` - -error[E0038]: the trait `Foo` cannot be made into an object - --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:11:11 - | -LL | trait Bar> {} - | ^^^^^^^^^^^^^^^ `Foo` cannot be made into an object - | -note: for a trait to be "dyn-compatible" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit - --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:8:8 - | -LL | trait Foo> { - | --- this trait cannot be made into an object... -... -LL | fn func() {} - | ^^^^ ...because associated function `func` has no `self` parameter -help: consider turning `func` into a method by giving it a `&self` argument - | -LL | fn func(&self) {} - | +++++ -help: alternatively, consider constraining `func` so it does not apply to trait objects - | -LL | fn func() where Self: Sized {} - | +++++++++++++++++ - -error: `(dyn Foo<2> + 'static)` is forbidden as the type of a const generic parameter - --> $DIR/ice-hir-wf-check-anon-const-issue-122989.rs:11:20 - | -LL | trait Bar> {} - | ^^^^^^ - | - = note: the only supported types are integers, `bool`, and `char` - -error: aborting due to 5 previous errors; 2 warnings emitted +error: aborting due to 1 previous error; 2 warnings emitted -Some errors have detailed explanations: E0038, E0391. -For more information about an error, try `rustc --explain E0038`. +For more information about this error, try `rustc --explain E0391`. From 060cecba1a049225cd83be0802d1583bc02e7422 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 5 Dec 2024 16:57:30 +0000 Subject: [PATCH 12/16] Hide errors whose suggestions would contain error constants or types --- compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs | 3 +++ tests/ui/associated-consts/assoc-const-eq-ambiguity.stderr | 6 ------ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs index 7ab254e5f4b84..3313339abb313 100644 --- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs +++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/mod.rs @@ -998,6 +998,9 @@ impl<'tcx> dyn HirTyLowerer<'tcx> + '_ { self.lower_const_arg(ct, FeedConstTy::No).into() } }; + if term.references_error() { + continue; + } // FIXME(#97583): This isn't syntactically well-formed! where_bounds.push(format!( " T: {trait}::{assoc_name} = {term}", diff --git a/tests/ui/associated-consts/assoc-const-eq-ambiguity.stderr b/tests/ui/associated-consts/assoc-const-eq-ambiguity.stderr index 4517610d8e5d5..aa1db4cb032ef 100644 --- a/tests/ui/associated-consts/assoc-const-eq-ambiguity.stderr +++ b/tests/ui/associated-consts/assoc-const-eq-ambiguity.stderr @@ -26,12 +26,6 @@ LL | trait Parent2 { const C: &'static str; } LL | LL | fn take1(_: impl Trait1) {} | ^^^^^^^ ambiguous associated constant `C` - | - = help: consider introducing a new type parameter `T` and adding `where` constraints: - where - T: Trait1, - T: Parent2::C = {const error}, - T: Parent1::C = {const error} error: aborting due to 2 previous errors From 85230741c7232819a01c71d158a7b763c39aeaaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jonathan=20D=C3=B6nszelmann?= Date: Fri, 6 Dec 2024 14:01:45 +0100 Subject: [PATCH 13/16] remove eq for attributes --- src/librustdoc/clean/types.rs | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/librustdoc/clean/types.rs b/src/librustdoc/clean/types.rs index 715bf68374a5f..cba947eb833b2 100644 --- a/src/librustdoc/clean/types.rs +++ b/src/librustdoc/clean/types.rs @@ -1241,19 +1241,6 @@ impl Attributes { } } -impl PartialEq for Attributes { - fn eq(&self, rhs: &Self) -> bool { - self.doc_strings == rhs.doc_strings - && self - .other_attrs - .iter() - .map(|attr| attr.id) - .eq(rhs.other_attrs.iter().map(|attr| attr.id)) - } -} - -impl Eq for Attributes {} - #[derive(Clone, PartialEq, Eq, Debug, Hash)] pub(crate) enum GenericBound { TraitBound(PolyTrait, hir::TraitBoundModifiers), From 71304f6595b8130526ea4008623c9f86b52a805c Mon Sep 17 00:00:00 2001 From: Weihang Lo Date: Fri, 6 Dec 2024 18:47:36 -0500 Subject: [PATCH 14/16] Update cargo --- src/tools/cargo | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/cargo b/src/tools/cargo index 05f54fdc34310..20a443231846b 160000 --- a/src/tools/cargo +++ b/src/tools/cargo @@ -1 +1 @@ -Subproject commit 05f54fdc34310f458033af8a63ce1d699fae8bf6 +Subproject commit 20a443231846b81c7b909691ec3f15eb173f2b18 From 7ba51929131e494482cccbec8038868dc1efef21 Mon Sep 17 00:00:00 2001 From: The Miri Cronjob Bot Date: Sun, 8 Dec 2024 04:55:19 +0000 Subject: [PATCH 15/16] Preparing for merge from rustc --- src/tools/miri/rust-version | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tools/miri/rust-version b/src/tools/miri/rust-version index ee21f2136cce4..57d0b27dfd3b7 100644 --- a/src/tools/miri/rust-version +++ b/src/tools/miri/rust-version @@ -1 +1 @@ -75716b45105e443199ce9800c7009ddfd6d2be53 +728f2daab42ba8f1b3d5caab62495798d1eabfa1 From 03c412ead4c3f61bc85a772cde5bcc1562975b09 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 8 Dec 2024 08:21:20 +0100 Subject: [PATCH 16/16] fix build --- src/tools/miri/src/shims/io_error.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/tools/miri/src/shims/io_error.rs b/src/tools/miri/src/shims/io_error.rs index 7596db8a1989e..acf3f74a93d8b 100644 --- a/src/tools/miri/src/shims/io_error.rs +++ b/src/tools/miri/src/shims/io_error.rs @@ -99,8 +99,8 @@ const WINDOWS_IO_ERROR_TABLE: &[(&str, std::io::ErrorKind)] = { ("ERROR_POSSIBLE_DEADLOCK", Deadlock), ("ERROR_DIR_NOT_EMPTY", DirectoryNotEmpty), ("ERROR_CANT_RESOLVE_FILENAME", FilesystemLoop), - ("ERROR_DISK_QUOTA_EXCEEDED", FilesystemQuotaExceeded), - ("WSAEDQUOT", FilesystemQuotaExceeded), + ("ERROR_DISK_QUOTA_EXCEEDED", QuotaExceeded), + ("WSAEDQUOT", QuotaExceeded), ("ERROR_FILE_TOO_LARGE", FileTooLarge), ("ERROR_HOST_UNREACHABLE", HostUnreachable), ("WSAEHOSTUNREACH", HostUnreachable),