Skip to content

Commit 1442308

Browse files
committed
Add hir::GeneratorKind::Gen
1 parent a61cf67 commit 1442308

File tree

12 files changed

+99
-22
lines changed

12 files changed

+99
-22
lines changed

compiler/rustc_ast_lowering/src/expr.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -712,7 +712,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
712712
let full_span = expr.span.to(await_kw_span);
713713
match self.coroutine_kind {
714714
Some(hir::CoroutineKind::Async(_)) => {}
715-
Some(hir::CoroutineKind::Coroutine) | None => {
715+
Some(hir::CoroutineKind::Coroutine) | Some(hir::CoroutineKind::Gen(_)) | None => {
716716
self.tcx.sess.emit_err(AwaitOnlyInAsyncFnAndBlocks {
717717
await_kw_span,
718718
item_span: self.current_item,
@@ -936,8 +936,8 @@ impl<'hir> LoweringContext<'_, 'hir> {
936936
}
937937
Some(movability)
938938
}
939-
Some(hir::CoroutineKind::Async(_)) => {
940-
panic!("non-`async` closure body turned `async` during lowering");
939+
Some(hir::CoroutineKind::Gen(_)) | Some(hir::CoroutineKind::Async(_)) => {
940+
panic!("non-`async`/`gen` closure body turned `async`/`gen` during lowering");
941941
}
942942
None => {
943943
if movability == Movability::Static {
@@ -1446,6 +1446,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
14461446
fn lower_expr_yield(&mut self, span: Span, opt_expr: Option<&Expr>) -> hir::ExprKind<'hir> {
14471447
match self.coroutine_kind {
14481448
Some(hir::CoroutineKind::Coroutine) => {}
1449+
Some(hir::CoroutineKind::Gen(_)) => {}
14491450
Some(hir::CoroutineKind::Async(_)) => {
14501451
self.tcx.sess.emit_err(AsyncCoroutinesNotSupported { span });
14511452
}

compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2505,6 +2505,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
25052505
};
25062506
let kind = match use_span.coroutine_kind() {
25072507
Some(coroutine_kind) => match coroutine_kind {
2508+
CoroutineKind::Gen(kind) => match kind {
2509+
CoroutineSource::Block => "gen block",
2510+
CoroutineSource::Closure => "gen closure",
2511+
_ => bug!("gen block/closure expected, but gen function found."),
2512+
},
25082513
CoroutineKind::Async(async_kind) => match async_kind {
25092514
CoroutineSource::Block => "async block",
25102515
CoroutineSource::Closure => "async closure",

compiler/rustc_borrowck/src/diagnostics/region_name.rs

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -698,6 +698,20 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
698698
" of async function"
699699
}
700700
},
701+
Some(hir::CoroutineKind::Gen(gen)) => match gen {
702+
hir::CoroutineSource::Block => " of gen block",
703+
hir::CoroutineSource::Closure => " of gen closure",
704+
hir::CoroutineSource::Fn => {
705+
let parent_item =
706+
hir.get_by_def_id(hir.get_parent_item(mir_hir_id).def_id);
707+
let output = &parent_item
708+
.fn_decl()
709+
.expect("coroutine lowered from gen fn should be in fn")
710+
.output;
711+
span = output.span();
712+
" of gen function"
713+
}
714+
},
701715
Some(hir::CoroutineKind::Coroutine) => " of coroutine",
702716
None => " of closure",
703717
};

compiler/rustc_codegen_ssa/src/debuginfo/type_names.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -560,6 +560,9 @@ pub fn push_item_name(tcx: TyCtxt<'_>, def_id: DefId, qualified: bool, output: &
560560

561561
fn coroutine_kind_label(coroutine_kind: Option<CoroutineKind>) -> &'static str {
562562
match coroutine_kind {
563+
Some(CoroutineKind::Gen(CoroutineSource::Block)) => "gen_block",
564+
Some(CoroutineKind::Gen(CoroutineSource::Closure)) => "gen_closure",
565+
Some(CoroutineKind::Gen(CoroutineSource::Fn)) => "gen_fn",
563566
Some(CoroutineKind::Async(CoroutineSource::Block)) => "async_block",
564567
Some(CoroutineKind::Async(CoroutineSource::Closure)) => "async_closure",
565568
Some(CoroutineKind::Async(CoroutineSource::Fn)) => "async_fn",

compiler/rustc_hir/src/hir.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1513,6 +1513,9 @@ pub enum CoroutineKind {
15131513
/// An explicit `async` block or the body of an async function.
15141514
Async(CoroutineSource),
15151515

1516+
/// An explicit `gen` block or the body of a `gen` function.
1517+
Gen(CoroutineSource),
1518+
15161519
/// A coroutine literal created via a `yield` inside a closure.
15171520
Coroutine,
15181521
}
@@ -1529,6 +1532,14 @@ impl fmt::Display for CoroutineKind {
15291532
k.fmt(f)
15301533
}
15311534
CoroutineKind::Coroutine => f.write_str("coroutine"),
1535+
CoroutineKind::Gen(k) => {
1536+
if f.alternate() {
1537+
f.write_str("`gen` ")?;
1538+
} else {
1539+
f.write_str("gen ")?
1540+
}
1541+
k.fmt(f)
1542+
}
15321543
}
15331544
}
15341545
}
@@ -2242,6 +2253,7 @@ impl From<CoroutineKind> for YieldSource {
22422253
// Guess based on the kind of the current coroutine.
22432254
CoroutineKind::Coroutine => Self::Yield,
22442255
CoroutineKind::Async(_) => Self::Await { expr: None },
2256+
CoroutineKind::Gen(_) => Self::Yield,
22452257
}
22462258
}
22472259
}

compiler/rustc_hir_typeck/src/check.rs

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -58,15 +58,16 @@ pub(super) fn check_fn<'a, 'tcx>(
5858
if let Some(kind) = body.coroutine_kind
5959
&& can_be_coroutine.is_some()
6060
{
61-
let yield_ty = if kind == hir::CoroutineKind::Coroutine {
62-
let yield_ty = fcx.next_ty_var(TypeVariableOrigin {
63-
kind: TypeVariableOriginKind::TypeInference,
64-
span,
65-
});
66-
fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType);
67-
yield_ty
68-
} else {
69-
Ty::new_unit(tcx)
61+
let yield_ty = match kind {
62+
hir::CoroutineKind::Gen(..) | hir::CoroutineKind::Coroutine => {
63+
let yield_ty = fcx.next_ty_var(TypeVariableOrigin {
64+
kind: TypeVariableOriginKind::TypeInference,
65+
span,
66+
});
67+
fcx.require_type_is_sized(yield_ty, span, traits::SizedYieldType);
68+
yield_ty
69+
}
70+
hir::CoroutineKind::Async(..) => Ty::new_unit(tcx),
7071
};
7172

7273
// Resume type defaults to `()` if the coroutine has no argument.

compiler/rustc_middle/src/mir/terminator.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,8 +148,14 @@ impl<O> AssertKind<O> {
148148
RemainderByZero(_) => "attempt to calculate the remainder with a divisor of zero",
149149
ResumedAfterReturn(CoroutineKind::Coroutine) => "coroutine resumed after completion",
150150
ResumedAfterReturn(CoroutineKind::Async(_)) => "`async fn` resumed after completion",
151+
ResumedAfterReturn(CoroutineKind::Gen(_)) => {
152+
bug!("`gen fn` should just keep returning `None` after the first time")
153+
}
151154
ResumedAfterPanic(CoroutineKind::Coroutine) => "coroutine resumed after panicking",
152155
ResumedAfterPanic(CoroutineKind::Async(_)) => "`async fn` resumed after panicking",
156+
ResumedAfterPanic(CoroutineKind::Gen(_)) => {
157+
bug!("`gen fn` should just keep returning `None` after panicking")
158+
}
153159
BoundsCheck { .. } | MisalignedPointerDereference { .. } => {
154160
bug!("Unexpected AssertKind")
155161
}
@@ -236,10 +242,14 @@ impl<O> AssertKind<O> {
236242
DivisionByZero(_) => middle_assert_divide_by_zero,
237243
RemainderByZero(_) => middle_assert_remainder_by_zero,
238244
ResumedAfterReturn(CoroutineKind::Async(_)) => middle_assert_async_resume_after_return,
245+
// FIXME(gen_blocks): custom error message for `gen` blocks
246+
ResumedAfterReturn(CoroutineKind::Gen(_)) => middle_assert_async_resume_after_return,
239247
ResumedAfterReturn(CoroutineKind::Coroutine) => {
240248
middle_assert_coroutine_resume_after_return
241249
}
242250
ResumedAfterPanic(CoroutineKind::Async(_)) => middle_assert_async_resume_after_panic,
251+
// FIXME(gen_blocks): custom error message for `gen` blocks
252+
ResumedAfterPanic(CoroutineKind::Gen(_)) => middle_assert_async_resume_after_panic,
243253
ResumedAfterPanic(CoroutineKind::Coroutine) => {
244254
middle_assert_coroutine_resume_after_panic
245255
}

compiler/rustc_middle/src/ty/util.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -749,6 +749,7 @@ impl<'tcx> TyCtxt<'tcx> {
749749
DefKind::Coroutine => match self.coroutine_kind(def_id).unwrap() {
750750
rustc_hir::CoroutineKind::Async(..) => "async closure",
751751
rustc_hir::CoroutineKind::Coroutine => "coroutine",
752+
rustc_hir::CoroutineKind::Gen(..) => "gen closure",
752753
},
753754
_ => def_kind.descr(def_id),
754755
}
@@ -766,6 +767,7 @@ impl<'tcx> TyCtxt<'tcx> {
766767
DefKind::Coroutine => match self.coroutine_kind(def_id).unwrap() {
767768
rustc_hir::CoroutineKind::Async(..) => "an",
768769
rustc_hir::CoroutineKind::Coroutine => "a",
770+
rustc_hir::CoroutineKind::Gen(..) => "a",
769771
},
770772
_ => def_kind.article(),
771773
}

compiler/rustc_smir/src/rustc_smir/mod.rs

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -880,18 +880,28 @@ impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> {
880880
}
881881
}
882882

883+
impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineSource {
884+
type T = stable_mir::mir::CoroutineSource;
885+
fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
886+
use rustc_hir::CoroutineSource;
887+
match self {
888+
CoroutineSource::Block => stable_mir::mir::CoroutineSource::Block,
889+
CoroutineSource::Closure => stable_mir::mir::CoroutineSource::Closure,
890+
CoroutineSource::Fn => stable_mir::mir::CoroutineSource::Fn,
891+
}
892+
}
893+
}
894+
883895
impl<'tcx> Stable<'tcx> for rustc_hir::CoroutineKind {
884896
type T = stable_mir::mir::CoroutineKind;
885-
fn stable(&self, _: &mut Tables<'tcx>) -> Self::T {
886-
use rustc_hir::{CoroutineKind, CoroutineSource};
897+
fn stable(&self, tables: &mut Tables<'tcx>) -> Self::T {
898+
use rustc_hir::CoroutineKind;
887899
match self {
888-
CoroutineKind::Async(async_gen) => {
889-
let async_gen = match async_gen {
890-
CoroutineSource::Block => stable_mir::mir::CoroutineSource::Block,
891-
CoroutineSource::Closure => stable_mir::mir::CoroutineSource::Closure,
892-
CoroutineSource::Fn => stable_mir::mir::CoroutineSource::Fn,
893-
};
894-
stable_mir::mir::CoroutineKind::Async(async_gen)
900+
CoroutineKind::Async(source) => {
901+
stable_mir::mir::CoroutineKind::Async(source.stable(tables))
902+
}
903+
CoroutineKind::Gen(source) => {
904+
stable_mir::mir::CoroutineKind::Gen(source.stable(tables))
895905
}
896906
CoroutineKind::Coroutine => stable_mir::mir::CoroutineKind::Coroutine,
897907
}

compiler/rustc_trait_selection/src/traits/error_reporting/suggestions.rs

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2425,6 +2425,21 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
24252425
CoroutineKind::Async(CoroutineSource::Closure) => {
24262426
format!("future created by async closure is not {trait_name}")
24272427
}
2428+
CoroutineKind::Gen(CoroutineSource::Fn) => self
2429+
.tcx
2430+
.parent(coroutine_did)
2431+
.as_local()
2432+
.map(|parent_did| hir.local_def_id_to_hir_id(parent_did))
2433+
.and_then(|parent_hir_id| hir.opt_name(parent_hir_id))
2434+
.map(|name| {
2435+
format!("iterator returned by `{name}` is not {trait_name}")
2436+
})?,
2437+
CoroutineKind::Gen(CoroutineSource::Block) => {
2438+
format!("iterator created by gen block is not {trait_name}")
2439+
}
2440+
CoroutineKind::Gen(CoroutineSource::Closure) => {
2441+
format!("iterator created by gen closure is not {trait_name}")
2442+
}
24282443
})
24292444
})
24302445
.unwrap_or_else(|| format!("{future_or_coroutine} is not {trait_name}"));
@@ -2905,7 +2920,7 @@ impl<'tcx> TypeErrCtxtExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
29052920
}
29062921
ObligationCauseCode::SizedCoroutineInterior(coroutine_def_id) => {
29072922
let what = match self.tcx.coroutine_kind(coroutine_def_id) {
2908-
None | Some(hir::CoroutineKind::Coroutine) => "yield",
2923+
None | Some(hir::CoroutineKind::Coroutine) | Some(hir::CoroutineKind::Gen(_)) => "yield",
29092924
Some(hir::CoroutineKind::Async(..)) => "await",
29102925
};
29112926
err.note(format!(

compiler/rustc_trait_selection/src/traits/error_reporting/type_err_ctxt_ext.rs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1614,6 +1614,9 @@ impl<'tcx> InferCtxtPrivExt<'tcx> for TypeErrCtxt<'_, 'tcx> {
16141614
hir::CoroutineKind::Async(hir::CoroutineSource::Block) => "an async block",
16151615
hir::CoroutineKind::Async(hir::CoroutineSource::Fn) => "an async function",
16161616
hir::CoroutineKind::Async(hir::CoroutineSource::Closure) => "an async closure",
1617+
hir::CoroutineKind::Gen(hir::CoroutineSource::Block) => "a gen block",
1618+
hir::CoroutineKind::Gen(hir::CoroutineSource::Fn) => "a gen function",
1619+
hir::CoroutineKind::Gen(hir::CoroutineSource::Closure) => "a gen closure",
16171620
})
16181621
}
16191622

compiler/stable_mir/src/mir/body.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,7 @@ pub enum UnOp {
137137
pub enum CoroutineKind {
138138
Async(CoroutineSource),
139139
Coroutine,
140+
Gen(CoroutineSource),
140141
}
141142

142143
#[derive(Clone, Debug)]

0 commit comments

Comments
 (0)