From e2d6334191917c9c78f27aadb19722511cad3f47 Mon Sep 17 00:00:00 2001 From: Christiaan Dirkx Date: Fri, 18 Jun 2021 15:56:22 +0200 Subject: [PATCH 01/20] Add `Ipv6Addr::is_benchmarking` --- library/std/src/net/ip.rs | 22 ++++++++++ library/std/src/net/ip/tests.rs | 74 ++++++++++++++++++++------------- 2 files changed, 67 insertions(+), 29 deletions(-) diff --git a/library/std/src/net/ip.rs b/library/std/src/net/ip.rs index baf1c5aa2b941..d09a7a99d565c 100644 --- a/library/std/src/net/ip.rs +++ b/library/std/src/net/ip.rs @@ -1370,6 +1370,28 @@ impl Ipv6Addr { (self.segments()[0] == 0x2001) && (self.segments()[1] == 0xdb8) } + /// Returns [`true`] if this is an address reserved for benchmarking (`2001:2::/48`). + /// + /// This property is defined in [IETF RFC 5180], where it is mistakenly specified as covering the range `2001:0200::/48`. + /// This is corrected in [IETF RFC Errata 1752] to `2001:0002::/48`. + /// + /// [IETF RFC 5180]: https://tools.ietf.org/html/rfc5180 + /// [IETF RFC Errata 1752]: https://www.rfc-editor.org/errata_search.php?eid=1752 + /// + /// ``` + /// #![feature(ip)] + /// + /// use std::net::Ipv6Addr; + /// + /// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc613, 0x0).is_benchmarking(), false); + /// assert_eq!(Ipv6Addr::new(0x2001, 0x2, 0, 0, 0, 0, 0, 0).is_benchmarking(), true); + /// ``` + #[unstable(feature = "ip", issue = "27709")] + #[inline] + pub const fn is_benchmarking(&self) -> bool { + (self.segments()[0] == 0x2001) && (self.segments()[1] == 0x2) && (self.segments()[2] == 0) + } + /// Returns [`true`] if the address is a globally routable unicast address. /// /// The following return false: diff --git a/library/std/src/net/ip/tests.rs b/library/std/src/net/ip/tests.rs index 2109980ad058d..557e04081cadf 100644 --- a/library/std/src/net/ip/tests.rs +++ b/library/std/src/net/ip/tests.rs @@ -475,21 +475,22 @@ fn ipv6_properties() { assert_eq!(&ip!($s).octets(), octets); assert_eq!(Ipv6Addr::from(*octets), ip!($s)); - let unspecified: u16 = 1 << 0; - let loopback: u16 = 1 << 1; - let unique_local: u16 = 1 << 2; - let global: u16 = 1 << 3; - let unicast_link_local: u16 = 1 << 4; - let unicast_global: u16 = 1 << 7; - let documentation: u16 = 1 << 8; - let multicast_interface_local: u16 = 1 << 9; - let multicast_link_local: u16 = 1 << 10; - let multicast_realm_local: u16 = 1 << 11; - let multicast_admin_local: u16 = 1 << 12; - let multicast_site_local: u16 = 1 << 13; - let multicast_organization_local: u16 = 1 << 14; - let multicast_global: u16 = 1 << 15; - let multicast: u16 = multicast_interface_local + let unspecified: u32 = 1 << 0; + let loopback: u32 = 1 << 1; + let unique_local: u32 = 1 << 2; + let global: u32 = 1 << 3; + let unicast_link_local: u32 = 1 << 4; + let unicast_global: u32 = 1 << 7; + let documentation: u32 = 1 << 8; + let benchmarking: u32 = 1 << 16; + let multicast_interface_local: u32 = 1 << 9; + let multicast_link_local: u32 = 1 << 10; + let multicast_realm_local: u32 = 1 << 11; + let multicast_admin_local: u32 = 1 << 12; + let multicast_site_local: u32 = 1 << 13; + let multicast_organization_local: u32 = 1 << 14; + let multicast_global: u32 = 1 << 15; + let multicast: u32 = multicast_interface_local | multicast_admin_local | multicast_global | multicast_link_local @@ -532,6 +533,11 @@ fn ipv6_properties() { } else { assert!(!ip!($s).is_documentation()); } + if ($mask & benchmarking) == benchmarking { + assert!(ip!($s).is_benchmarking()); + } else { + assert!(!ip!($s).is_benchmarking()); + } if ($mask & multicast) != 0 { assert!(ip!($s).multicast_scope().is_some()); assert!(ip!($s).is_multicast()); @@ -570,20 +576,21 @@ fn ipv6_properties() { } } - let unspecified: u16 = 1 << 0; - let loopback: u16 = 1 << 1; - let unique_local: u16 = 1 << 2; - let global: u16 = 1 << 3; - let unicast_link_local: u16 = 1 << 4; - let unicast_global: u16 = 1 << 7; - let documentation: u16 = 1 << 8; - let multicast_interface_local: u16 = 1 << 9; - let multicast_link_local: u16 = 1 << 10; - let multicast_realm_local: u16 = 1 << 11; - let multicast_admin_local: u16 = 1 << 12; - let multicast_site_local: u16 = 1 << 13; - let multicast_organization_local: u16 = 1 << 14; - let multicast_global: u16 = 1 << 15; + let unspecified: u32 = 1 << 0; + let loopback: u32 = 1 << 1; + let unique_local: u32 = 1 << 2; + let global: u32 = 1 << 3; + let unicast_link_local: u32 = 1 << 4; + let unicast_global: u32 = 1 << 7; + let documentation: u32 = 1 << 8; + let benchmarking: u32 = 1 << 16; + let multicast_interface_local: u32 = 1 << 9; + let multicast_link_local: u32 = 1 << 10; + let multicast_realm_local: u32 = 1 << 11; + let multicast_admin_local: u32 = 1 << 12; + let multicast_site_local: u32 = 1 << 13; + let multicast_organization_local: u32 = 1 << 14; + let multicast_global: u32 = 1 << 15; check!("::", &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], unspecified); @@ -679,6 +686,12 @@ fn ipv6_properties() { documentation ); + check!( + "2001:2::ac32:23ff:21", + &[0x20, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0xac, 0x32, 0x23, 0xff, 0, 0x21], + global | unicast_global | benchmarking + ); + check!( "102:304:506:708:90a:b0c:d0e:f10", &[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16], @@ -885,6 +898,9 @@ fn ipv6_const() { const IS_DOCUMENTATION: bool = IP_ADDRESS.is_documentation(); assert!(!IS_DOCUMENTATION); + const IS_BENCHMARKING: bool = IP_ADDRESS.is_benchmarking(); + assert!(!IS_BENCHMARKING); + const IS_UNICAST_GLOBAL: bool = IP_ADDRESS.is_unicast_global(); assert!(!IS_UNICAST_GLOBAL); From cbaccc12c700a2f4d4d22e2765c10b105497025e Mon Sep 17 00:00:00 2001 From: Christiaan Dirkx Date: Fri, 18 Jun 2021 16:13:05 +0200 Subject: [PATCH 02/20] Add `IpAddr::is_benchmarking` --- library/std/src/net/ip.rs | 24 ++++++++++++++++++++++++ library/std/src/net/ip/tests.rs | 15 ++++++++++++--- 2 files changed, 36 insertions(+), 3 deletions(-) diff --git a/library/std/src/net/ip.rs b/library/std/src/net/ip.rs index d09a7a99d565c..c57a50f5edede 100644 --- a/library/std/src/net/ip.rs +++ b/library/std/src/net/ip.rs @@ -252,6 +252,30 @@ impl IpAddr { } } + /// Returns [`true`] if this address is in a range designated for benchmarking. + /// + /// See the documentation for [`Ipv4Addr::is_benchmarking()`] and + /// [`Ipv6Addr::is_benchmarking()`] for more details. + /// + /// # Examples + /// + /// ``` + /// #![feature(ip)] + /// + /// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr}; + /// + /// assert_eq!(IpAddr::V4(Ipv4Addr::new(198, 19, 255, 255)).is_benchmarking(), true); + /// assert_eq!(IpAddr::V6(Ipv6Addr::new(0x2001, 0x2, 0, 0, 0, 0, 0, 0)).is_benchmarking(), true); + /// ``` + #[unstable(feature = "ip", issue = "27709")] + #[inline] + pub const fn is_benchmarking(&self) -> bool { + match self { + IpAddr::V4(ip) => ip.is_benchmarking(), + IpAddr::V6(ip) => ip.is_benchmarking(), + } + } + /// Returns [`true`] if this address is an [`IPv4` address], and [`false`] /// otherwise. /// diff --git a/library/std/src/net/ip/tests.rs b/library/std/src/net/ip/tests.rs index 557e04081cadf..ba387c3c048ce 100644 --- a/library/std/src/net/ip/tests.rs +++ b/library/std/src/net/ip/tests.rs @@ -224,6 +224,7 @@ fn ip_properties() { let global: u8 = 1 << 2; let multicast: u8 = 1 << 3; let doc: u8 = 1 << 4; + let benchmarking: u8 = 1 << 5; if ($mask & unspec) == unspec { assert!(ip!($s).is_unspecified()); @@ -254,6 +255,12 @@ fn ip_properties() { } else { assert!(!ip!($s).is_documentation()); } + + if ($mask & benchmarking) == benchmarking { + assert!(ip!($s).is_benchmarking()); + } else { + assert!(!ip!($s).is_benchmarking()); + } }}; } @@ -262,6 +269,7 @@ fn ip_properties() { let global: u8 = 1 << 2; let multicast: u8 = 1 << 3; let doc: u8 = 1 << 4; + let benchmarking: u8 = 1 << 5; check!("0.0.0.0", unspec); check!("0.0.0.1"); @@ -280,9 +288,9 @@ fn ip_properties() { check!("239.255.255.255", global | multicast); check!("255.255.255.255"); // make sure benchmarking addresses are not global - check!("198.18.0.0"); - check!("198.18.54.2"); - check!("198.19.255.255"); + check!("198.18.0.0", benchmarking); + check!("198.18.54.2", benchmarking); + check!("198.19.255.255", benchmarking); // make sure addresses reserved for protocol assignment are not global check!("192.0.0.0"); check!("192.0.0.255"); @@ -313,6 +321,7 @@ fn ip_properties() { check!("ff08::", multicast); check!("ff0e::", global | multicast); check!("2001:db8:85a3::8a2e:370:7334", doc); + check!("2001:2::ac32:23ff:21", global | benchmarking); check!("102:304:506:708:90a:b0c:d0e:f10", global); } From e394bb763be932c6748a16ddb49688e60464274a Mon Sep 17 00:00:00 2001 From: Stein Somers Date: Sun, 1 Aug 2021 11:06:21 +0200 Subject: [PATCH 03/20] BTree: refine some comments --- library/alloc/src/collections/btree/map.rs | 10 +++++----- library/alloc/src/collections/btree/navigate.rs | 6 ++---- library/alloc/src/collections/btree/node.rs | 4 ++-- 3 files changed, 9 insertions(+), 11 deletions(-) diff --git a/library/alloc/src/collections/btree/map.rs b/library/alloc/src/collections/btree/map.rs index 4b649e43371de..40aa91da75a35 100644 --- a/library/alloc/src/collections/btree/map.rs +++ b/library/alloc/src/collections/btree/map.rs @@ -17,16 +17,16 @@ mod entry; pub use entry::{Entry, OccupiedEntry, OccupiedError, VacantEntry}; use Entry::*; -/// Minimum number of elements in nodes that are not a root. +/// Minimum number of elements in a node that is not a root. /// We might temporarily have fewer elements during methods. pub(super) const MIN_LEN: usize = node::MIN_LEN_AFTER_SPLIT; // A tree in a `BTreeMap` is a tree in the `node` module with additional invariants: // - Keys must appear in ascending order (according to the key's type). -// - If the root node is internal, it must contain at least 1 element. +// - Every non-leaf node contains at least 1 element (has at least 2 children). // - Every non-root node contains at least MIN_LEN elements. // -// An empty map may be represented both by the absence of a root node or by a +// An empty map is represented either by the absence of a root node or by a // root node that is an empty leaf. /// A map based on a [B-Tree]. @@ -1723,8 +1723,8 @@ impl<'a, K: 'a, V: 'a> DrainFilterInner<'a, K, V> { pub(super) fn size_hint(&self) -> (usize, Option) { // In most of the btree iterators, `self.length` is the number of elements // yet to be visited. Here, it includes elements that were visited and that - // the predicate decided not to drain. Making this upper bound more accurate - // requires maintaining an extra field and is not worth while. + // the predicate decided not to drain. Making this upper bound more tight + // during iteration would require an extra field. (0, Some(*self.length)) } } diff --git a/library/alloc/src/collections/btree/navigate.rs b/library/alloc/src/collections/btree/navigate.rs index 7b1d4d68c4f56..9d0db34500945 100644 --- a/library/alloc/src/collections/btree/navigate.rs +++ b/library/alloc/src/collections/btree/navigate.rs @@ -440,8 +440,7 @@ impl Handle, marker::Edge> { /// - The given edge must not have been previously returned by counterpart /// `deallocating_next_back`. /// - The returned KV handle is only valid to access the key and value, - /// and only valid until the next call to this method or counterpart - /// `deallocating_next_back`. + /// and only valid until the next call to a `deallocating_` method. unsafe fn deallocating_next( self, ) -> Option<(Self, Handle, marker::KV>)> @@ -470,8 +469,7 @@ impl Handle, marker::Edge> { /// - The given edge must not have been previously returned by counterpart /// `deallocating_next`. /// - The returned KV handle is only valid to access the key and value, - /// and only valid until the next call to this method or counterpart - /// `deallocating_next`. + /// and only valid until the next call to a `deallocating_` method. unsafe fn deallocating_next_back( self, ) -> Option<(Self, Handle, marker::KV>)> diff --git a/library/alloc/src/collections/btree/node.rs b/library/alloc/src/collections/btree/node.rs index 8f6a2ec9ebd1f..dfce98f97bd44 100644 --- a/library/alloc/src/collections/btree/node.rs +++ b/library/alloc/src/collections/btree/node.rs @@ -574,7 +574,7 @@ impl NodeRef { /// no cleanup is done on any of the keys, values and other children. /// This decreases the height by 1 and is the opposite of `push_internal_level`. /// - /// Requires exclusive access to the `Root` object but not to the root node; + /// Requires exclusive access to the `NodeRef` object but not to the root node; /// it will not invalidate other handles or references to the root node. /// /// Panics if there is no internal level, i.e., if the root node is a leaf. @@ -1663,7 +1663,7 @@ pub mod marker { const PERMITS_TRAVERSAL: bool = true; } impl BorrowType for Owned { - // Traversal isn't needede, it happens using the result of `borrow_mut`. + // Traversal isn't needed, it happens using the result of `borrow_mut`. // By disabling traversal, and only creating new references to roots, // we know that every reference of the `Owned` type is to a root node. const PERMITS_TRAVERSAL: bool = false; From 22112e439092e26536a9c9aaa35e892ce36afbea Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?L=C3=A9o=20Lanteri=20Thauvin?= Date: Tue, 24 Aug 2021 10:07:16 +0200 Subject: [PATCH 04/20] Remove unnecessary unsafe block in `process_unix` --- library/std/src/sys/unix/process/process_unix.rs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index 12edf04a4e2e9..c4215e2c78d77 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -552,8 +552,7 @@ impl Process { use crate::os::unix::io::FromRawFd; use crate::sys_common::FromInner; // Safety: If `pidfd` is nonnegative, we assume it's valid and otherwise unowned. - let pidfd = (pidfd >= 0) - .then(|| PidFd::from_inner(unsafe { sys::fd::FileDesc::from_raw_fd(pidfd) })); + let pidfd = (pidfd >= 0).then(|| PidFd::from_inner(sys::fd::FileDesc::from_raw_fd(pidfd))); Process { pid, status: None, pidfd } } From 848a38ac9d9bc956cded893bdd55e1171a2706dd Mon Sep 17 00:00:00 2001 From: Ian Jackson Date: Tue, 24 Aug 2021 18:56:24 +0100 Subject: [PATCH 05/20] Manual Debug for Unix ExitCode ExitStatus ExitStatusError These structs have misleading names. An ExitStatus[Error] is actually a Unix wait status; an ExitCode is actually an exit status. The Display impls are fixed, but the Debug impls are still misleading, as reported in #74832. Fix this by pretending that these internal structs are called `unix_exit_status` and `unix_wait_status` as applicable. (We can't actually rename the structs because of the way that the cross-platform machinery works: the names are cross-platform.) Signed-off-by: Ian Jackson --- .../std/src/sys/unix/process/process_common.rs | 8 +++++++- library/std/src/sys/unix/process/process_unix.rs | 16 ++++++++++++++-- 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/library/std/src/sys/unix/process/process_common.rs b/library/std/src/sys/unix/process/process_common.rs index 7b261a302c33f..7ac2f9d8af75a 100644 --- a/library/std/src/sys/unix/process/process_common.rs +++ b/library/std/src/sys/unix/process/process_common.rs @@ -457,9 +457,15 @@ impl fmt::Debug for Command { } } -#[derive(PartialEq, Eq, Clone, Copy, Debug)] +#[derive(PartialEq, Eq, Clone, Copy)] pub struct ExitCode(u8); +impl fmt::Debug for ExitCode { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("unix_exit_status").field(&self.0).finish() + } +} + impl ExitCode { pub const SUCCESS: ExitCode = ExitCode(EXIT_SUCCESS as _); pub const FAILURE: ExitCode = ExitCode(EXIT_FAILURE as _); diff --git a/library/std/src/sys/unix/process/process_unix.rs b/library/std/src/sys/unix/process/process_unix.rs index 12edf04a4e2e9..7b8230d89daa7 100644 --- a/library/std/src/sys/unix/process/process_unix.rs +++ b/library/std/src/sys/unix/process/process_unix.rs @@ -607,9 +607,15 @@ impl Process { } /// Unix exit statuses -#[derive(PartialEq, Eq, Clone, Copy, Debug)] +#[derive(PartialEq, Eq, Clone, Copy)] pub struct ExitStatus(c_int); +impl fmt::Debug for ExitStatus { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("unix_wait_status").field(&self.0).finish() + } +} + impl ExitStatus { pub fn new(status: c_int) -> ExitStatus { ExitStatus(status) @@ -683,7 +689,7 @@ impl fmt::Display for ExitStatus { } } -#[derive(PartialEq, Eq, Clone, Copy, Debug)] +#[derive(PartialEq, Eq, Clone, Copy)] pub struct ExitStatusError(NonZero_c_int); impl Into for ExitStatusError { @@ -692,6 +698,12 @@ impl Into for ExitStatusError { } } +impl fmt::Debug for ExitStatusError { + fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { + f.debug_tuple("unix_wait_status").field(&self.0).finish() + } +} + impl ExitStatusError { pub fn code(self) -> Option { ExitStatus(self.0.into()).code().map(|st| st.try_into().unwrap()) From 905c2ba5f8592c9722c7317cbc2781a7561c250b Mon Sep 17 00:00:00 2001 From: Jacob Pratt Date: Thu, 26 Aug 2021 05:27:39 -0400 Subject: [PATCH 06/20] Partially stabilize `array_methods` This also makes `<[T; N]>::as_slice` const due to its trivial nature. --- library/core/src/array/mod.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/library/core/src/array/mod.rs b/library/core/src/array/mod.rs index 3c638e655dc91..3b21a980e8feb 100644 --- a/library/core/src/array/mod.rs +++ b/library/core/src/array/mod.rs @@ -368,14 +368,14 @@ impl [T; N] { } /// Returns a slice containing the entire array. Equivalent to `&s[..]`. - #[unstable(feature = "array_methods", issue = "76118")] - pub fn as_slice(&self) -> &[T] { + #[stable(feature = "array_as_slice", since = "1.57.0")] + pub const fn as_slice(&self) -> &[T] { self } /// Returns a mutable slice containing the entire array. Equivalent to /// `&mut s[..]`. - #[unstable(feature = "array_methods", issue = "76118")] + #[stable(feature = "array_as_slice", since = "1.57.0")] pub fn as_mut_slice(&mut self) -> &mut [T] { self } From ca88f10e39d421cbbd876a5da8d1ce52f84df73d Mon Sep 17 00:00:00 2001 From: Sebastian Widua Date: Thu, 26 Aug 2021 23:23:17 +0200 Subject: [PATCH 07/20] Add missing # Panics section to `Vec` method namely `Vec::extend_from_within` --- library/alloc/src/vec/mod.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index 87a0d37181562..39ed03c437943 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2164,7 +2164,12 @@ impl Vec { /// Copies elements from `src` range to the end of the vector. /// - /// ## Examples + /// # Panics + /// + /// Panics if the starting point is greater than the end point or if + /// the end point is greater than the length of the vector. + /// + /// # Examples /// /// ``` /// let mut vec = vec![0, 1, 2, 3, 4]; From 10ddabc194cc3349d4cd0951b00484d736edc6aa Mon Sep 17 00:00:00 2001 From: Lamb Date: Fri, 2 Jul 2021 23:34:52 +0200 Subject: [PATCH 08/20] const fn for option copied, take & replace + tests fix: move test that require mut to another Adding TODOs for Option::take and Option::copied TODO to FIXME + moving const stability under normal Moving const stability attr under normal stab attr move more rustc stability attributes --- library/core/src/lib.rs | 1 + library/core/src/option.rs | 23 ++++++++++++++++------- library/core/tests/option.rs | 13 +++++++++++++ 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index 1a6d1aed2fd1e..28433f734c656 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -91,6 +91,7 @@ #![feature(const_maybe_uninit_assume_init)] #![feature(const_option)] #![feature(const_pin)] +#![feature(const_replace)] #![feature(const_ptr_offset)] #![feature(const_ptr_offset_from)] #![feature(const_ptr_read)] diff --git a/library/core/src/option.rs b/library/core/src/option.rs index 47865240f6a6f..59ebc90222402 100644 --- a/library/core/src/option.rs +++ b/library/core/src/option.rs @@ -540,8 +540,8 @@ impl Option { /// ``` #[must_use = "if you intended to assert that this has a value, consider `.unwrap()` instead"] #[inline] - #[rustc_const_stable(feature = "const_option", since = "1.48.0")] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_stable(feature = "const_option", since = "1.48.0")] pub const fn is_some(&self) -> bool { matches!(*self, Some(_)) } @@ -560,8 +560,8 @@ impl Option { #[must_use = "if you intended to assert that this doesn't have a value, consider \ `.and_then(|_| panic!(\"`Option` had a value when expected `None`\"))` instead"] #[inline] - #[rustc_const_stable(feature = "const_option", since = "1.48.0")] #[stable(feature = "rust1", since = "1.0.0")] + #[rustc_const_stable(feature = "const_option", since = "1.48.0")] pub const fn is_none(&self) -> bool { !self.is_some() } @@ -1312,8 +1312,10 @@ impl Option { /// ``` #[inline] #[stable(feature = "rust1", since = "1.0.0")] - pub fn take(&mut self) -> Option { - mem::take(self) + #[rustc_const_unstable(feature = "const_option", issue = "67441")] + pub const fn take(&mut self) -> Option { + // FIXME replace `mem::replace` by `mem::take` when the latter is const ready + mem::replace(self, None) } /// Replaces the actual value in the option by the value given in parameter, @@ -1334,8 +1336,9 @@ impl Option { /// assert_eq!(old, None); /// ``` #[inline] + #[rustc_const_unstable(feature = "const_option", issue = "67441")] #[stable(feature = "option_replace", since = "1.31.0")] - pub fn replace(&mut self, value: T) -> Option { + pub const fn replace(&mut self, value: T) -> Option { mem::replace(self, Some(value)) } @@ -1440,8 +1443,14 @@ impl Option<&T> { /// assert_eq!(copied, Some(12)); /// ``` #[stable(feature = "copied", since = "1.35.0")] - pub fn copied(self) -> Option { - self.map(|&t| t) + #[rustc_const_unstable(feature = "const_option", issue = "67441")] + pub const fn copied(self) -> Option { + // FIXME: this implementation, which sidesteps using `Option::map` since it's not const + // ready yet, should be reverted when possible to avoid code repetition + match self { + Some(&v) => Some(v), + None => None, + } } } diff --git a/library/core/tests/option.rs b/library/core/tests/option.rs index cd8fdebe36a05..8995f96b1238a 100644 --- a/library/core/tests/option.rs +++ b/library/core/tests/option.rs @@ -367,6 +367,19 @@ fn option_const() { const IS_NONE: bool = OPTION.is_none(); assert!(!IS_NONE); + + const COPIED: Option = OPTION.as_ref().copied(); + assert_eq!(COPIED, OPTION); +} + +#[test] +const fn option_const_mut() { + // test that the methods of `Option` that take mutable references are usable in a const context + + let mut option: Option = Some(32); + + let _take = option.take(); + let _replace = option.replace(42); } #[test] From 74c4c0172ab1f5c19fef69a163349a0a3f9cd927 Mon Sep 17 00:00:00 2001 From: Iago-lito Date: Tue, 10 Aug 2021 09:34:12 +0200 Subject: [PATCH 09/20] Mark unsafe NonZero*::unchecked_(add|mul) as const --- library/core/src/num/nonzero.rs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs index dd9b9330aee2b..e44597279baf2 100644 --- a/library/core/src/num/nonzero.rs +++ b/library/core/src/num/nonzero.rs @@ -379,7 +379,7 @@ macro_rules! nonzero_unsigned_operations { /// ``` #[unstable(feature = "nonzero_ops", issue = "84186")] #[inline] - pub unsafe fn unchecked_add(self, other: $Int) -> $Ty { + pub const unsafe fn unchecked_add(self, other: $Int) -> $Ty { // SAFETY: The caller ensures there is no overflow. unsafe { $Ty::new_unchecked(self.get().unchecked_add(other)) } } @@ -750,7 +750,7 @@ macro_rules! nonzero_unsigned_signed_operations { /// ``` #[unstable(feature = "nonzero_ops", issue = "84186")] #[inline] - pub unsafe fn unchecked_mul(self, other: $Ty) -> $Ty { + pub const unsafe fn unchecked_mul(self, other: $Ty) -> $Ty { // SAFETY: The caller ensures there is no overflow. unsafe { $Ty::new_unchecked(self.get().unchecked_mul(other.get())) } } From a993d7d963eba62c9f4598923dab6306825d5ff2 Mon Sep 17 00:00:00 2001 From: Artyom Pavlov Date: Tue, 21 Sep 2021 05:36:03 +0000 Subject: [PATCH 10/20] Fix link in Ipv6Addr::to_ipv4 docs --- library/std/src/net/ip.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/library/std/src/net/ip.rs b/library/std/src/net/ip.rs index 9cf7ba9d57401..76a724209e7c2 100644 --- a/library/std/src/net/ip.rs +++ b/library/std/src/net/ip.rs @@ -1589,7 +1589,7 @@ impl Ipv6Addr { /// `::a.b.c.d` and `::ffff:a.b.c.d` become `a.b.c.d` /// All addresses *not* starting with either all zeroes or `::ffff` will return `None`. /// - /// [IPv4 address]: Ipv4Addr + /// [`IPv4` address]: Ipv4Addr /// [IPv4-compatible]: Ipv6Addr#ipv4-compatible-ipv6-addresses /// [IPv4-mapped]: Ipv6Addr#ipv4-mapped-ipv6-addresses /// [IETF RFC 4291 section 2.5.5.1]: https://tools.ietf.org/html/rfc4291#section-2.5.5.1 From e8e7f6e05cf664fe748caf0198983f72248489b4 Mon Sep 17 00:00:00 2001 From: Owen Gage Date: Thu, 30 Sep 2021 17:21:03 +0100 Subject: [PATCH 11/20] Add truncate note to Vec::resize --- library/alloc/src/vec/mod.rs | 1 + 1 file changed, 1 insertion(+) diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs index c37ec37556157..cc53df812bb54 100644 --- a/library/alloc/src/vec/mod.rs +++ b/library/alloc/src/vec/mod.rs @@ -2116,6 +2116,7 @@ impl Vec { /// in order to be able to clone the passed value. /// If you need more flexibility (or want to rely on [`Default`] instead of /// [`Clone`]), use [`Vec::resize_with`]. + /// If you only need to resize to a smaller size, use [`Vec::truncate`]. /// /// # Examples /// From e017e458abce863b1d3ce19852bf683fcd972980 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Tobias=20Nie=C3=9Fen?= Date: Sat, 2 Oct 2021 19:03:32 +0200 Subject: [PATCH 12/20] Fix typos in rustdoc/lints Refs: https://github.com/rust-lang/rust/pull/85223 --- src/doc/rustdoc/src/lints.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/doc/rustdoc/src/lints.md b/src/doc/rustdoc/src/lints.md index d5981dd83de8c..1773c15464a94 100644 --- a/src/doc/rustdoc/src/lints.md +++ b/src/doc/rustdoc/src/lints.md @@ -70,7 +70,7 @@ This lint **warns by default**. This lint detects when [intra-doc links] from pu For example: ```rust -#![warn(rustdoc::private_intra_doc_links)] // note: unecessary - warns by default. +#![warn(rustdoc::private_intra_doc_links)] // note: unnecessary - warns by default. /// [private] pub fn public() {} @@ -229,7 +229,7 @@ This lint **warns by default**. It detects code block attributes in documentation examples that have potentially mis-typed values. For example: ```rust -#![warn(rustdoc::invalid_codeblock_attributes)] // note: unecessary - warns by default. +#![warn(rustdoc::invalid_codeblock_attributes)] // note: unnecessary - warns by default. /// Example. /// @@ -348,7 +348,7 @@ This lint is **warn-by-default**. It detects URLs which are not links. For example: ```rust -#![warn(rustdoc::bare_urls)] // note: unecessary - warns by default. +#![warn(rustdoc::bare_urls)] // note: unnecessary - warns by default. /// http://example.org /// [http://example.net] From 83ddedf17086cb7f091efe4bf5fdc9a137bea3ff Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 29 Aug 2021 21:09:45 +0200 Subject: [PATCH 13/20] Remove various unused feature gates --- compiler/rustc_data_structures/src/lib.rs | 1 - compiler/rustc_lint/src/lib.rs | 1 - compiler/rustc_middle/src/lib.rs | 2 -- compiler/rustc_target/src/lib.rs | 1 - compiler/rustc_ty_utils/src/lib.rs | 2 -- 5 files changed, 7 deletions(-) diff --git a/compiler/rustc_data_structures/src/lib.rs b/compiler/rustc_data_structures/src/lib.rs index b1f04bfbf0a84..370e8ffed728b 100644 --- a/compiler/rustc_data_structures/src/lib.rs +++ b/compiler/rustc_data_structures/src/lib.rs @@ -7,7 +7,6 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![feature(allow_internal_unstable)] #![feature(array_windows)] #![feature(associated_type_bounds)] #![feature(auto_traits)] diff --git a/compiler/rustc_lint/src/lib.rs b/compiler/rustc_lint/src/lib.rs index 10285272130cc..17eb00545847c 100644 --- a/compiler/rustc_lint/src/lib.rs +++ b/compiler/rustc_lint/src/lib.rs @@ -26,7 +26,6 @@ //! This API is completely unstable and subject to change. #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] -#![cfg_attr(test, feature(test))] #![feature(array_windows)] #![feature(bool_to_option)] #![feature(box_patterns)] diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index 02f0294c8ad25..1f2bfa5e7d904 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -41,13 +41,11 @@ #![feature(once_cell)] #![feature(min_specialization)] #![feature(trusted_len)] -#![feature(test)] #![feature(in_band_lifetimes)] #![feature(crate_visibility_modifier)] #![feature(associated_type_bounds)] #![feature(rustc_attrs)] #![feature(half_open_range_patterns)] -#![feature(exclusive_range_pattern)] #![feature(control_flow_enum)] #![feature(associated_type_defaults)] #![feature(iter_zip)] diff --git a/compiler/rustc_target/src/lib.rs b/compiler/rustc_target/src/lib.rs index e75c52555b903..23d5d575d9447 100644 --- a/compiler/rustc_target/src/lib.rs +++ b/compiler/rustc_target/src/lib.rs @@ -15,7 +15,6 @@ #![feature(exhaustive_patterns)] #![feature(min_specialization)] #![feature(step_trait)] -#![feature(unchecked_math)] use std::path::{Path, PathBuf}; diff --git a/compiler/rustc_ty_utils/src/lib.rs b/compiler/rustc_ty_utils/src/lib.rs index 313571274c3de..60f8e196bcba1 100644 --- a/compiler/rustc_ty_utils/src/lib.rs +++ b/compiler/rustc_ty_utils/src/lib.rs @@ -6,8 +6,6 @@ #![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")] #![feature(control_flow_enum)] -#![feature(half_open_range_patterns)] -#![feature(exclusive_range_pattern)] #![feature(nll)] #![recursion_limit = "256"] From 998753c6f7a47cfa4072c73d5166d85d55d1187a Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 29 Aug 2021 19:42:41 +0200 Subject: [PATCH 14/20] Swap out unboxed_closures feature gate for min_specialization For some reason unboxed_closures supresses the feature gate for min_specialization when implementing TrustedStep. min_specialization is the true feature that is used. --- compiler/rustc_index/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs index 0093fa5e562af..f18f322b2220d 100644 --- a/compiler/rustc_index/src/lib.rs +++ b/compiler/rustc_index/src/lib.rs @@ -2,7 +2,7 @@ #![feature(bench_black_box)] #![feature(extend_one)] #![feature(iter_zip)] -#![feature(unboxed_closures)] +#![feature(min_specialization)] #![feature(test)] #![feature(fn_traits)] From e98f28907ec148a2aeff6bcdaa90151bdca05424 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sun, 29 Aug 2021 20:39:32 +0200 Subject: [PATCH 15/20] Turn a module non-doc comment into a doc comment --- compiler/rustc_middle/src/ty/codec.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_middle/src/ty/codec.rs b/compiler/rustc_middle/src/ty/codec.rs index 8b70692960df9..434008ecb1f4f 100644 --- a/compiler/rustc_middle/src/ty/codec.rs +++ b/compiler/rustc_middle/src/ty/codec.rs @@ -1,10 +1,10 @@ -// This module contains some shared code for encoding and decoding various -// things from the `ty` module, and in particular implements support for -// "shorthands" which allow to have pointers back into the already encoded -// stream instead of re-encoding the same thing twice. -// -// The functionality in here is shared between persisting to crate metadata and -// persisting to incr. comp. caches. +//! This module contains some shared code for encoding and decoding various +//! things from the `ty` module, and in particular implements support for +//! "shorthands" which allow to have pointers back into the already encoded +//! stream instead of re-encoding the same thing twice. +//! +//! The functionality in here is shared between persisting to crate metadata and +//! persisting to incr. comp. caches. use crate::arena::ArenaAllocatable; use crate::infer::canonical::{CanonicalVarInfo, CanonicalVarInfos}; From 9a6f2e655aa15bd600fc55949b17bbc51fc1565d Mon Sep 17 00:00:00 2001 From: Christiaan Dirkx Date: Mon, 24 May 2021 23:58:20 +0200 Subject: [PATCH 16/20] Only register `WSACleanup` if `WSAStartup` is actually ever called --- library/std/src/sys/windows/net.rs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/library/std/src/sys/windows/net.rs b/library/std/src/sys/windows/net.rs index 33152cc97abc0..84a5a389e0db3 100644 --- a/library/std/src/sys/windows/net.rs +++ b/library/std/src/sys/windows/net.rs @@ -2,13 +2,13 @@ use crate::cmp; use crate::io::{self, IoSlice, IoSliceMut, Read}; +use crate::lazy::SyncOnceCell; use crate::mem; use crate::net::{Shutdown, SocketAddr}; use crate::os::windows::io::{ AsRawSocket, AsSocket, BorrowedSocket, FromRawSocket, IntoRawSocket, OwnedSocket, RawSocket, }; use crate::ptr; -use crate::sync::Once; use crate::sys; use crate::sys::c; use crate::sys_common::net; @@ -29,26 +29,31 @@ pub mod netc { pub struct Socket(OwnedSocket); -static INIT: Once = Once::new(); +static WSA: SyncOnceCell i32> = SyncOnceCell::new(); /// Checks whether the Windows socket interface has been started already, and /// if not, starts it. pub fn init() { - INIT.call_once(|| unsafe { + let _ = WSA.get_or_init(|| unsafe { let mut data: c::WSADATA = mem::zeroed(); let ret = c::WSAStartup( 0x202, // version 2.2 &mut data, ); assert_eq!(ret, 0); + + // Only register `WSACleanup` if `WSAStartup` is actually ever called. + // Workaround to prevent linking to `WS2_32.dll` when no network functionality is used. + // See issue #85441. + c::WSACleanup }); } pub fn cleanup() { - if INIT.is_completed() { - // only close the socket interface if it has actually been started + // only perform cleanup if network functionality was actually initialized + if let Some(cleanup) = WSA.get() { unsafe { - c::WSACleanup(); + cleanup(); } } } From b7d2b465b9a3d375ad3c1fbce75fa2ed47cc9e99 Mon Sep 17 00:00:00 2001 From: Christiaan Dirkx Date: Tue, 25 May 2021 00:05:18 +0200 Subject: [PATCH 17/20] Add test for checking if WS2_32.dll is linked --- src/test/run-make/issue-85441/Makefile | 9 +++++++++ src/test/run-make/issue-85441/empty.rs | 1 + 2 files changed, 10 insertions(+) create mode 100644 src/test/run-make/issue-85441/Makefile create mode 100644 src/test/run-make/issue-85441/empty.rs diff --git a/src/test/run-make/issue-85441/Makefile b/src/test/run-make/issue-85441/Makefile new file mode 100644 index 0000000000000..0de956d3aee52 --- /dev/null +++ b/src/test/run-make/issue-85441/Makefile @@ -0,0 +1,9 @@ +# only-windows + +-include ../../run-make-fulldeps/tools.mk + +# Tests that WS2_32.dll is not unnecessarily linked, see issue #85441 + +all: + $(RUSTC) empty.rs + objdump -p $(TMPDIR)/empty.exe | $(CGREP) -v -i "WS2_32.dll" diff --git a/src/test/run-make/issue-85441/empty.rs b/src/test/run-make/issue-85441/empty.rs new file mode 100644 index 0000000000000..f328e4d9d04c3 --- /dev/null +++ b/src/test/run-make/issue-85441/empty.rs @@ -0,0 +1 @@ +fn main() {} From 5b4873a7597648998285c191a7a7a05fdec15ad4 Mon Sep 17 00:00:00 2001 From: Simonas Kazlauskas Date: Sat, 2 Oct 2021 22:10:00 +0300 Subject: [PATCH 18/20] Run the #85441 regression test on MSVC only On MinGW toolchains the various features (such as function sections) necessary to eliminate dead function references are disabled due to various bugs. This means that the windows sockets library will most likely remain linked to any mingw toolchain built program that also utilizes libstd. That said, I made an attempt to also enable `function-sections` and `--gc-sections` during my experiments, but the symbol references remained, sadly. --- library/std/src/sys/windows/net.rs | 6 +++--- src/test/run-make/issue-85441/Makefile | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/library/std/src/sys/windows/net.rs b/library/std/src/sys/windows/net.rs index 84a5a389e0db3..9c631e7e51c1d 100644 --- a/library/std/src/sys/windows/net.rs +++ b/library/std/src/sys/windows/net.rs @@ -29,12 +29,12 @@ pub mod netc { pub struct Socket(OwnedSocket); -static WSA: SyncOnceCell i32> = SyncOnceCell::new(); +static WSA_CLEANUP: SyncOnceCell i32> = SyncOnceCell::new(); /// Checks whether the Windows socket interface has been started already, and /// if not, starts it. pub fn init() { - let _ = WSA.get_or_init(|| unsafe { + let _ = WSA_CLEANUP.get_or_init(|| unsafe { let mut data: c::WSADATA = mem::zeroed(); let ret = c::WSAStartup( 0x202, // version 2.2 @@ -51,7 +51,7 @@ pub fn init() { pub fn cleanup() { // only perform cleanup if network functionality was actually initialized - if let Some(cleanup) = WSA.get() { + if let Some(cleanup) = WSA_CLEANUP.get() { unsafe { cleanup(); } diff --git a/src/test/run-make/issue-85441/Makefile b/src/test/run-make/issue-85441/Makefile index 0de956d3aee52..c7ae708c173c1 100644 --- a/src/test/run-make/issue-85441/Makefile +++ b/src/test/run-make/issue-85441/Makefile @@ -1,4 +1,4 @@ -# only-windows +# only-windows-msvc -include ../../run-make-fulldeps/tools.mk From 9f4cb862caf936858450721b548b303fb3eec351 Mon Sep 17 00:00:00 2001 From: bjorn3 Date: Sat, 2 Oct 2021 19:47:04 +0200 Subject: [PATCH 19/20] Replace Fn impls with RPIT impls in rustc_index This is cleaner and removes an unstable feature usage --- .../rustc_borrowck/src/member_constraints.rs | 2 +- .../rustc_borrowck/src/region_infer/mod.rs | 2 +- compiler/rustc_index/src/lib.rs | 1 - compiler/rustc_index/src/vec.rs | 61 ++++++------------- .../rustc_mir_dataflow/src/move_paths/mod.rs | 7 ++- 5 files changed, 23 insertions(+), 50 deletions(-) diff --git a/compiler/rustc_borrowck/src/member_constraints.rs b/compiler/rustc_borrowck/src/member_constraints.rs index 2e2578df01146..f22d355e61344 100644 --- a/compiler/rustc_borrowck/src/member_constraints.rs +++ b/compiler/rustc_borrowck/src/member_constraints.rs @@ -144,7 +144,7 @@ impl MemberConstraintSet<'tcx, R> where R: Copy + Hash + Eq, { - crate fn all_indices(&self) -> impl Iterator { + crate fn all_indices(&self) -> impl Iterator + '_ { self.constraints.indices() } diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index 65d6e3a4ae574..734a5b4972bcc 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -497,7 +497,7 @@ impl<'tcx> RegionInferenceContext<'tcx> { } /// Returns an iterator over all the region indices. - pub fn regions(&self) -> impl Iterator { + pub fn regions(&self) -> impl Iterator + '_ { self.definitions.indices() } diff --git a/compiler/rustc_index/src/lib.rs b/compiler/rustc_index/src/lib.rs index f18f322b2220d..a72a27e07bd77 100644 --- a/compiler/rustc_index/src/lib.rs +++ b/compiler/rustc_index/src/lib.rs @@ -4,7 +4,6 @@ #![feature(iter_zip)] #![feature(min_specialization)] #![feature(test)] -#![feature(fn_traits)] pub mod bit_set; pub mod vec; diff --git a/compiler/rustc_index/src/vec.rs b/compiler/rustc_index/src/vec.rs index 8535a7c866d96..56ea04539e57f 100644 --- a/compiler/rustc_index/src/vec.rs +++ b/compiler/rustc_index/src/vec.rs @@ -3,9 +3,9 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder}; use std::fmt; use std::fmt::Debug; use std::hash::Hash; -use std::iter::{self, FromIterator}; +use std::iter::FromIterator; use std::marker::PhantomData; -use std::ops::{Index, IndexMut, Range, RangeBounds}; +use std::ops::{Index, IndexMut, RangeBounds}; use std::slice; use std::vec; @@ -518,8 +518,6 @@ impl fmt::Debug for IndexVec { } } -pub type Enumerated = iter::Map, IntoIdx>; - impl IndexVec { #[inline] pub fn new() -> Self { @@ -596,8 +594,10 @@ impl IndexVec { } #[inline] - pub fn into_iter_enumerated(self) -> Enumerated> { - self.raw.into_iter().enumerate().map(IntoIdx { _marker: PhantomData }) + pub fn into_iter_enumerated( + self, + ) -> impl DoubleEndedIterator + ExactSizeIterator { + self.raw.into_iter().enumerate().map(|(n, t)| (I::new(n), t)) } #[inline] @@ -606,13 +606,15 @@ impl IndexVec { } #[inline] - pub fn iter_enumerated(&self) -> Enumerated> { - self.raw.iter().enumerate().map(IntoIdx { _marker: PhantomData }) + pub fn iter_enumerated( + &self, + ) -> impl DoubleEndedIterator + ExactSizeIterator + '_ { + self.raw.iter().enumerate().map(|(n, t)| (I::new(n), t)) } #[inline] - pub fn indices(&self) -> iter::Map, IntoIdx> { - (0..self.len()).map(IntoIdx { _marker: PhantomData }) + pub fn indices(&self) -> impl DoubleEndedIterator + ExactSizeIterator + 'static { + (0..self.len()).map(|n| I::new(n)) } #[inline] @@ -621,8 +623,10 @@ impl IndexVec { } #[inline] - pub fn iter_enumerated_mut(&mut self) -> Enumerated> { - self.raw.iter_mut().enumerate().map(IntoIdx { _marker: PhantomData }) + pub fn iter_enumerated_mut( + &mut self, + ) -> impl DoubleEndedIterator + ExactSizeIterator + '_ { + self.raw.iter_mut().enumerate().map(|(n, t)| (I::new(n), t)) } #[inline] @@ -638,7 +642,7 @@ impl IndexVec { &'a mut self, range: R, ) -> impl Iterator + 'a { - self.raw.drain(range).enumerate().map(IntoIdx { _marker: PhantomData }) + self.raw.drain(range).enumerate().map(|(n, t)| (I::new(n), t)) } #[inline] @@ -832,36 +836,5 @@ impl<'a, I: Idx, T> IntoIterator for &'a mut IndexVec { } } -pub struct IntoIdx { - _marker: PhantomData, -} -impl FnOnce<((usize, T),)> for IntoIdx { - type Output = (I, T); - - extern "rust-call" fn call_once(self, ((n, t),): ((usize, T),)) -> Self::Output { - (I::new(n), t) - } -} - -impl FnMut<((usize, T),)> for IntoIdx { - extern "rust-call" fn call_mut(&mut self, ((n, t),): ((usize, T),)) -> Self::Output { - (I::new(n), t) - } -} - -impl FnOnce<(usize,)> for IntoIdx { - type Output = I; - - extern "rust-call" fn call_once(self, (n,): (usize,)) -> Self::Output { - I::new(n) - } -} - -impl FnMut<(usize,)> for IntoIdx { - extern "rust-call" fn call_mut(&mut self, (n,): (usize,)) -> Self::Output { - I::new(n) - } -} - #[cfg(test)] mod tests; diff --git a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs index 699ec4bbff80f..f2b341593826b 100644 --- a/compiler/rustc_mir_dataflow/src/move_paths/mod.rs +++ b/compiler/rustc_mir_dataflow/src/move_paths/mod.rs @@ -1,6 +1,5 @@ -use core::slice::Iter; use rustc_data_structures::fx::FxHashMap; -use rustc_index::vec::{Enumerated, IndexVec}; +use rustc_index::vec::IndexVec; use rustc_middle::mir::*; use rustc_middle::ty::{ParamEnv, Ty, TyCtxt}; use rustc_span::Span; @@ -337,7 +336,9 @@ impl MovePathLookup { /// An enumerated iterator of `local`s and their associated /// `MovePathIndex`es. - pub fn iter_locals_enumerated(&self) -> Enumerated> { + pub fn iter_locals_enumerated( + &self, + ) -> impl DoubleEndedIterator + ExactSizeIterator { self.locals.iter_enumerated() } } From 5b6604825e20ecd962c7021131de6a20cc73a32e Mon Sep 17 00:00:00 2001 From: Aaron Hill Date: Sun, 3 Oct 2021 16:54:54 -0500 Subject: [PATCH 20/20] Add regression test for spurious const error with NLL Fixes #55825 --- src/test/ui/nll/issue-55825-const-fn.rs | 8 ++++++++ src/test/ui/nll/issue-55825-const-fn.stderr | 12 ++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 src/test/ui/nll/issue-55825-const-fn.rs create mode 100644 src/test/ui/nll/issue-55825-const-fn.stderr diff --git a/src/test/ui/nll/issue-55825-const-fn.rs b/src/test/ui/nll/issue-55825-const-fn.rs new file mode 100644 index 0000000000000..c9efccd15b7c5 --- /dev/null +++ b/src/test/ui/nll/issue-55825-const-fn.rs @@ -0,0 +1,8 @@ +// Regression test for issue #55825 +// Tests that we don't emit a spurious warning in NLL mode + +#![feature(nll)] + +const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() } //~ ERROR const + +fn main() { } diff --git a/src/test/ui/nll/issue-55825-const-fn.stderr b/src/test/ui/nll/issue-55825-const-fn.stderr new file mode 100644 index 0000000000000..9af5180343bf2 --- /dev/null +++ b/src/test/ui/nll/issue-55825-const-fn.stderr @@ -0,0 +1,12 @@ +error[E0658]: trait objects in const fn are unstable + --> $DIR/issue-55825-const-fn.rs:6:32 + | +LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() } + | ^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + | + = note: see issue #57563 for more information + = help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0658`.