Rollup merge of #122829 - ShoyuVanilla:gen-block-impl-fused-iter, r=compiler-errors

Implement `FusedIterator` for `gen` block

cc #117078
This commit is contained in:
Matthias Krüger
2024-03-22 01:07:31 +01:00
committed by GitHub
10 changed files with 105 additions and 7 deletions

View File

@@ -215,6 +215,13 @@ pub(super) trait GoalKind<'tcx>:
goal: Goal<'tcx, Self>,
) -> QueryResult<'tcx>;
/// A coroutine (that comes from a `gen` desugaring) is known to implement
/// `FusedIterator`
fn consider_builtin_fused_iterator_candidate(
ecx: &mut EvalCtxt<'_, 'tcx>,
goal: Goal<'tcx, Self>,
) -> QueryResult<'tcx>;
fn consider_builtin_async_iterator_candidate(
ecx: &mut EvalCtxt<'_, 'tcx>,
goal: Goal<'tcx, Self>,
@@ -497,6 +504,8 @@ impl<'tcx> EvalCtxt<'_, 'tcx> {
G::consider_builtin_future_candidate(self, goal)
} else if lang_items.iterator_trait() == Some(trait_def_id) {
G::consider_builtin_iterator_candidate(self, goal)
} else if lang_items.fused_iterator_trait() == Some(trait_def_id) {
G::consider_builtin_fused_iterator_candidate(self, goal)
} else if lang_items.async_iterator_trait() == Some(trait_def_id) {
G::consider_builtin_async_iterator_candidate(self, goal)
} else if lang_items.coroutine_trait() == Some(trait_def_id) {

View File

@@ -647,6 +647,13 @@ impl<'tcx> assembly::GoalKind<'tcx> for NormalizesTo<'tcx> {
)
}
fn consider_builtin_fused_iterator_candidate(
_ecx: &mut EvalCtxt<'_, 'tcx>,
goal: Goal<'tcx, Self>,
) -> QueryResult<'tcx> {
bug!("`FusedIterator` does not have an associated type: {:?}", goal);
}
fn consider_builtin_async_iterator_candidate(
ecx: &mut EvalCtxt<'_, 'tcx>,
goal: Goal<'tcx, Self>,

View File

@@ -456,6 +456,28 @@ impl<'tcx> assembly::GoalKind<'tcx> for TraitPredicate<'tcx> {
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
}
fn consider_builtin_fused_iterator_candidate(
ecx: &mut EvalCtxt<'_, 'tcx>,
goal: Goal<'tcx, Self>,
) -> QueryResult<'tcx> {
if goal.predicate.polarity != ty::ImplPolarity::Positive {
return Err(NoSolution);
}
let ty::Coroutine(def_id, _) = *goal.predicate.self_ty().kind() else {
return Err(NoSolution);
};
// Coroutines are not iterators unless they come from `gen` desugaring
let tcx = ecx.tcx();
if !tcx.coroutine_is_gen(def_id) {
return Err(NoSolution);
}
// Gen coroutines unconditionally implement `FusedIterator`
ecx.evaluate_added_goals_and_make_canonical_response(Certainty::Yes)
}
fn consider_builtin_async_iterator_candidate(
ecx: &mut EvalCtxt<'_, 'tcx>,
goal: Goal<'tcx, Self>,