diff options
| author | bors <bors@rust-lang.org> | 2023-10-20 21:20:57 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2023-10-20 21:20:57 +0000 |
| commit | 249624b5043013d18c00f0401ca431c1a6baa8cd (patch) | |
| tree | 1c081d1e77b79edf9043511fc7ef88ccdf0e9d67 /compiler/rustc_mir_transform/src | |
| parent | 96027d945b9d8cae622a2fa4e70d8040be2964f3 (diff) | |
| parent | 258af95a60d7ef05cb9531e675b4d05494676f85 (diff) | |
| download | rust-249624b5043013d18c00f0401ca431c1a6baa8cd.tar.gz rust-249624b5043013d18c00f0401ca431c1a6baa8cd.zip | |
Auto merge of #116958 - oli-obk:coro, r=pnkfelix
rename Generator to Coroutine implements https://github.com/rust-lang/compiler-team/issues/682 While I did an automated replacement, I went through all changes manually to avoid renaming things like "id generators", "code generator", ... I renamed files where that was necessary due to the contents referring to the crate name itself (mir opt, codegen or debuginfo tests), or required by tidy (feature gate docs) * [x] rename various remaining abbreviated references to generators. * [x] rename files * [x] rename folders * [x] add renamed feature: `generators`, ... r? `@ghost`
Diffstat (limited to 'compiler/rustc_mir_transform/src')
18 files changed, 215 insertions, 215 deletions
diff --git a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs index 74243f1f8f2..2b3d423ea61 100644 --- a/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs +++ b/compiler/rustc_mir_transform/src/abort_unwinding_calls.rs @@ -40,7 +40,7 @@ impl<'tcx> MirPass<'tcx> for AbortUnwindingCalls { let body_abi = match body_ty.kind() { ty::FnDef(..) => body_ty.fn_sig(tcx).abi(), ty::Closure(..) => Abi::RustCall, - ty::Generator(..) => Abi::Rust, + ty::Coroutine(..) => Abi::Rust, _ => span_bug!(body.span, "unexpected body ty: {:?}", body_ty), }; let body_can_unwind = layout::fn_can_unwind(tcx, Some(def_id), body_abi); diff --git a/compiler/rustc_mir_transform/src/check_unsafety.rs b/compiler/rustc_mir_transform/src/check_unsafety.rs index 7e4731f5d8a..8872f9a97d7 100644 --- a/compiler/rustc_mir_transform/src/check_unsafety.rs +++ b/compiler/rustc_mir_transform/src/check_unsafety.rs @@ -56,7 +56,7 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> { | TerminatorKind::Drop { .. } | TerminatorKind::Yield { .. } | TerminatorKind::Assert { .. } - | TerminatorKind::GeneratorDrop + | TerminatorKind::CoroutineDrop | TerminatorKind::UnwindResume | TerminatorKind::UnwindTerminate(_) | TerminatorKind::Return @@ -128,7 +128,7 @@ impl<'tcx> Visitor<'tcx> for UnsafetyChecker<'_, 'tcx> { ), } } - &AggregateKind::Closure(def_id, _) | &AggregateKind::Generator(def_id, _, _) => { + &AggregateKind::Closure(def_id, _) | &AggregateKind::Coroutine(def_id, _, _) => { let def_id = def_id.expect_local(); let UnsafetyCheckResult { violations, used_unsafe_blocks, .. } = self.tcx.unsafety_check_result(def_id); diff --git a/compiler/rustc_mir_transform/src/const_prop.rs b/compiler/rustc_mir_transform/src/const_prop.rs index 3450a0f3686..53c0d0dea29 100644 --- a/compiler/rustc_mir_transform/src/const_prop.rs +++ b/compiler/rustc_mir_transform/src/const_prop.rs @@ -82,11 +82,11 @@ impl<'tcx> MirPass<'tcx> for ConstProp { return; } - // FIXME(welseywiser) const prop doesn't work on generators because of query cycles + // FIXME(welseywiser) const prop doesn't work on coroutines because of query cycles // computing their layout. - let is_generator = def_kind == DefKind::Generator; - if is_generator { - trace!("ConstProp skipped for generator {:?}", def_id); + let is_coroutine = def_kind == DefKind::Coroutine; + if is_coroutine { + trace!("ConstProp skipped for coroutine {:?}", def_id); return; } @@ -512,7 +512,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> { fn replace_with_const(&mut self, place: Place<'tcx>) -> Option<Const<'tcx>> { // This will return None if the above `const_prop` invocation only "wrote" a - // type whose creation requires no write. E.g. a generator whose initial state + // type whose creation requires no write. E.g. a coroutine whose initial state // consists solely of uninitialized memory (so it doesn't capture any locals). let value = self.get_const(place)?; if !self.tcx.consider_optimizing(|| format!("ConstantPropagation - {value:?}")) { diff --git a/compiler/rustc_mir_transform/src/const_prop_lint.rs b/compiler/rustc_mir_transform/src/const_prop_lint.rs index aad513d7355..a23ba9c4aa9 100644 --- a/compiler/rustc_mir_transform/src/const_prop_lint.rs +++ b/compiler/rustc_mir_transform/src/const_prop_lint.rs @@ -59,10 +59,10 @@ impl<'tcx> MirLint<'tcx> for ConstPropLint { return; } - // FIXME(welseywiser) const prop doesn't work on generators because of query cycles + // FIXME(welseywiser) const prop doesn't work on coroutines because of query cycles // computing their layout. - if let DefKind::Generator = def_kind { - trace!("ConstPropLint skipped for generator {:?}", def_id); + if let DefKind::Coroutine = def_kind { + trace!("ConstPropLint skipped for coroutine {:?}", def_id); return; } @@ -648,7 +648,7 @@ impl<'tcx> Visitor<'tcx> for ConstPropagator<'_, 'tcx> { | TerminatorKind::Unreachable | TerminatorKind::Drop { .. } | TerminatorKind::Yield { .. } - | TerminatorKind::GeneratorDrop + | TerminatorKind::CoroutineDrop | TerminatorKind::FalseEdge { .. } | TerminatorKind::FalseUnwind { .. } | TerminatorKind::Call { .. } diff --git a/compiler/rustc_mir_transform/src/generator.rs b/compiler/rustc_mir_transform/src/coroutine.rs index a6693519e54..fa56d59dd80 100644 --- a/compiler/rustc_mir_transform/src/generator.rs +++ b/compiler/rustc_mir_transform/src/coroutine.rs @@ -1,53 +1,53 @@ -//! This is the implementation of the pass which transforms generators into state machines. +//! This is the implementation of the pass which transforms coroutines into state machines. //! -//! MIR generation for generators creates a function which has a self argument which -//! passes by value. This argument is effectively a generator type which only contains upvars and -//! is only used for this argument inside the MIR for the generator. +//! MIR generation for coroutines creates a function which has a self argument which +//! passes by value. This argument is effectively a coroutine type which only contains upvars and +//! is only used for this argument inside the MIR for the coroutine. //! It is passed by value to enable upvars to be moved out of it. Drop elaboration runs on that //! MIR before this pass and creates drop flags for MIR locals. -//! It will also drop the generator argument (which only consists of upvars) if any of the upvars -//! are moved out of. This pass elaborates the drops of upvars / generator argument in the case +//! It will also drop the coroutine argument (which only consists of upvars) if any of the upvars +//! are moved out of. This pass elaborates the drops of upvars / coroutine argument in the case //! that none of the upvars were moved out of. This is because we cannot have any drops of this -//! generator in the MIR, since it is used to create the drop glue for the generator. We'd get +//! coroutine in the MIR, since it is used to create the drop glue for the coroutine. We'd get //! infinite recursion otherwise. //! -//! This pass creates the implementation for either the `Generator::resume` or `Future::poll` -//! function and the drop shim for the generator based on the MIR input. -//! It converts the generator argument from Self to &mut Self adding derefs in the MIR as needed. -//! It computes the final layout of the generator struct which looks like this: +//! This pass creates the implementation for either the `Coroutine::resume` or `Future::poll` +//! function and the drop shim for the coroutine based on the MIR input. +//! It converts the coroutine argument from Self to &mut Self adding derefs in the MIR as needed. +//! It computes the final layout of the coroutine struct which looks like this: //! First upvars are stored -//! It is followed by the generator state field. +//! It is followed by the coroutine state field. //! Then finally the MIR locals which are live across a suspension point are stored. //! ```ignore (illustrative) -//! struct Generator { +//! struct Coroutine { //! upvars..., //! state: u32, //! mir_locals..., //! } //! ``` //! This pass computes the meaning of the state field and the MIR locals which are live -//! across a suspension point. There are however three hardcoded generator states: -//! 0 - Generator have not been resumed yet -//! 1 - Generator has returned / is completed -//! 2 - Generator has been poisoned +//! across a suspension point. There are however three hardcoded coroutine states: +//! 0 - Coroutine have not been resumed yet +//! 1 - Coroutine has returned / is completed +//! 2 - Coroutine has been poisoned //! -//! It also rewrites `return x` and `yield y` as setting a new generator state and returning -//! `GeneratorState::Complete(x)` and `GeneratorState::Yielded(y)`, +//! It also rewrites `return x` and `yield y` as setting a new coroutine state and returning +//! `CoroutineState::Complete(x)` and `CoroutineState::Yielded(y)`, //! or `Poll::Ready(x)` and `Poll::Pending` respectively. -//! MIR locals which are live across a suspension point are moved to the generator struct -//! with references to them being updated with references to the generator struct. +//! MIR locals which are live across a suspension point are moved to the coroutine struct +//! with references to them being updated with references to the coroutine struct. //! -//! The pass creates two functions which have a switch on the generator state giving +//! The pass creates two functions which have a switch on the coroutine state giving //! the action to take. //! -//! One of them is the implementation of `Generator::resume` / `Future::poll`. -//! For generators with state 0 (unresumed) it starts the execution of the generator. -//! For generators with state 1 (returned) and state 2 (poisoned) it panics. +//! One of them is the implementation of `Coroutine::resume` / `Future::poll`. +//! For coroutines with state 0 (unresumed) it starts the execution of the coroutine. +//! For coroutines with state 1 (returned) and state 2 (poisoned) it panics. //! Otherwise it continues the execution from the last suspension point. //! -//! The other function is the drop glue for the generator. -//! For generators with state 0 (unresumed) it drops the upvars of the generator. -//! For generators with state 1 (returned) and state 2 (poisoned) it does nothing. +//! The other function is the drop glue for the coroutine. +//! For coroutines with state 0 (unresumed) it drops the upvars of the coroutine. +//! For coroutines with state 1 (returned) and state 2 (poisoned) it does nothing. //! Otherwise it drops all the values in scope at the last suspension point. use crate::abort_unwinding_calls; @@ -60,7 +60,7 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet}; use rustc_errors::pluralize; use rustc_hir as hir; use rustc_hir::lang_items::LangItem; -use rustc_hir::GeneratorKind; +use rustc_hir::CoroutineKind; use rustc_index::bit_set::{BitMatrix, BitSet, GrowableBitSet}; use rustc_index::{Idx, IndexVec}; use rustc_middle::mir::dump_mir; @@ -68,7 +68,7 @@ use rustc_middle::mir::visit::{MutVisitor, PlaceContext, Visitor}; use rustc_middle::mir::*; use rustc_middle::ty::InstanceDef; use rustc_middle::ty::{self, AdtDef, Ty, TyCtxt}; -use rustc_middle::ty::{GeneratorArgs, GenericArgsRef}; +use rustc_middle::ty::{CoroutineArgs, GenericArgsRef}; use rustc_mir_dataflow::impls::{ MaybeBorrowedLocals, MaybeLiveLocals, MaybeRequiresStorage, MaybeStorageLive, }; @@ -196,19 +196,19 @@ fn replace_base<'tcx>(place: &mut Place<'tcx>, new_base: Place<'tcx>, tcx: TyCtx const SELF_ARG: Local = Local::from_u32(1); -/// Generator has not been resumed yet. -const UNRESUMED: usize = GeneratorArgs::UNRESUMED; -/// Generator has returned / is completed. -const RETURNED: usize = GeneratorArgs::RETURNED; -/// Generator has panicked and is poisoned. -const POISONED: usize = GeneratorArgs::POISONED; +/// Coroutine has not been resumed yet. +const UNRESUMED: usize = CoroutineArgs::UNRESUMED; +/// Coroutine has returned / is completed. +const RETURNED: usize = CoroutineArgs::RETURNED; +/// Coroutine has panicked and is poisoned. +const POISONED: usize = CoroutineArgs::POISONED; -/// Number of variants to reserve in generator state. Corresponds to -/// `UNRESUMED` (beginning of a generator) and `RETURNED`/`POISONED` -/// (end of a generator) states. +/// Number of variants to reserve in coroutine state. Corresponds to +/// `UNRESUMED` (beginning of a coroutine) and `RETURNED`/`POISONED` +/// (end of a coroutine) states. const RESERVED_VARIANTS: usize = 3; -/// A `yield` point in the generator. +/// A `yield` point in the coroutine. struct SuspensionPoint<'tcx> { /// State discriminant used when suspending or resuming at this point. state: usize, @@ -216,7 +216,7 @@ struct SuspensionPoint<'tcx> { resume: BasicBlock, /// Where to move the resume argument after resumption. resume_arg: Place<'tcx>, - /// Which block to jump to if the generator is dropped in this state. + /// Which block to jump to if the coroutine is dropped in this state. drop: Option<BasicBlock>, /// Set of locals that have live storage while at this suspension point. storage_liveness: GrowableBitSet<Local>, @@ -228,10 +228,10 @@ struct TransformVisitor<'tcx> { state_adt_ref: AdtDef<'tcx>, state_args: GenericArgsRef<'tcx>, - // The type of the discriminant in the generator struct + // The type of the discriminant in the coroutine struct discr_ty: Ty<'tcx>, - // Mapping from Local to (type of local, generator struct index) + // Mapping from Local to (type of local, coroutine struct index) // FIXME(eddyb) This should use `IndexVec<Local, Option<_>>`. remap: FxHashMap<Local, (Ty<'tcx>, VariantIdx, FieldIdx)>, @@ -249,9 +249,9 @@ struct TransformVisitor<'tcx> { } impl<'tcx> TransformVisitor<'tcx> { - // Make a `GeneratorState` or `Poll` variant assignment. + // Make a `CoroutineState` or `Poll` variant assignment. // - // `core::ops::GeneratorState` only has single element tuple variants, + // `core::ops::CoroutineState` only has single element tuple variants, // so we can just write to the downcasted first field and then set the // discriminant to the appropriate variant. fn make_state( @@ -262,8 +262,8 @@ impl<'tcx> TransformVisitor<'tcx> { statements: &mut Vec<Statement<'tcx>>, ) { let idx = VariantIdx::new(match (is_return, self.is_async_kind) { - (true, false) => 1, // GeneratorState::Complete - (false, false) => 0, // GeneratorState::Yielded + (true, false) => 1, // CoroutineState::Complete + (false, false) => 0, // CoroutineState::Yielded (true, true) => 0, // Poll::Ready (false, true) => 1, // Poll::Pending }); @@ -285,7 +285,7 @@ impl<'tcx> TransformVisitor<'tcx> { return; } - // else: `Poll::Ready(x)`, `GeneratorState::Yielded(x)` or `GeneratorState::Complete(x)` + // else: `Poll::Ready(x)`, `CoroutineState::Yielded(x)` or `CoroutineState::Complete(x)` assert_eq!(self.state_adt_ref.variant(idx).fields.len(), 1); statements.push(Statement { @@ -297,7 +297,7 @@ impl<'tcx> TransformVisitor<'tcx> { }); } - // Create a Place referencing a generator struct field + // Create a Place referencing a coroutine struct field fn make_field(&self, variant_index: VariantIdx, idx: FieldIdx, ty: Ty<'tcx>) -> Place<'tcx> { let self_place = Place::from(SELF_ARG); let base = self.tcx.mk_place_downcast_unnamed(self_place, variant_index); @@ -349,7 +349,7 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> { _context: PlaceContext, _location: Location, ) { - // Replace an Local in the remap with a generator struct access + // Replace an Local in the remap with a coroutine struct access if let Some(&(ty, variant_index, idx)) = self.remap.get(&place.local) { replace_base(place, self.make_field(variant_index, idx, ty), self.tcx); } @@ -413,7 +413,7 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> { } } -fn make_generator_state_argument_indirect<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { +fn make_coroutine_state_argument_indirect<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let gen_ty = body.local_decls.raw[1].ty; let ref_gen_ty = Ty::new_ref( @@ -422,14 +422,14 @@ fn make_generator_state_argument_indirect<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Bo ty::TypeAndMut { ty: gen_ty, mutbl: Mutability::Mut }, ); - // Replace the by value generator argument + // Replace the by value coroutine argument body.local_decls.raw[1].ty = ref_gen_ty; - // Add a deref to accesses of the generator state + // Add a deref to accesses of the coroutine state DerefArgVisitor { tcx }.visit_body(body); } -fn make_generator_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { +fn make_coroutine_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let ref_gen_ty = body.local_decls.raw[1].ty; let pin_did = tcx.require_lang_item(LangItem::Pin, Some(body.span)); @@ -437,10 +437,10 @@ fn make_generator_state_argument_pinned<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body let args = tcx.mk_args(&[ref_gen_ty.into()]); let pin_ref_gen_ty = Ty::new_adt(tcx, pin_adt_ref, args); - // Replace the by ref generator argument + // Replace the by ref coroutine argument body.local_decls.raw[1].ty = pin_ref_gen_ty; - // Add the Pin field access to accesses of the generator state + // Add the Pin field access to accesses of the coroutine state PinArgVisitor { ref_gen_ty, tcx }.visit_body(body); } @@ -465,7 +465,7 @@ fn replace_local<'tcx>( new_local } -/// Transforms the `body` of the generator applying the following transforms: +/// Transforms the `body` of the coroutine applying the following transforms: /// /// - Eliminates all the `get_context` calls that async lowering created. /// - Replace all `Local` `ResumeTy` types with `&mut Context<'_>` (`context_mut_ref`). @@ -485,7 +485,7 @@ fn replace_local<'tcx>( /// /// The async lowering step and the type / lifetime inference / checking are /// still using the `ResumeTy` indirection for the time being, and that indirection -/// is removed here. After this transform, the generator body only knows about `&mut Context<'_>`. +/// is removed here. After this transform, the coroutine body only knows about `&mut Context<'_>`. fn transform_async_context<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let context_mut_ref = Ty::new_task_context(tcx); @@ -565,10 +565,10 @@ fn replace_resume_ty_local<'tcx>( struct LivenessInfo { /// Which locals are live across any suspension point. - saved_locals: GeneratorSavedLocals, + saved_locals: CoroutineSavedLocals, /// The set of saved locals live at each suspension point. - live_locals_at_suspension_points: Vec<BitSet<GeneratorSavedLocal>>, + live_locals_at_suspension_points: Vec<BitSet<CoroutineSavedLocal>>, /// Parallel vec to the above with SourceInfo for each yield terminator. source_info_at_suspension_points: Vec<SourceInfo>, @@ -576,7 +576,7 @@ struct LivenessInfo { /// For every saved local, the set of other saved locals that are /// storage-live at the same time as this local. We cannot overlap locals in /// the layout which have conflicting storage. - storage_conflicts: BitMatrix<GeneratorSavedLocal, GeneratorSavedLocal>, + storage_conflicts: BitMatrix<CoroutineSavedLocal, CoroutineSavedLocal>, /// For every suspending block, the locals which are storage-live across /// that suspension point. @@ -601,7 +601,7 @@ fn locals_live_across_suspend_points<'tcx>( // Calculate the MIR locals which have been previously // borrowed (even if they are still active). let borrowed_locals_results = - MaybeBorrowedLocals.into_engine(tcx, body_ref).pass_name("generator").iterate_to_fixpoint(); + MaybeBorrowedLocals.into_engine(tcx, body_ref).pass_name("coroutine").iterate_to_fixpoint(); let mut borrowed_locals_cursor = borrowed_locals_results.cloned_results_cursor(body_ref); @@ -616,7 +616,7 @@ fn locals_live_across_suspend_points<'tcx>( // Calculate the liveness of MIR locals ignoring borrows. let mut liveness = MaybeLiveLocals .into_engine(tcx, body_ref) - .pass_name("generator") + .pass_name("coroutine") .iterate_to_fixpoint() .into_results_cursor(body_ref); @@ -635,8 +635,8 @@ fn locals_live_across_suspend_points<'tcx>( if !movable { // The `liveness` variable contains the liveness of MIR locals ignoring borrows. - // This is correct for movable generators since borrows cannot live across - // suspension points. However for immovable generators we need to account for + // This is correct for movable coroutines since borrows cannot live across + // suspension points. However for immovable coroutines we need to account for // borrows, so we conservatively assume that all borrowed locals are live until // we find a StorageDead statement referencing the locals. // To do this we just union our `liveness` result with `borrowed_locals`, which @@ -659,7 +659,7 @@ fn locals_live_across_suspend_points<'tcx>( requires_storage_cursor.seek_before_primary_effect(loc); live_locals.intersect(requires_storage_cursor.get()); - // The generator argument is ignored. + // The coroutine argument is ignored. live_locals.remove(SELF_ARG); debug!("loc = {:?}, live_locals = {:?}", loc, live_locals); @@ -674,7 +674,7 @@ fn locals_live_across_suspend_points<'tcx>( } debug!("live_locals_anywhere = {:?}", live_locals_at_any_suspension_point); - let saved_locals = GeneratorSavedLocals(live_locals_at_any_suspension_point); + let saved_locals = CoroutineSavedLocals(live_locals_at_any_suspension_point); // Renumber our liveness_map bitsets to include only the locals we are // saving. @@ -701,21 +701,21 @@ fn locals_live_across_suspend_points<'tcx>( /// The set of `Local`s that must be saved across yield points. /// -/// `GeneratorSavedLocal` is indexed in terms of the elements in this set; -/// i.e. `GeneratorSavedLocal::new(1)` corresponds to the second local +/// `CoroutineSavedLocal` is indexed in terms of the elements in this set; +/// i.e. `CoroutineSavedLocal::new(1)` corresponds to the second local /// included in this set. -struct GeneratorSavedLocals(BitSet<Local>); +struct CoroutineSavedLocals(BitSet<Local>); -impl GeneratorSavedLocals { - /// Returns an iterator over each `GeneratorSavedLocal` along with the `Local` it corresponds +impl CoroutineSavedLocals { + /// Returns an iterator over each `CoroutineSavedLocal` along with the `Local` it corresponds /// to. - fn iter_enumerated(&self) -> impl '_ + Iterator<Item = (GeneratorSavedLocal, Local)> { - self.iter().enumerate().map(|(i, l)| (GeneratorSavedLocal::from(i), l)) + fn iter_enumerated(&self) -> impl '_ + Iterator<Item = (CoroutineSavedLocal, Local)> { + self.iter().enumerate().map(|(i, l)| (CoroutineSavedLocal::from(i), l)) } /// Transforms a `BitSet<Local>` that contains only locals saved across yield points to the - /// equivalent `BitSet<GeneratorSavedLocal>`. - fn renumber_bitset(&self, input: &BitSet<Local>) -> BitSet<GeneratorSavedLocal> { + /// equivalent `BitSet<CoroutineSavedLocal>`. + fn renumber_bitset(&self, input: &BitSet<Local>) -> BitSet<CoroutineSavedLocal> { assert!(self.superset(&input), "{:?} not a superset of {:?}", self.0, input); let mut out = BitSet::new_empty(self.count()); for (saved_local, local) in self.iter_enumerated() { @@ -726,17 +726,17 @@ impl GeneratorSavedLocals { out } - fn get(&self, local: Local) -> Option<GeneratorSavedLocal> { + fn get(&self, local: Local) -> Option<CoroutineSavedLocal> { if !self.contains(local) { return None; } let idx = self.iter().take_while(|&l| l < local).count(); - Some(GeneratorSavedLocal::new(idx)) + Some(CoroutineSavedLocal::new(idx)) } } -impl ops::Deref for GeneratorSavedLocals { +impl ops::Deref for CoroutineSavedLocals { type Target = BitSet<Local>; fn deref(&self) -> &Self::Target { @@ -747,13 +747,13 @@ impl ops::Deref for GeneratorSavedLocals { /// For every saved local, looks for which locals are StorageLive at the same /// time. Generates a bitset for every local of all the other locals that may be /// StorageLive simultaneously with that local. This is used in the layout -/// computation; see `GeneratorLayout` for more. +/// computation; see `CoroutineLayout` for more. fn compute_storage_conflicts<'mir, 'tcx>( body: &'mir Body<'tcx>, - saved_locals: &GeneratorSavedLocals, + saved_locals: &CoroutineSavedLocals, always_live_locals: BitSet<Local>, mut requires_storage: rustc_mir_dataflow::Results<'tcx, MaybeRequiresStorage<'_, 'mir, 'tcx>>, -) -> BitMatrix<GeneratorSavedLocal, GeneratorSavedLocal> { +) -> BitMatrix<CoroutineSavedLocal, CoroutineSavedLocal> { assert_eq!(body.local_decls.len(), saved_locals.domain_size()); debug!("compute_storage_conflicts({:?})", body.span); @@ -775,7 +775,7 @@ fn compute_storage_conflicts<'mir, 'tcx>( let local_conflicts = visitor.local_conflicts; - // Compress the matrix using only stored locals (Local -> GeneratorSavedLocal). + // Compress the matrix using only stored locals (Local -> CoroutineSavedLocal). // // NOTE: Today we store a full conflict bitset for every local. Technically // this is twice as many bits as we need, since the relation is symmetric. @@ -801,9 +801,9 @@ fn compute_storage_conflicts<'mir, 'tcx>( struct StorageConflictVisitor<'mir, 'tcx, 's> { body: &'mir Body<'tcx>, - saved_locals: &'s GeneratorSavedLocals, + saved_locals: &'s CoroutineSavedLocals, // FIXME(tmandry): Consider using sparse bitsets here once we have good - // benchmarks for generators. + // benchmarks for coroutines. local_conflicts: BitMatrix<Local, Local>, } @@ -858,7 +858,7 @@ fn compute_layout<'tcx>( body: &Body<'tcx>, ) -> ( FxHashMap<Local, (Ty<'tcx>, VariantIdx, FieldIdx)>, - GeneratorLayout<'tcx>, + CoroutineLayout<'tcx>, IndexVec<BasicBlock, Option<BitSet<Local>>>, ) { let LivenessInfo { @@ -870,10 +870,10 @@ fn compute_layout<'tcx>( } = liveness; // Gather live local types and their indices. - let mut locals = IndexVec::<GeneratorSavedLocal, _>::new(); - let mut tys = IndexVec::<GeneratorSavedLocal, _>::new(); + let mut locals = IndexVec::<CoroutineSavedLocal, _>::new(); + let mut tys = IndexVec::<CoroutineSavedLocal, _>::new(); for (saved_local, local) in saved_locals.iter_enumerated() { - debug!("generator saved local {:?} => {:?}", saved_local, local); + debug!("coroutine saved local {:?} => {:?}", saved_local, local); locals.push(local); let decl = &body.local_decls[local]; @@ -895,7 +895,7 @@ fn compute_layout<'tcx>( _ => false, }; let decl = - GeneratorSavedTy { ty: decl.ty, source_info: decl.source_info, ignore_for_traits }; + CoroutineSavedTy { ty: decl.ty, source_info: decl.source_info, ignore_for_traits }; debug!(?decl); tys.push(decl); @@ -914,9 +914,9 @@ fn compute_layout<'tcx>( .copied() .collect(); - // Build the generator variant field list. - // Create a map from local indices to generator struct indices. - let mut variant_fields: IndexVec<VariantIdx, IndexVec<FieldIdx, GeneratorSavedLocal>> = + // Build the coroutine variant field list. + // Create a map from local indices to coroutine struct indices. + let mut variant_fields: IndexVec<VariantIdx, IndexVec<FieldIdx, CoroutineSavedLocal>> = iter::repeat(IndexVec::new()).take(RESERVED_VARIANTS).collect(); let mut remap = FxHashMap::default(); for (suspension_point_idx, live_locals) in live_locals_at_suspension_points.iter().enumerate() { @@ -926,7 +926,7 @@ fn compute_layout<'tcx>( fields.push(saved_local); // Note that if a field is included in multiple variants, we will // just use the first one here. That's fine; fields do not move - // around inside generators, so it doesn't matter which variant + // around inside coroutines, so it doesn't matter which variant // index we access them by. let idx = FieldIdx::from_usize(idx); remap.entry(locals[saved_local]).or_insert((tys[saved_local].ty, variant_index, idx)); @@ -934,8 +934,8 @@ fn compute_layout<'tcx>( variant_fields.push(fields); variant_source_info.push(source_info_at_suspension_points[suspension_point_idx]); } - debug!("generator variant_fields = {:?}", variant_fields); - debug!("generator storage_conflicts = {:#?}", storage_conflicts); + debug!("coroutine variant_fields = {:?}", variant_fields); + debug!("coroutine storage_conflicts = {:#?}", storage_conflicts); let mut field_names = IndexVec::from_elem(None, &tys); for var in &body.var_debug_info { @@ -947,7 +947,7 @@ fn compute_layout<'tcx>( field_names.get_or_insert_with(saved_local, || var.name); } - let layout = GeneratorLayout { + let layout = CoroutineLayout { field_tys: tys, field_names, variant_fields, @@ -959,7 +959,7 @@ fn compute_layout<'tcx>( (remap, layout, storage_liveness) } -/// Replaces the entry point of `body` with a block that switches on the generator discriminant and +/// Replaces the entry point of `body` with a block that switches on the coroutine discriminant and /// dispatches to blocks according to `cases`. /// /// After this function, the former entry point of the function will be bb1. @@ -992,14 +992,14 @@ fn insert_switch<'tcx>( } } -fn elaborate_generator_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { +fn elaborate_coroutine_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { use crate::shim::DropShimElaborator; use rustc_middle::mir::patch::MirPatch; use rustc_mir_dataflow::elaborate_drops::{elaborate_drop, Unwind}; - // Note that `elaborate_drops` only drops the upvars of a generator, and + // Note that `elaborate_drops` only drops the upvars of a coroutine, and // this is ok because `open_drop` can only be reached within that own - // generator's resume function. + // coroutine's resume function. let def_id = body.source.def_id(); let param_env = tcx.param_env(def_id); @@ -1047,7 +1047,7 @@ fn elaborate_generator_drops<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { elaborator.patch.apply(body); } -fn create_generator_drop_shim<'tcx>( +fn create_coroutine_drop_shim<'tcx>( tcx: TyCtxt<'tcx>, transform: &TransformVisitor<'tcx>, gen_ty: Ty<'tcx>, @@ -1070,7 +1070,7 @@ fn create_generator_drop_shim<'tcx>( for block in body.basic_blocks_mut() { let kind = &mut block.terminator_mut().kind; - if let TerminatorKind::GeneratorDrop = *kind { + if let TerminatorKind::CoroutineDrop = *kind { *kind = TerminatorKind::Return; } } @@ -1078,9 +1078,9 @@ fn create_generator_drop_shim<'tcx>( // Replace the return variable body.local_decls[RETURN_PLACE] = LocalDecl::with_source_info(Ty::new_unit(tcx), source_info); - make_generator_state_argument_indirect(tcx, &mut body); + make_coroutine_state_argument_indirect(tcx, &mut body); - // Change the generator argument from &mut to *mut + // Change the coroutine argument from &mut to *mut body.local_decls[SELF_ARG] = LocalDecl::with_source_info( Ty::new_ptr(tcx, ty::TypeAndMut { ty: gen_ty, mutbl: hir::Mutability::Mut }), source_info, @@ -1104,10 +1104,10 @@ fn create_generator_drop_shim<'tcx>( None, ); - // Temporary change MirSource to generator's instance so that dump_mir produces more sensible + // Temporary change MirSource to coroutine's instance so that dump_mir produces more sensible // filename. body.source.instance = gen_instance; - dump_mir(tcx, false, "generator_drop", &0, &body, |_, _| Ok(())); + dump_mir(tcx, false, "coroutine_drop", &0, &body, |_, _| Ok(())); body.source.instance = drop_instance; body @@ -1182,7 +1182,7 @@ fn can_unwind<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) -> bool { | TerminatorKind::UnwindTerminate(_) | TerminatorKind::Return | TerminatorKind::Unreachable - | TerminatorKind::GeneratorDrop + | TerminatorKind::CoroutineDrop | TerminatorKind::FalseEdge { .. } | TerminatorKind::FalseUnwind { .. } => {} @@ -1191,7 +1191,7 @@ fn can_unwind<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) -> bool { TerminatorKind::UnwindResume => {} TerminatorKind::Yield { .. } => { - unreachable!("`can_unwind` called before generator transform") + unreachable!("`can_unwind` called before coroutine transform") } // These may unwind. @@ -1206,7 +1206,7 @@ fn can_unwind<'tcx>(tcx: TyCtxt<'tcx>, body: &Body<'tcx>) -> bool { false } -fn create_generator_resume_function<'tcx>( +fn create_coroutine_resume_function<'tcx>( tcx: TyCtxt<'tcx>, transform: TransformVisitor<'tcx>, body: &mut Body<'tcx>, @@ -1214,7 +1214,7 @@ fn create_generator_resume_function<'tcx>( ) { let can_unwind = can_unwind(tcx, body); - // Poison the generator when it unwinds + // Poison the coroutine when it unwinds if can_unwind { let source_info = SourceInfo::outermost(body.span); let poison_block = body.basic_blocks_mut().push(BasicBlockData { @@ -1253,26 +1253,26 @@ fn create_generator_resume_function<'tcx>( cases.insert(0, (UNRESUMED, START_BLOCK)); // Panic when resumed on the returned or poisoned state - let generator_kind = body.generator_kind().unwrap(); + let coroutine_kind = body.coroutine_kind().unwrap(); if can_unwind { cases.insert( 1, - (POISONED, insert_panic_block(tcx, body, ResumedAfterPanic(generator_kind))), + (POISONED, insert_panic_block(tcx, body, ResumedAfterPanic(coroutine_kind))), ); } if can_return { cases.insert( 1, - (RETURNED, insert_panic_block(tcx, body, ResumedAfterReturn(generator_kind))), + (RETURNED, insert_panic_block(tcx, body, ResumedAfterReturn(coroutine_kind))), ); } insert_switch(body, cases, &transform, TerminatorKind::Unreachable); - make_generator_state_argument_indirect(tcx, body); - make_generator_state_argument_pinned(tcx, body); + make_coroutine_state_argument_indirect(tcx, body); + make_coroutine_state_argument_pinned(tcx, body); // Make sure we remove dead blocks to remove // unrelated code from the drop part of the function @@ -1280,7 +1280,7 @@ fn create_generator_resume_function<'tcx>( pm::run_passes_no_validate(tcx, body, &[&abort_unwinding_calls::AbortUnwindingCalls], None); - dump_mir(tcx, false, "generator_resume", &0, body, |_, _| Ok(())); + dump_mir(tcx, false, "coroutine_resume", &0, body, |_, _| Ok(())); } fn insert_clean_drop(body: &mut Body<'_>) -> BasicBlock { @@ -1294,7 +1294,7 @@ fn insert_clean_drop(body: &mut Body<'_>) -> BasicBlock { }; let source_info = SourceInfo::outermost(body.span); - // Create a block to destroy an unresumed generators. This can only destroy upvars. + // Create a block to destroy an unresumed coroutines. This can only destroy upvars. body.basic_blocks_mut().push(BasicBlockData { statements: Vec::new(), terminator: Some(Terminator { source_info, kind: term }), @@ -1302,7 +1302,7 @@ fn insert_clean_drop(body: &mut Body<'_>) -> BasicBlock { }) } -/// An operation that can be performed on a generator. +/// An operation that can be performed on a coroutine. #[derive(PartialEq, Copy, Clone)] enum Operation { Resume, @@ -1381,64 +1381,64 @@ fn create_cases<'tcx>( } #[instrument(level = "debug", skip(tcx), ret)] -pub(crate) fn mir_generator_witnesses<'tcx>( +pub(crate) fn mir_coroutine_witnesses<'tcx>( tcx: TyCtxt<'tcx>, def_id: LocalDefId, -) -> Option<GeneratorLayout<'tcx>> { +) -> Option<CoroutineLayout<'tcx>> { let (body, _) = tcx.mir_promoted(def_id); let body = body.borrow(); let body = &*body; - // The first argument is the generator type passed by value + // The first argument is the coroutine type passed by value let gen_ty = body.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty; // Get the interior types and args which typeck computed let movable = match *gen_ty.kind() { - ty::Generator(_, _, movability) => movability == hir::Movability::Movable, + ty::Coroutine(_, _, movability) => movability == hir::Movability::Movable, ty::Error(_) => return None, - _ => span_bug!(body.span, "unexpected generator type {}", gen_ty), + _ => span_bug!(body.span, "unexpected coroutine type {}", gen_ty), }; - // When first entering the generator, move the resume argument into its new local. + // When first entering the coroutine, move the resume argument into its new local. let always_live_locals = always_storage_live_locals(&body); let liveness_info = locals_live_across_suspend_points(tcx, body, &always_live_locals, movable); // Extract locals which are live across suspension point into `layout` - // `remap` gives a mapping from local indices onto generator struct indices + // `remap` gives a mapping from local indices onto coroutine struct indices // `storage_liveness` tells us which locals have live storage at suspension points - let (_, generator_layout, _) = compute_layout(liveness_info, body); + let (_, coroutine_layout, _) = compute_layout(liveness_info, body); - check_suspend_tys(tcx, &generator_layout, &body); + check_suspend_tys(tcx, &coroutine_layout, &body); - Some(generator_layout) + Some(coroutine_layout) } impl<'tcx> MirPass<'tcx> for StateTransform { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { let Some(yield_ty) = body.yield_ty() else { - // This only applies to generators + // This only applies to coroutines return; }; - assert!(body.generator_drop().is_none()); + assert!(body.coroutine_drop().is_none()); - // The first argument is the generator type passed by value + // The first argument is the coroutine type passed by value let gen_ty = body.local_decls.raw[1].ty; // Get the discriminant type and args which typeck computed let (discr_ty, movable) = match *gen_ty.kind() { - ty::Generator(_, args, movability) => { - let args = args.as_generator(); + ty::Coroutine(_, args, movability) => { + let args = args.as_coroutine(); (args.discr_ty(tcx), movability == hir::Movability::Movable) } _ => { - tcx.sess.delay_span_bug(body.span, format!("unexpected generator type {gen_ty}")); + tcx.sess.delay_span_bug(body.span, format!("unexpected coroutine type {gen_ty}")); return; } }; - let is_async_kind = matches!(body.generator_kind(), Some(GeneratorKind::Async(_))); + let is_async_kind = matches!(body.coroutine_kind(), Some(CoroutineKind::Async(_))); let (state_adt_ref, state_args) = if is_async_kind { // Compute Poll<return_ty> let poll_did = tcx.require_lang_item(LangItem::Poll, None); @@ -1446,8 +1446,8 @@ impl<'tcx> MirPass<'tcx> for StateTransform { let poll_args = tcx.mk_args(&[body.return_ty().into()]); (poll_adt_ref, poll_args) } else { - // Compute GeneratorState<yield_ty, return_ty> - let state_did = tcx.require_lang_item(LangItem::GeneratorState, None); + // Compute CoroutineState<yield_ty, return_ty> + let state_did = tcx.require_lang_item(LangItem::CoroutineState, None); let state_adt_ref = tcx.adt_def(state_did); let state_args = tcx.mk_args(&[yield_ty.into(), body.return_ty().into()]); (state_adt_ref, state_args) @@ -1465,8 +1465,8 @@ impl<'tcx> MirPass<'tcx> for StateTransform { // We also replace the resume argument and insert an `Assign`. // This is needed because the resume argument `_2` might be live across a `yield`, in which - // case there is no `Assign` to it that the transform can turn into a store to the generator - // state. After the yield the slot in the generator state would then be uninitialized. + // case there is no `Assign` to it that the transform can turn into a store to the coroutine + // state. After the yield the slot in the coroutine state would then be uninitialized. let resume_local = Local::new(2); let resume_ty = if is_async_kind { Ty::new_task_context(tcx) @@ -1475,7 +1475,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform { }; let new_resume_local = replace_local(resume_local, resume_ty, body, tcx); - // When first entering the generator, move the resume argument into its new local. + // When first entering the coroutine, move the resume argument into its new local. let source_info = SourceInfo::outermost(body.span); let stmts = &mut body.basic_blocks_mut()[START_BLOCK].statements; stmts.insert( @@ -1495,7 +1495,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform { locals_live_across_suspend_points(tcx, body, &always_live_locals, movable); if tcx.sess.opts.unstable_opts.validate_mir { - let mut vis = EnsureGeneratorFieldAssignmentsNeverAlias { + let mut vis = EnsureCoroutineFieldAssignmentsNeverAlias { assigned_local: None, saved_locals: &liveness_info.saved_locals, storage_conflicts: &liveness_info.storage_conflicts, @@ -1505,16 +1505,16 @@ impl<'tcx> MirPass<'tcx> for StateTransform { } // Extract locals which are live across suspension point into `layout` - // `remap` gives a mapping from local indices onto generator struct indices + // `remap` gives a mapping from local indices onto coroutine struct indices // `storage_liveness` tells us which locals have live storage at suspension points let (remap, layout, storage_liveness) = compute_layout(liveness_info, body); let can_return = can_return(tcx, body, tcx.param_env(body.source.def_id())); - // Run the transformation which converts Places from Local to generator struct + // Run the transformation which converts Places from Local to coroutine struct // accesses for locals in `remap`. - // It also rewrites `return x` and `yield y` as writing a new generator state and returning - // either GeneratorState::Complete(x) and GeneratorState::Yielded(y), + // It also rewrites `return x` and `yield y` as writing a new coroutine state and returning + // either CoroutineState::Complete(x) and CoroutineState::Yielded(y), // or Poll::Ready(x) and Poll::Pending respectively depending on `is_async_kind`. let mut transform = TransformVisitor { tcx, @@ -1541,30 +1541,30 @@ impl<'tcx> MirPass<'tcx> for StateTransform { var.argument_index = None; } - body.generator.as_mut().unwrap().yield_ty = None; - body.generator.as_mut().unwrap().generator_layout = Some(layout); + body.coroutine.as_mut().unwrap().yield_ty = None; + body.coroutine.as_mut().unwrap().coroutine_layout = Some(layout); - // Insert `drop(generator_struct)` which is used to drop upvars for generators in + // Insert `drop(coroutine_struct)` which is used to drop upvars for coroutines in // the unresumed state. - // This is expanded to a drop ladder in `elaborate_generator_drops`. + // This is expanded to a drop ladder in `elaborate_coroutine_drops`. let drop_clean = insert_clean_drop(body); - dump_mir(tcx, false, "generator_pre-elab", &0, body, |_, _| Ok(())); + dump_mir(tcx, false, "coroutine_pre-elab", &0, body, |_, _| Ok(())); - // Expand `drop(generator_struct)` to a drop ladder which destroys upvars. + // Expand `drop(coroutine_struct)` to a drop ladder which destroys upvars. // If any upvars are moved out of, drop elaboration will handle upvar destruction. // However we need to also elaborate the code generated by `insert_clean_drop`. - elaborate_generator_drops(tcx, body); + elaborate_coroutine_drops(tcx, body); - dump_mir(tcx, false, "generator_post-transform", &0, body, |_, _| Ok(())); + dump_mir(tcx, false, "coroutine_post-transform", &0, body, |_, _| Ok(())); - // Create a copy of our MIR and use it to create the drop shim for the generator - let drop_shim = create_generator_drop_shim(tcx, &transform, gen_ty, body, drop_clean); + // Create a copy of our MIR and use it to create the drop shim for the coroutine + let drop_shim = create_coroutine_drop_shim(tcx, &transform, gen_ty, body, drop_clean); - body.generator.as_mut().unwrap().generator_drop = Some(drop_shim); + body.coroutine.as_mut().unwrap().coroutine_drop = Some(drop_shim); - // Create the Generator::resume / Future::poll function - create_generator_resume_function(tcx, transform, body, can_return); + // Create the Coroutine::resume / Future::poll function + create_coroutine_resume_function(tcx, transform, body, can_return); // Run derefer to fix Derefs that are not in the first place deref_finder(tcx, body); @@ -1572,25 +1572,25 @@ impl<'tcx> MirPass<'tcx> for StateTransform { } /// Looks for any assignments between locals (e.g., `_4 = _5`) that will both be converted to fields -/// in the generator state machine but whose storage is not marked as conflicting +/// in the coroutine state machine but whose storage is not marked as conflicting /// /// Validation needs to happen immediately *before* `TransformVisitor` is invoked, not after. /// /// This condition would arise when the assignment is the last use of `_5` but the initial /// definition of `_4` if we weren't extra careful to mark all locals used inside a statement as -/// conflicting. Non-conflicting generator saved locals may be stored at the same location within -/// the generator state machine, which would result in ill-formed MIR: the left-hand and right-hand +/// conflicting. Non-conflicting coroutine saved locals may be stored at the same location within +/// the coroutine state machine, which would result in ill-formed MIR: the left-hand and right-hand /// sides of an assignment may not alias. This caused a miscompilation in [#73137]. /// /// [#73137]: https://github.com/rust-lang/rust/issues/73137 -struct EnsureGeneratorFieldAssignmentsNeverAlias<'a> { - saved_locals: &'a GeneratorSavedLocals, - storage_conflicts: &'a BitMatrix<GeneratorSavedLocal, GeneratorSavedLocal>, - assigned_local: Option<GeneratorSavedLocal>, +struct EnsureCoroutineFieldAssignmentsNeverAlias<'a> { + saved_locals: &'a CoroutineSavedLocals, + storage_conflicts: &'a BitMatrix<CoroutineSavedLocal, CoroutineSavedLocal>, + assigned_local: Option<CoroutineSavedLocal>, } -impl EnsureGeneratorFieldAssignmentsNeverAlias<'_> { - fn saved_local_for_direct_place(&self, place: Place<'_>) -> Option<GeneratorSavedLocal> { +impl EnsureCoroutineFieldAssignmentsNeverAlias<'_> { + fn saved_local_for_direct_place(&self, place: Place<'_>) -> Option<CoroutineSavedLocal> { if place.is_indirect() { return None; } @@ -1609,7 +1609,7 @@ impl EnsureGeneratorFieldAssignmentsNeverAlias<'_> { } } -impl<'tcx> Visitor<'tcx> for EnsureGeneratorFieldAssignmentsNeverAlias<'_> { +impl<'tcx> Visitor<'tcx> for EnsureCoroutineFieldAssignmentsNeverAlias<'_> { fn visit_place(&mut self, place: &Place<'tcx>, context: PlaceContext, location: Location) { let Some(lhs) = self.assigned_local else { // This visitor only invokes `visit_place` for the right-hand side of an assignment @@ -1624,7 +1624,7 @@ impl<'tcx> Visitor<'tcx> for EnsureGeneratorFieldAssignmentsNeverAlias<'_> { if !self.storage_conflicts.contains(lhs, rhs) { bug!( - "Assignment between generator saved locals whose storage is not \ + "Assignment between coroutine saved locals whose storage is not \ marked as conflicting: {:?}: {:?} = {:?}", location, lhs, @@ -1691,14 +1691,14 @@ impl<'tcx> Visitor<'tcx> for EnsureGeneratorFieldAssignmentsNeverAlias<'_> { | TerminatorKind::Unreachable | TerminatorKind::Drop { .. } | TerminatorKind::Assert { .. } - | TerminatorKind::GeneratorDrop + | TerminatorKind::CoroutineDrop | TerminatorKind::FalseEdge { .. } | TerminatorKind::FalseUnwind { .. } => {} } } } -fn check_suspend_tys<'tcx>(tcx: TyCtxt<'tcx>, layout: &GeneratorLayout<'tcx>, body: &Body<'tcx>) { +fn check_suspend_tys<'tcx>(tcx: TyCtxt<'tcx>, layout: &CoroutineLayout<'tcx>, body: &Body<'tcx>) { let mut linted_tys = FxHashSet::default(); // We want a user-facing param-env. diff --git a/compiler/rustc_mir_transform/src/coverage/graph.rs b/compiler/rustc_mir_transform/src/coverage/graph.rs index 9a7adaada09..6bab62aa854 100644 --- a/compiler/rustc_mir_transform/src/coverage/graph.rs +++ b/compiler/rustc_mir_transform/src/coverage/graph.rs @@ -147,7 +147,7 @@ impl CoverageGraph { | TerminatorKind::Unreachable | TerminatorKind::Drop { .. } | TerminatorKind::Call { .. } - | TerminatorKind::GeneratorDrop + | TerminatorKind::CoroutineDrop | TerminatorKind::Assert { .. } | TerminatorKind::FalseEdge { .. } | TerminatorKind::FalseUnwind { .. } diff --git a/compiler/rustc_mir_transform/src/coverage/spans.rs b/compiler/rustc_mir_transform/src/coverage/spans.rs index f1a0f762041..3f7ba572510 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans.rs @@ -93,7 +93,7 @@ impl CoverageSpan { ) -> Self { let is_closure = match statement.kind { StatementKind::Assign(box (_, Rvalue::Aggregate(box ref kind, _))) => { - matches!(kind, AggregateKind::Closure(_, _) | AggregateKind::Generator(_, _, _)) + matches!(kind, AggregateKind::Closure(_, _) | AggregateKind::Coroutine(_, _, _)) } _ => false, }; diff --git a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs index 4c20997e633..02e2cf6b05e 100644 --- a/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs +++ b/compiler/rustc_mir_transform/src/coverage/spans/from_mir.rs @@ -160,7 +160,7 @@ fn filtered_terminator_span(terminator: &Terminator<'_>) -> Option<Span> { | TerminatorKind::UnwindTerminate(_) | TerminatorKind::Return | TerminatorKind::Yield { .. } - | TerminatorKind::GeneratorDrop + | TerminatorKind::CoroutineDrop | TerminatorKind::FalseUnwind { .. } | TerminatorKind::InlineAsm { .. } => { Some(terminator.source_info.span) diff --git a/compiler/rustc_mir_transform/src/dest_prop.rs b/compiler/rustc_mir_transform/src/dest_prop.rs index 99b070c018e..15502adfb5a 100644 --- a/compiler/rustc_mir_transform/src/dest_prop.rs +++ b/compiler/rustc_mir_transform/src/dest_prop.rs @@ -114,7 +114,7 @@ //! approach that only works for some classes of CFGs: //! - rustc now has a powerful dataflow analysis framework that can handle forwards and backwards //! analyses efficiently. -//! - Layout optimizations for generators have been added to improve code generation for +//! - Layout optimizations for coroutines have been added to improve code generation for //! async/await, which are very similar in spirit to what this optimization does. //! //! Also, rustc now has a simple NRVO pass (see `nrvo.rs`), which handles a subset of the cases that @@ -655,7 +655,7 @@ impl WriteInfo { // `Drop`s create a `&mut` and so are not considered } TerminatorKind::Yield { .. } - | TerminatorKind::GeneratorDrop + | TerminatorKind::CoroutineDrop | TerminatorKind::FalseEdge { .. } | TerminatorKind::FalseUnwind { .. } => { bug!("{:?} not found in this MIR phase", terminator) diff --git a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs index d202860840c..26fcfad8287 100644 --- a/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs +++ b/compiler/rustc_mir_transform/src/ffi_unwind_calls.rs @@ -58,7 +58,7 @@ fn has_ffi_unwind_calls(tcx: TyCtxt<'_>, local_def_id: LocalDefId) -> bool { let body_abi = match body_ty.kind() { ty::FnDef(..) => body_ty.fn_sig(tcx).abi(), ty::Closure(..) => Abi::RustCall, - ty::Generator(..) => Abi::Rust, + ty::Coroutine(..) => Abi::Rust, _ => span_bug!(body.span, "unexpected body ty: {:?}", body_ty), }; let body_can_unwind = layout::fn_can_unwind(tcx, Some(def_id), body_abi); diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index c710e460dcb..eece7c3e834 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -383,7 +383,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { AggregateKind::Array(..) | AggregateKind::Tuple | AggregateKind::Closure(..) - | AggregateKind::Generator(..) => FIRST_VARIANT, + | AggregateKind::Coroutine(..) => FIRST_VARIANT, AggregateKind::Adt(_, variant_index, _, _, None) => variant_index, // Do not track unions. AggregateKind::Adt(_, _, _, _, Some(_)) => return None, diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 8f578b69694..757b2aeca7b 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -79,10 +79,10 @@ fn inline<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool { if body.source.promoted.is_some() { return false; } - // Avoid inlining into generators, since their `optimized_mir` is used for layout computation, + // Avoid inlining into coroutines, since their `optimized_mir` is used for layout computation, // which can create a cycle, even when no attempt is made to inline the function in the other // direction. - if body.generator.is_some() { + if body.coroutine.is_some() { return false; } @@ -1014,7 +1014,7 @@ impl<'tcx> MutVisitor<'tcx> for Integrator<'_, 'tcx> { } match terminator.kind { - TerminatorKind::GeneratorDrop | TerminatorKind::Yield { .. } => bug!(), + TerminatorKind::CoroutineDrop | TerminatorKind::Yield { .. } => bug!(), TerminatorKind::Goto { ref mut target } => { *target = self.map_block(*target); } diff --git a/compiler/rustc_mir_transform/src/lib.rs b/compiler/rustc_mir_transform/src/lib.rs index d579420ecb8..6c0aa51795b 100644 --- a/compiler/rustc_mir_transform/src/lib.rs +++ b/compiler/rustc_mir_transform/src/lib.rs @@ -61,6 +61,7 @@ mod const_goto; mod const_prop; mod const_prop_lint; mod copy_prop; +mod coroutine; mod coverage; mod cross_crate_inline; mod ctfe_limit; @@ -77,7 +78,6 @@ mod elaborate_drops; mod errors; mod ffi_unwind_calls; mod function_item_references; -mod generator; mod gvn; pub mod inline; mod instsimplify; @@ -132,7 +132,7 @@ pub fn provide(providers: &mut Providers) { mir_promoted, mir_drops_elaborated_and_const_checked, mir_for_ctfe, - mir_generator_witnesses: generator::mir_generator_witnesses, + mir_coroutine_witnesses: coroutine::mir_coroutine_witnesses, optimized_mir, is_mir_available, is_ctfe_mir_available: |tcx, did| is_mir_available(tcx, did), @@ -375,8 +375,8 @@ fn inner_mir_for_ctfe(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> { /// mir borrowck *before* doing so in order to ensure that borrowck can be run and doesn't /// end up missing the source MIR due to stealing happening. fn mir_drops_elaborated_and_const_checked(tcx: TyCtxt<'_>, def: LocalDefId) -> &Steal<Body<'_>> { - if let DefKind::Generator = tcx.def_kind(def) { - tcx.ensure_with_value().mir_generator_witnesses(def); + if let DefKind::Coroutine = tcx.def_kind(def) { + tcx.ensure_with_value().mir_coroutine_witnesses(def); } let mir_borrowck = tcx.mir_borrowck(def); @@ -509,7 +509,7 @@ fn run_runtime_lowering_passes<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { // `AddRetag` needs to run after `ElaborateDrops`. Otherwise it should run fairly late, // but before optimizations begin. &elaborate_box_derefs::ElaborateBoxDerefs, - &generator::StateTransform, + &coroutine::StateTransform, &add_retag::AddRetag, &Lint(const_prop_lint::ConstPropLint), ]; diff --git a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs index 8c48a667786..54892442c87 100644 --- a/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs +++ b/compiler/rustc_mir_transform/src/remove_noop_landing_pads.rs @@ -69,7 +69,7 @@ impl RemoveNoopLandingPads { | TerminatorKind::FalseUnwind { .. } => { terminator.successors().all(|succ| nop_landing_pads.contains(succ)) } - TerminatorKind::GeneratorDrop + TerminatorKind::CoroutineDrop | TerminatorKind::Yield { .. } | TerminatorKind::Return | TerminatorKind::UnwindTerminate(_) diff --git a/compiler/rustc_mir_transform/src/remove_zsts.rs b/compiler/rustc_mir_transform/src/remove_zsts.rs index b4784b69f7f..5aa3c3cfe4d 100644 --- a/compiler/rustc_mir_transform/src/remove_zsts.rs +++ b/compiler/rustc_mir_transform/src/remove_zsts.rs @@ -13,8 +13,8 @@ impl<'tcx> MirPass<'tcx> for RemoveZsts { } fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { - // Avoid query cycles (generators require optimized MIR for layout). - if tcx.type_of(body.source.def_id()).instantiate_identity().is_generator() { + // Avoid query cycles (coroutines require optimized MIR for layout). + if tcx.type_of(body.source.def_id()).instantiate_identity().is_coroutine() { return; } let param_env = tcx.param_env_reveal_all_normalized(body.source.def_id()); diff --git a/compiler/rustc_mir_transform/src/separate_const_switch.rs b/compiler/rustc_mir_transform/src/separate_const_switch.rs index e1e4acccccd..907cfe7581a 100644 --- a/compiler/rustc_mir_transform/src/separate_const_switch.rs +++ b/compiler/rustc_mir_transform/src/separate_const_switch.rs @@ -118,7 +118,7 @@ pub fn separate_const_switch(body: &mut Body<'_>) -> usize { | TerminatorKind::Return | TerminatorKind::Unreachable | TerminatorKind::InlineAsm { .. } - | TerminatorKind::GeneratorDrop => { + | TerminatorKind::CoroutineDrop => { continue 'predec_iter; } } @@ -169,7 +169,7 @@ pub fn separate_const_switch(body: &mut Body<'_>) -> usize { | TerminatorKind::UnwindTerminate(_) | TerminatorKind::Return | TerminatorKind::Unreachable - | TerminatorKind::GeneratorDrop + | TerminatorKind::CoroutineDrop | TerminatorKind::Assert { .. } | TerminatorKind::FalseUnwind { .. } | TerminatorKind::Drop { .. } diff --git a/compiler/rustc_mir_transform/src/shim.rs b/compiler/rustc_mir_transform/src/shim.rs index e9895d97dfe..2400cfa21fb 100644 --- a/compiler/rustc_mir_transform/src/shim.rs +++ b/compiler/rustc_mir_transform/src/shim.rs @@ -4,7 +4,7 @@ use rustc_hir::lang_items::LangItem; use rustc_middle::mir::*; use rustc_middle::query::Providers; use rustc_middle::ty::GenericArgs; -use rustc_middle::ty::{self, EarlyBinder, GeneratorArgs, Ty, TyCtxt}; +use rustc_middle::ty::{self, CoroutineArgs, EarlyBinder, Ty, TyCtxt}; use rustc_target::abi::{FieldIdx, VariantIdx, FIRST_VARIANT}; use rustc_index::{Idx, IndexVec}; @@ -67,10 +67,10 @@ fn make_shim<'tcx>(tcx: TyCtxt<'tcx>, instance: ty::InstanceDef<'tcx>) -> Body<' } ty::InstanceDef::DropGlue(def_id, ty) => { - // FIXME(#91576): Drop shims for generators aren't subject to the MIR passes at the end + // FIXME(#91576): Drop shims for coroutines aren't subject to the MIR passes at the end // of this function. Is this intentional? - if let Some(ty::Generator(gen_def_id, args, _)) = ty.map(Ty::kind) { - let body = tcx.optimized_mir(*gen_def_id).generator_drop().unwrap(); + if let Some(ty::Coroutine(gen_def_id, args, _)) = ty.map(Ty::kind) { + let body = tcx.optimized_mir(*gen_def_id).coroutine_drop().unwrap(); let mut body = EarlyBinder::bind(body.clone()).instantiate(tcx, args); debug!("make_shim({:?}) = {:?}", instance, body); @@ -171,7 +171,7 @@ fn local_decls_for_sig<'tcx>( fn build_drop_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, ty: Option<Ty<'tcx>>) -> Body<'tcx> { debug!("build_drop_shim(def_id={:?}, ty={:?})", def_id, ty); - assert!(!matches!(ty, Some(ty) if ty.is_generator())); + assert!(!matches!(ty, Some(ty) if ty.is_coroutine())); let args = if let Some(ty) = ty { tcx.mk_args(&[ty.into()]) @@ -392,8 +392,8 @@ fn build_clone_shim<'tcx>(tcx: TyCtxt<'tcx>, def_id: DefId, self_ty: Ty<'tcx>) - _ if is_copy => builder.copy_shim(), ty::Closure(_, args) => builder.tuple_like_shim(dest, src, args.as_closure().upvar_tys()), ty::Tuple(..) => builder.tuple_like_shim(dest, src, self_ty.tuple_fields()), - ty::Generator(gen_def_id, args, hir::Movability::Movable) => { - builder.generator_shim(dest, src, *gen_def_id, args.as_generator()) + ty::Coroutine(gen_def_id, args, hir::Movability::Movable) => { + builder.coroutine_shim(dest, src, *gen_def_id, args.as_coroutine()) } _ => bug!("clone shim for `{:?}` which is not `Copy` and is not an aggregate", self_ty), }; @@ -593,12 +593,12 @@ impl<'tcx> CloneShimBuilder<'tcx> { let _final_cleanup_block = self.clone_fields(dest, src, target, unwind, tys); } - fn generator_shim( + fn coroutine_shim( &mut self, dest: Place<'tcx>, src: Place<'tcx>, gen_def_id: DefId, - args: GeneratorArgs<'tcx>, + args: CoroutineArgs<'tcx>, ) { self.block(vec![], TerminatorKind::Goto { target: self.block_index_offset(3) }, false); let unwind = self.block(vec![], TerminatorKind::UnwindResume, true); diff --git a/compiler/rustc_mir_transform/src/sroa.rs b/compiler/rustc_mir_transform/src/sroa.rs index c21b1724cbb..427cc1e1924 100644 --- a/compiler/rustc_mir_transform/src/sroa.rs +++ b/compiler/rustc_mir_transform/src/sroa.rs @@ -20,8 +20,8 @@ impl<'tcx> MirPass<'tcx> for ScalarReplacementOfAggregates { fn run_pass(&self, tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) { debug!(def_id = ?body.source.def_id()); - // Avoid query cycles (generators require optimized MIR for layout). - if tcx.type_of(body.source.def_id()).instantiate_identity().is_generator() { + // Avoid query cycles (coroutines require optimized MIR for layout). + if tcx.type_of(body.source.def_id()).instantiate_identity().is_coroutine() { return; } |
