s/generator/coroutine/
This commit is contained in:
parent
60956837cf
commit
e96ce20b34
468 changed files with 2201 additions and 2197 deletions
|
@ -48,7 +48,7 @@ pub(super) fn build_custom_mir<'tcx>(
|
|||
source: MirSource::item(did),
|
||||
phase: MirPhase::Built,
|
||||
source_scopes: IndexVec::new(),
|
||||
generator: None,
|
||||
coroutine: None,
|
||||
local_decls: IndexVec::new(),
|
||||
user_type_annotations: IndexVec::new(),
|
||||
arg_count: params.len(),
|
||||
|
|
|
@ -75,7 +75,7 @@ pub(in crate::build) struct PlaceBuilder<'tcx> {
|
|||
|
||||
/// Given a list of MIR projections, convert them to list of HIR ProjectionKind.
|
||||
/// The projections are truncated to represent a path that might be captured by a
|
||||
/// closure/generator. This implies the vector returned from this function doesn't contain
|
||||
/// closure/coroutine. This implies the vector returned from this function doesn't contain
|
||||
/// ProjectionElems `Downcast`, `ConstantIndex`, `Index`, or `Subslice` because those will never be
|
||||
/// part of a path that is captured by a closure. We stop applying projections once we see the first
|
||||
/// projection that isn't captured by a closure.
|
||||
|
@ -213,7 +213,7 @@ fn to_upvars_resolved_place_builder<'tcx>(
|
|||
/// projections.
|
||||
///
|
||||
/// Supports only HIR projection kinds that represent a path that might be
|
||||
/// captured by a closure or a generator, i.e., an `Index` or a `Subslice`
|
||||
/// captured by a closure or a coroutine, i.e., an `Index` or a `Subslice`
|
||||
/// projection kinds are unsupported.
|
||||
fn strip_prefix<'a, 'tcx>(
|
||||
mut base_ty: Ty<'tcx>,
|
||||
|
|
|
@ -181,7 +181,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
block = success;
|
||||
|
||||
// The `Box<T>` temporary created here is not a part of the HIR,
|
||||
// and therefore is not considered during generator auto-trait
|
||||
// and therefore is not considered during coroutine auto-trait
|
||||
// determination. See the comment about `box` at `yield_in_scope`.
|
||||
let result = this.local_decls.push(LocalDecl::new(expr.ty, expr_span));
|
||||
this.cfg.push(
|
||||
|
|
|
@ -547,7 +547,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
source_info,
|
||||
TerminatorKind::Yield { value, resume, resume_arg: destination, drop: None },
|
||||
);
|
||||
this.generator_drop_cleanup(block);
|
||||
this.coroutine_drop_cleanup(block);
|
||||
resume.unit()
|
||||
}
|
||||
|
||||
|
|
|
@ -173,7 +173,7 @@ struct Builder<'a, 'tcx> {
|
|||
check_overflow: bool,
|
||||
fn_span: Span,
|
||||
arg_count: usize,
|
||||
generator_kind: Option<CoroutineKind>,
|
||||
coroutine_kind: Option<CoroutineKind>,
|
||||
|
||||
/// The current set of scopes, updated as we traverse;
|
||||
/// see the `scope` module for more details.
|
||||
|
@ -448,7 +448,7 @@ fn construct_fn<'tcx>(
|
|||
) -> Body<'tcx> {
|
||||
let span = tcx.def_span(fn_def);
|
||||
let fn_id = tcx.hir().local_def_id_to_hir_id(fn_def);
|
||||
let generator_kind = tcx.generator_kind(fn_def);
|
||||
let coroutine_kind = tcx.coroutine_kind(fn_def);
|
||||
|
||||
// The representation of thir for `-Zunpretty=thir-tree` relies on
|
||||
// the entry expression being the last element of `thir.exprs`.
|
||||
|
@ -478,12 +478,12 @@ fn construct_fn<'tcx>(
|
|||
|
||||
let arguments = &thir.params;
|
||||
|
||||
let (yield_ty, return_ty) = if generator_kind.is_some() {
|
||||
let (yield_ty, return_ty) = if coroutine_kind.is_some() {
|
||||
let gen_ty = arguments[thir::UPVAR_ENV_PARAM].ty;
|
||||
let gen_sig = match gen_ty.kind() {
|
||||
ty::Coroutine(_, gen_args, ..) => gen_args.as_generator().sig(),
|
||||
ty::Coroutine(_, gen_args, ..) => gen_args.as_coroutine().sig(),
|
||||
_ => {
|
||||
span_bug!(span, "generator w/o generator type: {:?}", gen_ty)
|
||||
span_bug!(span, "coroutine w/o coroutine type: {:?}", gen_ty)
|
||||
}
|
||||
};
|
||||
(Some(gen_sig.yield_ty), gen_sig.return_ty)
|
||||
|
@ -519,7 +519,7 @@ fn construct_fn<'tcx>(
|
|||
safety,
|
||||
return_ty,
|
||||
return_ty_span,
|
||||
generator_kind,
|
||||
coroutine_kind,
|
||||
);
|
||||
|
||||
let call_site_scope =
|
||||
|
@ -553,7 +553,7 @@ fn construct_fn<'tcx>(
|
|||
None
|
||||
};
|
||||
if yield_ty.is_some() {
|
||||
body.generator.as_mut().unwrap().yield_ty = yield_ty;
|
||||
body.coroutine.as_mut().unwrap().yield_ty = yield_ty;
|
||||
}
|
||||
body
|
||||
}
|
||||
|
@ -619,7 +619,7 @@ fn construct_const<'a, 'tcx>(
|
|||
fn construct_error(tcx: TyCtxt<'_>, def: LocalDefId, err: ErrorGuaranteed) -> Body<'_> {
|
||||
let span = tcx.def_span(def);
|
||||
let hir_id = tcx.hir().local_def_id_to_hir_id(def);
|
||||
let generator_kind = tcx.generator_kind(def);
|
||||
let coroutine_kind = tcx.coroutine_kind(def);
|
||||
let body_owner_kind = tcx.hir().body_owner_kind(def);
|
||||
|
||||
let ty = Ty::new_error(tcx, err);
|
||||
|
@ -630,7 +630,7 @@ fn construct_error(tcx: TyCtxt<'_>, def: LocalDefId, err: ErrorGuaranteed) -> Bo
|
|||
match ty.kind() {
|
||||
ty::Closure(_, args) => 1 + args.as_closure().sig().inputs().skip_binder().len(),
|
||||
ty::Coroutine(..) => 2,
|
||||
_ => bug!("expected closure or generator, found {ty:?}"),
|
||||
_ => bug!("expected closure or coroutine, found {ty:?}"),
|
||||
}
|
||||
}
|
||||
hir::BodyOwnerKind::Const { .. } => 0,
|
||||
|
@ -669,10 +669,10 @@ fn construct_error(tcx: TyCtxt<'_>, def: LocalDefId, err: ErrorGuaranteed) -> Bo
|
|||
num_params,
|
||||
vec![],
|
||||
span,
|
||||
generator_kind,
|
||||
coroutine_kind,
|
||||
Some(err),
|
||||
);
|
||||
body.generator.as_mut().map(|gen| gen.yield_ty = Some(ty));
|
||||
body.coroutine.as_mut().map(|gen| gen.yield_ty = Some(ty));
|
||||
body
|
||||
}
|
||||
|
||||
|
@ -687,7 +687,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
safety: Safety,
|
||||
return_ty: Ty<'tcx>,
|
||||
return_span: Span,
|
||||
generator_kind: Option<CoroutineKind>,
|
||||
coroutine_kind: Option<CoroutineKind>,
|
||||
) -> Builder<'a, 'tcx> {
|
||||
let tcx = infcx.tcx;
|
||||
let attrs = tcx.hir().attrs(hir_id);
|
||||
|
@ -718,7 +718,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
cfg: CFG { basic_blocks: IndexVec::new() },
|
||||
fn_span: span,
|
||||
arg_count,
|
||||
generator_kind,
|
||||
coroutine_kind,
|
||||
scopes: scope::Scopes::new(),
|
||||
block_context: BlockContext::new(),
|
||||
source_scopes: IndexVec::new(),
|
||||
|
@ -760,7 +760,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
self.arg_count,
|
||||
self.var_debug_info,
|
||||
self.fn_span,
|
||||
self.generator_kind,
|
||||
self.coroutine_kind,
|
||||
None,
|
||||
)
|
||||
}
|
||||
|
|
|
@ -109,7 +109,7 @@ pub struct Scopes<'tcx> {
|
|||
unwind_drops: DropTree,
|
||||
|
||||
/// Drops that need to be done on paths to the `CoroutineDrop` terminator.
|
||||
generator_drops: DropTree,
|
||||
coroutine_drops: DropTree,
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -133,8 +133,8 @@ struct Scope {
|
|||
cached_unwind_block: Option<DropIdx>,
|
||||
|
||||
/// The drop index that will drop everything in and below this scope on a
|
||||
/// generator drop path.
|
||||
cached_generator_drop_block: Option<DropIdx>,
|
||||
/// coroutine drop path.
|
||||
cached_coroutine_drop_block: Option<DropIdx>,
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
|
@ -194,7 +194,7 @@ const ROOT_NODE: DropIdx = DropIdx::from_u32(0);
|
|||
/// A tree of drops that we have deferred lowering. It's used for:
|
||||
///
|
||||
/// * Drops on unwind paths
|
||||
/// * Drops on generator drop paths (when a suspended generator is dropped)
|
||||
/// * Drops on coroutine drop paths (when a suspended coroutine is dropped)
|
||||
/// * Drops on return and loop exit paths
|
||||
/// * Drops on the else path in an `if let` chain
|
||||
///
|
||||
|
@ -222,8 +222,8 @@ impl Scope {
|
|||
/// * polluting the cleanup MIR with StorageDead creates
|
||||
/// landing pads even though there's no actual destructors
|
||||
/// * freeing up stack space has no effect during unwinding
|
||||
/// Note that for generators we do emit StorageDeads, for the
|
||||
/// use of optimizations in the MIR generator transform.
|
||||
/// Note that for coroutines we do emit StorageDeads, for the
|
||||
/// use of optimizations in the MIR coroutine transform.
|
||||
fn needs_cleanup(&self) -> bool {
|
||||
self.drops.iter().any(|drop| match drop.kind {
|
||||
DropKind::Value => true,
|
||||
|
@ -233,7 +233,7 @@ impl Scope {
|
|||
|
||||
fn invalidate_cache(&mut self) {
|
||||
self.cached_unwind_block = None;
|
||||
self.cached_generator_drop_block = None;
|
||||
self.cached_coroutine_drop_block = None;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -407,7 +407,7 @@ impl<'tcx> Scopes<'tcx> {
|
|||
breakable_scopes: Vec::new(),
|
||||
if_then_scope: None,
|
||||
unwind_drops: DropTree::new(),
|
||||
generator_drops: DropTree::new(),
|
||||
coroutine_drops: DropTree::new(),
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -419,7 +419,7 @@ impl<'tcx> Scopes<'tcx> {
|
|||
drops: vec![],
|
||||
moved_locals: vec![],
|
||||
cached_unwind_block: None,
|
||||
cached_generator_drop_block: None,
|
||||
cached_coroutine_drop_block: None,
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -734,7 +734,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
// If we are emitting a `drop` statement, we need to have the cached
|
||||
// diverge cleanup pads ready in case that drop panics.
|
||||
let needs_cleanup = self.scopes.scopes.last().is_some_and(|scope| scope.needs_cleanup());
|
||||
let is_generator = self.generator_kind.is_some();
|
||||
let is_coroutine = self.coroutine_kind.is_some();
|
||||
let unwind_to = if needs_cleanup { self.diverge_cleanup() } else { DropIdx::MAX };
|
||||
|
||||
let scope = self.scopes.scopes.last().expect("leave_top_scope called with no scopes");
|
||||
|
@ -744,7 +744,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
scope,
|
||||
block,
|
||||
unwind_to,
|
||||
is_generator && needs_cleanup,
|
||||
is_coroutine && needs_cleanup,
|
||||
self.arg_count,
|
||||
))
|
||||
}
|
||||
|
@ -984,11 +984,11 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
// caches gets invalidated. i.e., if a new drop is added into the middle scope, the
|
||||
// cache of outer scope stays intact.
|
||||
//
|
||||
// Since we only cache drops for the unwind path and the generator drop
|
||||
// Since we only cache drops for the unwind path and the coroutine drop
|
||||
// path, we only need to invalidate the cache for drops that happen on
|
||||
// the unwind or generator drop paths. This means that for
|
||||
// non-generators we don't need to invalidate caches for `DropKind::Storage`.
|
||||
let invalidate_caches = needs_drop || self.generator_kind.is_some();
|
||||
// the unwind or coroutine drop paths. This means that for
|
||||
// non-coroutines we don't need to invalidate caches for `DropKind::Storage`.
|
||||
let invalidate_caches = needs_drop || self.coroutine_kind.is_some();
|
||||
for scope in self.scopes.scopes.iter_mut().rev() {
|
||||
if invalidate_caches {
|
||||
scope.invalidate_cache();
|
||||
|
@ -1101,10 +1101,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
return cached_drop;
|
||||
}
|
||||
|
||||
let is_generator = self.generator_kind.is_some();
|
||||
let is_coroutine = self.coroutine_kind.is_some();
|
||||
for scope in &mut self.scopes.scopes[uncached_scope..=target] {
|
||||
for drop in &scope.drops {
|
||||
if is_generator || drop.kind == DropKind::Value {
|
||||
if is_coroutine || drop.kind == DropKind::Value {
|
||||
cached_drop = self.scopes.unwind_drops.add_drop(*drop, cached_drop);
|
||||
}
|
||||
}
|
||||
|
@ -1137,17 +1137,17 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
}
|
||||
|
||||
/// Sets up a path that performs all required cleanup for dropping a
|
||||
/// generator, starting from the given block that ends in
|
||||
/// coroutine, starting from the given block that ends in
|
||||
/// [TerminatorKind::Yield].
|
||||
///
|
||||
/// This path terminates in CoroutineDrop.
|
||||
pub(crate) fn generator_drop_cleanup(&mut self, yield_block: BasicBlock) {
|
||||
pub(crate) fn coroutine_drop_cleanup(&mut self, yield_block: BasicBlock) {
|
||||
debug_assert!(
|
||||
matches!(
|
||||
self.cfg.block_data(yield_block).terminator().kind,
|
||||
TerminatorKind::Yield { .. }
|
||||
),
|
||||
"generator_drop_cleanup called on block with non-yield terminator."
|
||||
"coroutine_drop_cleanup called on block with non-yield terminator."
|
||||
);
|
||||
let (uncached_scope, mut cached_drop) = self
|
||||
.scopes
|
||||
|
@ -1156,18 +1156,18 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
|
|||
.enumerate()
|
||||
.rev()
|
||||
.find_map(|(scope_idx, scope)| {
|
||||
scope.cached_generator_drop_block.map(|cached_block| (scope_idx + 1, cached_block))
|
||||
scope.cached_coroutine_drop_block.map(|cached_block| (scope_idx + 1, cached_block))
|
||||
})
|
||||
.unwrap_or((0, ROOT_NODE));
|
||||
|
||||
for scope in &mut self.scopes.scopes[uncached_scope..] {
|
||||
for drop in &scope.drops {
|
||||
cached_drop = self.scopes.generator_drops.add_drop(*drop, cached_drop);
|
||||
cached_drop = self.scopes.coroutine_drops.add_drop(*drop, cached_drop);
|
||||
}
|
||||
scope.cached_generator_drop_block = Some(cached_drop);
|
||||
scope.cached_coroutine_drop_block = Some(cached_drop);
|
||||
}
|
||||
|
||||
self.scopes.generator_drops.add_entry(yield_block, cached_drop);
|
||||
self.scopes.coroutine_drops.add_entry(yield_block, cached_drop);
|
||||
}
|
||||
|
||||
/// Utility function for *non*-scope code to build their own drops
|
||||
|
@ -1274,7 +1274,7 @@ fn build_scope_drops<'tcx>(
|
|||
// drops panic (panicking while unwinding will abort, so there's no need for
|
||||
// another set of arrows).
|
||||
//
|
||||
// For generators, we unwind from a drop on a local to its StorageDead
|
||||
// For coroutines, we unwind from a drop on a local to its StorageDead
|
||||
// statement. For other functions we don't worry about StorageDead. The
|
||||
// drops for the unwind path should have already been generated by
|
||||
// `diverge_cleanup_gen`.
|
||||
|
@ -1346,7 +1346,7 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
|
|||
blocks[ROOT_NODE] = continue_block;
|
||||
|
||||
drops.build_mir::<ExitScopes>(&mut self.cfg, &mut blocks);
|
||||
let is_generator = self.generator_kind.is_some();
|
||||
let is_coroutine = self.coroutine_kind.is_some();
|
||||
|
||||
// Link the exit drop tree to unwind drop tree.
|
||||
if drops.drops.iter().any(|(drop, _)| drop.kind == DropKind::Value) {
|
||||
|
@ -1355,7 +1355,7 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
|
|||
for (drop_idx, drop_data) in drops.drops.iter_enumerated().skip(1) {
|
||||
match drop_data.0.kind {
|
||||
DropKind::Storage => {
|
||||
if is_generator {
|
||||
if is_coroutine {
|
||||
let unwind_drop = self
|
||||
.scopes
|
||||
.unwind_drops
|
||||
|
@ -1381,10 +1381,10 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
|
|||
blocks[ROOT_NODE].map(BasicBlock::unit)
|
||||
}
|
||||
|
||||
/// Build the unwind and generator drop trees.
|
||||
/// Build the unwind and coroutine drop trees.
|
||||
pub(crate) fn build_drop_trees(&mut self) {
|
||||
if self.generator_kind.is_some() {
|
||||
self.build_generator_drop_trees();
|
||||
if self.coroutine_kind.is_some() {
|
||||
self.build_coroutine_drop_trees();
|
||||
} else {
|
||||
Self::build_unwind_tree(
|
||||
&mut self.cfg,
|
||||
|
@ -1395,9 +1395,9 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn build_generator_drop_trees(&mut self) {
|
||||
// Build the drop tree for dropping the generator while it's suspended.
|
||||
let drops = &mut self.scopes.generator_drops;
|
||||
fn build_coroutine_drop_trees(&mut self) {
|
||||
// Build the drop tree for dropping the coroutine while it's suspended.
|
||||
let drops = &mut self.scopes.coroutine_drops;
|
||||
let cfg = &mut self.cfg;
|
||||
let fn_span = self.fn_span;
|
||||
let mut blocks = IndexVec::from_elem(None, &drops.drops);
|
||||
|
@ -1416,11 +1416,11 @@ impl<'a, 'tcx: 'a> Builder<'a, 'tcx> {
|
|||
Self::build_unwind_tree(cfg, unwind_drops, fn_span, resume_block);
|
||||
|
||||
// Build the drop tree for unwinding when dropping a suspended
|
||||
// generator.
|
||||
// coroutine.
|
||||
//
|
||||
// This is a different tree to the standard unwind paths here to
|
||||
// prevent drop elaboration from creating drop flags that would have
|
||||
// to be captured by the generator. I'm not sure how important this
|
||||
// to be captured by the coroutine. I'm not sure how important this
|
||||
// optimization is, but it is here.
|
||||
for (drop_idx, drop_data) in drops.drops.iter_enumerated() {
|
||||
if let DropKind::Value = drop_data.0.kind {
|
||||
|
@ -1474,7 +1474,7 @@ impl<'tcx> DropTreeBuilder<'tcx> for CoroutineDrop {
|
|||
} else {
|
||||
span_bug!(
|
||||
term.source_info.span,
|
||||
"cannot enter generator drop tree from {:?}",
|
||||
"cannot enter coroutine drop tree from {:?}",
|
||||
term.kind
|
||||
)
|
||||
}
|
||||
|
|
|
@ -121,7 +121,7 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
|
|||
self.tcx.lint_level_at_node(UNSAFE_OP_IN_UNSAFE_FN, self.hir_context).0 == Level::Allow
|
||||
}
|
||||
|
||||
/// Handle closures/generators/inline-consts, which is unsafecked with their parent body.
|
||||
/// Handle closures/coroutines/inline-consts, which is unsafecked with their parent body.
|
||||
fn visit_inner_body(&mut self, def: LocalDefId) {
|
||||
if let Ok((inner_thir, expr)) = self.tcx.thir_body(def) {
|
||||
let inner_thir = &inner_thir.borrow();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue