Skip to content

Commit 44593ae

Browse files
committedOct 4, 2021
Auto merge of rust-lang#89512 - Manishearth:rollup-meh9x7r, r=Manishearth
Rollup of 14 pull requests Successful merges: - rust-lang#86434 (Add `Ipv6Addr::is_benchmarking`) - rust-lang#86828 (const fn for option copied, take & replace) - rust-lang#87679 (BTree: refine some comments) - rust-lang#87910 (Mark unsafe methods NonZero*::unchecked_(add|mul) as const.) - rust-lang#88286 (Remove unnecessary unsafe block in `process_unix`) - rust-lang#88305 (Manual Debug for Unix ExitCode ExitStatus ExitStatusError) - rust-lang#88353 (Partially stabilize `array_methods`) - rust-lang#88370 (Add missing `# Panics` section to `Vec` method) - rust-lang#88481 (Remove some feature gates) - rust-lang#89138 (Fix link in Ipv6Addr::to_ipv4 docs) - rust-lang#89401 (Add truncate note to Vec::resize) - rust-lang#89467 (Fix typos in rustdoc/lints) - rust-lang#89472 (Only register `WSACleanup` if `WSAStartup` is actually ever called) - rust-lang#89505 (Add regression test for spurious const error with NLL) Failed merges: r? `@ghost` `@rustbot` modify labels: rollup
2 parents d25de31 + 5c5dde8 commit 44593ae

File tree

30 files changed

+251
-135
lines changed

30 files changed

+251
-135
lines changed
 

‎compiler/rustc_borrowck/src/member_constraints.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ impl<R> MemberConstraintSet<'tcx, R>
144144
where
145145
R: Copy + Hash + Eq,
146146
{
147-
crate fn all_indices(&self) -> impl Iterator<Item = NllMemberConstraintIndex> {
147+
crate fn all_indices(&self) -> impl Iterator<Item = NllMemberConstraintIndex> + '_ {
148148
self.constraints.indices()
149149
}
150150

‎compiler/rustc_borrowck/src/region_infer/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -497,7 +497,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
497497
}
498498

499499
/// Returns an iterator over all the region indices.
500-
pub fn regions(&self) -> impl Iterator<Item = RegionVid> {
500+
pub fn regions(&self) -> impl Iterator<Item = RegionVid> + '_ {
501501
self.definitions.indices()
502502
}
503503

‎compiler/rustc_data_structures/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
//! This API is completely unstable and subject to change.
88
99
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
10-
#![feature(allow_internal_unstable)]
1110
#![feature(array_windows)]
1211
#![feature(associated_type_bounds)]
1312
#![feature(auto_traits)]

‎compiler/rustc_index/src/lib.rs

+1-2
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,8 @@
22
#![feature(bench_black_box)]
33
#![feature(extend_one)]
44
#![feature(iter_zip)]
5-
#![feature(unboxed_closures)]
5+
#![feature(min_specialization)]
66
#![feature(test)]
7-
#![feature(fn_traits)]
87

98
pub mod bit_set;
109
pub mod vec;

‎compiler/rustc_index/src/vec.rs

+17-44
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ use rustc_serialize::{Decodable, Decoder, Encodable, Encoder};
33
use std::fmt;
44
use std::fmt::Debug;
55
use std::hash::Hash;
6-
use std::iter::{self, FromIterator};
6+
use std::iter::FromIterator;
77
use std::marker::PhantomData;
8-
use std::ops::{Index, IndexMut, Range, RangeBounds};
8+
use std::ops::{Index, IndexMut, RangeBounds};
99
use std::slice;
1010
use std::vec;
1111

@@ -518,8 +518,6 @@ impl<I: Idx, T: fmt::Debug> fmt::Debug for IndexVec<I, T> {
518518
}
519519
}
520520

