Auto merge of #116447 - oli-obk:gen_fn, r=compiler-errors
Implement `gen` blocks in the 2024 edition Coroutines tracking issue https://github.com/rust-lang/rust/issues/43122 `gen` block tracking issue https://github.com/rust-lang/rust/issues/117078 This PR implements `gen` blocks that implement `Iterator`. Most of the logic with `async` blocks is shared, and thus I renamed various types that were referring to `async` specifically. An example usage of `gen` blocks is ```rust fn foo() -> impl Iterator<Item = i32> { gen { yield 42; for i in 5..18 { if i.is_even() { continue } yield i * 2; } } } ``` The limitations (to be resolved) of the implementation are listed in the tracking issue
This commit is contained in:
commit
2cad938a81
75 changed files with 1096 additions and 148 deletions
|
@ -148,8 +148,15 @@ impl<O> AssertKind<O> {
|
|||
RemainderByZero(_) => "attempt to calculate the remainder with a divisor of zero",
|
||||
ResumedAfterReturn(CoroutineKind::Coroutine) => "coroutine resumed after completion",
|
||||
ResumedAfterReturn(CoroutineKind::Async(_)) => "`async fn` resumed after completion",
|
||||
ResumedAfterReturn(CoroutineKind::Gen(_)) => {
|
||||
"`gen fn` should just keep returning `None` after completion"
|
||||
}
|
||||
ResumedAfterPanic(CoroutineKind::Coroutine) => "coroutine resumed after panicking",
|
||||
ResumedAfterPanic(CoroutineKind::Async(_)) => "`async fn` resumed after panicking",
|
||||
ResumedAfterPanic(CoroutineKind::Gen(_)) => {
|
||||
"`gen fn` should just keep returning `None` after panicking"
|
||||
}
|
||||
|
||||
BoundsCheck { .. } | MisalignedPointerDereference { .. } => {
|
||||
bug!("Unexpected AssertKind")
|
||||
}
|
||||
|
@ -236,10 +243,15 @@ impl<O> AssertKind<O> {
|
|||
DivisionByZero(_) => middle_assert_divide_by_zero,
|
||||
RemainderByZero(_) => middle_assert_remainder_by_zero,
|
||||
ResumedAfterReturn(CoroutineKind::Async(_)) => middle_assert_async_resume_after_return,
|
||||
ResumedAfterReturn(CoroutineKind::Gen(_)) => {
|
||||
bug!("gen blocks can be resumed after they return and will keep returning `None`")
|
||||
}
|
||||
ResumedAfterReturn(CoroutineKind::Coroutine) => {
|
||||
middle_assert_coroutine_resume_after_return
|
||||
}
|
||||
ResumedAfterPanic(CoroutineKind::Async(_)) => middle_assert_async_resume_after_panic,
|
||||
// FIXME(gen_blocks): custom error message for `gen` blocks
|
||||
ResumedAfterPanic(CoroutineKind::Gen(_)) => middle_assert_async_resume_after_panic,
|
||||
ResumedAfterPanic(CoroutineKind::Coroutine) => {
|
||||
middle_assert_coroutine_resume_after_panic
|
||||
}
|
||||
|
|
|
@ -144,6 +144,10 @@ pub enum SelectionCandidate<'tcx> {
|
|||
/// generated for an async construct.
|
||||
FutureCandidate,
|
||||
|
||||
/// Implementation of an `Iterator` trait by one of the generator types
|
||||
/// generated for a gen construct.
|
||||
IteratorCandidate,
|
||||
|
||||
/// Implementation of a `Fn`-family trait by one of the anonymous
|
||||
/// types generated for a fn pointer type (e.g., `fn(int) -> int`)
|
||||
FnPointerCandidate {
|
||||
|
|
|
@ -782,6 +782,17 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
matches!(self.coroutine_kind(def_id), Some(hir::CoroutineKind::Async(_)))
|
||||
}
|
||||
|
||||
/// Returns `true` if the node pointed to by `def_id` is a general coroutine that implements `Coroutine`.
|
||||
/// This means it is neither an `async` or `gen` construct.
|
||||
pub fn is_general_coroutine(self, def_id: DefId) -> bool {
|
||||
matches!(self.coroutine_kind(def_id), Some(hir::CoroutineKind::Coroutine))
|
||||
}
|
||||
|
||||
/// Returns `true` if the node pointed to by `def_id` is a coroutine for a gen construct.
|
||||
pub fn coroutine_is_gen(self, def_id: DefId) -> bool {
|
||||
matches!(self.coroutine_kind(def_id), Some(hir::CoroutineKind::Gen(_)))
|
||||
}
|
||||
|
||||
pub fn stability(self) -> &'tcx stability::Index {
|
||||
self.stability_index(())
|
||||
}
|
||||
|
|
|
@ -749,6 +749,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
DefKind::Coroutine => match self.coroutine_kind(def_id).unwrap() {
|
||||
rustc_hir::CoroutineKind::Async(..) => "async closure",
|
||||
rustc_hir::CoroutineKind::Coroutine => "coroutine",
|
||||
rustc_hir::CoroutineKind::Gen(..) => "gen closure",
|
||||
},
|
||||
_ => def_kind.descr(def_id),
|
||||
}
|
||||
|
@ -766,6 +767,7 @@ impl<'tcx> TyCtxt<'tcx> {
|
|||
DefKind::Coroutine => match self.coroutine_kind(def_id).unwrap() {
|
||||
rustc_hir::CoroutineKind::Async(..) => "an",
|
||||
rustc_hir::CoroutineKind::Coroutine => "a",
|
||||
rustc_hir::CoroutineKind::Gen(..) => "a",
|
||||
},
|
||||
_ => def_kind.article(),
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue