Skip to content

Commit b3bb1af

Browse files
committed
Auto merge of rust-lang#122846 - jhpratt:rollup-ijix3wt, r=jhpratt
Rollup of 6 pull requests Successful merges: - rust-lang#121881 (std::net: adding acceptfilter feature for netbsd/freebsd.) - rust-lang#122817 (Doc Guarantee: BTree(Set|Map): `IntoIter` Iterate in Sorted by key Order) - rust-lang#122829 (Implement `FusedIterator` for `gen` block) - rust-lang#122831 (make failure logs less verbose) - rust-lang#122837 (add test for rust-lang#122549) - rust-lang#122838 (Avoid noop rewrite of issues.txt) r? `@ghost` `@rustbot` modify labels: rollup
2 parents 0ad927c + 12c0915 commit b3bb1af

File tree

19 files changed

+308
-21
lines changed

19 files changed

+308
-21
lines changed

compiler/rustc_hir/src/lang_items.rs

+1
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,7 @@ language_item_table! {
214214
FnOnceOutput, sym::fn_once_output, fn_once_output, Target::AssocTy, GenericRequirement::None;
215215

216216
Iterator, sym::iterator, iterator_trait, Target::Trait, GenericRequirement::Exact(0);
217+
FusedIterator, sym::fused_iterator, fused_iterator_trait, Target::Trait, GenericRequirement::Exact(0);
217218
Future, sym::future_trait, future_trait, Target::Trait, GenericRequirement::Exact(0);
218219
AsyncIterator, sym::async_iterator, async_iterator_trait, Target::Trait, GenericRequirement::Exact(0);
219220

compiler/rustc_span/src/symbol.rs

+2
Original file line numberDiff line numberDiff line change
@@ -207,6 +207,7 @@ symbols! {
207207
FromResidual,
208208
FsOpenOptions,
209209
FsPermissions,
210+
FusedIterator,
210211
Future,
211212
FutureOutput,
212213
GlobalAlloc,
@@ -886,6 +887,7 @@ symbols! {
886887
fsub_algebraic,
887888
fsub_fast,
888889
fundamental,
890+
fused_iterator,
889891
future,
890892
future_trait,
891893
gdb_script_file,

compiler/rustc_trait_selection/src/solve/assembly/mod.rs

+9
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,13 @@ pub(super) trait GoalKind<'tcx>:
215215
goal: Goal<'tcx, Self>,
216216
) -> QueryResult<'tcx>;
217217

218+
/// A coroutine (that comes from a `gen` desugaring) is known to implement
219+
/// `FusedIterator`
220+
fn consider_builtin_fused_iterator_candidate(
221+
ecx: &mut EvalCtxt<'_, 'tcx>,
222+
goal: Goal<'tcx, Self>,
223+
) -> QueryResult<'tcx>;
224+
218225
fn consider_builtin_async_iterator_candidate(
219226
ecx: &mut EvalCtxt<'_, 'tcx>,
220227
goal: Goal<'tcx, Self>,
@@ -497,6 +504,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
497504
G::consider_builtin_future_candidate(self, goal)
498505
} else if lang_items.iterator_trait() == Some(trait_def_id) {
499506
G::consider_builtin_iterator_candidate(self, goal)
507+
} else if lang_items.fused_iterator_trait() == Some(trait_def_id) {
508+
G::consider_builtin_fused_iterator_candidate(self, goal)
500509
} else if lang_items.async_iterator_trait() == Some(trait_def_id) {
501510
G::consider_builtin_async_iterator_candidate(self, goal)
502511
} else if lang_items.coroutine_trait() == Some(trait_def_id) {

compiler/rustc_trait_selection/src/solve/normalizes_to/mod.rs

+7
Original file line numberDiff line numberDiff line change
@@ -647,6 +647,13 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
647647
)
648648
}
649649

650+
fn consider_builtin_fused_iterator_candidate(
651+
_ecx: &mut EvalCtxt<'_, 'tcx>,
652+
goal: Goal<'tcx, Self>,
653+
) -> QueryResult<'tcx> {
654+
bug!("`FusedIterator` does not have an associated type: {:?}", goal);
655+
}
656+
650657
fn consider_builtin_async_iterator_candidate(
651658
ecx: &mut EvalCtxt<'_, 'tcx>,
652659
goal: Goal<'tcx, Self>,

compiler/rustc_trait_selection/src/solve/trait_goals.rs

+22
Original file line numberDiff line numberDiff line change
@@ -456,6 +456,28 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
456456
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
457457
}
458458

459+
fn consider_builtin_fused_iterator_candidate(
460+
ecx: &mut EvalCtxt<'_, 'tcx>,
461+
goal: Goal<'tcx, Self>,
462+
) -> QueryResult<'tcx> {
463+
if goal.predicate.polarity != ty::ImplPolarity::Positive {
464+
return Err(NoSolution);
465+
}
466+
467+
let ty::Coroutine(def_id, _) = *goal.predicate.self_ty().kind() else {
468+
return Err(NoSolution);
469+
};
470+
471+
// Coroutines are not iterators unless they come from `gen` desugaring
472+
let tcx = ecx.tcx();
473+
if !tcx.coroutine_is_gen(def_id) {
474+
return Err(NoSolution);
475+
}
476+
477+
// Gen coroutines unconditionally implement `FusedIterator`
478+
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
479+
}
480+
459481
fn consider_builtin_async_iterator_candidate(
460482
ecx: &mut EvalCtxt<'_, 'tcx>,
461483
goal: Goal<'tcx, Self>,

compiler/rustc_trait_selection/src/traits/select/candidate_assembly.rs

+26-7
Original file line numberDiff line numberDiff line change
@@ -118,6 +118,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
118118
self.assemble_future_candidates(obligation, &mut candidates);
119119
} else if lang_items.iterator_trait() == Some(def_id) {
120120
self.assemble_iterator_candidates(obligation, &mut candidates);
121+
} else if lang_items.fused_iterator_trait() == Some(def_id) {
122+
self.assemble_fused_iterator_candidates(obligation, &mut candidates);
121123
} else if lang_items.async_iterator_trait() == Some(def_id) {
122124
self.assemble_async_iterator_candidates(obligation, &mut candidates);
123125
} else if lang_items.async_fn_kind_helper() == Some(def_id) {
@@ -302,14 +304,31 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
302304
candidates: &mut SelectionCandidateSet<'tcx>,
303305
) {
304306
let self_ty = obligation.self_ty().skip_binder();
305-
if let ty::Coroutine(did, ..) = self_ty.kind() {
306-
// gen constructs get lowered to a special kind of coroutine that
307-
// should directly `impl Iterator`.
308-
if self.tcx().coroutine_is_gen(*did) {
309-
debug!(?self_ty, ?obligation, "assemble_iterator_candidates",);
307+
// gen constructs get lowered to a special kind of coroutine that
308+
// should directly `impl Iterator`.
309+
if let ty::Coroutine(did, ..) = self_ty.kind()
310+
&& self.tcx().coroutine_is_gen(*did)
311+
{
312+
debug!(?self_ty, ?obligation, "assemble_iterator_candidates",);
310313

311-
candidates.vec.push(IteratorCandidate);
312-
}
314+
candidates.vec.push(IteratorCandidate);
315+
}
316+
}
317+
318+
fn assemble_fused_iterator_candidates(
319+
&mut self,
320+
obligation: &PolyTraitObligation<'tcx>,
321+
candidates: &mut SelectionCandidateSet<'tcx>,
322+
) {
323+
let self_ty = obligation.self_ty().skip_binder();
324+
// gen constructs get lowered to a special kind of coroutine that
325+
// should directly `impl FusedIterator`.
326+
if let ty::Coroutine(did, ..) = self_ty.kind()
327+
&& self.tcx().coroutine_is_gen(*did)
328+
{
329+
debug!(?self_ty, ?obligation, "assemble_fused_iterator_candidates",);
330+
331+
candidates.vec.push(BuiltinCandidate { has_nested: false });
313332
}
314333
}
315334

compiler/rustc_trait_selection/src/traits/select/confirmation.rs

+2
Original file line numberDiff line numberDiff line change
@@ -267,6 +267,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
267267
self.copy_clone_conditions(obligation)
268268
} else if Some(trait_def) == lang_items.clone_trait() {
269269
self.copy_clone_conditions(obligation)
270+
} else if Some(trait_def) == lang_items.fused_iterator_trait() {
271+
self.fused_iterator_conditions(obligation)
270272
} else {
271273
bug!("unexpected builtin trait {:?}", trait_def)
272274
};

compiler/rustc_trait_selection/src/traits/select/mod.rs

+14
Original file line numberDiff line numberDiff line change
@@ -2259,6 +2259,20 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
22592259
}
22602260
}
22612261

2262+
fn fused_iterator_conditions(
2263+
&mut self,
2264+
obligation: &PolyTraitObligation<'tcx>,
2265+
) -> BuiltinImplConditions<'tcx> {
2266+
let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
2267+
if let ty::Coroutine(did, ..) = *self_ty.kind()
2268+
&& self.tcx().coroutine_is_gen(did)
2269+
{
2270+
BuiltinImplConditions::Where(ty::Binder::dummy(Vec::new()))
2271+
} else {
2272+
BuiltinImplConditions::None
2273+
}
2274+
}
2275+
22622276
/// For default impls, we need to break apart a type into its
22632277
/// "constituent types" -- meaning, the types that it contains.
22642278
///

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

+3-2
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ pub(super) const MIN_LEN: usize = node::MIN_LEN_AFTER_SPLIT;
7272
/// `BTreeMap` that observed the logic error and not result in undefined behavior. This could
7373
/// include panics, incorrect results, aborts, memory leaks, and non-termination.
7474
///
75-
/// Iterators obtained from functions such as [`BTreeMap::iter`], [`BTreeMap::values`], or
75+
/// Iterators obtained from functions such as [`BTreeMap::iter`], [`BTreeMap::into_iter`], [`BTreeMap::values`], or
7676
/// [`BTreeMap::keys`] produce their items in order by key, and take worst-case logarithmic and
7777
/// amortized constant time per item returned.
7878
///
@@ -415,7 +415,7 @@ impl<'a, K: 'a, V: 'a> Default for IterMut<'a, K, V> {
415415
}
416416
}
417417

418-
/// An owning iterator over the entries of a `BTreeMap`.
418+
/// An owning iterator over the entries of a `BTreeMap`, sorted by key.
419419
///
420420
/// This `struct` is created by the [`into_iter`] method on [`BTreeMap`]
421421
/// (provided by the [`IntoIterator`] trait). See its documentation for more.
@@ -1637,6 +1637,7 @@ impl<K, V, A: Allocator + Clone> IntoIterator for BTreeMap<K, V, A> {
16371637
type Item = (K, V);
16381638
type IntoIter = IntoIter<K, V, A>;
16391639

1640+
/// Gets an owning iterator over the entries of the map, sorted by key.
16401641
fn into_iter(self) -> IntoIter<K, V, A> {
16411642
let mut me = ManuallyDrop::new(self);
16421643
if let Some(root) = me.root.take() {

library/alloc/src/collections/btree/set.rs

+3-3
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ use crate::alloc::{Allocator, Global};
2727
/// `BTreeSet` that observed the logic error and not result in undefined behavior. This could
2828
/// include panics, incorrect results, aborts, memory leaks, and non-termination.
2929
///
30-
/// Iterators returned by [`BTreeSet::iter`] produce their items in order, and take worst-case
30+
/// Iterators returned by [`BTreeSet::iter`] and [`BTreeSet::into_iter`] produce their items in order, and take worst-case
3131
/// logarithmic and amortized constant time per item returned.
3232
///
3333
/// [`Cell`]: core::cell::Cell
@@ -140,7 +140,7 @@ impl<T: fmt::Debug> fmt::Debug for Iter<'_, T> {
140140
}
141141
}
142142

143-
/// An owning iterator over the items of a `BTreeSet`.
143+
/// An owning iterator over the items of a `BTreeSet` in ascending order.
144144
///
145145
/// This `struct` is created by the [`into_iter`] method on [`BTreeSet`]
146146
/// (provided by the [`IntoIterator`] trait). See its documentation for more.
@@ -1237,7 +1237,7 @@ impl<T, A: Allocator + Clone> IntoIterator for BTreeSet<T, A> {
12371237
type Item = T;
12381238
type IntoIter = IntoIter<T, A>;
12391239

1240-
/// Gets an iterator for moving out the `BTreeSet`'s contents.
1240+
/// Gets an iterator for moving out the `BTreeSet`'s contents in ascending order.
12411241
///
12421242
/// # Examples
12431243
///

library/core/src/iter/traits/marker.rs

+1
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ pub unsafe trait TrustedFused {}
2828
#[rustc_unsafe_specialization_marker]
2929
// FIXME: this should be a #[marker] and have another blanket impl for T: TrustedFused
3030
// but that ICEs iter::Fuse specializations.
31+
#[cfg_attr(not(bootstrap), lang = "fused_iterator")]
3132
pub trait FusedIterator: Iterator {}
3233

3334
#[stable(feature = "fused", since = "1.26.0")]

library/std/src/os/freebsd/net.rs

+26
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
#![unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
44

5+
use crate::ffi::CStr;
56
use crate::io;
67
use crate::os::unix::net;
78
use crate::sealed::Sealed;
@@ -40,6 +41,15 @@ pub trait UnixSocketExt: Sealed {
4041
/// ```
4142
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
4243
fn set_local_creds_persistent(&self, local_creds_persistent: bool) -> io::Result<()>;
44+
45+
/// Get a filter name if one had been set previously on the socket.
46+
#[unstable(feature = "acceptfilter", issue = "121891")]
47+
fn acceptfilter(&self) -> io::Result<&CStr>;
48+
49+
/// Set or disable a filter on the socket to filter incoming connections
50+
/// to defer it before accept(2)
51+
#[unstable(feature = "acceptfilter", issue = "121891")]
52+
fn set_acceptfilter(&self, name: &CStr) -> io::Result<()>;
4353
}
4454

4555
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
@@ -51,6 +61,14 @@ impl UnixSocketExt for net::UnixDatagram {
5161
fn set_local_creds_persistent(&self, local_creds_persistent: bool) -> io::Result<()> {
5262
self.as_inner().set_local_creds_persistent(local_creds_persistent)
5363
}
64+
65+
fn acceptfilter(&self) -> io::Result<&CStr> {
66+
self.as_inner().acceptfilter()
67+
}
68+
69+
fn set_acceptfilter(&self, name: &CStr) -> io::Result<()> {
70+
self.as_inner().set_acceptfilter(name)
71+
}
5472
}
5573

5674
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
@@ -62,4 +80,12 @@ impl UnixSocketExt for net::UnixStream {
6280
fn set_local_creds_persistent(&self, local_creds_persistent: bool) -> io::Result<()> {
6381
self.as_inner().set_local_creds_persistent(local_creds_persistent)
6482
}
83+
84+
fn acceptfilter(&self) -> io::Result<&CStr> {
85+
self.as_inner().acceptfilter()
86+
}
87+
88+
fn set_acceptfilter(&self, name: &CStr) -> io::Result<()> {
89+
self.as_inner().set_acceptfilter(name)
90+
}
6591
}

library/std/src/os/netbsd/net.rs

+26
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
33
#![unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
44

5+
use crate::ffi::CStr;
56
use crate::io;
67
use crate::os::unix::net;
78
use crate::sealed::Sealed;
@@ -40,6 +41,15 @@ pub trait UnixSocketExt: Sealed {
4041
/// ```
4142
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
4243
fn set_local_creds(&self, local_creds: bool) -> io::Result<()>;
44+
45+
/// Get a filter name if one had been set previously on the socket.
46+
#[unstable(feature = "acceptfilter", issue = "121891")]
47+
fn acceptfilter(&self) -> io::Result<&CStr>;
48+
49+
/// Set or disable a filter on the socket to filter incoming connections
50+
/// to defer it before accept(2)
51+
#[unstable(feature = "acceptfilter", issue = "121891")]
52+
fn set_acceptfilter(&self, name: &CStr) -> io::Result<()>;
4353
}
4454

4555
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
@@ -51,6 +61,14 @@ impl UnixSocketExt for net::UnixDatagram {
5161
fn set_local_creds(&self, local_creds: bool) -> io::Result<()> {
5262
self.as_inner().set_local_creds(local_creds)
5363
}
64+
65+
fn acceptfilter(&self) -> io::Result<&CStr> {
66+
self.as_inner().acceptfilter()
67+
}
68+
69+
fn set_acceptfilter(&self, name: &CStr) -> io::Result<()> {
70+
self.as_inner().set_acceptfilter(name)
71+
}
5472
}
5573

5674
#[unstable(feature = "unix_socket_ancillary_data", issue = "76915")]
@@ -62,4 +80,12 @@ impl UnixSocketExt for net::UnixStream {
6280
fn set_local_creds(&self, local_creds: bool) -> io::Result<()> {
6381
self.as_inner().set_local_creds(local_creds)
6482
}
83+
84+
fn acceptfilter(&self) -> io::Result<&CStr> {
85+
self.as_inner().acceptfilter()
86+
}
87+
88+
fn set_acceptfilter(&self, name: &CStr) -> io::Result<()> {
89+
self.as_inner().set_acceptfilter(name)
90+
}
6591
}

library/std/src/sys/pal/unix/net.rs

+31
Original file line numberDiff line numberDiff line change
@@ -453,6 +453,37 @@ impl Socket {
453453
Ok(raw as u32)
454454
}
455455

456+
#[cfg(any(target_os = "freebsd", target_os = "netbsd"))]
457+
pub fn set_acceptfilter(&self, name: &CStr) -> io::Result<()> {
458+
if !name.to_bytes().is_empty() {
459+
const AF_NAME_MAX: usize = 16;
460+
let mut buf = [0; AF_NAME_MAX];
461+
for (src, dst) in name.to_bytes().iter().zip(&mut buf[..AF_NAME_MAX - 1]) {
462+
*dst = *src as i8;
463+
}
464+
let mut arg: libc::accept_filter_arg = unsafe { mem::zeroed() };
465+
arg.af_name = buf;
466+
setsockopt(self, libc::SOL_SOCKET, libc::SO_ACCEPTFILTER, &mut arg)
467+
} else {
468+
setsockopt(
469+
self,
470+
libc::SOL_SOCKET,
471+
libc::SO_ACCEPTFILTER,
472+
core::ptr::null_mut() as *mut c_void,
473+
)
474+
}
475+
}
476+
477+
#[cfg(any(target_os = "freebsd", target_os = "netbsd"))]
478+
pub fn acceptfilter(&self) -> io::Result<&CStr> {
479+
let arg: libc::accept_filter_arg =
480+
getsockopt(self, libc::SOL_SOCKET, libc::SO_ACCEPTFILTER)?;
481+
let s: &[u8] =
482+
unsafe { core::slice::from_raw_parts(arg.af_name.as_ptr() as *const u8, 16) };
483+
let name = CStr::from_bytes_with_nul(s).unwrap();
484+
Ok(name)
485+
}
486+
456487
#[cfg(any(target_os = "android", target_os = "linux",))]
457488
pub fn set_passcred(&self, passcred: bool) -> io::Result<()> {
458489
setsockopt(self, libc::SOL_SOCKET, libc::SO_PASSCRED, passcred as libc::c_int)

0 commit comments

Comments
 (0)