521-
pub type Enumerated<I, J> = iter::Map<iter::Enumerate<J>, IntoIdx<I>>;
522-
523521
impl<I: Idx, T> IndexVec<I, T> {
524522
#[inline]
525523
pub fn new() -> Self {
@@ -596,8 +594,10 @@ impl<I: Idx, T> IndexVec<I, T> {
596594
}
597595

598596
#[inline]
599-
pub fn into_iter_enumerated(self) -> Enumerated<I, vec::IntoIter<T>> {
600-
self.raw.into_iter().enumerate().map(IntoIdx { _marker: PhantomData })
597+
pub fn into_iter_enumerated(
598+
self,
599+
) -> impl DoubleEndedIterator<Item = (I, T)> + ExactSizeIterator {
600+
self.raw.into_iter().enumerate().map(|(n, t)| (I::new(n), t))
601601
}
602602

603603
#[inline]
@@ -606,13 +606,15 @@ impl<I: Idx, T> IndexVec<I, T> {
606606
}
607607

608608
#[inline]
609-
pub fn iter_enumerated(&self) -> Enumerated<I, slice::Iter<'_, T>> {
610-
self.raw.iter().enumerate().map(IntoIdx { _marker: PhantomData })
609+
pub fn iter_enumerated(
610+
&self,
611+
) -> impl DoubleEndedIterator<Item = (I, &T)> + ExactSizeIterator + '_ {
612+
self.raw.iter().enumerate().map(|(n, t)| (I::new(n), t))
611613
}
612614

613615
#[inline]
614-
pub fn indices(&self) -> iter::Map<Range<usize>, IntoIdx<I>> {
615-
(0..self.len()).map(IntoIdx { _marker: PhantomData })
616+
pub fn indices(&self) -> impl DoubleEndedIterator<Item = I> + ExactSizeIterator + 'static {
617+
(0..self.len()).map(|n| I::new(n))
616618
}
617619

618620
#[inline]
@@ -621,8 +623,10 @@ impl<I: Idx, T> IndexVec<I, T> {
621623
}
622624

623625
#[inline]
624-
pub fn iter_enumerated_mut(&mut self) -> Enumerated<I, slice::IterMut<'_, T>> {
625-
self.raw.iter_mut().enumerate().map(IntoIdx { _marker: PhantomData })
626+
pub fn iter_enumerated_mut(
627+
&mut self,
628+
) -> impl DoubleEndedIterator<Item = (I, &mut T)> + ExactSizeIterator + '_ {
629+
self.raw.iter_mut().enumerate().map(|(n, t)| (I::new(n), t))
626630
}
627631

628632
#[inline]
@@ -638,7 +642,7 @@ impl<I: Idx, T> IndexVec<I, T> {
638642
&'a mut self,
639643
range: R,
640644
) -> impl Iterator<Item = (I, T)> + 'a {
641-
self.raw.drain(range).enumerate().map(IntoIdx { _marker: PhantomData })
645+
self.raw.drain(range).enumerate().map(|(n, t)| (I::new(n), t))
642646
}
643647

644648
#[inline]
@@ -832,36 +836,5 @@ impl<'a, I: Idx, T> IntoIterator for &'a mut IndexVec<I, T> {
832836
}
833837
}
834838

835-
pub struct IntoIdx<I: Idx> {
836-
_marker: PhantomData<fn(&I)>,
837-
}
838-
impl<I: Idx, T> FnOnce<((usize, T),)> for IntoIdx<I> {
839-
type Output = (I, T);
840-
841-
extern "rust-call" fn call_once(self, ((n, t),): ((usize, T),)) -> Self::Output {
842-
(I::new(n), t)
843-
}
844-
}
845-
846-
impl<I: Idx, T> FnMut<((usize, T),)> for IntoIdx<I> {
847-
extern "rust-call" fn call_mut(&mut self, ((n, t),): ((usize, T),)) -> Self::Output {
848-
(I::new(n), t)
849-
}
850-
}
851-
852-
impl<I: Idx> FnOnce<(usize,)> for IntoIdx<I> {
853-
type Output = I;
854-
855-
extern "rust-call" fn call_once(self, (n,): (usize,)) -> Self::Output {
856-
I::new(n)
857-
}
858-
}
859-
860-
impl<I: Idx> FnMut<(usize,)> for IntoIdx<I> {
861-
extern "rust-call" fn call_mut(&mut self, (n,): (usize,)) -> Self::Output {
862-
I::new(n)
863-
}
864-
}
865-
866839
#[cfg(test)]
867840
mod tests;

‎compiler/rustc_lint/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,6 @@
2626
//! This API is completely unstable and subject to change.
2727
2828
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
29-
#![cfg_attr(test, feature(test))]
3029
#![feature(array_windows)]
3130
#![feature(bool_to_option)]
3231
#![feature(box_patterns)]

‎compiler/rustc_middle/src/lib.rs

-2
Original file line numberDiff line numberDiff line change
@@ -41,13 +41,11 @@
4141
#![feature(once_cell)]
4242
#![feature(min_specialization)]
4343
#![feature(trusted_len)]
44-
#![feature(test)]
4544
#![feature(in_band_lifetimes)]
4645
#![feature(crate_visibility_modifier)]
4746
#![feature(associated_type_bounds)]
4847
#![feature(rustc_attrs)]
4948
#![feature(half_open_range_patterns)]
50-
#![feature(exclusive_range_pattern)]
5149
#![feature(control_flow_enum)]
5250
#![feature(associated_type_defaults)]
5351
#![feature(iter_zip)]

‎compiler/rustc_middle/src/ty/codec.rs

+7-7
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
1-
// This module contains some shared code for encoding and decoding various
2-
// things from the `ty` module, and in particular implements support for
3-
// "shorthands" which allow to have pointers back into the already encoded
4-
// stream instead of re-encoding the same thing twice.
5-
//
6-
// The functionality in here is shared between persisting to crate metadata and
7-
// persisting to incr. comp. caches.
1+
//! This module contains some shared code for encoding and decoding various
2+
//! things from the `ty` module, and in particular implements support for
3+
//! "shorthands" which allow to have pointers back into the already encoded
4+
//! stream instead of re-encoding the same thing twice.
5+
//!
6+
//! The functionality in here is shared between persisting to crate metadata and
7+
//! persisting to incr. comp. caches.
88
99
use crate::arena::ArenaAllocatable;
1010
use crate::infer::canonical::{CanonicalVarInfo, CanonicalVarInfos};

‎compiler/rustc_mir_dataflow/src/move_paths/mod.rs

