Skip to content

Commit 3c069a0

Browse files
Change MIR building to fill in the resume place
This changes `Yield` from `as_rvalue` to `into` lowering, which could have a possible performance impact. I could imagine special-casing some resume types here to use a simpler lowering for them, but it's unclear if that makes sense at this stage.
1 parent f2c1468 commit 3c069a0

File tree

4 files changed

+40
-26
lines changed

4 files changed

+40
-26
lines changed

src/librustc_mir_build/build/expr/as_rvalue.rs

Lines changed: 2 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -230,18 +230,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
230230
block = unpack!(this.stmt_expr(block, expr, None));
231231
block.and(this.unit_rvalue())
232232
}
233-
ExprKind::Yield { value } => {
234-
let value = unpack!(block = this.as_operand(block, scope, value));
235-
let resume = this.cfg.start_new_block();
236-
let cleanup = this.generator_drop_cleanup();
237-
this.cfg.terminate(
238-
block,
239-
source_info,
240-
TerminatorKind::Yield { value: value, resume: resume, drop: cleanup },
241-
);
242-
resume.and(this.unit_rvalue())
243-
}
244-
ExprKind::Literal { .. }
233+
ExprKind::Yield { .. }
234+
| ExprKind::Literal { .. }
245235
| ExprKind::StaticRef { .. }
246236
| ExprKind::Block { .. }
247237
| ExprKind::Match { .. }

src/librustc_mir_build/build/expr/category.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ impl Category {
5050
| ExprKind::Adt { .. }
5151
| ExprKind::Borrow { .. }
5252
| ExprKind::AddressOf { .. }
53+
| ExprKind::Yield { .. }
5354
| ExprKind::Call { .. } => Some(Category::Rvalue(RvalueFunc::Into)),
5455

5556
ExprKind::Array { .. }
@@ -63,7 +64,6 @@ impl Category {
6364
| ExprKind::Repeat { .. }
6465
| ExprKind::Assign { .. }
6566
| ExprKind::AssignOp { .. }
66-
| ExprKind::Yield { .. }
6767
| ExprKind::InlineAsm { .. } => Some(Category::Rvalue(RvalueFunc::AsRvalue)),
6868

6969
ExprKind::Literal { .. } | ExprKind::StaticRef { .. } => Some(Category::Constant),

src/librustc_mir_build/build/expr/into.rs

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -365,6 +365,24 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
365365
block.unit()
366366
}
367367

368+
ExprKind::Yield { value } => {
369+
let scope = this.local_scope();
370+
let value = unpack!(block = this.as_operand(block, scope, value));
371+
let resume = this.cfg.start_new_block();
372+
let cleanup = this.generator_drop_cleanup();
373+
this.cfg.terminate(
374+
block,
375+
source_info,
376+
TerminatorKind::Yield {
377+
value,
378+
resume,
379+
resume_arg: destination.clone(),
380+
drop: cleanup,
381+
},
382+
);
383+
resume.unit()
384+
}
385+
368386
// these are the cases that are more naturally handled by some other mode
369387
ExprKind::Unary { .. }
370388
| ExprKind::Binary { .. }
@@ -376,8 +394,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
376394
| ExprKind::Tuple { .. }
377395
| ExprKind::Closure { .. }
378396
| ExprKind::Literal { .. }
379-
| ExprKind::StaticRef { .. }
380-
| ExprKind::Yield { .. } => {
397+
| ExprKind::StaticRef { .. } => {
381398
debug_assert!(match Category::of(&expr.kind).unwrap() {
382399
// should be handled above
383400
Category::Rvalue(RvalueFunc::Into) => false,

src/librustc_mir_build/build/mod.rs

Lines changed: 18 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,12 @@ fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> BodyAndCache<'_> {
6868
let fn_sig = cx.tables().liberated_fn_sigs()[id];
6969
let fn_def_id = tcx.hir().local_def_id(id);
7070

71+
let safety = match fn_sig.unsafety {
72+
hir::Unsafety::Normal => Safety::Safe,
73+
hir::Unsafety::Unsafe => Safety::FnUnsafe,
74+
};
75+
76+
let body = tcx.hir().body(body_id);
7177
let ty = tcx.type_of(fn_def_id);
7278
let mut abi = fn_sig.abi;
7379
let implicit_argument = match ty.kind {
@@ -77,22 +83,23 @@ fn mir_build(tcx: TyCtxt<'_>, def_id: DefId) -> BodyAndCache<'_> {
7783
abi = Abi::Rust;
7884
vec![ArgInfo(liberated_closure_env_ty(tcx, id, body_id), None, None, None)]
7985
}
80-
ty::Generator(..) => {
86+
ty::Generator(def_id, substs, _) => {
8187
let gen_ty = tcx.body_tables(body_id).node_type(id);
82-
vec![
83-
ArgInfo(gen_ty, None, None, None),
84-
ArgInfo(tcx.mk_unit(), None, None, None),
85-
]
88+
let resume_ty = substs.as_generator().resume_ty(def_id, tcx);
89+
90+
// The resume argument may be missing, in that case we need to provide it here.
91+
if body.params.is_empty() {
92+
vec![
93+
ArgInfo(gen_ty, None, None, None),
94+
ArgInfo(resume_ty, None, None, None),
95+
]
96+
} else {
97+
vec![ArgInfo(gen_ty, None, None, None)]
98+
}
8699
}
87100
_ => vec![],
88101
};
89102

90-
let safety = match fn_sig.unsafety {
91-
hir::Unsafety::Normal => Safety::Safe,
92-
hir::Unsafety::Unsafe => Safety::FnUnsafe,
93-
};
94-
95-
let body = tcx.hir().body(body_id);
96103
let explicit_arguments = body.params.iter().enumerate().map(|(index, arg)| {
97104
let owner_id = tcx.hir().body_owner(body_id);
98105
let opt_ty_info;

0 commit comments

Comments
 (0)