Rollup merge of #97424 - matthiaskrgr:clippy_complexity_may26, r=oli-obk
clippy::complexity fixes
clone_on_copy
useless_format
bind_instead_of_map
filter_map_identity
useless_conversion
map_flatten
unnecessary_unwrap
diff --git a/compiler/rustc_monomorphize/src/collector.rs b/compiler/rustc_monomorphize/src/collector.rs
index ee02151..a9ca892 100644
--- a/compiler/rustc_monomorphize/src/collector.rs
+++ b/compiler/rustc_monomorphize/src/collector.rs
@@ -201,7 +201,6 @@
use rustc_session::Limit;
use rustc_span::source_map::{dummy_spanned, respan, Span, Spanned, DUMMY_SP};
use rustc_target::abi::Size;
-use smallvec::SmallVec;
use std::iter;
use std::ops::Range;
use std::path::PathBuf;
@@ -226,6 +225,44 @@
inlines: GrowableBitSet<usize>,
}
+/// Struct to store mono items in each collecting and if they should
+/// be inlined. We call `instantiation_mode` to get their inlining
+/// status when inserting new elements, which avoids calling it in
+/// `inlining_map.lock_mut()`. See the `collect_items_rec` implementation
+/// below.
+struct MonoItems<'tcx> {
+ // If this is false, we do not need to compute whether items
+ // will need to be inlined.
+ compute_inlining: bool,
+
+ // The TyCtxt used to determine whether the a item should
+ // be inlined.
+ tcx: TyCtxt<'tcx>,
+
+ // The collected mono items. The bool field in each element
+ // indicates whether this element should be inlined.
+ items: Vec<(Spanned<MonoItem<'tcx>>, bool /*inlined*/)>,
+}
+
+impl<'tcx> MonoItems<'tcx> {
+ #[inline]
+ fn push(&mut self, item: Spanned<MonoItem<'tcx>>) {
+ self.extend([item]);
+ }
+
+ #[inline]
+ fn extend<T: IntoIterator<Item = Spanned<MonoItem<'tcx>>>>(&mut self, iter: T) {
+ self.items.extend(iter.into_iter().map(|mono_item| {
+ let inlined = if !self.compute_inlining {
+ false
+ } else {
+ mono_item.node.instantiation_mode(self.tcx) == InstantiationMode::LocalCopy
+ };
+ (mono_item, inlined)
+ }))
+ }
+}
+
impl<'tcx> InliningMap<'tcx> {
fn new() -> InliningMap<'tcx> {
InliningMap {
@@ -235,7 +272,13 @@
}
}
- fn record_accesses(&mut self, source: MonoItem<'tcx>, new_targets: &[(MonoItem<'tcx>, bool)]) {
+ fn record_accesses<'a>(
+ &mut self,
+ source: MonoItem<'tcx>,
+ new_targets: &'a [(Spanned<MonoItem<'tcx>>, bool)],
+ ) where
+ 'tcx: 'a,
+ {
let start_index = self.targets.len();
let new_items_count = new_targets.len();
let new_items_count_total = new_items_count + self.targets.len();
@@ -243,9 +286,9 @@
self.targets.reserve(new_items_count);
self.inlines.ensure(new_items_count_total);
- for (i, (target, inline)) in new_targets.iter().enumerate() {
- self.targets.push(*target);
- if *inline {
+ for (i, (Spanned { node: mono_item, .. }, inlined)) in new_targets.into_iter().enumerate() {
+ self.targets.push(*mono_item);
+ if *inlined {
self.inlines.insert(i + start_index);
}
}
@@ -321,7 +364,7 @@
// start monomorphizing from.
fn collect_roots(tcx: TyCtxt<'_>, mode: MonoItemCollectionMode) -> Vec<MonoItem<'_>> {
debug!("collecting roots");
- let mut roots = Vec::new();
+ let mut roots = MonoItems { compute_inlining: false, tcx, items: Vec::new() };
{
let entry_fn = tcx.entry_fn(());
@@ -347,8 +390,11 @@
// whose predicates hold. Luckily, items that aren't instantiable
// can't actually be used, so we can just skip codegenning them.
roots
+ .items
.into_iter()
- .filter_map(|root| root.node.is_instantiable(tcx).then_some(root.node))
+ .filter_map(|(Spanned { node: mono_item, .. }, _)| {
+ mono_item.is_instantiable(tcx).then_some(mono_item)
+ })
.collect()
}
@@ -368,7 +414,7 @@
}
debug!("BEGIN collect_items_rec({})", starting_point.node);
- let mut neighbors = Vec::new();
+ let mut neighbors = MonoItems { compute_inlining: true, tcx, items: Vec::new() };
let recursion_depth_reset;
//
@@ -483,10 +529,9 @@
&format!("the above error was encountered while instantiating `{}`", formatted_item),
);
}
+ inlining_map.lock_mut().record_accesses(starting_point.node, &neighbors.items);
- record_accesses(tcx, starting_point.node, neighbors.iter().map(|i| &i.node), inlining_map);
-
- for neighbour in neighbors {
+ for (neighbour, _) in neighbors.items {
collect_items_rec(tcx, neighbour, visited, recursion_depths, recursion_limit, inlining_map);
}
@@ -497,25 +542,6 @@
debug!("END collect_items_rec({})", starting_point.node);
}
-fn record_accesses<'a, 'tcx: 'a>(
- tcx: TyCtxt<'tcx>,
- caller: MonoItem<'tcx>,
- callees: impl Iterator<Item = &'a MonoItem<'tcx>>,
- inlining_map: MTRef<'_, MTLock<InliningMap<'tcx>>>,
-) {
- let is_inlining_candidate = |mono_item: &MonoItem<'tcx>| {
- mono_item.instantiation_mode(tcx) == InstantiationMode::LocalCopy
- };
-
- // We collect this into a `SmallVec` to avoid calling `is_inlining_candidate` in the lock.
- // FIXME: Call `is_inlining_candidate` when pushing to `neighbors` in `collect_items_rec`
- // instead to avoid creating this `SmallVec`.
- let accesses: SmallVec<[_; 128]> =
- callees.map(|mono_item| (*mono_item, is_inlining_candidate(mono_item))).collect();
-
- inlining_map.lock_mut().record_accesses(caller, &accesses);
-}
-
/// Format instance name that is already known to be too long for rustc.
/// Show only the first and last 32 characters to avoid blasting
/// the user's terminal with thousands of lines of type-name.
@@ -627,7 +653,7 @@
struct MirNeighborCollector<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
body: &'a mir::Body<'tcx>,
- output: &'a mut Vec<Spanned<MonoItem<'tcx>>>,
+ output: &'a mut MonoItems<'tcx>,
instance: Instance<'tcx>,
}
@@ -905,7 +931,7 @@
ty: Ty<'tcx>,
is_direct_call: bool,
source: Span,
- output: &mut Vec<Spanned<MonoItem<'tcx>>>,
+ output: &mut MonoItems<'tcx>,
) {
let instance = Instance::resolve_drop_in_place(tcx, ty);
visit_instance_use(tcx, instance, is_direct_call, source, output);
@@ -916,7 +942,7 @@
ty: Ty<'tcx>,
is_direct_call: bool,
source: Span,
- output: &mut Vec<Spanned<MonoItem<'tcx>>>,
+ output: &mut MonoItems<'tcx>,
) {
if let ty::FnDef(def_id, substs) = *ty.kind() {
let instance = if is_direct_call {
@@ -934,7 +960,7 @@
instance: ty::Instance<'tcx>,
is_direct_call: bool,
source: Span,
- output: &mut Vec<Spanned<MonoItem<'tcx>>>,
+ output: &mut MonoItems<'tcx>,
) {
debug!("visit_item_use({:?}, is_direct_call={:?})", instance, is_direct_call);
if !should_codegen_locally(tcx, &instance) {
@@ -1117,7 +1143,7 @@
trait_ty: Ty<'tcx>,
impl_ty: Ty<'tcx>,
source: Span,
- output: &mut Vec<Spanned<MonoItem<'tcx>>>,
+ output: &mut MonoItems<'tcx>,
) {
assert!(!trait_ty.has_escaping_bound_vars() && !impl_ty.has_escaping_bound_vars());
@@ -1159,7 +1185,7 @@
struct RootCollector<'a, 'tcx> {
tcx: TyCtxt<'tcx>,
mode: MonoItemCollectionMode,
- output: &'a mut Vec<Spanned<MonoItem<'tcx>>>,
+ output: &'a mut MonoItems<'tcx>,
entry_fn: Option<(DefId, EntryFnType)>,
}
@@ -1305,7 +1331,7 @@
fn create_mono_items_for_default_impls<'tcx>(
tcx: TyCtxt<'tcx>,
item: &'tcx hir::Item<'tcx>,
- output: &mut Vec<Spanned<MonoItem<'tcx>>>,
+ output: &mut MonoItems<'tcx>,
) {
match item.kind {
hir::ItemKind::Impl(ref impl_) => {
@@ -1361,11 +1387,7 @@
}
/// Scans the miri alloc in order to find function calls, closures, and drop-glue.
-fn collect_miri<'tcx>(
- tcx: TyCtxt<'tcx>,
- alloc_id: AllocId,
- output: &mut Vec<Spanned<MonoItem<'tcx>>>,
-) {
+fn collect_miri<'tcx>(tcx: TyCtxt<'tcx>, alloc_id: AllocId, output: &mut MonoItems<'tcx>) {
match tcx.global_alloc(alloc_id) {
GlobalAlloc::Static(def_id) => {
assert!(!tcx.is_thread_local_static(def_id));
@@ -1396,7 +1418,7 @@
fn collect_neighbours<'tcx>(
tcx: TyCtxt<'tcx>,
instance: Instance<'tcx>,
- output: &mut Vec<Spanned<MonoItem<'tcx>>>,
+ output: &mut MonoItems<'tcx>,
) {
debug!("collect_neighbours: {:?}", instance.def_id());
let body = tcx.instance_mir(instance.def);
@@ -1407,7 +1429,7 @@
fn collect_const_value<'tcx>(
tcx: TyCtxt<'tcx>,
value: ConstValue<'tcx>,
- output: &mut Vec<Spanned<MonoItem<'tcx>>>,
+ output: &mut MonoItems<'tcx>,
) {
match value {
ConstValue::Scalar(Scalar::Ptr(ptr, _size)) => collect_miri(tcx, ptr.provenance, output),
diff --git a/library/alloc/src/str.rs b/library/alloc/src/str.rs
index 0eaa263..39dfd98 100644
--- a/library/alloc/src/str.rs
+++ b/library/alloc/src/str.rs
@@ -383,15 +383,23 @@
without modifying the original"]
#[stable(feature = "unicode_case_mapping", since = "1.2.0")]
pub fn to_lowercase(&self) -> String {
- let mut s = String::with_capacity(self.len());
- for (i, c) in self[..].char_indices() {
+ let out = convert_while_ascii(self.as_bytes(), u8::to_ascii_lowercase);
+
+ // Safety: we know this is a valid char boundary since
+ // out.len() is only progressed if ascii bytes are found
+ let rest = unsafe { self.get_unchecked(out.len()..) };
+
+ // Safety: We have written only valid ASCII to our vec
+ let mut s = unsafe { String::from_utf8_unchecked(out) };
+
+ for (i, c) in rest[..].char_indices() {
if c == 'Σ' {
// Σ maps to σ, except at the end of a word where it maps to ς.
// This is the only conditional (contextual) but language-independent mapping
// in `SpecialCasing.txt`,
// so hard-code it rather than have a generic "condition" mechanism.
// See https://github.com/rust-lang/rust/issues/26035
- map_uppercase_sigma(self, i, &mut s)
+ map_uppercase_sigma(rest, i, &mut s)
} else {
match conversions::to_lower(c) {
[a, '\0', _] => s.push(a),
@@ -466,8 +474,16 @@
without modifying the original"]
#[stable(feature = "unicode_case_mapping", since = "1.2.0")]
pub fn to_uppercase(&self) -> String {
- let mut s = String::with_capacity(self.len());
- for c in self[..].chars() {
+ let out = convert_while_ascii(self.as_bytes(), u8::to_ascii_uppercase);
+
+ // Safety: we know this is a valid char boundary since
+ // out.len() is only progressed if ascii bytes are found
+ let rest = unsafe { self.get_unchecked(out.len()..) };
+
+ // Safety: We have written only valid ASCII to our vec
+ let mut s = unsafe { String::from_utf8_unchecked(out) };
+
+ for c in rest.chars() {
match conversions::to_upper(c) {
[a, '\0', _] => s.push(a),
[a, b, '\0'] => {
@@ -619,3 +635,51 @@
pub unsafe fn from_boxed_utf8_unchecked(v: Box<[u8]>) -> Box<str> {
unsafe { Box::from_raw(Box::into_raw(v) as *mut str) }
}
+
+/// Converts the bytes while the bytes are still ascii.
+/// For better average performance, this is happens in chunks of `2*size_of::<usize>()`.
+/// Returns a vec with the converted bytes.
+#[inline]
+#[cfg(not(test))]
+#[cfg(not(no_global_oom_handling))]
+fn convert_while_ascii(b: &[u8], convert: fn(&u8) -> u8) -> Vec<u8> {
+ let mut out = Vec::with_capacity(b.len());
+
+ const USIZE_SIZE: usize = mem::size_of::<usize>();
+ const MAGIC_UNROLL: usize = 2;
+ const N: usize = USIZE_SIZE * MAGIC_UNROLL;
+ const NONASCII_MASK: usize = usize::from_ne_bytes([0x80; USIZE_SIZE]);
+
+ let mut i = 0;
+ unsafe {
+ while i + N <= b.len() {
+ // Safety: we have checks the sizes `b` and `out` to know that our
+ let in_chunk = b.get_unchecked(i..i + N);
+ let out_chunk = out.spare_capacity_mut().get_unchecked_mut(i..i + N);
+
+ let mut bits = 0;
+ for j in 0..MAGIC_UNROLL {
+ // read the bytes 1 usize at a time (unaligned since we haven't checked the alignment)
+ // safety: in_chunk is valid bytes in the range
+ bits |= in_chunk.as_ptr().cast::<usize>().add(j).read_unaligned();
+ }
+ // if our chunks aren't ascii, then return only the prior bytes as init
+ if bits & NONASCII_MASK != 0 {
+ break;
+ }
+
+ // perform the case conversions on N bytes (gets heavily autovec'd)
+ for j in 0..N {
+ // safety: in_chunk and out_chunk is valid bytes in the range
+ let out = out_chunk.get_unchecked_mut(j);
+ out.write(convert(in_chunk.get_unchecked(j)));
+ }
+
+ // mark these bytes as initialised
+ i += N;
+ }
+ out.set_len(i);
+ }
+
+ out
+}
diff --git a/library/alloc/tests/str.rs b/library/alloc/tests/str.rs
index 273b39a..7379569 100644
--- a/library/alloc/tests/str.rs
+++ b/library/alloc/tests/str.rs
@@ -1772,6 +1772,20 @@
assert_eq!("ΑΣΑ".to_lowercase(), "ασα");
assert_eq!("ΑΣ'Α".to_lowercase(), "ασ'α");
assert_eq!("ΑΣ''Α".to_lowercase(), "ασ''α");
+
+ // a really long string that has it's lowercase form
+ // even longer. this tests that implementations don't assume
+ // an incorrect upper bound on allocations
+ let upper = str::repeat("İ", 512);
+ let lower = str::repeat("i̇", 512);
+ assert_eq!(upper.to_lowercase(), lower);
+
+ // a really long ascii-only string.
+ // This test that the ascii hot-path
+ // functions correctly
+ let upper = str::repeat("A", 511);
+ let lower = str::repeat("a", 511);
+ assert_eq!(upper.to_lowercase(), lower);
}
#[test]
diff --git a/library/core/src/option.rs b/library/core/src/option.rs
index d074669..28ea45e 100644
--- a/library/core/src/option.rs
+++ b/library/core/src/option.rs
@@ -708,6 +708,26 @@
/// let x: Option<&str> = None;
/// x.expect("fruits are healthy"); // panics with `fruits are healthy`
/// ```
+ ///
+ /// # Recommended Message Style
+ ///
+ /// We recommend that `expect` messages are used to describe the reason you
+ /// _expect_ the `Option` should be `Some`.
+ ///
+ /// ```should_panic
+ /// # let slice: &[u8] = &[];
+ /// let item = slice.get(0)
+ /// .expect("slice should not be empty");
+ /// ```
+ ///
+ /// **Hint**: If you're having trouble remembering how to phrase expect
+ /// error messages remember to focus on the word "should" as in "env
+ /// variable should be set by blah" or "the given binary should be available
+ /// and executable by the current user".
+ ///
+ /// For more detail on expect message styles and the reasoning behind our
+ /// recommendation please refer to the section on ["Common Message
+ /// Styles"](../../std/error/index.html#common-message-styles) in the [`std::error`](../../std/error/index.html) module docs.
#[inline]
#[track_caller]
#[stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/core/src/result.rs b/library/core/src/result.rs
index 5e5f8a5..c4dc34f 100644
--- a/library/core/src/result.rs
+++ b/library/core/src/result.rs
@@ -1023,6 +1023,26 @@
/// let x: Result<u32, &str> = Err("emergency failure");
/// x.expect("Testing expect"); // panics with `Testing expect: emergency failure`
/// ```
+ ///
+ /// # Recommended Message Style
+ ///
+ /// We recommend that `expect` messages are used to describe the reason you
+ /// _expect_ the `Result` should be `Ok`.
+ ///
+ /// ```should_panic
+ /// let path = std::env::var("IMPORTANT_PATH")
+ /// .expect("env variable `IMPORTANT_PATH` should be set by `wrapper_script.sh`");
+ /// ```
+ ///
+ /// **Hint**: If you're having trouble remembering how to phrase expect
+ /// error messages remember to focus on the word "should" as in "env
+ /// variable should be set by blah" or "the given binary should be available
+ /// and executable by the current user".
+ ///
+ /// For more detail on expect message styles and the reasoning behind our recommendation please
+ /// refer to the section on ["Common Message
+ /// Styles"](../../std/error/index.html#common-message-styles) in the
+ /// [`std::error`](../../std/error/index.html) module docs.
#[inline]
#[track_caller]
#[stable(feature = "result_expect", since = "1.4.0")]
diff --git a/library/std/src/error.rs b/library/std/src/error.rs
index 438304e..c2d3061 100644
--- a/library/std/src/error.rs
+++ b/library/std/src/error.rs
@@ -1,4 +1,140 @@
-//! Traits for working with Errors.
+//! Interfaces for working with Errors.
+//!
+//! # Error Handling In Rust
+//!
+//! The Rust language provides two complementary systems for constructing /
+//! representing, reporting, propagating, reacting to, and discarding errors.
+//! These responsibilities are collectively known as "error handling." The
+//! components of the first system, the panic runtime and interfaces, are most
+//! commonly used to represent bugs that have been detected in your program. The
+//! components of the second system, `Result`, the error traits, and user
+//! defined types, are used to represent anticipated runtime failure modes of
+//! your program.
+//!
+//! ## The Panic Interfaces
+//!
+//! The following are the primary interfaces of the panic system and the
+//! responsibilities they cover:
+//!
+//! * [`panic!`] and [`panic_any`] (Constructing, Propagated automatically)
+//! * [`PanicInfo`] (Reporting)
+//! * [`set_hook`], [`take_hook`], and [`#[panic_handler]`][panic-handler] (Reporting)
+//! * [`catch_unwind`] and [`resume_unwind`] (Discarding, Propagating)
+//!
+//! The following are the primary interfaces of the error system and the
+//! responsibilities they cover:
+//!
+//! * [`Result`] (Propagating, Reacting)
+//! * The [`Error`] trait (Reporting)
+//! * User defined types (Constructing / Representing)
+//! * [`match`] and [`downcast`] (Reacting)
+//! * The question mark operator ([`?`]) (Propagating)
+//! * The partially stable [`Try`] traits (Propagating, Constructing)
+//! * [`Termination`] (Reporting)
+//!
+//! ## Converting Errors into Panics
+//!
+//! The panic and error systems are not entirely distinct. Often times errors
+//! that are anticipated runtime failures in an API might instead represent bugs
+//! to a caller. For these situations the standard library provides APIs for
+//! constructing panics with an `Error` as it's source.
+//!
+//! * [`Result::unwrap`]
+//! * [`Result::expect`]
+//!
+//! These functions are equivalent, they either return the inner value if the
+//! `Result` is `Ok` or panic if the `Result` is `Err` printing the inner error
+//! as the source. The only difference between them is that with `expect` you
+//! provide a panic error message to be printed alongside the source, whereas
+//! `unwrap` has a default message indicating only that you unwraped an `Err`.
+//!
+//! Of the two, `expect` is generally preferred since its `msg` field allows you
+//! to convey your intent and assumptions which makes tracking down the source
+//! of a panic easier. `unwrap` on the other hand can still be a good fit in
+//! situations where you can trivially show that a piece of code will never
+//! panick, such as `"127.0.0.1".parse::<std::net::IpAddr>().unwrap()` or early
+//! prototyping.
+//!
+//! # Common Message Styles
+//!
+//! There are two common styles for how people word `expect` messages. Using
+//! the message to present information to users encountering a panic
+//! ("expect as error message") or using the message to present information
+//! to developers debugging the panic ("expect as precondition").
+//!
+//! In the former case the expect message is used to describe the error that
+//! has occurred which is considered a bug. Consider the following example:
+//!
+//! ```should_panic
+//! // Read environment variable, panic if it is not present
+//! let path = std::env::var("IMPORTANT_PATH").unwrap();
+//! ```
+//!
+//! In the "expect as error message" style we would use expect to describe
+//! that the environment variable was not set when it should have been:
+//!
+//! ```should_panic
+//! let path = std::env::var("IMPORTANT_PATH")
+//! .expect("env variable `IMPORTANT_PATH` is not set");
+//! ```
+//!
+//! In the "expect as precondition" style, we would instead describe the
+//! reason we _expect_ the `Result` should be `Ok`. With this style we would
+//! prefer to write:
+//!
+//! ```should_panic
+//! let path = std::env::var("IMPORTANT_PATH")
+//! .expect("env variable `IMPORTANT_PATH` should be set by `wrapper_script.sh`");
+//! ```
+//!
+//! The "expect as error message" style does not work as well with the
+//! default output of the std panic hooks, and often ends up repeating
+//! information that is already communicated by the source error being
+//! unwrapped:
+//!
+//! ```text
+//! thread 'main' panicked at 'env variable `IMPORTANT_PATH` is not set: NotPresent', src/main.rs:4:6
+//! ```
+//!
+//! In this example we end up mentioning that an env variable is not set,
+//! followed by our source message that says the env is not present, the
+//! only additional information we're communicating is the name of the
+//! environment variable being checked.
+//!
+//! The "expect as precondition" style instead focuses on source code
+//! readability, making it easier to understand what must have gone wrong in
+//! situations where panics are being used to represent bugs exclusively.
+//! Also, by framing our expect in terms of what "SHOULD" have happened to
+//! prevent the source error, we end up introducing new information that is
+//! independent from our source error.
+//!
+//! ```text
+//! thread 'main' panicked at 'env variable `IMPORTANT_PATH` should be set by `wrapper_script.sh`: NotPresent', src/main.rs:4:6
+//! ```
+//!
+//! In this example we are communicating not only the name of the
+//! environment variable that should have been set, but also an explanation
+//! for why it should have been set, and we let the source error display as
+//! a clear contradiction to our expectation.
+//!
+//! **Hint**: If you're having trouble remembering how to phrase
+//! expect-as-precondition style error messages remember to focus on the word
+//! "should" as in "env variable should be set by blah" or "the given binary
+//! should be available and executable by the current user".
+//!
+//! [`panic_any`]: crate::panic::panic_any
+//! [`PanicInfo`]: crate::panic::PanicInfo
+//! [`catch_unwind`]: crate::panic::catch_unwind
+//! [`resume_unwind`]: crate::panic::resume_unwind
+//! [`downcast`]: crate::error::Error
+//! [`Termination`]: crate::process::Termination
+//! [`Try`]: crate::ops::Try
+//! [panic hook]: crate::panic::set_hook
+//! [`set_hook`]: crate::panic::set_hook
+//! [`take_hook`]: crate::panic::take_hook
+//! [panic-handler]: <https://doc.rust-lang.org/nomicon/panic-handler.html>
+//! [`match`]: ../../std/keyword.match.html
+//! [`?`]: ../../std/result/index.html#the-question-mark-operator-
#![stable(feature = "rust1", since = "1.0.0")]
diff --git a/library/std/src/os/unix/net/ancillary.rs b/library/std/src/os/unix/net/ancillary.rs
index 9e31b8b..ecee123 100644
--- a/library/std/src/os/unix/net/ancillary.rs
+++ b/library/std/src/os/unix/net/ancillary.rs
@@ -1,3 +1,5 @@
+// FIXME: This is currently disabled on *BSD.
+
use super::{sockaddr_un, SocketAddr};
use crate::io::{self, IoSlice, IoSliceMut};
use crate::marker::PhantomData;
diff --git a/library/std/src/os/unix/net/datagram.rs b/library/std/src/os/unix/net/datagram.rs
index 872058b..0b1d9b0 100644
--- a/library/std/src/os/unix/net/datagram.rs
+++ b/library/std/src/os/unix/net/datagram.rs
@@ -1,24 +1,7 @@
-#[cfg(any(
- doc,
- target_os = "android",
- target_os = "dragonfly",
- target_os = "emscripten",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd",
-))]
+#[cfg(any(doc, target_os = "android", target_os = "linux"))]
use super::{recv_vectored_with_ancillary_from, send_vectored_with_ancillary_to, SocketAncillary};
use super::{sockaddr_un, SocketAddr};
-#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "emscripten",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd",
-))]
+#[cfg(any(doc, target_os = "android", target_os = "linux"))]
use crate::io::{IoSlice, IoSliceMut};
use crate::net::Shutdown;
use crate::os::unix::io::{AsFd, AsRawFd, BorrowedFd, FromRawFd, IntoRawFd, OwnedFd, RawFd};
@@ -403,7 +386,8 @@
///
/// # Examples
///
- /// ```no_run
+ #[cfg_attr(any(target_os = "android", target_os = "linux"), doc = "```no_run")]
+ #[cfg_attr(not(any(target_os = "android", target_os = "linux")), doc = "```ignore")]
/// #![feature(unix_socket_ancillary_data)]
/// use std::os::unix::net::{UnixDatagram, SocketAncillary, AncillaryData};
/// use std::io::IoSliceMut;
@@ -433,15 +417,7 @@
/// Ok(())
/// }
/// ```
- #[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "emscripten",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd",
- ))]
+ #[cfg(any(doc, target_os = "android", target_os = "linux"))]
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
pub fn recv_vectored_with_ancillary_from(
&self,
@@ -460,7 +436,8 @@
///
/// # Examples
///
- /// ```no_run
+ #[cfg_attr(any(target_os = "android", target_os = "linux"), doc = "```no_run")]
+ #[cfg_attr(not(any(target_os = "android", target_os = "linux")), doc = "```ignore")]
/// #![feature(unix_socket_ancillary_data)]
/// use std::os::unix::net::{UnixDatagram, SocketAncillary, AncillaryData};
/// use std::io::IoSliceMut;
@@ -490,15 +467,7 @@
/// Ok(())
/// }
/// ```
- #[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "emscripten",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd",
- ))]
+ #[cfg(any(doc, target_os = "android", target_os = "linux"))]
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
pub fn recv_vectored_with_ancillary(
&self,
@@ -609,7 +578,8 @@
///
/// # Examples
///
- /// ```no_run
+ #[cfg_attr(any(target_os = "android", target_os = "linux"), doc = "```no_run")]
+ #[cfg_attr(not(any(target_os = "android", target_os = "linux")), doc = "```ignore")]
/// #![feature(unix_socket_ancillary_data)]
/// use std::os::unix::net::{UnixDatagram, SocketAncillary};
/// use std::io::IoSlice;
@@ -633,15 +603,7 @@
/// Ok(())
/// }
/// ```
- #[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "emscripten",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd",
- ))]
+ #[cfg(any(doc, target_os = "android", target_os = "linux"))]
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
pub fn send_vectored_with_ancillary_to<P: AsRef<Path>>(
&self,
@@ -658,7 +620,8 @@
///
/// # Examples
///
- /// ```no_run
+ #[cfg_attr(any(target_os = "android", target_os = "linux"), doc = "```no_run")]
+ #[cfg_attr(not(any(target_os = "android", target_os = "linux")), doc = "```ignore")]
/// #![feature(unix_socket_ancillary_data)]
/// use std::os::unix::net::{UnixDatagram, SocketAncillary};
/// use std::io::IoSlice;
@@ -682,15 +645,7 @@
/// Ok(())
/// }
/// ```
- #[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "emscripten",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd",
- ))]
+ #[cfg(any(doc, target_os = "android", target_os = "linux"))]
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
pub fn send_vectored_with_ancillary(
&self,
diff --git a/library/std/src/os/unix/net/mod.rs b/library/std/src/os/unix/net/mod.rs
index 8ce8220..6da3e350 100644
--- a/library/std/src/os/unix/net/mod.rs
+++ b/library/std/src/os/unix/net/mod.rs
@@ -1,27 +1,11 @@
//! Unix-specific networking functionality.
+#![allow(irrefutable_let_patterns)]
#![stable(feature = "unix_socket", since = "1.10.0")]
mod addr;
-#[doc(cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "emscripten",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd",
-)))]
-#[cfg(any(
- doc,
- target_os = "android",
- target_os = "dragonfly",
- target_os = "emscripten",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd",
-))]
+#[doc(cfg(any(target_os = "android", target_os = "linux")))]
+#[cfg(any(doc, target_os = "android", target_os = "linux"))]
mod ancillary;
mod datagram;
mod listener;
@@ -31,16 +15,7 @@
#[stable(feature = "unix_socket", since = "1.10.0")]
pub use self::addr::*;
-#[cfg(any(
- doc,
- target_os = "android",
- target_os = "dragonfly",
- target_os = "emscripten",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd",
-))]
+#[cfg(any(doc, target_os = "android", target_os = "linux"))]
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
pub use self::ancillary::*;
#[stable(feature = "unix_socket", since = "1.10.0")]
diff --git a/library/std/src/os/unix/net/stream.rs b/library/std/src/os/unix/net/stream.rs
index cd1aa01..2a5790e 100644
--- a/library/std/src/os/unix/net/stream.rs
+++ b/library/std/src/os/unix/net/stream.rs
@@ -1,13 +1,4 @@
-#[cfg(any(
- doc,
- target_os = "android",
- target_os = "dragonfly",
- target_os = "emscripten",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd",
-))]
+#[cfg(any(doc, target_os = "android", target_os = "linux"))]
use super::{recv_vectored_with_ancillary_from, send_vectored_with_ancillary_to, SocketAncillary};
use super::{sockaddr_un, SocketAddr};
use crate::fmt;
@@ -511,7 +502,8 @@
///
/// # Examples
///
- /// ```no_run
+ #[cfg_attr(any(target_os = "android", target_os = "linux"), doc = "```no_run")]
+ #[cfg_attr(not(any(target_os = "android", target_os = "linux")), doc = "```ignore")]
/// #![feature(unix_socket_ancillary_data)]
/// use std::os::unix::net::{UnixStream, SocketAncillary, AncillaryData};
/// use std::io::IoSliceMut;
@@ -541,15 +533,7 @@
/// Ok(())
/// }
/// ```
- #[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "emscripten",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd",
- ))]
+ #[cfg(any(doc, target_os = "android", target_os = "linux"))]
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
pub fn recv_vectored_with_ancillary(
&self,
@@ -567,7 +551,8 @@
///
/// # Examples
///
- /// ```no_run
+ #[cfg_attr(any(target_os = "android", target_os = "linux"), doc = "```no_run")]
+ #[cfg_attr(not(any(target_os = "android", target_os = "linux")), doc = "```ignore")]
/// #![feature(unix_socket_ancillary_data)]
/// use std::os::unix::net::{UnixStream, SocketAncillary};
/// use std::io::IoSlice;
@@ -591,15 +576,7 @@
/// Ok(())
/// }
/// ```
- #[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "emscripten",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd",
- ))]
+ #[cfg(any(doc, target_os = "android", target_os = "linux"))]
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
pub fn send_vectored_with_ancillary(
&self,
diff --git a/library/std/src/os/unix/net/tests.rs b/library/std/src/os/unix/net/tests.rs
index c1f11c5..e4499f9 100644
--- a/library/std/src/os/unix/net/tests.rs
+++ b/library/std/src/os/unix/net/tests.rs
@@ -1,24 +1,7 @@
use super::*;
use crate::io::prelude::*;
use crate::io::{self, ErrorKind, IoSlice, IoSliceMut};
-#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "emscripten",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd",
-))]
-#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "emscripten",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd",
-))]
+#[cfg(any(target_os = "android", target_os = "linux"))]
use crate::os::unix::io::AsRawFd;
use crate::sys_common::io::test::tmpdir;
use crate::thread;
@@ -618,15 +601,7 @@
assert_eq!(msg, &buf[..]);
}
-#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "emscripten",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd",
-))]
+#[cfg(any(target_os = "android", target_os = "linux"))]
#[test]
fn test_send_vectored_fds_unix_stream() {
let (s1, s2) = or_panic!(UnixStream::pair());
@@ -664,7 +639,7 @@
}
}
-#[cfg(any(target_os = "android", target_os = "emscripten", target_os = "linux",))]
+#[cfg(any(target_os = "android", target_os = "linux",))]
#[test]
fn test_send_vectored_with_ancillary_to_unix_datagram() {
fn getpid() -> libc::pid_t {
@@ -731,15 +706,7 @@
}
}
-#[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "emscripten",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd",
-))]
+#[cfg(any(target_os = "android", target_os = "linux"))]
#[test]
fn test_send_vectored_with_ancillary_unix_datagram() {
let dir = tmpdir();
diff --git a/library/std/src/sys/unix/net.rs b/library/std/src/sys/unix/net.rs
index 9bf9607..a1bbc2d 100644
--- a/library/std/src/sys/unix/net.rs
+++ b/library/std/src/sys/unix/net.rs
@@ -289,15 +289,7 @@
self.recv_from_with_flags(buf, 0)
}
- #[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "emscripten",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd",
- ))]
+ #[cfg(any(target_os = "android", target_os = "linux"))]
pub fn recv_msg(&self, msg: &mut libc::msghdr) -> io::Result<usize> {
let n = cvt(unsafe { libc::recvmsg(self.as_raw_fd(), msg, libc::MSG_CMSG_CLOEXEC) })?;
Ok(n as usize)
@@ -320,15 +312,7 @@
self.0.is_write_vectored()
}
- #[cfg(any(
- target_os = "android",
- target_os = "dragonfly",
- target_os = "emscripten",
- target_os = "freebsd",
- target_os = "linux",
- target_os = "netbsd",
- target_os = "openbsd",
- ))]
+ #[cfg(any(target_os = "android", target_os = "linux"))]
pub fn send_msg(&self, msg: &mut libc::msghdr) -> io::Result<usize> {
let n = cvt(unsafe { libc::sendmsg(self.as_raw_fd(), msg, 0) })?;
Ok(n as usize)