+4-3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
1-
use core::slice::Iter;
21
use rustc_data_structures::fx::FxHashMap;
3-
use rustc_index::vec::{Enumerated, IndexVec};
2+
use rustc_index::vec::IndexVec;
43
use rustc_middle::mir::*;
54
use rustc_middle::ty::{ParamEnv, Ty, TyCtxt};
65
use rustc_span::Span;
@@ -337,7 +336,9 @@ impl MovePathLookup {
337336

338337
/// An enumerated iterator of `local`s and their associated
339338
/// `MovePathIndex`es.
340-
pub fn iter_locals_enumerated(&self) -> Enumerated<Local, Iter<'_, MovePathIndex>> {
339+
pub fn iter_locals_enumerated(
340+
&self,
341+
) -> impl DoubleEndedIterator<Item = (Local, &MovePathIndex)> + ExactSizeIterator {
341342
self.locals.iter_enumerated()
342343
}
343344
}

‎compiler/rustc_target/src/lib.rs

-1
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@
1515
#![feature(exhaustive_patterns)]
1616
#![feature(min_specialization)]
1717
#![feature(step_trait)]
18-
#![feature(unchecked_math)]
1918

2019
use std::path::{Path, PathBuf};
2120

‎compiler/rustc_ty_utils/src/lib.rs

-2
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,6 @@
66
77
#![doc(html_root_url = "https://doc.rust-lang.org/nightly/nightly-rustc/")]
88
#![feature(control_flow_enum)]
9-
#![feature(half_open_range_patterns)]
10-
#![feature(exclusive_range_pattern)]
119
#![feature(nll)]
1210
#![recursion_limit = "256"]
1311

‎library/alloc/src/collections/btree/map.rs

+5-5
Original file line numberDiff line numberDiff line change
@@ -19,16 +19,16 @@ mod entry;
1919
pub use entry::{Entry, OccupiedEntry, OccupiedError, VacantEntry};
2020
use Entry::*;
2121

22-
/// Minimum number of elements in nodes that are not a root.
22+
/// Minimum number of elements in a node that is not a root.
2323
/// We might temporarily have fewer elements during methods.
2424
pub(super) const MIN_LEN: usize = node::MIN_LEN_AFTER_SPLIT;
2525

2626
// A tree in a `BTreeMap` is a tree in the `node` module with additional invariants:
2727
// - Keys must appear in ascending order (according to the key's type).
28-
// - If the root node is internal, it must contain at least 1 element.
28+
// - Every non-leaf node contains at least 1 element (has at least 2 children).
2929
// - Every non-root node contains at least MIN_LEN elements.
3030
//
31-
// An empty map may be represented both by the absence of a root node or by a
31+
// An empty map is represented either by the absence of a root node or by a
3232
// root node that is an empty leaf.
3333

3434
/// A map based on a [B-Tree].
@@ -1735,8 +1735,8 @@ impl<'a, K: 'a, V: 'a> DrainFilterInner<'a, K, V> {
17351735
pub(super) fn size_hint(&self) -> (usize, Option<usize>) {
17361736
// In most of the btree iterators, `self.length` is the number of elements
17371737
// yet to be visited. Here, it includes elements that were visited and that
1738-
// the predicate decided not to drain. Making this upper bound more accurate
1739-
// requires maintaining an extra field and is not worth while.
1738+
// the predicate decided not to drain. Making this upper bound more tight
1739+
// during iteration would require an extra field.
17401740
(0, Some(*self.length))
17411741
}
17421742
}

‎library/alloc/src/collections/btree/navigate.rs

+2-4
Original file line numberDiff line numberDiff line change
@@ -440,8 +440,7 @@ impl<K, V> Handle<NodeRef<marker::Dying, K, V, marker::Leaf>, marker::Edge> {
440440
/// - The given edge must not have been previously returned by counterpart
441441
/// `deallocating_next_back`.
442442
/// - The returned KV handle is only valid to access the key and value,
443-
/// and only valid until the next call to this method or counterpart
444-
/// `deallocating_next_back`.
443+
/// and only valid until the next call to a `deallocating_` method.
445444
unsafe fn deallocating_next(
446445
self,
447446
) -> Option<(Self, Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV>)>
@@ -470,8 +469,7 @@ impl<K, V> Handle<NodeRef<marker::Dying, K, V, marker::Leaf>, marker::Edge> {
470469
/// - The given edge must not have been previously returned by counterpart
471470
/// `deallocating_next`.
472471
/// - The returned KV handle is only valid to access the key and value,
473-
/// and only valid until the next call to this method or counterpart
474-
/// `deallocating_next`.
472+
/// and only valid until the next call to a `deallocating_` method.
475473
unsafe fn deallocating_next_back(
476474
self,
477475
) -> Option<(Self, Handle<NodeRef<marker::Dying, K, V, marker::LeafOrInternal>, marker::KV>)>

‎library/alloc/src/collections/btree/node.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -574,7 +574,7 @@ impl<K, V> NodeRef<marker::Owned, K, V, marker::LeafOrInternal> {
574574
/// no cleanup is done on any of the keys, values and other children.
575575
/// This decreases the height by 1 and is the opposite of `push_internal_level`.
576576
///
577-
/// Requires exclusive access to the `Root` object but not to the root node;
577+
/// Requires exclusive access to the `NodeRef` object but not to the root node;
578578
/// it will not invalidate other handles or references to the root node.
579579
///
580580
/// Panics if there is no internal level, i.e., if the root node is a leaf.

‎library/alloc/src/vec/mod.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -2137,6 +2137,7 @@ impl<T: Clone, A: Allocator> Vec<T, A> {
21372137
/// in order to be able to clone the passed value.
21382138
/// If you need more flexibility (or want to rely on [`Default`] instead of
21392139
/// [`Clone`]), use [`Vec::resize_with`].
2140+
/// If you only need to resize to a smaller size, use [`Vec::truncate`].
21402141
///
21412142
/// # Examples
21422143
///
@@ -2188,7 +2189,12 @@ impl<T: Clone, A: Allocator> Vec<T, A> {
21882189

21892190
/// Copies elements from `src` range to the end of the vector.
21902191
///
2191-
/// ## Examples
2192+
/// # Panics
2193+
///
2194+
/// Panics if the starting point is greater than the end point or if
2195+
/// the end point is greater than the length of the vector.
2196+
///
2197+
/// # Examples
21922198
///
21932199
/// ```
21942200
/// let mut vec = vec![0, 1, 2, 3, 4];

‎library/core/src/array/mod.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -368,14 +368,14 @@ impl<T, const N: usize> [T; N] {
368368
}
369369

370370
/// Returns a slice containing the entire array. Equivalent to `&s[..]`.
371-
#[unstable(feature = "array_methods", issue = "76118")]
372-
pub fn as_slice(&self) -> &[T] {
371+
#[stable(feature = "array_as_slice", since = "1.57.0")]
372+
pub const fn as_slice(&self) -> &[T] {
373373
self
374374
}
375375

376376
/// Returns a mutable slice containing the entire array. Equivalent to
377377
/// `&mut s[..]`.
378-
#[unstable(feature = "array_methods", issue = "76118")]
378+
#[stable(feature = "array_as_slice", since = "1.57.0")]
379379
pub fn as_mut_slice(&mut self) -> &mut [T] {
380380
self
381381
}

‎library/core/src/lib.rs

+1
Original file line numberDiff line numberDiff line change
@@ -91,6 +91,7 @@
9191
#![feature(const_maybe_uninit_assume_init)]
9292
#![feature(const_option)]
9393
#![feature(const_pin)]
94+
#![feature(const_replace)]
9495
#![feature(const_ptr_offset)]
9596
#![feature(const_ptr_offset_from)]
9697
#![feature(const_ptr_read)]

‎library/core/src/num/nonzero.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,7 @@ macro_rules! nonzero_unsigned_operations {
379379
/// ```
380380
#[unstable(feature = "nonzero_ops", issue = "84186")]
381381
#[inline]
382-
pub unsafe fn unchecked_add(self, other: $Int) -> $Ty {
382+
pub const unsafe fn unchecked_add(self, other: $Int) -> $Ty {
383383
// SAFETY: The caller ensures there is no overflow.
384384
unsafe { $Ty::new_unchecked(self.get().unchecked_add(other)) }
385385
}
@@ -750,7 +750,7 @@ macro_rules! nonzero_unsigned_signed_operations {
750750
/// ```
751751
#[unstable(feature = "nonzero_ops", issue = "84186")]
752752
#[inline]
753-
pub unsafe fn unchecked_mul(self, other: $Ty) -> $Ty {
753+
pub const unsafe fn unchecked_mul(self, other: $Ty) -> $Ty {
754754
// SAFETY: The caller ensures there is no overflow.
755755
unsafe { $Ty::new_unchecked(self.get().unchecked_mul(other.get())) }
756756
}

‎library/core/src/option.rs

+16-7
Original file line numberDiff line numberDiff line change
@@ -544,8 +544,8 @@ impl<T> Option<T> {
544544
/// ```
545545
#[must_use = "if you intended to assert that this has a value, consider `.unwrap()` instead"]
546546
#[inline]
547-
#[rustc_const_stable(feature = "const_option", since = "1.48.0")]
548547
#[stable(feature = "rust1", since = "1.0.0")]
548+
#[rustc_const_stable(feature = "const_option", since = "1.48.0")]
549549
pub const fn is_some(&self) -> bool {
550550
matches!(*self, Some(_))
551551
}
@@ -564,8 +564,8 @@ impl<T> Option<T> {
564564
#[must_use = "if you intended to assert that this doesn't have a value, consider \
565565
`.and_then(|_| panic!(\"`Option` had a value when expected `None`\"))` instead"]
566566
#[inline]
567-
#[rustc_const_stable(feature = "const_option", since = "1.48.0")]
568567
#[stable(feature = "rust1", since = "1.0.0")]
568+
#[rustc_const_stable(feature = "const_option", since = "1.48.0")]
569569
pub const fn is_none(&self) -> bool {
570570
!self.is_some()
571571
}
@@ -1318,8 +1318,10 @@ impl<T> Option<T> {
13181318
/// ```
13191319
#[inline]
13201320
#[stable(feature = "rust1", since = "1.0.0")]
1321-
pub fn take(&mut self) -> Option<T> {
1322-
mem::take(self)
1321+
#[rustc_const_unstable(feature = "const_option", issue = "67441")]
1322+
pub const fn take(&mut self) -> Option<T> {
1323+
// FIXME replace `mem::replace` by `mem::take` when the latter is const ready
1324+
mem::replace(self, None)
13231325
}
13241326

13251327
/// Replaces the actual value in the option by the value given in parameter,
@@ -1340,8 +1342,9 @@ impl<T> Option<T> {
13401342
/// assert_eq!(old, None);
13411343
/// ```
13421344
#[inline]
1345+
#[rustc_const_unstable(feature = "const_option", issue = "67441")]
13431346
#[stable(feature = "option_replace", since = "1.31.0")]
1344-
pub fn replace(&mut self, value: T) -> Option<T> {
1347+
pub const fn replace(&mut self, value: T) -> Option<T> {
13451348
mem::replace(self, Some(value))
13461349
}
13471350

@@ -1446,8 +1449,14 @@ impl<T: Copy> Option<&T> {
14461449
/// assert_eq!(copied, Some(12));
14471450
/// ```
14481451
#[stable(feature = "copied", since = "1.35.0")]
1449-
pub fn copied(self) -> Option<T> {
1450-
self.map(|&t| t)
1452+
#[rustc_const_unstable(feature = "const_option", issue = "67441")]
1453+
pub const fn copied(self) -> Option<T> {
1454+
// FIXME: this implementation, which sidesteps using `Option::map` since it's not const
1455+
// ready yet, should be reverted when possible to avoid code repetition
1456+
match self {
1457+
Some(&v) => Some(v),
1458+
None => None,
1459+
}
14511460
}
14521461
}
14531462

‎library/core/tests/option.rs

+13
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,19 @@ fn option_const() {
367367

368368
const IS_NONE: bool = OPTION.is_none();
369369
assert!(!IS_NONE);
370+
371+
const COPIED: Option<usize> = OPTION.as_ref().copied();
372+
assert_eq!(COPIED, OPTION);
373+
}
374+
375+
#[test]
376+
const fn option_const_mut() {
377+
// test that the methods of `Option` that take mutable references are usable in a const context
378+
379+
let mut option: Option<usize> = Some(32);
380+
381+
let _take = option.take();
382+
let _replace = option.replace(42);
370383
}
371384

372385
#[test]

‎library/std/src/net/ip.rs

+47-1
Original file line numberDiff line numberDiff line change
@@ -340,6 +340,30 @@ impl IpAddr {
340340
}
341341
}
342342

343+
/// Returns [`true`] if this address is in a range designated for benchmarking.
344+
///
345+
/// See the documentation for [`Ipv4Addr::is_benchmarking()`] and
346+
/// [`Ipv6Addr::is_benchmarking()`] for more details.
347+
///
348+
/// # Examples
349+
///
350+
/// ```
351+
/// #![feature(ip)]
352+
///
353+
/// use std::net::{IpAddr, Ipv4Addr, Ipv6Addr};
354+
///
355+
/// assert_eq!(IpAddr::V4(Ipv4Addr::new(198, 19, 255, 255)).is_benchmarking(), true);
356+
/// assert_eq!(IpAddr::V6(Ipv6Addr::new(0x2001, 0x2, 0, 0, 0, 0, 0, 0)).is_benchmarking(), true);
357+
/// ```
358+
#[unstable(feature = "ip", issue = "27709")]
359+
#[inline]
360+
pub const fn is_benchmarking(&self) -> bool {
361+
match self {
362+
IpAddr::V4(ip) => ip.is_benchmarking(),
363+
IpAddr::V6(ip) => ip.is_benchmarking(),
364+
}
365+
}
366+
343367
/// Returns [`true`] if this address is an [`IPv4` address], and [`false`]
344368
/// otherwise.
345369
///
@@ -1449,6 +1473,28 @@ impl Ipv6Addr {
14491473
(self.segments()[0] == 0x2001) && (self.segments()[1] == 0xdb8)
14501474
}
14511475

1476+
/// Returns [`true`] if this is an address reserved for benchmarking (`2001:2::/48`).
1477+
///
1478+
/// This property is defined in [IETF RFC 5180], where it is mistakenly specified as covering the range `2001:0200::/48`.
1479+
/// This is corrected in [IETF RFC Errata 1752] to `2001:0002::/48`.
1480+
///
1481+
/// [IETF RFC 5180]: https://tools.ietf.org/html/rfc5180
1482+
/// [IETF RFC Errata 1752]: https://www.rfc-editor.org/errata_search.php?eid=1752
1483+
///
1484+
/// ```
1485+
/// #![feature(ip)]
1486+
///
1487+
/// use std::net::Ipv6Addr;
1488+
///
1489+
/// assert_eq!(Ipv6Addr::new(0, 0, 0, 0, 0, 0xffff, 0xc613, 0x0).is_benchmarking(), false);
1490+
/// assert_eq!(Ipv6Addr::new(0x2001, 0x2, 0, 0, 0, 0, 0, 0).is_benchmarking(), true);
1491+
/// ```
1492+
#[unstable(feature = "ip", issue = "27709")]
1493+
#[inline]
1494+
pub const fn is_benchmarking(&self) -> bool {
1495+
(self.segments()[0] == 0x2001) && (self.segments()[1] == 0x2) && (self.segments()[2] == 0)
1496+
}
1497+
14521498
/// Returns [`true`] if the address is a globally routable unicast address.
14531499
///
14541500
/// The following return false:
@@ -1589,7 +1635,7 @@ impl Ipv6Addr {
15891635
/// `::a.b.c.d` and `::ffff:a.b.c.d` become `a.b.c.d`
15901636
/// All addresses *not* starting with either all zeroes or `::ffff` will return `None`.
15911637
///
1592-
/// [IPv4 address]: Ipv4Addr
1638+
/// [`IPv4` address]: Ipv4Addr
15931639
/// [IPv4-compatible]: Ipv6Addr#ipv4-compatible-ipv6-addresses
15941640
/// [IPv4-mapped]: Ipv6Addr#ipv4-mapped-ipv6-addresses
15951641
/// [IETF RFC 4291 section 2.5.5.1]: https://tools.ietf.org/html/rfc4291#section-2.5.5.1

‎library/std/src/net/ip/tests.rs

+57-32
Original file line numberDiff line numberDiff line change
@@ -224,6 +224,7 @@ fn ip_properties() {
224224
let global: u8 = 1 << 2;
225225
let multicast: u8 = 1 << 3;
226226
let doc: u8 = 1 << 4;
227+
let benchmarking: u8 = 1 << 5;
227228

228229
if ($mask & unspec) == unspec {
229230
assert!(ip!($s).is_unspecified());
@@ -254,6 +255,12 @@ fn ip_properties() {
254255
} else {
255256
assert!(!ip!($s).is_documentation());
256257
}
258+
259+
if ($mask & benchmarking) == benchmarking {
260+
assert!(ip!($s).is_benchmarking());
261+
} else {
262+
assert!(!ip!($s).is_benchmarking());
263+
}
257264
}};
258265
}
259266

@@ -262,6 +269,7 @@ fn ip_properties() {
262269
let global: u8 = 1 << 2;
263270
let multicast: u8 = 1 << 3;
264271
let doc: u8 = 1 << 4;
272+
let benchmarking: u8 = 1 << 5;
265273

266274
check!("0.0.0.0", unspec);
267275
check!("0.0.0.1");
@@ -280,9 +288,9 @@ fn ip_properties() {
280288
check!("239.255.255.255", global | multicast);
281289
check!("255.255.255.255");
282290
// make sure benchmarking addresses are not global
283-
check!("198.18.0.0");
284-
check!("198.18.54.2");
285-
check!("198.19.255.255");
291+
check!("198.18.0.0", benchmarking);
292+
check!("198.18.54.2", benchmarking);
293+
check!("198.19.255.255", benchmarking);
286294
// make sure addresses reserved for protocol assignment are not global
287295
check!("192.0.0.0");
288296
check!("192.0.0.255");
@@ -313,6 +321,7 @@ fn ip_properties() {
313321
check!("ff08::", multicast);
314322
check!("ff0e::", global | multicast);
315323
check!("2001:db8:85a3::8a2e:370:7334", doc);
324+
check!("2001:2::ac32:23ff:21", global | benchmarking);
316325
check!("102:304:506:708:90a:b0c:d0e:f10", global);
317326
}
318327

@@ -467,21 +476,22 @@ fn ipv6_properties() {
467476
assert_eq!(&ip!($s).octets(), octets);
468477
assert_eq!(Ipv6Addr::from(*octets), ip!($s));
469478

470-
let unspecified: u16 = 1 << 0;
471-
let loopback: u16 = 1 << 1;
472-
let unique_local: u16 = 1 << 2;
473-
let global: u16 = 1 << 3;
474-
let unicast_link_local: u16 = 1 << 4;
475-
let unicast_global: u16 = 1 << 7;
476-
let documentation: u16 = 1 << 8;
477-
let multicast_interface_local: u16 = 1 << 9;
478-
let multicast_link_local: u16 = 1 << 10;
479-
let multicast_realm_local: u16 = 1 << 11;
480-
let multicast_admin_local: u16 = 1 << 12;
481-
let multicast_site_local: u16 = 1 << 13;
482-
let multicast_organization_local: u16 = 1 << 14;
483-
let multicast_global: u16 = 1 << 15;
484-
let multicast: u16 = multicast_interface_local
479+
let unspecified: u32 = 1 << 0;
480+
let loopback: u32 = 1 << 1;
481+
let unique_local: u32 = 1 << 2;
482+
let global: u32 = 1 << 3;
483+
let unicast_link_local: u32 = 1 << 4;
484+
let unicast_global: u32 = 1 << 7;
485+
let documentation: u32 = 1 << 8;
486+
let benchmarking: u32 = 1 << 16;
487+
let multicast_interface_local: u32 = 1 << 9;
488+
let multicast_link_local: u32 = 1 << 10;
489+
let multicast_realm_local: u32 = 1 << 11;
490+
let multicast_admin_local: u32 = 1 << 12;
491+
let multicast_site_local: u32 = 1 << 13;
492+
let multicast_organization_local: u32 = 1 << 14;
493+
let multicast_global: u32 = 1 << 15;
494+
let multicast: u32 = multicast_interface_local
485495
| multicast_admin_local
486496
| multicast_global
487497
| multicast_link_local
@@ -524,6 +534,11 @@ fn ipv6_properties() {
524534
} else {
525535
assert!(!ip!($s).is_documentation());
526536
}
537+
if ($mask & benchmarking) == benchmarking {
538+
assert!(ip!($s).is_benchmarking());
539+
} else {
540+
assert!(!ip!($s).is_benchmarking());
541+
}
527542
if ($mask & multicast) != 0 {
528543
assert!(ip!($s).multicast_scope().is_some());
529544
assert!(ip!($s).is_multicast());
@@ -562,20 +577,21 @@ fn ipv6_properties() {
562577
}
563578
}
564579

565-
let unspecified: u16 = 1 << 0;
566-
let loopback: u16 = 1 << 1;
567-
let unique_local: u16 = 1 << 2;
568-
let global: u16 = 1 << 3;
569-
let unicast_link_local: u16 = 1 << 4;
570-
let unicast_global: u16 = 1 << 7;
571-
let documentation: u16 = 1 << 8;
572-
let multicast_interface_local: u16 = 1 << 9;
573-
let multicast_link_local: u16 = 1 << 10;
574-
let multicast_realm_local: u16 = 1 << 11;
575-
let multicast_admin_local: u16 = 1 << 12;
576-
let multicast_site_local: u16 = 1 << 13;
577-
let multicast_organization_local: u16 = 1 << 14;
578-
let multicast_global: u16 = 1 << 15;
580+
let unspecified: u32 = 1 << 0;
581+
let loopback: u32 = 1 << 1;
582+
let unique_local: u32 = 1 << 2;
583+
let global: u32 = 1 << 3;
584+
let unicast_link_local: u32 = 1 << 4;
585+
let unicast_global: u32 = 1 << 7;
586+
let documentation: u32 = 1 << 8;
587+
let benchmarking: u32 = 1 << 16;
588+
let multicast_interface_local: u32 = 1 << 9;
589+
let multicast_link_local: u32 = 1 << 10;
590+
let multicast_realm_local: u32 = 1 << 11;
591+
let multicast_admin_local: u32 = 1 << 12;
592+
let multicast_site_local: u32 = 1 << 13;
593+
let multicast_organization_local: u32 = 1 << 14;
594+
let multicast_global: u32 = 1 << 15;
579595

580596
check!("::", &[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], unspecified);
581597

@@ -671,6 +687,12 @@ fn ipv6_properties() {
671687
documentation
672688
);
673689

690+
check!(
691+
"2001:2::ac32:23ff:21",
692+
&[0x20, 1, 0, 2, 0, 0, 0, 0, 0, 0, 0xac, 0x32, 0x23, 0xff, 0, 0x21],
693+
global | unicast_global | benchmarking
694+
);
695+
674696
check!(
675697
"102:304:506:708:90a:b0c:d0e:f10",
676698
&[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16],
@@ -874,6 +896,9 @@ fn ipv6_const() {
874896
const IS_DOCUMENTATION: bool = IP_ADDRESS.is_documentation();
875897
assert!(!IS_DOCUMENTATION);
876898

899+
const IS_BENCHMARKING: bool = IP_ADDRESS.is_benchmarking();
900+
assert!(!IS_BENCHMARKING);
901+
877902
const IS_UNICAST_GLOBAL: bool = IP_ADDRESS.is_unicast_global();
878903
assert!(!IS_UNICAST_GLOBAL);
879904

‎library/std/src/sys/unix/process/process_common.rs

+7-1
Original file line numberDiff line numberDiff line change
@@ -457,9 +457,15 @@ impl fmt::Debug for Command {
457457
}
458458
}
459459

460-
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
460+
#[derive(PartialEq, Eq, Clone, Copy)]
461461
pub struct ExitCode(u8);
462462

463+
impl fmt::Debug for ExitCode {
464+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
465+
f.debug_tuple("unix_exit_status").field(&self.0).finish()
466+
}
467+
}
468+
463469
impl ExitCode {
464470
pub const SUCCESS: ExitCode = ExitCode(EXIT_SUCCESS as _);
465471
pub const FAILURE: ExitCode = ExitCode(EXIT_FAILURE as _);

‎library/std/src/sys/unix/process/process_unix.rs

+15-4
Original file line numberDiff line numberDiff line change
@@ -552,8 +552,7 @@ impl Process {
552552
use crate::os::unix::io::FromRawFd;
553553
use crate::sys_common::FromInner;
554554
// Safety: If `pidfd` is nonnegative, we assume it's valid and otherwise unowned.
555-
let pidfd = (pidfd >= 0)
556-
.then(|| PidFd::from_inner(unsafe { sys::fd::FileDesc::from_raw_fd(pidfd) }));
555+
let pidfd = (pidfd >= 0).then(|| PidFd::from_inner(sys::fd::FileDesc::from_raw_fd(pidfd)));
557556
Process { pid, status: None, pidfd }
558557
}
559558

@@ -607,9 +606,15 @@ impl Process {
607606
}
608607

609608
/// Unix exit statuses
610-
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
609+
#[derive(PartialEq, Eq, Clone, Copy)]
611610
pub struct ExitStatus(c_int);
612611

612+
impl fmt::Debug for ExitStatus {
613+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
614+
f.debug_tuple("unix_wait_status").field(&self.0).finish()
615+
}
616+
}
617+
613618
impl ExitStatus {
614619
pub fn new(status: c_int) -> ExitStatus {
615620
ExitStatus(status)
@@ -683,7 +688,7 @@ impl fmt::Display for ExitStatus {
683688
}
684689
}
685690

686-
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
691+
#[derive(PartialEq, Eq, Clone, Copy)]
687692
pub struct ExitStatusError(NonZero_c_int);
688693

689694
impl Into<ExitStatus> for ExitStatusError {
@@ -692,6 +697,12 @@ impl Into<ExitStatus> for ExitStatusError {
692697
}
693698
}
694699

700+
impl fmt::Debug for ExitStatusError {
701+
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
702+
f.debug_tuple("unix_wait_status").field(&self.0).finish()
703+
}
704+
}
705+
695706
impl ExitStatusError {
696707
pub fn code(self) -> Option<NonZeroI32> {
697708
ExitStatus(self.0.into()).code().map(|st| st.try_into().unwrap())

‎library/std/src/sys/windows/net.rs

+11-6
Original file line numberDiff line numberDiff line change
@@ -2,13 +2,13 @@
22

33
use crate::cmp;
44
use crate::io::{self, IoSlice, IoSliceMut, Read};
5+
use crate::lazy::SyncOnceCell;
56
use crate::mem;
67
use crate::net::{Shutdown, SocketAddr};
78
use crate::os::windows::io::{
89
AsRawSocket, AsSocket, BorrowedSocket, FromRawSocket, IntoRawSocket, OwnedSocket, RawSocket,
910
};
1011
use crate::ptr;
11-
use crate::sync::Once;
1212
use crate::sys;
1313
use crate::sys::c;
1414
use crate::sys_common::net;
@@ -29,26 +29,31 @@ pub mod netc {
2929

3030
pub struct Socket(OwnedSocket);
3131

32-
static INIT: Once = Once::new();
32+
static WSA_CLEANUP: SyncOnceCell<unsafe extern "system" fn() -> i32> = SyncOnceCell::new();
3333

3434
/// Checks whether the Windows socket interface has been started already, and
3535
/// if not, starts it.
3636
pub fn init() {
37-
INIT.call_once(|| unsafe {
37+
let _ = WSA_CLEANUP.get_or_init(|| unsafe {
3838
let mut data: c::WSADATA = mem::zeroed();
3939
let ret = c::WSAStartup(
4040
0x202, // version 2.2
4141
&mut data,
4242
);
4343
assert_eq!(ret, 0);
44+
45+
// Only register `WSACleanup` if `WSAStartup` is actually ever called.
46+
// Workaround to prevent linking to `WS2_32.dll` when no network functionality is used.
47+
// See issue #85441.
48+
c::WSACleanup
4449
});
4550
}
4651

4752
pub fn cleanup() {
48-
if INIT.is_completed() {
49-
// only close the socket interface if it has actually been started
53+
// only perform cleanup if network functionality was actually initialized
54+
if let Some(cleanup) = WSA_CLEANUP.get() {
5055
unsafe {
51-
c::WSACleanup();
56+
cleanup();
5257
}
5358
}
5459
}

‎src/doc/rustdoc/src/lints.md

+3-3
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ This lint **warns by default**. This lint detects when [intra-doc links] from pu
7070
For example:
7171

7272
```rust
73-
#![warn(rustdoc::private_intra_doc_links)] // note: unecessary - warns by default.
73+
#![warn(rustdoc::private_intra_doc_links)] // note: unnecessary - warns by default.
7474

7575
/// [private]
7676
pub fn public() {}
@@ -229,7 +229,7 @@ This lint **warns by default**. It detects code block attributes in
229229
documentation examples that have potentially mis-typed values. For example:
230230

231231
```rust
232-
#![warn(rustdoc::invalid_codeblock_attributes)] // note: unecessary - warns by default.
232+
#![warn(rustdoc::invalid_codeblock_attributes)] // note: unnecessary - warns by default.
233233

234234
/// Example.
235235
///
@@ -348,7 +348,7 @@ This lint is **warn-by-default**. It detects URLs which are not links.
348348
For example:
349349

350350
```rust
351-
#![warn(rustdoc::bare_urls)] // note: unecessary - warns by default.
351+
#![warn(rustdoc::bare_urls)] // note: unnecessary - warns by default.
352352

353353
/// http://example.org
354354
/// [http://example.net]
+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# only-windows-msvc
2+
3+
-include ../../run-make-fulldeps/tools.mk
4+
5+
# Tests that WS2_32.dll is not unnecessarily linked, see issue #85441
6+
7+
all:
8+
$(RUSTC) empty.rs
9+
objdump -p $(TMPDIR)/empty.exe | $(CGREP) -v -i "WS2_32.dll"
+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
fn main() {}
+8
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
// Regression test for issue #55825
2+
// Tests that we don't emit a spurious warning in NLL mode
3+
4+
#![feature(nll)]
5+
6+
const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() } //~ ERROR const
7+
8+
fn main() { }
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0658]: trait objects in const fn are unstable
2+
--> $DIR/issue-55825-const-fn.rs:6:32
3+
|
4+
LL | const fn no_dyn_trait_ret() -> &'static dyn std::fmt::Debug { &() }
5+
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
6+
|
7+
= note: see issue #57563 <https://github.com/rust-lang/rust/issues/57563> for more information
8+
= help: add `#![feature(const_fn_trait_bound)]` to the crate attributes to enable
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0658`.

0 commit comments

Comments
 (0)
Please sign in to comment.