s/Generator/Coroutine/
This commit is contained in:
parent
96027d945b
commit
60956837cf
310 changed files with 1271 additions and 1271 deletions
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -84,7 +84,7 @@ impl<'tcx> MirPass<'tcx> for ConstProp {
|
|||
|
||||
// FIXME(welseywiser) const prop doesn't work on generators because of query cycles
|
||||
// computing their layout.
|
||||
let is_generator = def_kind == DefKind::Generator;
|
||||
let is_generator = def_kind == DefKind::Coroutine;
|
||||
if is_generator {
|
||||
trace!("ConstProp skipped for generator {:?}", def_id);
|
||||
return;
|
||||
|
|
|
@ -61,7 +61,7 @@ impl<'tcx> MirLint<'tcx> for ConstPropLint {
|
|||
|
||||
// FIXME(welseywiser) const prop doesn't work on generators because of query cycles
|
||||
// computing their layout.
|
||||
if let DefKind::Generator = def_kind {
|
||||
if let DefKind::Coroutine = def_kind {
|
||||
trace!("ConstPropLint skipped for generator {:?}", 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 { .. }
|
||||
|
|
|
@ -147,7 +147,7 @@ impl CoverageGraph {
|
|||
| TerminatorKind::Unreachable
|
||||
| TerminatorKind::Drop { .. }
|
||||
| TerminatorKind::Call { .. }
|
||||
| TerminatorKind::GeneratorDrop
|
||||
| TerminatorKind::CoroutineDrop
|
||||
| TerminatorKind::Assert { .. }
|
||||
| TerminatorKind::FalseEdge { .. }
|
||||
| TerminatorKind::FalseUnwind { .. }
|
||||
|
|
|
@ -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,
|
||||
};
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
//! generator in the MIR, since it is used to create the drop glue for the generator. We'd get
|
||||
//! infinite recursion otherwise.
|
||||
//!
|
||||
//! This pass creates the implementation for either the `Generator::resume` or `Future::poll`
|
||||
//! This pass creates the implementation for either the `Coroutine::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:
|
||||
|
@ -19,7 +19,7 @@
|
|||
//! It is followed by the generator 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...,
|
||||
|
@ -27,12 +27,12 @@
|
|||
//! ```
|
||||
//! 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
|
||||
//! 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)`,
|
||||
//! `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.
|
||||
|
@ -40,7 +40,7 @@
|
|||
//! The pass creates two functions which have a switch on the generator state giving
|
||||
//! the action to take.
|
||||
//!
|
||||
//! One of them is the implementation of `Generator::resume` / `Future::poll`.
|
||||
//! One of them is the implementation of `Coroutine::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.
|
||||
//! Otherwise it continues the execution from the last suspension point.
|
||||
|
@ -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,12 +196,12 @@ 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`
|
||||
|
@ -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 {
|
||||
|
@ -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.
|
||||
|
@ -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,7 +801,7 @@ 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.
|
||||
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,8 +870,8 @@ 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);
|
||||
|
||||
|
@ -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);
|
||||
|
@ -916,7 +916,7 @@ fn compute_layout<'tcx>(
|
|||
|
||||
// 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>> =
|
||||
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() {
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
@ -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 { .. } => {}
|
||||
|
||||
|
@ -1384,7 +1384,7 @@ fn create_cases<'tcx>(
|
|||
pub(crate) fn mir_generator_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;
|
||||
|
@ -1394,7 +1394,7 @@ pub(crate) fn mir_generator_witnesses<'tcx>(
|
|||
|
||||
// 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),
|
||||
};
|
||||
|
@ -1428,7 +1428,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
|
|||
|
||||
// Get the discriminant type and args which typeck computed
|
||||
let (discr_ty, movable) = match *gen_ty.kind() {
|
||||
ty::Generator(_, args, movability) => {
|
||||
ty::Coroutine(_, args, movability) => {
|
||||
let args = args.as_generator();
|
||||
(args.discr_ty(tcx), movability == hir::Movability::Movable)
|
||||
}
|
||||
|
@ -1438,7 +1438,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
|
|||
}
|
||||
};
|
||||
|
||||
let is_async_kind = matches!(body.generator_kind(), Some(GeneratorKind::Async(_)));
|
||||
let is_async_kind = matches!(body.generator_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)
|
||||
|
@ -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,
|
||||
|
@ -1514,7 +1514,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
|
|||
// Run the transformation which converts Places from Local to generator 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),
|
||||
// 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,
|
||||
|
@ -1563,7 +1563,7 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
|
|||
|
||||
body.generator.as_mut().unwrap().generator_drop = Some(drop_shim);
|
||||
|
||||
// Create the Generator::resume / Future::poll function
|
||||
// Create the Coroutine::resume / Future::poll function
|
||||
create_generator_resume_function(tcx, transform, body, can_return);
|
||||
|
||||
// Run derefer to fix Derefs that are not in the first place
|
||||
|
@ -1583,14 +1583,14 @@ impl<'tcx> MirPass<'tcx> for StateTransform {
|
|||
/// 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
|
||||
|
@ -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.
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
|
@ -375,7 +375,7 @@ 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) {
|
||||
if let DefKind::Coroutine = tcx.def_kind(def) {
|
||||
tcx.ensure_with_value().mir_generator_witnesses(def);
|
||||
}
|
||||
let mir_borrowck = tcx.mir_borrowck(def);
|
||||
|
|
|
@ -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(_)
|
||||
|
|
|
@ -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 { .. }
|
||||
|
|
|
@ -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};
|
||||
|
@ -69,7 +69,7 @@ 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
|
||||
// of this function. Is this intentional?
|
||||
if let Some(ty::Generator(gen_def_id, args, _)) = ty.map(Ty::kind) {
|
||||
if let Some(ty::Coroutine(gen_def_id, args, _)) = ty.map(Ty::kind) {
|
||||
let body = tcx.optimized_mir(*gen_def_id).generator_drop().unwrap();
|
||||
let mut body = EarlyBinder::bind(body.clone()).instantiate(tcx, args);
|
||||
debug!("make_shim({:?}) = {:?}", instance, body);
|
||||
|
@ -392,7 +392,7 @@ 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) => {
|
||||
ty::Coroutine(gen_def_id, args, hir::Movability::Movable) => {
|
||||
builder.generator_shim(dest, src, *gen_def_id, args.as_generator())
|
||||
}
|
||||
_ => bug!("clone shim for `{:?}` which is not `Copy` and is not an aggregate", self_ty),
|
||||
|
@ -598,7 +598,7 @@ impl<'tcx> CloneShimBuilder<'tcx> {
|
|||
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);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue