Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.

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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 2 additions & 0 deletions
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

Lines changed: 9 additions & 0 deletions
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

Lines changed: 7 additions & 0 deletions
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

Lines changed: 22 additions & 0 deletions
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

Lines changed: 26 additions & 7 deletions
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

Lines changed: 2 additions & 0 deletions
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

Lines changed: 14 additions & 0 deletions
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

Lines changed: 3 additions & 2 deletions
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

Lines changed: 3 additions & 3 deletions
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
///

0 commit comments

Comments
 (0)