Add iter macro
This adds an `iter!` macro that can be used to create movable generators. This also adds a yield_expr feature so the `yield` keyword can be used within iter! macro bodies. This was needed because several unstable features each need `yield` expressions, so this allows us to stabilize them separately from any individual feature. Co-authored-by: Oli Scherer <github35764891676564198441@oli-obk.de> Co-authored-by: Jieyou Xu <jieyouxu@outlook.com> Co-authored-by: Travis Cross <tc@traviscross.com>
This commit is contained in:
@@ -11,7 +11,7 @@ use std::ops::ControlFlow;
|
||||
use hir::LangItem;
|
||||
use hir::def_id::DefId;
|
||||
use rustc_data_structures::fx::{FxHashSet, FxIndexSet};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::{self as hir, CoroutineDesugaring, CoroutineKind};
|
||||
use rustc_infer::traits::{Obligation, PolyTraitObligation, SelectionError};
|
||||
use rustc_middle::ty::fast_reject::DeepRejectCtxt;
|
||||
use rustc_middle::ty::{self, Ty, TypeVisitableExt, TypingMode, elaborate};
|
||||
@@ -438,6 +438,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
#[instrument(level = "debug", skip(self, candidates))]
|
||||
fn assemble_async_closure_candidates(
|
||||
&mut self,
|
||||
obligation: &PolyTraitObligation<'tcx>,
|
||||
@@ -446,15 +447,30 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
|
||||
let goal_kind =
|
||||
self.tcx().async_fn_trait_kind_from_def_id(obligation.predicate.def_id()).unwrap();
|
||||
|
||||
debug!("self_ty = {:?}", obligation.self_ty().skip_binder().kind());
|
||||
match *obligation.self_ty().skip_binder().kind() {
|
||||
ty::CoroutineClosure(_, args) => {
|
||||
ty::CoroutineClosure(def_id, args) => {
|
||||
if let Some(closure_kind) =
|
||||
args.as_coroutine_closure().kind_ty().to_opt_closure_kind()
|
||||
&& !closure_kind.extends(goal_kind)
|
||||
{
|
||||
return;
|
||||
}
|
||||
candidates.vec.push(AsyncClosureCandidate);
|
||||
|
||||
// Make sure this is actually an async closure.
|
||||
let Some(coroutine_kind) =
|
||||
self.tcx().coroutine_kind(self.tcx().coroutine_for_closure(def_id))
|
||||
else {
|
||||
bug!("coroutine with no kind");
|
||||
};
|
||||
|
||||
debug!(?coroutine_kind);
|
||||
match coroutine_kind {
|
||||
CoroutineKind::Desugared(CoroutineDesugaring::Async, _) => {
|
||||
candidates.vec.push(AsyncClosureCandidate);
|
||||
}
|
||||
_ => (),
|
||||
}
|
||||
}
|
||||
// Closures and fn pointers implement `AsyncFn*` if their return types
|
||||
// implement `Future`, which is checked later.
|
||||
|
||||
Reference in New Issue
Block a user