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:
@@ -118,6 +118,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
self.assemble_future_candidates(obligation, &mut candidates);
|
||||
} else if lang_items.iterator_trait() == Some(def_id) {
|
||||
self.assemble_iterator_candidates(obligation, &mut candidates);
|
||||
} else if lang_items.fused_iterator_trait() == Some(def_id) {
|
||||
self.assemble_fused_iterator_candidates(obligation, &mut candidates);
|
||||
} else if lang_items.async_iterator_trait() == Some(def_id) {
|
||||
self.assemble_async_iterator_candidates(obligation, &mut candidates);
|
||||
} else if lang_items.async_fn_kind_helper() == Some(def_id) {
|
||||
@@ -302,14 +304,31 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
candidates: &mut SelectionCandidateSet<'tcx>,
|
||||
) {
|
||||
let self_ty = obligation.self_ty().skip_binder();
|
||||
if let ty::Coroutine(did, ..) = self_ty.kind() {
|
||||
// gen constructs get lowered to a special kind of coroutine that
|
||||
// should directly `impl Iterator`.
|
||||
if self.tcx().coroutine_is_gen(*did) {
|
||||
debug!(?self_ty, ?obligation, "assemble_iterator_candidates",);
|
||||
// gen constructs get lowered to a special kind of coroutine that
|
||||
// should directly `impl Iterator`.
|
||||
if let ty::Coroutine(did, ..) = self_ty.kind()
|
||||
&& self.tcx().coroutine_is_gen(*did)
|
||||
{
|
||||
debug!(?self_ty, ?obligation, "assemble_iterator_candidates",);
|
||||
|
||||
candidates.vec.push(IteratorCandidate);
|
||||
}
|
||||
candidates.vec.push(IteratorCandidate);
|
||||
}
|
||||
}
|
||||
|
||||
fn assemble_fused_iterator_candidates(
|
||||
&mut self,
|
||||
obligation: &PolyTraitObligation<'tcx>,
|
||||
candidates: &mut SelectionCandidateSet<'tcx>,
|
||||
) {
|
||||
let self_ty = obligation.self_ty().skip_binder();
|
||||
// gen constructs get lowered to a special kind of coroutine that
|
||||
// should directly `impl FusedIterator`.
|
||||
if let ty::Coroutine(did, ..) = self_ty.kind()
|
||||
&& self.tcx().coroutine_is_gen(*did)
|
||||
{
|
||||
debug!(?self_ty, ?obligation, "assemble_fused_iterator_candidates",);
|
||||
|
||||
candidates.vec.push(BuiltinCandidate { has_nested: false });
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -267,6 +267,8 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
self.copy_clone_conditions(obligation)
|
||||
} else if Some(trait_def) == lang_items.clone_trait() {
|
||||
self.copy_clone_conditions(obligation)
|
||||
} else if Some(trait_def) == lang_items.fused_iterator_trait() {
|
||||
self.fused_iterator_conditions(obligation)
|
||||
} else {
|
||||
bug!("unexpected builtin trait {:?}", trait_def)
|
||||
};
|
||||
|
||||
@@ -2259,6 +2259,20 @@ impl<'tcx> SelectionContext<'_, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
fn fused_iterator_conditions(
|
||||
&mut self,
|
||||
obligation: &PolyTraitObligation<'tcx>,
|
||||
) -> BuiltinImplConditions<'tcx> {
|
||||
let self_ty = self.infcx.shallow_resolve(obligation.self_ty().skip_binder());
|
||||
if let ty::Coroutine(did, ..) = *self_ty.kind()
|
||||
&& self.tcx().coroutine_is_gen(did)
|
||||
{
|
||||
BuiltinImplConditions::Where(ty::Binder::dummy(Vec::new()))
|
||||
} else {
|
||||
BuiltinImplConditions::None
|
||||
}
|
||||
}
|
||||
|
||||
/// For default impls, we need to break apart a type into its
|
||||
/// "constituent types" -- meaning, the types that it contains.
|
||||
///
|
||||
|
||||
Reference in New Issue
Block a user