s/generator/coroutine/

This commit is contained in:
Oli Scherer 2023-10-19 21:46:28 +00:00
parent 60956837cf
commit e96ce20b34
468 changed files with 2201 additions and 2197 deletions

View File

@ -1502,7 +1502,7 @@ pub struct LayoutS<FieldIdx: Idx, VariantIdx: Idx> {
/// Encodes information about multi-variant layouts. /// Encodes information about multi-variant layouts.
/// Even with `Multiple` variants, a layout still has its own fields! Those are then /// Even with `Multiple` variants, a layout still has its own fields! Those are then
/// shared between all variants. One of them will be the discriminant, /// shared between all variants. One of them will be the discriminant,
/// but e.g. generators can have more. /// but e.g. coroutines can have more.
/// ///
/// To access all fields of this layout, both `fields` and the fields of the active variant /// To access all fields of this layout, both `fields` and the fields of the active variant
/// must be taken into account. /// must be taken into account.

View File

@ -11,8 +11,8 @@ ast_lowering_argument = argument
ast_lowering_assoc_ty_parentheses = ast_lowering_assoc_ty_parentheses =
parenthesized generic arguments cannot be used in associated type constraints parenthesized generic arguments cannot be used in associated type constraints
ast_lowering_async_generators_not_supported = ast_lowering_async_coroutines_not_supported =
`async` generators are not yet supported `async` coroutines are not yet supported
ast_lowering_async_non_move_closure_not_supported = ast_lowering_async_non_move_closure_not_supported =
`async` non-`move` closures with parameters are not currently supported `async` non-`move` closures with parameters are not currently supported
@ -42,6 +42,9 @@ ast_lowering_clobber_abi_not_supported =
ast_lowering_closure_cannot_be_static = closures cannot be static ast_lowering_closure_cannot_be_static = closures cannot be static
ast_lowering_coroutine_too_many_parameters =
too many parameters for a coroutine (expected 0 or 1 parameters)
ast_lowering_does_not_support_modifiers = ast_lowering_does_not_support_modifiers =
the `{$class_name}` register class does not support template modifiers the `{$class_name}` register class does not support template modifiers
@ -53,9 +56,6 @@ ast_lowering_functional_record_update_destructuring_assignment =
functional record updates are not allowed in destructuring assignments functional record updates are not allowed in destructuring assignments
.suggestion = consider removing the trailing pattern .suggestion = consider removing the trailing pattern
ast_lowering_generator_too_many_parameters =
too many parameters for a generator (expected 0 or 1 parameters)
ast_lowering_generic_type_with_parentheses = ast_lowering_generic_type_with_parentheses =
parenthesized type parameters may only be used with a `Fn` trait parenthesized type parameters may only be used with a `Fn` trait
.label = only `Fn` traits may use parentheses .label = only `Fn` traits may use parentheses

View File

@ -131,7 +131,7 @@ pub struct AwaitOnlyInAsyncFnAndBlocks {
} }
#[derive(Diagnostic, Clone, Copy)] #[derive(Diagnostic, Clone, Copy)]
#[diag(ast_lowering_generator_too_many_parameters, code = "E0628")] #[diag(ast_lowering_coroutine_too_many_parameters, code = "E0628")]
pub struct CoroutineTooManyParameters { pub struct CoroutineTooManyParameters {
#[primary_span] #[primary_span]
pub fn_decl_span: Span, pub fn_decl_span: Span,
@ -161,7 +161,7 @@ pub struct FunctionalRecordUpdateDestructuringAssignment {
} }
#[derive(Diagnostic, Clone, Copy)] #[derive(Diagnostic, Clone, Copy)]
#[diag(ast_lowering_async_generators_not_supported, code = "E0727")] #[diag(ast_lowering_async_coroutines_not_supported, code = "E0727")]
pub struct AsyncCoroutinesNotSupported { pub struct AsyncCoroutinesNotSupported {
#[primary_span] #[primary_span]
pub span: Span, pub span: Span,

View File

@ -583,7 +583,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
} }
} }
/// Lower an `async` construct to a generator that implements `Future`. /// Lower an `async` construct to a coroutine that implements `Future`.
/// ///
/// This results in: /// This results in:
/// ///
@ -613,7 +613,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
span: unstable_span, span: unstable_span,
}; };
// The closure/generator `FnDecl` takes a single (resume) argument of type `input_ty`. // The closure/coroutine `FnDecl` takes a single (resume) argument of type `input_ty`.
let fn_decl = self.arena.alloc(hir::FnDecl { let fn_decl = self.arena.alloc(hir::FnDecl {
inputs: arena_vec![self; input_ty], inputs: arena_vec![self; input_ty],
output, output,
@ -637,7 +637,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
let params = arena_vec![self; param]; let params = arena_vec![self; param];
let body = self.lower_body(move |this| { let body = self.lower_body(move |this| {
this.generator_kind = Some(hir::CoroutineKind::Async(async_gen_kind)); this.coroutine_kind = Some(hir::CoroutineKind::Async(async_gen_kind));
let old_ctx = this.task_context; let old_ctx = this.task_context;
this.task_context = Some(task_context_hid); this.task_context = Some(task_context_hid);
@ -710,7 +710,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
/// ``` /// ```
fn lower_expr_await(&mut self, await_kw_span: Span, expr: &Expr) -> hir::ExprKind<'hir> { fn lower_expr_await(&mut self, await_kw_span: Span, expr: &Expr) -> hir::ExprKind<'hir> {
let full_span = expr.span.to(await_kw_span); let full_span = expr.span.to(await_kw_span);
match self.generator_kind { match self.coroutine_kind {
Some(hir::CoroutineKind::Async(_)) => {} Some(hir::CoroutineKind::Async(_)) => {}
Some(hir::CoroutineKind::Gen) | None => { Some(hir::CoroutineKind::Gen) | None => {
self.tcx.sess.emit_err(AwaitOnlyInAsyncFnAndBlocks { self.tcx.sess.emit_err(AwaitOnlyInAsyncFnAndBlocks {
@ -887,19 +887,19 @@ impl<'hir> LoweringContext<'_, 'hir> {
) -> hir::ExprKind<'hir> { ) -> hir::ExprKind<'hir> {
let (binder_clause, generic_params) = self.lower_closure_binder(binder); let (binder_clause, generic_params) = self.lower_closure_binder(binder);
let (body_id, generator_option) = self.with_new_scopes(move |this| { let (body_id, coroutine_option) = self.with_new_scopes(move |this| {
let prev = this.current_item; let prev = this.current_item;
this.current_item = Some(fn_decl_span); this.current_item = Some(fn_decl_span);
let mut generator_kind = None; let mut coroutine_kind = None;
let body_id = this.lower_fn_body(decl, |this| { let body_id = this.lower_fn_body(decl, |this| {
let e = this.lower_expr_mut(body); let e = this.lower_expr_mut(body);
generator_kind = this.generator_kind; coroutine_kind = this.coroutine_kind;
e e
}); });
let generator_option = let coroutine_option =
this.generator_movability_for_fn(&decl, fn_decl_span, generator_kind, movability); this.coroutine_movability_for_fn(&decl, fn_decl_span, coroutine_kind, movability);
this.current_item = prev; this.current_item = prev;
(body_id, generator_option) (body_id, coroutine_option)
}); });
let bound_generic_params = self.lower_lifetime_binder(closure_id, generic_params); let bound_generic_params = self.lower_lifetime_binder(closure_id, generic_params);
@ -915,21 +915,21 @@ impl<'hir> LoweringContext<'_, 'hir> {
body: body_id, body: body_id,
fn_decl_span: self.lower_span(fn_decl_span), fn_decl_span: self.lower_span(fn_decl_span),
fn_arg_span: Some(self.lower_span(fn_arg_span)), fn_arg_span: Some(self.lower_span(fn_arg_span)),
movability: generator_option, movability: coroutine_option,
constness: self.lower_constness(constness), constness: self.lower_constness(constness),
}); });
hir::ExprKind::Closure(c) hir::ExprKind::Closure(c)
} }
fn generator_movability_for_fn( fn coroutine_movability_for_fn(
&mut self, &mut self,
decl: &FnDecl, decl: &FnDecl,
fn_decl_span: Span, fn_decl_span: Span,
generator_kind: Option<hir::CoroutineKind>, coroutine_kind: Option<hir::CoroutineKind>,
movability: Movability, movability: Movability,
) -> Option<hir::Movability> { ) -> Option<hir::Movability> {
match generator_kind { match coroutine_kind {
Some(hir::CoroutineKind::Gen) => { Some(hir::CoroutineKind::Gen) => {
if decl.inputs.len() > 1 { if decl.inputs.len() > 1 {
self.tcx.sess.emit_err(CoroutineTooManyParameters { fn_decl_span }); self.tcx.sess.emit_err(CoroutineTooManyParameters { fn_decl_span });
@ -1444,12 +1444,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
} }
fn lower_expr_yield(&mut self, span: Span, opt_expr: Option<&Expr>) -> hir::ExprKind<'hir> { fn lower_expr_yield(&mut self, span: Span, opt_expr: Option<&Expr>) -> hir::ExprKind<'hir> {
match self.generator_kind { match self.coroutine_kind {
Some(hir::CoroutineKind::Gen) => {} Some(hir::CoroutineKind::Gen) => {}
Some(hir::CoroutineKind::Async(_)) => { Some(hir::CoroutineKind::Async(_)) => {
self.tcx.sess.emit_err(AsyncCoroutinesNotSupported { span }); self.tcx.sess.emit_err(AsyncCoroutinesNotSupported { span });
} }
None => self.generator_kind = Some(hir::CoroutineKind::Gen), None => self.coroutine_kind = Some(hir::CoroutineKind::Gen),
} }
let expr = let expr =

View File

@ -82,7 +82,7 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> {
is_in_loop_condition: false, is_in_loop_condition: false,
is_in_trait_impl: false, is_in_trait_impl: false,
is_in_dyn_type: false, is_in_dyn_type: false,
generator_kind: None, coroutine_kind: None,
task_context: None, task_context: None,
current_item: None, current_item: None,
impl_trait_defs: Vec::new(), impl_trait_defs: Vec::new(),
@ -974,7 +974,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
value: hir::Expr<'hir>, value: hir::Expr<'hir>,
) -> hir::BodyId { ) -> hir::BodyId {
let body = hir::Body { let body = hir::Body {
generator_kind: self.generator_kind, coroutine_kind: self.coroutine_kind,
params, params,
value: self.arena.alloc(value), value: self.arena.alloc(value),
}; };
@ -988,12 +988,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
&mut self, &mut self,
f: impl FnOnce(&mut Self) -> (&'hir [hir::Param<'hir>], hir::Expr<'hir>), f: impl FnOnce(&mut Self) -> (&'hir [hir::Param<'hir>], hir::Expr<'hir>),
) -> hir::BodyId { ) -> hir::BodyId {
let prev_gen_kind = self.generator_kind.take(); let prev_gen_kind = self.coroutine_kind.take();
let task_context = self.task_context.take(); let task_context = self.task_context.take();
let (parameters, result) = f(self); let (parameters, result) = f(self);
let body_id = self.record_body(parameters, result); let body_id = self.record_body(parameters, result);
self.task_context = task_context; self.task_context = task_context;
self.generator_kind = prev_gen_kind; self.coroutine_kind = prev_gen_kind;
body_id body_id
} }

View File

@ -111,10 +111,10 @@ struct LoweringContext<'a, 'hir> {
/// Collect items that were created by lowering the current owner. /// Collect items that were created by lowering the current owner.
children: Vec<(LocalDefId, hir::MaybeOwner<&'hir hir::OwnerInfo<'hir>>)>, children: Vec<(LocalDefId, hir::MaybeOwner<&'hir hir::OwnerInfo<'hir>>)>,
generator_kind: Option<hir::CoroutineKind>, coroutine_kind: Option<hir::CoroutineKind>,
/// When inside an `async` context, this is the `HirId` of the /// When inside an `async` context, this is the `HirId` of the
/// `task_context` local bound to the resume argument of the generator. /// `task_context` local bound to the resume argument of the coroutine.
task_context: Option<hir::HirId>, task_context: Option<hir::HirId>,
/// Used to get the current `fn`'s def span to point to when using `await` /// Used to get the current `fn`'s def span to point to when using `await`

View File

@ -554,7 +554,7 @@ pub fn check_crate(krate: &ast::Crate, sess: &Session, features: &Features) {
"consider removing `for<...>`" "consider removing `for<...>`"
); );
gate_all!(more_qualified_paths, "usage of qualified paths in this context is experimental"); gate_all!(more_qualified_paths, "usage of qualified paths in this context is experimental");
gate_all!(generators, "yield syntax is experimental"); gate_all!(coroutines, "yield syntax is experimental");
gate_all!(raw_ref_op, "raw address of syntax is experimental"); gate_all!(raw_ref_op, "raw address of syntax is experimental");
gate_all!(const_trait_impl, "const trait impls are experimental"); gate_all!(const_trait_impl, "const trait impls are experimental");
gate_all!( gate_all!(

View File

@ -1,20 +1,20 @@
borrowck_assign_due_to_use_closure = borrowck_assign_due_to_use_closure =
assignment occurs due to use in closure assignment occurs due to use in closure
borrowck_assign_due_to_use_generator = borrowck_assign_due_to_use_coroutine =
assign occurs due to use in generator assign occurs due to use in coroutine
borrowck_assign_part_due_to_use_closure = borrowck_assign_part_due_to_use_closure =
assignment to part occurs due to use in closure assignment to part occurs due to use in closure
borrowck_assign_part_due_to_use_generator = borrowck_assign_part_due_to_use_coroutine =
assign to part occurs due to use in generator assign to part occurs due to use in coroutine
borrowck_borrow_due_to_use_closure = borrowck_borrow_due_to_use_closure =
borrow occurs due to use in closure borrow occurs due to use in closure
borrowck_borrow_due_to_use_generator = borrowck_borrow_due_to_use_coroutine =
borrow occurs due to use in generator borrow occurs due to use in coroutine
borrowck_calling_operator_moves_lhs = borrowck_calling_operator_moves_lhs =
calling this operator moves the left-hand side calling this operator moves the left-hand side
@ -142,11 +142,11 @@ borrowck_partial_var_move_by_use_in_closure =
*[false] moved *[false] moved
} due to use in closure } due to use in closure
borrowck_partial_var_move_by_use_in_generator = borrowck_partial_var_move_by_use_in_coroutine =
variable {$is_partial -> variable {$is_partial ->
[true] partially moved [true] partially moved
*[false] moved *[false] moved
} due to use in generator } due to use in coroutine
borrowck_returned_async_block_escaped = borrowck_returned_async_block_escaped =
returns an `async` block that contains a reference to a captured variable, which then escapes the closure body returns an `async` block that contains a reference to a captured variable, which then escapes the closure body
@ -180,15 +180,15 @@ borrowck_ty_no_impl_copy =
borrowck_use_due_to_use_closure = borrowck_use_due_to_use_closure =
use occurs due to use in closure use occurs due to use in closure
borrowck_use_due_to_use_generator = borrowck_use_due_to_use_coroutine =
use occurs due to use in generator use occurs due to use in coroutine
borrowck_used_impl_require_static = borrowck_used_impl_require_static =
the used `impl` has a `'static` requirement the used `impl` has a `'static` requirement
borrowck_value_capture_here = borrowck_value_capture_here =
value captured {$is_within -> value captured {$is_within ->
[true] here by generator [true] here by coroutine
*[false] here *[false] here
} }
@ -207,8 +207,8 @@ borrowck_value_moved_here =
borrowck_var_borrow_by_use_in_closure = borrowck_var_borrow_by_use_in_closure =
borrow occurs due to use in closure borrow occurs due to use in closure
borrowck_var_borrow_by_use_in_generator = borrowck_var_borrow_by_use_in_coroutine =
borrow occurs due to use in generator borrow occurs due to use in coroutine
borrowck_var_borrow_by_use_place_in_closure = borrowck_var_borrow_by_use_place_in_closure =
{$is_single_var -> {$is_single_var ->
@ -216,11 +216,11 @@ borrowck_var_borrow_by_use_place_in_closure =
[false] borrows occur [false] borrows occur
} due to use of {$place} in closure } due to use of {$place} in closure
borrowck_var_borrow_by_use_place_in_generator = borrowck_var_borrow_by_use_place_in_coroutine =
{$is_single_var -> {$is_single_var ->
*[true] borrow occurs *[true] borrow occurs
[false] borrows occur [false] borrows occur
} due to use of {$place} in generator } due to use of {$place} in coroutine
borrowck_var_cannot_escape_closure = borrowck_var_cannot_escape_closure =
captured variable cannot escape `FnMut` closure body captured variable cannot escape `FnMut` closure body
@ -234,8 +234,8 @@ borrowck_var_does_not_need_mut =
borrowck_var_first_borrow_by_use_place_in_closure = borrowck_var_first_borrow_by_use_place_in_closure =
first borrow occurs due to use of {$place} in closure first borrow occurs due to use of {$place} in closure
borrowck_var_first_borrow_by_use_place_in_generator = borrowck_var_first_borrow_by_use_place_in_coroutine =
first borrow occurs due to use of {$place} in generator first borrow occurs due to use of {$place} in coroutine
borrowck_var_here_captured = variable captured here borrowck_var_here_captured = variable captured here
@ -244,8 +244,8 @@ borrowck_var_here_defined = variable defined here
borrowck_var_move_by_use_in_closure = borrowck_var_move_by_use_in_closure =
move occurs due to use in closure move occurs due to use in closure
borrowck_var_move_by_use_in_generator = borrowck_var_move_by_use_in_coroutine =
move occurs due to use in generator move occurs due to use in coroutine
borrowck_var_mutable_borrow_by_use_place_in_closure = borrowck_var_mutable_borrow_by_use_place_in_closure =
mutable borrow occurs due to use of {$place} in closure mutable borrow occurs due to use of {$place} in closure
@ -253,5 +253,5 @@ borrowck_var_mutable_borrow_by_use_place_in_closure =
borrowck_var_second_borrow_by_use_place_in_closure = borrowck_var_second_borrow_by_use_place_in_closure =
second borrow occurs due to use of {$place} in closure second borrow occurs due to use of {$place} in closure
borrowck_var_second_borrow_by_use_place_in_generator = borrowck_var_second_borrow_by_use_place_in_coroutine =
second borrow occurs due to use of {$place} in generator second borrow occurs due to use of {$place} in coroutine

View File

@ -368,7 +368,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
err err
} }
pub(crate) fn cannot_borrow_across_generator_yield( pub(crate) fn cannot_borrow_across_coroutine_yield(
&self, &self,
span: Span, span: Span,
yield_span: Span, yield_span: Span,
@ -377,7 +377,7 @@ impl<'cx, 'tcx> crate::MirBorrowckCtxt<'cx, 'tcx> {
self, self,
span, span,
E0626, E0626,
"borrow may still be in use when generator yields", "borrow may still be in use when coroutine yields",
); );
err.span_label(yield_span, "possible yield occurs here"); err.span_label(yield_span, "possible yield occurs here");
err err

View File

@ -44,7 +44,7 @@ pub fn categorize(context: PlaceContext) -> Option<DefUse> {
PlaceContext::MutatingUse(MutatingUseContext::Projection) | PlaceContext::MutatingUse(MutatingUseContext::Projection) |
// Borrows only consider their local used at the point of the borrow. // Borrows only consider their local used at the point of the borrow.
// This won't affect the results since we use this analysis for generators // This won't affect the results since we use this analysis for coroutines
// and we only care about the result at suspension points. Borrows cannot // and we only care about the result at suspension points. Borrows cannot
// cross suspension points so this behavior is unproblematic. // cross suspension points so this behavior is unproblematic.
PlaceContext::MutatingUse(MutatingUseContext::Borrow) | PlaceContext::MutatingUse(MutatingUseContext::Borrow) |

View File

@ -926,8 +926,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let borrow_spans = self.borrow_spans(span, location); let borrow_spans = self.borrow_spans(span, location);
let span = borrow_spans.args_or_use(); let span = borrow_spans.args_or_use();
let container_name = if issued_spans.for_generator() || borrow_spans.for_generator() { let container_name = if issued_spans.for_coroutine() || borrow_spans.for_coroutine() {
"generator" "coroutine"
} else { } else {
"closure" "closure"
}; };
@ -1575,7 +1575,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
// Get closure's arguments // Get closure's arguments
let ty::Closure(_, args) = typeck_results.expr_ty(closure_expr).kind() else { let ty::Closure(_, args) = typeck_results.expr_ty(closure_expr).kind() else {
/* hir::Closure can be a generator too */ /* hir::Closure can be a coroutine too */
return; return;
}; };
let sig = args.as_closure().sig(); let sig = args.as_closure().sig();
@ -1949,7 +1949,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
( (
Some(name), Some(name),
BorrowExplanation::UsedLater(LaterUseKind::ClosureCapture, var_or_use_span, _), BorrowExplanation::UsedLater(LaterUseKind::ClosureCapture, var_or_use_span, _),
) if borrow_spans.for_generator() || borrow_spans.for_closure() => self ) if borrow_spans.for_coroutine() || borrow_spans.for_closure() => self
.report_escaping_closure_capture( .report_escaping_closure_capture(
borrow_spans, borrow_spans,
borrow_span, borrow_span,
@ -1974,7 +1974,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
span, span,
.. ..
}, },
) if borrow_spans.for_generator() || borrow_spans.for_closure() => self ) if borrow_spans.for_coroutine() || borrow_spans.for_closure() => self
.report_escaping_closure_capture( .report_escaping_closure_capture(
borrow_spans, borrow_spans,
borrow_span, borrow_span,
@ -2077,8 +2077,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
.unwrap_or_else(|| { .unwrap_or_else(|| {
match &self.infcx.tcx.def_kind(self.mir_def_id()) { match &self.infcx.tcx.def_kind(self.mir_def_id()) {
DefKind::Closure => "enclosing closure", DefKind::Closure => "enclosing closure",
DefKind::Coroutine => "enclosing generator", DefKind::Coroutine => "enclosing coroutine",
kind => bug!("expected closure or generator, found {:?}", kind), kind => bug!("expected closure or coroutine, found {:?}", kind),
} }
.to_string() .to_string()
}) })
@ -2112,7 +2112,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
borrow_spans.args_subdiag(&mut err, |args_span| { borrow_spans.args_subdiag(&mut err, |args_span| {
crate::session_diagnostics::CaptureArgLabel::Capture { crate::session_diagnostics::CaptureArgLabel::Capture {
is_within: borrow_spans.for_generator(), is_within: borrow_spans.for_coroutine(),
args_span, args_span,
} }
}); });
@ -2353,7 +2353,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
borrow_spans.args_subdiag(&mut err, |args_span| { borrow_spans.args_subdiag(&mut err, |args_span| {
crate::session_diagnostics::CaptureArgLabel::Capture { crate::session_diagnostics::CaptureArgLabel::Capture {
is_within: borrow_spans.for_generator(), is_within: borrow_spans.for_coroutine(),
args_span, args_span,
} }
}); });
@ -2481,14 +2481,14 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
} }
Err(_) => (args_span, "move |<args>| <body>"), Err(_) => (args_span, "move |<args>| <body>"),
}; };
let kind = match use_span.generator_kind() { let kind = match use_span.coroutine_kind() {
Some(generator_kind) => match generator_kind { Some(coroutine_kind) => match coroutine_kind {
CoroutineKind::Async(async_kind) => match async_kind { CoroutineKind::Async(async_kind) => match async_kind {
AsyncCoroutineKind::Block => "async block", AsyncCoroutineKind::Block => "async block",
AsyncCoroutineKind::Closure => "async closure", AsyncCoroutineKind::Closure => "async closure",
_ => bug!("async block/closure expected, but async function found."), _ => bug!("async block/closure expected, but async function found."),
}, },
CoroutineKind::Gen => "generator", CoroutineKind::Gen => "coroutine",
}, },
None => "closure", None => "closure",
}; };
@ -2517,7 +2517,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
} }
ConstraintCategory::CallArgument(_) => { ConstraintCategory::CallArgument(_) => {
fr_name.highlight_region_name(&mut err); fr_name.highlight_region_name(&mut err);
if matches!(use_span.generator_kind(), Some(CoroutineKind::Async(_))) { if matches!(use_span.coroutine_kind(), Some(CoroutineKind::Async(_))) {
err.note( err.note(
"async blocks are not executed immediately and must either take a \ "async blocks are not executed immediately and must either take a \
reference or ownership of outside variables they use", reference or ownership of outside variables they use",

View File

@ -182,7 +182,7 @@ impl<'tcx> BorrowExplanation<'tcx> {
// Otherwise, just report the whole type (and use // Otherwise, just report the whole type (and use
// the intentionally fuzzy phrase "destructor") // the intentionally fuzzy phrase "destructor")
ty::Closure(..) => ("destructor", "closure".to_owned()), ty::Closure(..) => ("destructor", "closure".to_owned()),
ty::Coroutine(..) => ("destructor", "generator".to_owned()), ty::Coroutine(..) => ("destructor", "coroutine".to_owned()),
_ => ("destructor", format!("type `{}`", local_decl.ty)), _ => ("destructor", format!("type `{}`", local_decl.ty)),
}; };

View File

@ -501,8 +501,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
pub(super) enum UseSpans<'tcx> { pub(super) enum UseSpans<'tcx> {
/// The access is caused by capturing a variable for a closure. /// The access is caused by capturing a variable for a closure.
ClosureUse { ClosureUse {
/// This is true if the captured variable was from a generator. /// This is true if the captured variable was from a coroutine.
generator_kind: Option<CoroutineKind>, coroutine_kind: Option<CoroutineKind>,
/// The span of the args of the closure, including the `move` keyword if /// The span of the args of the closure, including the `move` keyword if
/// it's present. /// it's present.
args_span: Span, args_span: Span,
@ -569,9 +569,9 @@ impl UseSpans<'_> {
} }
} }
pub(super) fn generator_kind(self) -> Option<CoroutineKind> { pub(super) fn coroutine_kind(self) -> Option<CoroutineKind> {
match self { match self {
UseSpans::ClosureUse { generator_kind, .. } => generator_kind, UseSpans::ClosureUse { coroutine_kind, .. } => coroutine_kind,
_ => None, _ => None,
} }
} }
@ -596,8 +596,8 @@ impl UseSpans<'_> {
) { ) {
use crate::InitializationRequiringAction::*; use crate::InitializationRequiringAction::*;
use CaptureVarPathUseCause::*; use CaptureVarPathUseCause::*;
if let UseSpans::ClosureUse { generator_kind, path_span, .. } = self { if let UseSpans::ClosureUse { coroutine_kind, path_span, .. } = self {
match generator_kind { match coroutine_kind {
Some(_) => { Some(_) => {
err.subdiagnostic(match action { err.subdiagnostic(match action {
Borrow => BorrowInCoroutine { path_span }, Borrow => BorrowInCoroutine { path_span },
@ -626,7 +626,7 @@ impl UseSpans<'_> {
kind: Option<rustc_middle::mir::BorrowKind>, kind: Option<rustc_middle::mir::BorrowKind>,
f: impl FnOnce(Option<CoroutineKind>, Span) -> CaptureVarCause, f: impl FnOnce(Option<CoroutineKind>, Span) -> CaptureVarCause,
) { ) {
if let UseSpans::ClosureUse { generator_kind, capture_kind_span, path_span, .. } = self { if let UseSpans::ClosureUse { coroutine_kind, capture_kind_span, path_span, .. } = self {
if capture_kind_span != path_span { if capture_kind_span != path_span {
err.subdiagnostic(match kind { err.subdiagnostic(match kind {
Some(kd) => match kd { Some(kd) => match kd {
@ -642,7 +642,7 @@ impl UseSpans<'_> {
None => CaptureVarKind::Move { kind_span: capture_kind_span }, None => CaptureVarKind::Move { kind_span: capture_kind_span },
}); });
}; };
let diag = f(generator_kind, path_span); let diag = f(coroutine_kind, path_span);
match handler { match handler {
Some(hd) => err.eager_subdiagnostic(hd, diag), Some(hd) => err.eager_subdiagnostic(hd, diag),
None => err.subdiagnostic(diag), None => err.subdiagnostic(diag),
@ -653,15 +653,15 @@ impl UseSpans<'_> {
/// Returns `false` if this place is not used in a closure. /// Returns `false` if this place is not used in a closure.
pub(super) fn for_closure(&self) -> bool { pub(super) fn for_closure(&self) -> bool {
match *self { match *self {
UseSpans::ClosureUse { generator_kind, .. } => generator_kind.is_none(), UseSpans::ClosureUse { coroutine_kind, .. } => coroutine_kind.is_none(),
_ => false, _ => false,
} }
} }
/// Returns `false` if this place is not used in a generator. /// Returns `false` if this place is not used in a coroutine.
pub(super) fn for_generator(&self) -> bool { pub(super) fn for_coroutine(&self) -> bool {
match *self { match *self {
UseSpans::ClosureUse { generator_kind, .. } => generator_kind.is_some(), UseSpans::ClosureUse { coroutine_kind, .. } => coroutine_kind.is_some(),
_ => false, _ => false,
} }
} }
@ -785,10 +785,10 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
{ {
debug!("move_spans: def_id={:?} places={:?}", def_id, places); debug!("move_spans: def_id={:?} places={:?}", def_id, places);
let def_id = def_id.expect_local(); let def_id = def_id.expect_local();
if let Some((args_span, generator_kind, capture_kind_span, path_span)) = if let Some((args_span, coroutine_kind, capture_kind_span, path_span)) =
self.closure_span(def_id, moved_place, places) self.closure_span(def_id, moved_place, places)
{ {
return ClosureUse { generator_kind, args_span, capture_kind_span, path_span }; return ClosureUse { coroutine_kind, args_span, capture_kind_span, path_span };
} }
} }
@ -800,11 +800,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
| FakeReadCause::ForLet(Some(closure_def_id)) => { | FakeReadCause::ForLet(Some(closure_def_id)) => {
debug!("move_spans: def_id={:?} place={:?}", closure_def_id, place); debug!("move_spans: def_id={:?} place={:?}", closure_def_id, place);
let places = &[Operand::Move(place)]; let places = &[Operand::Move(place)];
if let Some((args_span, generator_kind, capture_kind_span, path_span)) = if let Some((args_span, coroutine_kind, capture_kind_span, path_span)) =
self.closure_span(closure_def_id, moved_place, IndexSlice::from_raw(places)) self.closure_span(closure_def_id, moved_place, IndexSlice::from_raw(places))
{ {
return ClosureUse { return ClosureUse {
generator_kind, coroutine_kind,
args_span, args_span,
capture_kind_span, capture_kind_span,
path_span, path_span,
@ -914,7 +914,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
for stmt in statements.chain(maybe_additional_statement) { for stmt in statements.chain(maybe_additional_statement) {
if let StatementKind::Assign(box (_, Rvalue::Aggregate(kind, places))) = &stmt.kind { if let StatementKind::Assign(box (_, Rvalue::Aggregate(kind, places))) = &stmt.kind {
let (&def_id, is_generator) = match kind { let (&def_id, is_coroutine) = match kind {
box AggregateKind::Closure(def_id, _) => (def_id, false), box AggregateKind::Closure(def_id, _) => (def_id, false),
box AggregateKind::Coroutine(def_id, _, _) => (def_id, true), box AggregateKind::Coroutine(def_id, _, _) => (def_id, true),
_ => continue, _ => continue,
@ -922,13 +922,13 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
let def_id = def_id.expect_local(); let def_id = def_id.expect_local();
debug!( debug!(
"borrow_spans: def_id={:?} is_generator={:?} places={:?}", "borrow_spans: def_id={:?} is_coroutine={:?} places={:?}",
def_id, is_generator, places def_id, is_coroutine, places
); );
if let Some((args_span, generator_kind, capture_kind_span, path_span)) = if let Some((args_span, coroutine_kind, capture_kind_span, path_span)) =
self.closure_span(def_id, Place::from(target).as_ref(), places) self.closure_span(def_id, Place::from(target).as_ref(), places)
{ {
return ClosureUse { generator_kind, args_span, capture_kind_span, path_span }; return ClosureUse { coroutine_kind, args_span, capture_kind_span, path_span };
} else { } else {
return OtherUse(use_span); return OtherUse(use_span);
} }
@ -942,7 +942,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
OtherUse(use_span) OtherUse(use_span)
} }
/// Finds the spans of a captured place within a closure or generator. /// Finds the spans of a captured place within a closure or coroutine.
/// The first span is the location of the use resulting in the capture kind of the capture /// The first span is the location of the use resulting in the capture kind of the capture
/// The second span is the location the use resulting in the captured path of the capture /// The second span is the location the use resulting in the captured path of the capture
fn closure_span( fn closure_span(
@ -968,11 +968,11 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
{ {
debug!("closure_span: found captured local {:?}", place); debug!("closure_span: found captured local {:?}", place);
let body = self.infcx.tcx.hir().body(body); let body = self.infcx.tcx.hir().body(body);
let generator_kind = body.generator_kind(); let coroutine_kind = body.coroutine_kind();
return Some(( return Some((
fn_decl_span, fn_decl_span,
generator_kind, coroutine_kind,
captured_place.get_capture_kind_span(self.infcx.tcx), captured_place.get_capture_kind_span(self.infcx.tcx),
captured_place.get_path_span(self.infcx.tcx), captured_place.get_path_span(self.infcx.tcx),
)); ));

View File

@ -62,7 +62,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
local, local,
projection: [proj_base @ .., ProjectionElem::Field(upvar_index, _)], projection: [proj_base @ .., ProjectionElem::Field(upvar_index, _)],
} => { } => {
debug_assert!(is_closure_or_generator( debug_assert!(is_closure_or_coroutine(
Place::ty_from(local, proj_base, self.body, self.infcx.tcx).ty Place::ty_from(local, proj_base, self.body, self.infcx.tcx).ty
)); ));
@ -122,7 +122,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
{ {
item_msg = access_place_desc; item_msg = access_place_desc;
debug_assert!(self.body.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty.is_ref()); debug_assert!(self.body.local_decls[ty::CAPTURE_STRUCT_LOCAL].ty.is_ref());
debug_assert!(is_closure_or_generator( debug_assert!(is_closure_or_coroutine(
the_place_err.ty(self.body, self.infcx.tcx).ty the_place_err.ty(self.body, self.infcx.tcx).ty
)); ));
@ -385,7 +385,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
local, local,
projection: [proj_base @ .., ProjectionElem::Field(upvar_index, _)], projection: [proj_base @ .., ProjectionElem::Field(upvar_index, _)],
} => { } => {
debug_assert!(is_closure_or_generator( debug_assert!(is_closure_or_coroutine(
Place::ty_from(local, proj_base, self.body, self.infcx.tcx).ty Place::ty_from(local, proj_base, self.body, self.infcx.tcx).ty
)); ));
@ -1377,8 +1377,8 @@ fn suggest_ampmut<'tcx>(
} }
} }
fn is_closure_or_generator(ty: Ty<'_>) -> bool { fn is_closure_or_coroutine(ty: Ty<'_>) -> bool {
ty.is_closure() || ty.is_generator() ty.is_closure() || ty.is_coroutine()
} }
/// Given a field that needs to be mutable, returns a span where the " mut " could go. /// Given a field that needs to be mutable, returns a span where the " mut " could go.

View File

@ -580,7 +580,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
let err = FnMutError { let err = FnMutError {
span: *span, span: *span,
ty_err: match output_ty.kind() { ty_err: match output_ty.kind() {
ty::Coroutine(def, ..) if self.infcx.tcx.generator_is_async(*def) => { ty::Coroutine(def, ..) if self.infcx.tcx.coroutine_is_async(*def) => {
FnMutReturnTypeErr::ReturnAsyncBlock { span: *span } FnMutReturnTypeErr::ReturnAsyncBlock { span: *span }
} }
_ if output_ty.contains_closure() => { _ if output_ty.contains_closure() => {
@ -1036,7 +1036,7 @@ impl<'a, 'tcx> MirBorrowckCtxt<'a, 'tcx> {
.. ..
}) => { }) => {
let body = map.body(*body); let body = map.body(*body);
if !matches!(body.generator_kind, Some(hir::CoroutineKind::Async(..))) { if !matches!(body.coroutine_kind, Some(hir::CoroutineKind::Async(..))) {
closure_span = Some(expr.span.shrink_to_lo()); closure_span = Some(expr.span.shrink_to_lo());
} }
} }

View File

@ -41,7 +41,7 @@ pub(crate) enum RegionNameSource {
AnonRegionFromUpvar(Span, Symbol), AnonRegionFromUpvar(Span, Symbol),
/// The region corresponding to the return type of a closure. /// The region corresponding to the return type of a closure.
AnonRegionFromOutput(RegionNameHighlight, &'static str), AnonRegionFromOutput(RegionNameHighlight, &'static str),
/// The region from a type yielded by a generator. /// The region from a type yielded by a coroutine.
AnonRegionFromYieldTy(Span, String), AnonRegionFromYieldTy(Span, String),
/// An anonymous region from an async fn. /// An anonymous region from an async fn.
AnonRegionFromAsyncFn(Span), AnonRegionFromAsyncFn(Span),
@ -322,7 +322,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
let def_ty = self.regioncx.universal_regions().defining_ty; let def_ty = self.regioncx.universal_regions().defining_ty;
let DefiningTy::Closure(_, args) = def_ty else { let DefiningTy::Closure(_, args) = def_ty else {
// Can't have BrEnv in functions, constants or generators. // Can't have BrEnv in functions, constants or coroutines.
bug!("BrEnv outside of closure."); bug!("BrEnv outside of closure.");
}; };
let hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }) = let hir::ExprKind::Closure(&hir::Closure { fn_decl_span, .. }) =
@ -680,7 +680,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
} }
hir::FnRetTy::Return(hir_ty) => (fn_decl.output.span(), Some(hir_ty)), hir::FnRetTy::Return(hir_ty) => (fn_decl.output.span(), Some(hir_ty)),
}; };
let mir_description = match hir.body(body).generator_kind { let mir_description = match hir.body(body).coroutine_kind {
Some(hir::CoroutineKind::Async(gen)) => match gen { Some(hir::CoroutineKind::Async(gen)) => match gen {
hir::AsyncCoroutineKind::Block => " of async block", hir::AsyncCoroutineKind::Block => " of async block",
hir::AsyncCoroutineKind::Closure => " of async closure", hir::AsyncCoroutineKind::Closure => " of async closure",
@ -689,7 +689,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
hir.get_by_def_id(hir.get_parent_item(mir_hir_id).def_id); hir.get_by_def_id(hir.get_parent_item(mir_hir_id).def_id);
let output = &parent_item let output = &parent_item
.fn_decl() .fn_decl()
.expect("generator lowered from async fn should be in fn") .expect("coroutine lowered from async fn should be in fn")
.output; .output;
span = output.span(); span = output.span();
if let hir::FnRetTy::Return(ret) = output { if let hir::FnRetTy::Return(ret) = output {
@ -698,7 +698,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
" of async function" " of async function"
} }
}, },
Some(hir::CoroutineKind::Gen) => " of generator", Some(hir::CoroutineKind::Gen) => " of coroutine",
None => " of closure", None => " of closure",
}; };
(span, mir_description, hir_ty) (span, mir_description, hir_ty)
@ -793,7 +793,7 @@ impl<'tcx> MirBorrowckCtxt<'_, 'tcx> {
&self, &self,
fr: RegionVid, fr: RegionVid,
) -> Option<RegionName> { ) -> Option<RegionName> {
// Note: generators from `async fn` yield `()`, so we don't have to // Note: coroutines from `async fn` yield `()`, so we don't have to
// worry about them here. // worry about them here.
let yield_ty = self.regioncx.universal_regions().yield_ty?; let yield_ty = self.regioncx.universal_regions().yield_ty?;
debug!("give_name_if_anonymous_region_appears_in_yield_ty: yield_ty = {:?}", yield_ty); debug!("give_name_if_anonymous_region_appears_in_yield_ty: yield_ty = {:?}", yield_ty);

View File

@ -302,8 +302,8 @@ fn do_mir_borrowck<'tcx>(
.pass_name("borrowck") .pass_name("borrowck")
.iterate_to_fixpoint(); .iterate_to_fixpoint();
let movable_generator = let movable_coroutine =
// The first argument is the generator type passed by value // The first argument is the coroutine type passed by value
if let Some(local) = body.local_decls.raw.get(1) if let Some(local) = body.local_decls.raw.get(1)
// Get the interior types and args which typeck computed // Get the interior types and args which typeck computed
&& let ty::Coroutine(_, _, hir::Movability::Static) = local.ty.kind() && let ty::Coroutine(_, _, hir::Movability::Static) = local.ty.kind()
@ -323,7 +323,7 @@ fn do_mir_borrowck<'tcx>(
body: promoted_body, body: promoted_body,
move_data: &move_data, move_data: &move_data,
location_table, // no need to create a real one for the promoted, it is not used location_table, // no need to create a real one for the promoted, it is not used
movable_generator, movable_coroutine,
fn_self_span_reported: Default::default(), fn_self_span_reported: Default::default(),
locals_are_invalidated_at_exit, locals_are_invalidated_at_exit,
access_place_error_reported: Default::default(), access_place_error_reported: Default::default(),
@ -351,7 +351,7 @@ fn do_mir_borrowck<'tcx>(
body, body,
move_data: &mdpe.move_data, move_data: &mdpe.move_data,
location_table, location_table,
movable_generator, movable_coroutine,
locals_are_invalidated_at_exit, locals_are_invalidated_at_exit,
fn_self_span_reported: Default::default(), fn_self_span_reported: Default::default(),
access_place_error_reported: Default::default(), access_place_error_reported: Default::default(),
@ -536,7 +536,7 @@ struct MirBorrowckCtxt<'cx, 'tcx> {
/// when MIR borrowck begins. /// when MIR borrowck begins.
location_table: &'cx LocationTable, location_table: &'cx LocationTable,
movable_generator: bool, movable_coroutine: bool,
/// This keeps track of whether local variables are free-ed when the function /// This keeps track of whether local variables are free-ed when the function
/// exits even without a `StorageDead`, which appears to be the case for /// exits even without a `StorageDead`, which appears to be the case for
/// constants. /// constants.
@ -797,7 +797,7 @@ impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorro
match term.kind { match term.kind {
TerminatorKind::Yield { value: _, resume: _, resume_arg: _, drop: _ } => { TerminatorKind::Yield { value: _, resume: _, resume_arg: _, drop: _ } => {
if self.movable_generator { if self.movable_coroutine {
// Look for any active borrows to locals // Look for any active borrows to locals
let borrow_set = self.borrow_set.clone(); let borrow_set = self.borrow_set.clone();
for i in flow_state.borrows.iter() { for i in flow_state.borrows.iter() {
@ -1549,12 +1549,12 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
} }
/// Reports an error if this is a borrow of local data. /// Reports an error if this is a borrow of local data.
/// This is called for all Yield expressions on movable generators /// This is called for all Yield expressions on movable coroutines
fn check_for_local_borrow(&mut self, borrow: &BorrowData<'tcx>, yield_span: Span) { fn check_for_local_borrow(&mut self, borrow: &BorrowData<'tcx>, yield_span: Span) {
debug!("check_for_local_borrow({:?})", borrow); debug!("check_for_local_borrow({:?})", borrow);
if borrow_of_local_data(borrow.borrowed_place) { if borrow_of_local_data(borrow.borrowed_place) {
let err = self.cannot_borrow_across_generator_yield( let err = self.cannot_borrow_across_coroutine_yield(
self.retrieve_borrow_spans(borrow).var_or_use(), self.retrieve_borrow_spans(borrow).var_or_use(),
yield_span, yield_span,
); );

View File

@ -137,7 +137,7 @@ pub(super) fn is_active<'tcx>(
} }
/// Determines if a given borrow is borrowing local data /// Determines if a given borrow is borrowing local data
/// This is called for all Yield expressions on movable generators /// This is called for all Yield expressions on movable coroutines
pub(super) fn borrow_of_local_data(place: Place<'_>) -> bool { pub(super) fn borrow_of_local_data(place: Place<'_>) -> bool {
// Reborrow of already borrowed data is ignored // Reborrow of already borrowed data is ignored
// Any errors will be caught on the initial borrow // Any errors will be caught on the initial borrow
@ -165,7 +165,7 @@ pub(crate) fn is_upvar_field_projection<'tcx>(
match place_ref.last_projection() { match place_ref.last_projection() {
Some((place_base, ProjectionElem::Field(field, _ty))) => { Some((place_base, ProjectionElem::Field(field, _ty))) => {
let base_ty = place_base.ty(body, tcx).ty; let base_ty = place_base.ty(body, tcx).ty;
if (base_ty.is_closure() || base_ty.is_generator()) if (base_ty.is_closure() || base_ty.is_coroutine())
&& (!by_ref || upvars[field.index()].by_ref) && (!by_ref || upvars[field.index()].by_ref)
{ {
Some(field) Some(field)

View File

@ -139,22 +139,22 @@ pub(crate) enum RequireStaticErr {
#[derive(Subdiagnostic)] #[derive(Subdiagnostic)]
pub(crate) enum CaptureVarPathUseCause { pub(crate) enum CaptureVarPathUseCause {
#[label(borrowck_borrow_due_to_use_generator)] #[label(borrowck_borrow_due_to_use_coroutine)]
BorrowInCoroutine { BorrowInCoroutine {
#[primary_span] #[primary_span]
path_span: Span, path_span: Span,
}, },
#[label(borrowck_use_due_to_use_generator)] #[label(borrowck_use_due_to_use_coroutine)]
UseInCoroutine { UseInCoroutine {
#[primary_span] #[primary_span]
path_span: Span, path_span: Span,
}, },
#[label(borrowck_assign_due_to_use_generator)] #[label(borrowck_assign_due_to_use_coroutine)]
AssignInCoroutine { AssignInCoroutine {
#[primary_span] #[primary_span]
path_span: Span, path_span: Span,
}, },
#[label(borrowck_assign_part_due_to_use_generator)] #[label(borrowck_assign_part_due_to_use_coroutine)]
AssignPartInCoroutine { AssignPartInCoroutine {
#[primary_span] #[primary_span]
path_span: Span, path_span: Span,
@ -202,7 +202,7 @@ pub(crate) enum CaptureVarKind {
#[derive(Subdiagnostic)] #[derive(Subdiagnostic)]
pub(crate) enum CaptureVarCause { pub(crate) enum CaptureVarCause {
#[label(borrowck_var_borrow_by_use_place_in_generator)] #[label(borrowck_var_borrow_by_use_place_in_coroutine)]
BorrowUsePlaceCoroutine { BorrowUsePlaceCoroutine {
is_single_var: bool, is_single_var: bool,
place: String, place: String,
@ -216,7 +216,7 @@ pub(crate) enum CaptureVarCause {
#[primary_span] #[primary_span]
var_span: Span, var_span: Span,
}, },
#[label(borrowck_var_borrow_by_use_in_generator)] #[label(borrowck_var_borrow_by_use_in_coroutine)]
BorrowUseInCoroutine { BorrowUseInCoroutine {
#[primary_span] #[primary_span]
var_span: Span, var_span: Span,
@ -226,7 +226,7 @@ pub(crate) enum CaptureVarCause {
#[primary_span] #[primary_span]
var_span: Span, var_span: Span,
}, },
#[label(borrowck_var_move_by_use_in_generator)] #[label(borrowck_var_move_by_use_in_coroutine)]
MoveUseInCoroutine { MoveUseInCoroutine {
#[primary_span] #[primary_span]
var_span: Span, var_span: Span,
@ -236,7 +236,7 @@ pub(crate) enum CaptureVarCause {
#[primary_span] #[primary_span]
var_span: Span, var_span: Span,
}, },
#[label(borrowck_var_first_borrow_by_use_place_in_generator)] #[label(borrowck_var_first_borrow_by_use_place_in_coroutine)]
FirstBorrowUsePlaceCoroutine { FirstBorrowUsePlaceCoroutine {
place: String, place: String,
#[primary_span] #[primary_span]
@ -248,7 +248,7 @@ pub(crate) enum CaptureVarCause {
#[primary_span] #[primary_span]
var_span: Span, var_span: Span,
}, },
#[label(borrowck_var_second_borrow_by_use_place_in_generator)] #[label(borrowck_var_second_borrow_by_use_place_in_coroutine)]
SecondBorrowUsePlaceCoroutine { SecondBorrowUsePlaceCoroutine {
place: String, place: String,
#[primary_span] #[primary_span]
@ -266,7 +266,7 @@ pub(crate) enum CaptureVarCause {
#[primary_span] #[primary_span]
var_span: Span, var_span: Span,
}, },
#[label(borrowck_partial_var_move_by_use_in_generator)] #[label(borrowck_partial_var_move_by_use_in_coroutine)]
PartialMoveUseInCoroutine { PartialMoveUseInCoroutine {
#[primary_span] #[primary_span]
var_span: Span, var_span: Span,

View File

@ -101,7 +101,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
); );
// We will not have a universal_regions.yield_ty if we yield (by accident) // We will not have a universal_regions.yield_ty if we yield (by accident)
// outside of a generator and return an `impl Trait`, so emit a delay_span_bug // outside of a coroutine and return an `impl Trait`, so emit a delay_span_bug
// because we don't want to panic in an assert here if we've already got errors. // because we don't want to panic in an assert here if we've already got errors.
if body.yield_ty().is_some() != universal_regions.yield_ty.is_some() { if body.yield_ty().is_some() != universal_regions.yield_ty.is_some() {
self.tcx().sess.delay_span_bug( self.tcx().sess.delay_span_bug(

View File

@ -101,7 +101,7 @@ pub(super) fn trace<'mir, 'tcx>(
results.dropck_boring_locals(boring_locals); results.dropck_boring_locals(boring_locals);
} }
/// Contextual state for the type-liveness generator. /// Contextual state for the type-liveness coroutine.
struct LivenessContext<'me, 'typeck, 'flow, 'tcx> { struct LivenessContext<'me, 'typeck, 'flow, 'tcx> {
/// Current type-checker, giving us our inference context etc. /// Current type-checker, giving us our inference context etc.
typeck: &'me mut TypeChecker<'typeck, 'tcx>, typeck: &'me mut TypeChecker<'typeck, 'tcx>,

View File

@ -671,8 +671,8 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
PlaceTy { ty: base_ty, variant_index: Some(index) } PlaceTy { ty: base_ty, variant_index: Some(index) }
} }
} }
// We do not need to handle generators here, because this runs // We do not need to handle coroutines here, because this runs
// before the generator transform stage. // before the coroutine transform stage.
_ => { _ => {
let ty = if let Some(name) = maybe_name { let ty = if let Some(name) = maybe_name {
span_mirbug_and_err!( span_mirbug_and_err!(
@ -775,12 +775,12 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
PlaceTy { ty, variant_index: Some(variant_index) } => match *ty.kind() { PlaceTy { ty, variant_index: Some(variant_index) } => match *ty.kind() {
ty::Adt(adt_def, args) => (adt_def.variant(variant_index), args), ty::Adt(adt_def, args) => (adt_def.variant(variant_index), args),
ty::Coroutine(def_id, args, _) => { ty::Coroutine(def_id, args, _) => {
let mut variants = args.as_generator().state_tys(def_id, tcx); let mut variants = args.as_coroutine().state_tys(def_id, tcx);
let Some(mut variant) = variants.nth(variant_index.into()) else { let Some(mut variant) = variants.nth(variant_index.into()) else {
bug!( bug!(
"variant_index of generator out of range: {:?}/{:?}", "variant_index of coroutine out of range: {:?}/{:?}",
variant_index, variant_index,
args.as_generator().state_tys(def_id, tcx).count() args.as_coroutine().state_tys(def_id, tcx).count()
); );
}; };
return match variant.nth(field.index()) { return match variant.nth(field.index()) {
@ -788,7 +788,7 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
None => Err(FieldAccessError::OutOfRange { field_count: variant.count() }), None => Err(FieldAccessError::OutOfRange { field_count: variant.count() }),
}; };
} }
_ => bug!("can't have downcast of non-adt non-generator type"), _ => bug!("can't have downcast of non-adt non-coroutine type"),
}, },
PlaceTy { ty, variant_index: None } => match *ty.kind() { PlaceTy { ty, variant_index: None } => match *ty.kind() {
ty::Adt(adt_def, args) if !adt_def.is_enum() => { ty::Adt(adt_def, args) if !adt_def.is_enum() => {
@ -805,10 +805,10 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
ty::Coroutine(_, args, _) => { ty::Coroutine(_, args, _) => {
// Only prefix fields (upvars and current state) are // Only prefix fields (upvars and current state) are
// accessible without a variant index. // accessible without a variant index.
return match args.as_generator().prefix_tys().get(field.index()) { return match args.as_coroutine().prefix_tys().get(field.index()) {
Some(ty) => Ok(*ty), Some(ty) => Ok(*ty),
None => Err(FieldAccessError::OutOfRange { None => Err(FieldAccessError::OutOfRange {
field_count: args.as_generator().prefix_tys().len(), field_count: args.as_coroutine().prefix_tys().len(),
}), }),
}; };
} }
@ -1468,7 +1468,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
let value_ty = value.ty(body, tcx); let value_ty = value.ty(body, tcx);
match body.yield_ty() { match body.yield_ty() {
None => span_mirbug!(self, term, "yield in non-generator"), None => span_mirbug!(self, term, "yield in non-coroutine"),
Some(ty) => { Some(ty) => {
if let Err(terr) = self.sub_types( if let Err(terr) = self.sub_types(
value_ty, value_ty,
@ -1650,7 +1650,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
} }
TerminatorKind::CoroutineDrop { .. } => { TerminatorKind::CoroutineDrop { .. } => {
if is_cleanup { if is_cleanup {
span_mirbug!(self, block_data, "generator_drop in cleanup block") span_mirbug!(self, block_data, "coroutine_drop in cleanup block")
} }
} }
TerminatorKind::Yield { resume, drop, .. } => { TerminatorKind::Yield { resume, drop, .. } => {
@ -1801,10 +1801,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
// It doesn't make sense to look at a field beyond the prefix; // It doesn't make sense to look at a field beyond the prefix;
// these require a variant index, and are not initialized in // these require a variant index, and are not initialized in
// aggregate rvalues. // aggregate rvalues.
match args.as_generator().prefix_tys().get(field_index.as_usize()) { match args.as_coroutine().prefix_tys().get(field_index.as_usize()) {
Some(ty) => Ok(*ty), Some(ty) => Ok(*ty),
None => Err(FieldAccessError::OutOfRange { None => Err(FieldAccessError::OutOfRange {
field_count: args.as_generator().prefix_tys().len(), field_count: args.as_coroutine().prefix_tys().len(),
}), }),
} }
} }
@ -2673,7 +2673,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
let parent_args = match tcx.def_kind(def_id) { let parent_args = match tcx.def_kind(def_id) {
DefKind::Closure => args.as_closure().parent_args(), DefKind::Closure => args.as_closure().parent_args(),
DefKind::Coroutine => args.as_generator().parent_args(), DefKind::Coroutine => args.as_coroutine().parent_args(),
DefKind::InlineConst => args.as_inline_const().parent_args(), DefKind::InlineConst => args.as_inline_const().parent_args(),
other => bug!("unexpected item {:?}", other), other => bug!("unexpected item {:?}", other),
}; };

View File

@ -58,7 +58,7 @@ pub struct UniversalRegions<'tcx> {
num_universals: usize, num_universals: usize,
/// The "defining" type for this function, with all universal /// The "defining" type for this function, with all universal
/// regions instantiated. For a closure or generator, this is the /// regions instantiated. For a closure or coroutine, this is the
/// closure type, but for a top-level function it's the `FnDef`. /// closure type, but for a top-level function it's the `FnDef`.
pub defining_ty: DefiningTy<'tcx>, pub defining_ty: DefiningTy<'tcx>,
@ -91,9 +91,9 @@ pub enum DefiningTy<'tcx> {
/// `ClosureArgs::closure_sig_ty`. /// `ClosureArgs::closure_sig_ty`.
Closure(DefId, GenericArgsRef<'tcx>), Closure(DefId, GenericArgsRef<'tcx>),
/// The MIR is a generator. The signature is that generators take /// The MIR is a coroutine. The signature is that coroutines take
/// no parameters and return the result of /// no parameters and return the result of
/// `ClosureArgs::generator_return_ty`. /// `ClosureArgs::coroutine_return_ty`.
Coroutine(DefId, GenericArgsRef<'tcx>, hir::Movability), Coroutine(DefId, GenericArgsRef<'tcx>, hir::Movability),
/// The MIR is a fn item with the given `DefId` and args. The signature /// The MIR is a fn item with the given `DefId` and args. The signature
@ -112,13 +112,13 @@ pub enum DefiningTy<'tcx> {
impl<'tcx> DefiningTy<'tcx> { impl<'tcx> DefiningTy<'tcx> {
/// Returns a list of all the upvar types for this MIR. If this is /// Returns a list of all the upvar types for this MIR. If this is
/// not a closure or generator, there are no upvars, and hence it /// not a closure or coroutine, there are no upvars, and hence it
/// will be an empty list. The order of types in this list will /// will be an empty list. The order of types in this list will
/// match up with the upvar order in the HIR, typesystem, and MIR. /// match up with the upvar order in the HIR, typesystem, and MIR.
pub fn upvar_tys(self) -> &'tcx ty::List<Ty<'tcx>> { pub fn upvar_tys(self) -> &'tcx ty::List<Ty<'tcx>> {
match self { match self {
DefiningTy::Closure(_, args) => args.as_closure().upvar_tys(), DefiningTy::Closure(_, args) => args.as_closure().upvar_tys(),
DefiningTy::Coroutine(_, args, _) => args.as_generator().upvar_tys(), DefiningTy::Coroutine(_, args, _) => args.as_coroutine().upvar_tys(),
DefiningTy::FnDef(..) | DefiningTy::Const(..) | DefiningTy::InlineConst(..) => { DefiningTy::FnDef(..) | DefiningTy::Const(..) | DefiningTy::InlineConst(..) => {
ty::List::empty() ty::List::empty()
} }
@ -178,7 +178,7 @@ pub enum RegionClassification {
Global, Global,
/// An **external** region is only relevant for /// An **external** region is only relevant for
/// closures, generators, and inline consts. In that /// closures, coroutines, and inline consts. In that
/// case, it refers to regions that are free in the type /// case, it refers to regions that are free in the type
/// -- basically, something bound in the surrounding context. /// -- basically, something bound in the surrounding context.
/// ///
@ -196,7 +196,7 @@ pub enum RegionClassification {
/// Here, the lifetimes `'a` and `'b` would be **external** to the /// Here, the lifetimes `'a` and `'b` would be **external** to the
/// closure. /// closure.
/// ///
/// If we are not analyzing a closure/generator/inline-const, /// If we are not analyzing a closure/coroutine/inline-const,
/// there are no external lifetimes. /// there are no external lifetimes.
External, External,
@ -362,7 +362,7 @@ impl<'tcx> UniversalRegions<'tcx> {
.collect::<Vec<_>>() .collect::<Vec<_>>()
); );
err.note(format!( err.note(format!(
"defining type: {} with generator args [\n {},\n]", "defining type: {} with coroutine args [\n {},\n]",
tcx.def_path_str_with_args(def_id, args), tcx.def_path_str_with_args(def_id, args),
v.join(",\n "), v.join(",\n "),
)); ));
@ -426,13 +426,13 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
let typeck_root_def_id = self.infcx.tcx.typeck_root_def_id(self.mir_def.to_def_id()); let typeck_root_def_id = self.infcx.tcx.typeck_root_def_id(self.mir_def.to_def_id());
// If this is a 'root' body (not a closure/generator/inline const), then // If this is a 'root' body (not a closure/coroutine/inline const), then
// there are no extern regions, so the local regions start at the same // there are no extern regions, so the local regions start at the same
// position as the (empty) sub-list of extern regions // position as the (empty) sub-list of extern regions
let first_local_index = if self.mir_def.to_def_id() == typeck_root_def_id { let first_local_index = if self.mir_def.to_def_id() == typeck_root_def_id {
first_extern_index first_extern_index
} else { } else {
// If this is a closure, generator, or inline-const, then the late-bound regions from the enclosing // If this is a closure, coroutine, or inline-const, then the late-bound regions from the enclosing
// function/closures are actually external regions to us. For example, here, 'a is not local // function/closures are actually external regions to us. For example, here, 'a is not local
// to the closure c (although it is local to the fn foo): // to the closure c (although it is local to the fn foo):
// fn foo<'a>() { // fn foo<'a>() {
@ -528,7 +528,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
debug!("build: local regions = {}..{}", first_local_index, num_universals); debug!("build: local regions = {}..{}", first_local_index, num_universals);
let yield_ty = match defining_ty { let yield_ty = match defining_ty {
DefiningTy::Coroutine(_, args, _) => Some(args.as_generator().yield_ty()), DefiningTy::Coroutine(_, args, _) => Some(args.as_coroutine().yield_ty()),
_ => None, _ => None,
}; };
@ -688,11 +688,11 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
DefiningTy::Coroutine(def_id, args, movability) => { DefiningTy::Coroutine(def_id, args, movability) => {
assert_eq!(self.mir_def.to_def_id(), def_id); assert_eq!(self.mir_def.to_def_id(), def_id);
let resume_ty = args.as_generator().resume_ty(); let resume_ty = args.as_coroutine().resume_ty();
let output = args.as_generator().return_ty(); let output = args.as_coroutine().return_ty();
let generator_ty = Ty::new_generator(tcx, def_id, args, movability); let coroutine_ty = Ty::new_coroutine(tcx, def_id, args, movability);
let inputs_and_output = let inputs_and_output =
self.infcx.tcx.mk_type_list(&[generator_ty, resume_ty, output]); self.infcx.tcx.mk_type_list(&[coroutine_ty, resume_ty, output]);
ty::Binder::dummy(inputs_and_output) ty::Binder::dummy(inputs_and_output)
} }

View File

@ -179,7 +179,7 @@ fn entry_point_type(item: &ast::Item, at_root: bool) -> EntryPointType {
} }
/// A folder used to remove any entry points (like fn main) because the harness /// A folder used to remove any entry points (like fn main) because the harness
/// generator will provide its own /// coroutine will provide its own
struct EntryPointCleaner<'a> { struct EntryPointCleaner<'a> {
// Current depth in the ast // Current depth in the ast
sess: &'a Session, sess: &'a Session,

View File

@ -1,7 +1,7 @@
#![feature( #![feature(
core_intrinsics, core_intrinsics,
generators, coroutines,
generator_trait, coroutine_trait,
is_sorted, is_sorted,
repr_simd, repr_simd,
tuple_trait, tuple_trait,

View File

@ -1,4 +1,4 @@
#![feature(core_intrinsics, generators, generator_trait, is_sorted)] #![feature(core_intrinsics, coroutines, coroutine_trait, is_sorted)]
#[cfg(feature="master")] #[cfg(feature="master")]
use std::arch::x86_64::*; use std::arch::x86_64::*;

View File

@ -460,7 +460,7 @@ pub fn type_di_node<'ll, 'tcx>(cx: &CodegenCx<'ll, 'tcx>, t: Ty<'tcx>) -> &'ll D
} }
ty::FnDef(..) | ty::FnPtr(_) => build_subroutine_type_di_node(cx, unique_type_id), ty::FnDef(..) | ty::FnPtr(_) => build_subroutine_type_di_node(cx, unique_type_id),
ty::Closure(..) => build_closure_env_di_node(cx, unique_type_id), ty::Closure(..) => build_closure_env_di_node(cx, unique_type_id),
ty::Coroutine(..) => enums::build_generator_di_node(cx, unique_type_id), ty::Coroutine(..) => enums::build_coroutine_di_node(cx, unique_type_id),
ty::Adt(def, ..) => match def.adt_kind() { ty::Adt(def, ..) => match def.adt_kind() {
AdtKind::Struct => build_struct_type_di_node(cx, unique_type_id), AdtKind::Struct => build_struct_type_di_node(cx, unique_type_id),
AdtKind::Union => build_union_type_di_node(cx, unique_type_id), AdtKind::Union => build_union_type_di_node(cx, unique_type_id),
@ -1026,20 +1026,20 @@ fn build_struct_type_di_node<'ll, 'tcx>(
// Tuples // Tuples
//=----------------------------------------------------------------------------- //=-----------------------------------------------------------------------------
/// Builds the DW_TAG_member debuginfo nodes for the upvars of a closure or generator. /// Builds the DW_TAG_member debuginfo nodes for the upvars of a closure or coroutine.
/// For a generator, this will handle upvars shared by all states. /// For a coroutine, this will handle upvars shared by all states.
fn build_upvar_field_di_nodes<'ll, 'tcx>( fn build_upvar_field_di_nodes<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>, cx: &CodegenCx<'ll, 'tcx>,
closure_or_generator_ty: Ty<'tcx>, closure_or_coroutine_ty: Ty<'tcx>,
closure_or_generator_di_node: &'ll DIType, closure_or_coroutine_di_node: &'ll DIType,
) -> SmallVec<&'ll DIType> { ) -> SmallVec<&'ll DIType> {
let (&def_id, up_var_tys) = match closure_or_generator_ty.kind() { let (&def_id, up_var_tys) = match closure_or_coroutine_ty.kind() {
ty::Coroutine(def_id, args, _) => (def_id, args.as_generator().prefix_tys()), ty::Coroutine(def_id, args, _) => (def_id, args.as_coroutine().prefix_tys()),
ty::Closure(def_id, args) => (def_id, args.as_closure().upvar_tys()), ty::Closure(def_id, args) => (def_id, args.as_closure().upvar_tys()),
_ => { _ => {
bug!( bug!(
"build_upvar_field_di_nodes() called with non-closure-or-generator-type: {:?}", "build_upvar_field_di_nodes() called with non-closure-or-coroutine-type: {:?}",
closure_or_generator_ty closure_or_coroutine_ty
) )
} }
}; };
@ -1049,7 +1049,7 @@ fn build_upvar_field_di_nodes<'ll, 'tcx>(
); );
let capture_names = cx.tcx.closure_saved_names_of_captured_variables(def_id); let capture_names = cx.tcx.closure_saved_names_of_captured_variables(def_id);
let layout = cx.layout_of(closure_or_generator_ty); let layout = cx.layout_of(closure_or_coroutine_ty);
up_var_tys up_var_tys
.into_iter() .into_iter()
@ -1058,7 +1058,7 @@ fn build_upvar_field_di_nodes<'ll, 'tcx>(
.map(|(index, (up_var_ty, capture_name))| { .map(|(index, (up_var_ty, capture_name))| {
build_field_di_node( build_field_di_node(
cx, cx,
closure_or_generator_di_node, closure_or_coroutine_di_node,
capture_name.as_str(), capture_name.as_str(),
cx.size_and_align_of(up_var_ty), cx.size_and_align_of(up_var_ty),
layout.fields.offset(index), layout.fields.offset(index),

View File

@ -268,18 +268,18 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
) )
} }
/// A generator debuginfo node looks the same as a that of an enum type. /// A coroutine debuginfo node looks the same as a that of an enum type.
/// ///
/// See [build_enum_type_di_node] for more information. /// See [build_enum_type_di_node] for more information.
pub(super) fn build_generator_di_node<'ll, 'tcx>( pub(super) fn build_coroutine_di_node<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>, cx: &CodegenCx<'ll, 'tcx>,
unique_type_id: UniqueTypeId<'tcx>, unique_type_id: UniqueTypeId<'tcx>,
) -> DINodeCreationResult<'ll> { ) -> DINodeCreationResult<'ll> {
let generator_type = unique_type_id.expect_ty(); let coroutine_type = unique_type_id.expect_ty();
let generator_type_and_layout = cx.layout_of(generator_type); let coroutine_type_and_layout = cx.layout_of(coroutine_type);
let generator_type_name = compute_debuginfo_type_name(cx.tcx, generator_type, false); let coroutine_type_name = compute_debuginfo_type_name(cx.tcx, coroutine_type, false);
debug_assert!(!wants_c_like_enum_debuginfo(generator_type_and_layout)); debug_assert!(!wants_c_like_enum_debuginfo(coroutine_type_and_layout));
type_map::build_type_with_children( type_map::build_type_with_children(
cx, cx,
@ -287,24 +287,24 @@ pub(super) fn build_generator_di_node<'ll, 'tcx>(
cx, cx,
type_map::Stub::Union, type_map::Stub::Union,
unique_type_id, unique_type_id,
&generator_type_name, &coroutine_type_name,
size_and_align_of(generator_type_and_layout), size_and_align_of(coroutine_type_and_layout),
NO_SCOPE_METADATA, NO_SCOPE_METADATA,
DIFlags::FlagZero, DIFlags::FlagZero,
), ),
|cx, generator_type_di_node| match generator_type_and_layout.variants { |cx, coroutine_type_di_node| match coroutine_type_and_layout.variants {
Variants::Multiple { tag_encoding: TagEncoding::Direct, .. } => { Variants::Multiple { tag_encoding: TagEncoding::Direct, .. } => {
build_union_fields_for_direct_tag_generator( build_union_fields_for_direct_tag_coroutine(
cx, cx,
generator_type_and_layout, coroutine_type_and_layout,
generator_type_di_node, coroutine_type_di_node,
) )
} }
Variants::Single { .. } Variants::Single { .. }
| Variants::Multiple { tag_encoding: TagEncoding::Niche { .. }, .. } => { | Variants::Multiple { tag_encoding: TagEncoding::Niche { .. }, .. } => {
bug!( bug!(
"Encountered generator with non-direct-tag layout: {:?}", "Encountered coroutine with non-direct-tag layout: {:?}",
generator_type_and_layout coroutine_type_and_layout
) )
} }
}, },
@ -428,7 +428,7 @@ fn build_union_fields_for_enum<'ll, 'tcx>(
}) })
.collect(); .collect();
build_union_fields_for_direct_tag_enum_or_generator( build_union_fields_for_direct_tag_enum_or_coroutine(
cx, cx,
enum_type_and_layout, enum_type_and_layout,
enum_type_di_node, enum_type_di_node,
@ -469,8 +469,8 @@ fn build_variant_names_type_di_node<'ll, 'tcx>(
fn build_variant_struct_wrapper_type_di_node<'ll, 'tcx>( fn build_variant_struct_wrapper_type_di_node<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>, cx: &CodegenCx<'ll, 'tcx>,
enum_or_generator_type_and_layout: TyAndLayout<'tcx>, enum_or_coroutine_type_and_layout: TyAndLayout<'tcx>,
enum_or_generator_type_di_node: &'ll DIType, enum_or_coroutine_type_di_node: &'ll DIType,
variant_index: VariantIdx, variant_index: VariantIdx,
untagged_variant_index: Option<VariantIdx>, untagged_variant_index: Option<VariantIdx>,
variant_struct_type_di_node: &'ll DIType, variant_struct_type_di_node: &'ll DIType,
@ -486,13 +486,13 @@ fn build_variant_struct_wrapper_type_di_node<'ll, 'tcx>(
Stub::Struct, Stub::Struct,
UniqueTypeId::for_enum_variant_struct_type_wrapper( UniqueTypeId::for_enum_variant_struct_type_wrapper(
cx.tcx, cx.tcx,
enum_or_generator_type_and_layout.ty, enum_or_coroutine_type_and_layout.ty,
variant_index, variant_index,
), ),
&variant_struct_wrapper_type_name(variant_index), &variant_struct_wrapper_type_name(variant_index),
// NOTE: We use size and align of enum_type, not from variant_layout: // NOTE: We use size and align of enum_type, not from variant_layout:
size_and_align_of(enum_or_generator_type_and_layout), size_and_align_of(enum_or_coroutine_type_and_layout),
Some(enum_or_generator_type_di_node), Some(enum_or_coroutine_type_di_node),
DIFlags::FlagZero, DIFlags::FlagZero,
), ),
|cx, wrapper_struct_type_di_node| { |cx, wrapper_struct_type_di_node| {
@ -535,7 +535,7 @@ fn build_variant_struct_wrapper_type_di_node<'ll, 'tcx>(
cx, cx,
wrapper_struct_type_di_node, wrapper_struct_type_di_node,
"value", "value",
size_and_align_of(enum_or_generator_type_and_layout), size_and_align_of(enum_or_coroutine_type_and_layout),
Size::ZERO, Size::ZERO,
DIFlags::FlagZero, DIFlags::FlagZero,
variant_struct_type_di_node, variant_struct_type_di_node,
@ -662,40 +662,40 @@ fn split_128(value: u128) -> Split128 {
Split128 { hi: (value >> 64) as u64, lo: value as u64 } Split128 { hi: (value >> 64) as u64, lo: value as u64 }
} }
fn build_union_fields_for_direct_tag_generator<'ll, 'tcx>( fn build_union_fields_for_direct_tag_coroutine<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>, cx: &CodegenCx<'ll, 'tcx>,
generator_type_and_layout: TyAndLayout<'tcx>, coroutine_type_and_layout: TyAndLayout<'tcx>,
generator_type_di_node: &'ll DIType, coroutine_type_di_node: &'ll DIType,
) -> SmallVec<&'ll DIType> { ) -> SmallVec<&'ll DIType> {
let Variants::Multiple { tag_encoding: TagEncoding::Direct, tag_field, .. } = let Variants::Multiple { tag_encoding: TagEncoding::Direct, tag_field, .. } =
generator_type_and_layout.variants coroutine_type_and_layout.variants
else { else {
bug!("This function only supports layouts with directly encoded tags.") bug!("This function only supports layouts with directly encoded tags.")
}; };
let (generator_def_id, generator_args) = match generator_type_and_layout.ty.kind() { let (coroutine_def_id, coroutine_args) = match coroutine_type_and_layout.ty.kind() {
&ty::Coroutine(def_id, args, _) => (def_id, args.as_generator()), &ty::Coroutine(def_id, args, _) => (def_id, args.as_coroutine()),
_ => unreachable!(), _ => unreachable!(),
}; };
let generator_layout = cx.tcx.optimized_mir(generator_def_id).generator_layout().unwrap(); let coroutine_layout = cx.tcx.optimized_mir(coroutine_def_id).coroutine_layout().unwrap();
let common_upvar_names = cx.tcx.closure_saved_names_of_captured_variables(generator_def_id); let common_upvar_names = cx.tcx.closure_saved_names_of_captured_variables(coroutine_def_id);
let variant_range = generator_args.variant_range(generator_def_id, cx.tcx); let variant_range = coroutine_args.variant_range(coroutine_def_id, cx.tcx);
let variant_count = (variant_range.start.as_u32()..variant_range.end.as_u32()).len(); let variant_count = (variant_range.start.as_u32()..variant_range.end.as_u32()).len();
let tag_base_type = tag_base_type(cx, generator_type_and_layout); let tag_base_type = tag_base_type(cx, coroutine_type_and_layout);
let variant_names_type_di_node = build_variant_names_type_di_node( let variant_names_type_di_node = build_variant_names_type_di_node(
cx, cx,
generator_type_di_node, coroutine_type_di_node,
variant_range variant_range
.clone() .clone()
.map(|variant_index| (variant_index, CoroutineArgs::variant_name(variant_index))), .map(|variant_index| (variant_index, CoroutineArgs::variant_name(variant_index))),
); );
let discriminants: IndexVec<VariantIdx, DiscrResult> = { let discriminants: IndexVec<VariantIdx, DiscrResult> = {
let discriminants_iter = generator_args.discriminants(generator_def_id, cx.tcx); let discriminants_iter = coroutine_args.discriminants(coroutine_def_id, cx.tcx);
let mut discriminants: IndexVec<VariantIdx, DiscrResult> = let mut discriminants: IndexVec<VariantIdx, DiscrResult> =
IndexVec::with_capacity(variant_count); IndexVec::with_capacity(variant_count);
for (variant_index, discr) in discriminants_iter { for (variant_index, discr) in discriminants_iter {
@ -709,16 +709,16 @@ fn build_union_fields_for_direct_tag_generator<'ll, 'tcx>(
// Build the type node for each field. // Build the type node for each field.
let variant_field_infos: SmallVec<VariantFieldInfo<'ll>> = variant_range let variant_field_infos: SmallVec<VariantFieldInfo<'ll>> = variant_range
.map(|variant_index| { .map(|variant_index| {
let variant_struct_type_di_node = super::build_generator_variant_struct_type_di_node( let variant_struct_type_di_node = super::build_coroutine_variant_struct_type_di_node(
cx, cx,
variant_index, variant_index,
generator_type_and_layout, coroutine_type_and_layout,
generator_type_di_node, coroutine_type_di_node,
generator_layout, coroutine_layout,
&common_upvar_names, &common_upvar_names,
); );
let span = generator_layout.variant_source_info[variant_index].span; let span = coroutine_layout.variant_source_info[variant_index].span;
let source_info = if !span.is_dummy() { let source_info = if !span.is_dummy() {
let loc = cx.lookup_debug_loc(span.lo()); let loc = cx.lookup_debug_loc(span.lo());
Some((file_metadata(cx, &loc.file), loc.line as c_uint)) Some((file_metadata(cx, &loc.file), loc.line as c_uint))
@ -735,10 +735,10 @@ fn build_union_fields_for_direct_tag_generator<'ll, 'tcx>(
}) })
.collect(); .collect();
build_union_fields_for_direct_tag_enum_or_generator( build_union_fields_for_direct_tag_enum_or_coroutine(
cx, cx,
generator_type_and_layout, coroutine_type_and_layout,
generator_type_di_node, coroutine_type_di_node,
&variant_field_infos[..], &variant_field_infos[..],
variant_names_type_di_node, variant_names_type_di_node,
tag_base_type, tag_base_type,
@ -747,9 +747,9 @@ fn build_union_fields_for_direct_tag_generator<'ll, 'tcx>(
) )
} }
/// This is a helper function shared between enums and generators that makes sure fields have the /// This is a helper function shared between enums and coroutines that makes sure fields have the
/// expect names. /// expect names.
fn build_union_fields_for_direct_tag_enum_or_generator<'ll, 'tcx>( fn build_union_fields_for_direct_tag_enum_or_coroutine<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>, cx: &CodegenCx<'ll, 'tcx>,
enum_type_and_layout: TyAndLayout<'tcx>, enum_type_and_layout: TyAndLayout<'tcx>,
enum_type_di_node: &'ll DIType, enum_type_di_node: &'ll DIType,

View File

@ -66,14 +66,14 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
} }
} }
pub(super) fn build_generator_di_node<'ll, 'tcx>( pub(super) fn build_coroutine_di_node<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>, cx: &CodegenCx<'ll, 'tcx>,
unique_type_id: UniqueTypeId<'tcx>, unique_type_id: UniqueTypeId<'tcx>,
) -> DINodeCreationResult<'ll> { ) -> DINodeCreationResult<'ll> {
if cpp_like_debuginfo(cx.tcx) { if cpp_like_debuginfo(cx.tcx) {
cpp_like::build_generator_di_node(cx, unique_type_id) cpp_like::build_coroutine_di_node(cx, unique_type_id)
} else { } else {
native::build_generator_di_node(cx, unique_type_id) native::build_coroutine_di_node(cx, unique_type_id)
} }
} }
@ -101,7 +101,7 @@ fn build_c_style_enum_di_node<'ll, 'tcx>(
} }
} }
/// Extract the type with which we want to describe the tag of the given enum or generator. /// Extract the type with which we want to describe the tag of the given enum or coroutine.
fn tag_base_type<'ll, 'tcx>( fn tag_base_type<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>, cx: &CodegenCx<'ll, 'tcx>,
enum_type_and_layout: TyAndLayout<'tcx>, enum_type_and_layout: TyAndLayout<'tcx>,
@ -300,8 +300,8 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>(
.di_node .di_node
} }
/// Build the struct type for describing a single generator state. /// Build the struct type for describing a single coroutine state.
/// See [build_generator_variant_struct_type_di_node]. /// See [build_coroutine_variant_struct_type_di_node].
/// ///
/// ```txt /// ```txt
/// ///
@ -317,25 +317,25 @@ fn build_enum_variant_struct_type_di_node<'ll, 'tcx>(
/// ---> DW_TAG_structure_type (type of variant 3) /// ---> DW_TAG_structure_type (type of variant 3)
/// ///
/// ``` /// ```
pub fn build_generator_variant_struct_type_di_node<'ll, 'tcx>( pub fn build_coroutine_variant_struct_type_di_node<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>, cx: &CodegenCx<'ll, 'tcx>,
variant_index: VariantIdx, variant_index: VariantIdx,
generator_type_and_layout: TyAndLayout<'tcx>, coroutine_type_and_layout: TyAndLayout<'tcx>,
generator_type_di_node: &'ll DIType, coroutine_type_di_node: &'ll DIType,
generator_layout: &CoroutineLayout<'tcx>, coroutine_layout: &CoroutineLayout<'tcx>,
common_upvar_names: &IndexSlice<FieldIdx, Symbol>, common_upvar_names: &IndexSlice<FieldIdx, Symbol>,
) -> &'ll DIType { ) -> &'ll DIType {
let variant_name = CoroutineArgs::variant_name(variant_index); let variant_name = CoroutineArgs::variant_name(variant_index);
let unique_type_id = UniqueTypeId::for_enum_variant_struct_type( let unique_type_id = UniqueTypeId::for_enum_variant_struct_type(
cx.tcx, cx.tcx,
generator_type_and_layout.ty, coroutine_type_and_layout.ty,
variant_index, variant_index,
); );
let variant_layout = generator_type_and_layout.for_variant(cx, variant_index); let variant_layout = coroutine_type_and_layout.for_variant(cx, variant_index);
let generator_args = match generator_type_and_layout.ty.kind() { let coroutine_args = match coroutine_type_and_layout.ty.kind() {
ty::Coroutine(_, args, _) => args.as_generator(), ty::Coroutine(_, args, _) => args.as_coroutine(),
_ => unreachable!(), _ => unreachable!(),
}; };
@ -346,17 +346,17 @@ pub fn build_generator_variant_struct_type_di_node<'ll, 'tcx>(
Stub::Struct, Stub::Struct,
unique_type_id, unique_type_id,
&variant_name, &variant_name,
size_and_align_of(generator_type_and_layout), size_and_align_of(coroutine_type_and_layout),
Some(generator_type_di_node), Some(coroutine_type_di_node),
DIFlags::FlagZero, DIFlags::FlagZero,
), ),
|cx, variant_struct_type_di_node| { |cx, variant_struct_type_di_node| {
// Fields that just belong to this variant/state // Fields that just belong to this variant/state
let state_specific_fields: SmallVec<_> = (0..variant_layout.fields.count()) let state_specific_fields: SmallVec<_> = (0..variant_layout.fields.count())
.map(|field_index| { .map(|field_index| {
let generator_saved_local = generator_layout.variant_fields[variant_index] let coroutine_saved_local = coroutine_layout.variant_fields[variant_index]
[FieldIdx::from_usize(field_index)]; [FieldIdx::from_usize(field_index)];
let field_name_maybe = generator_layout.field_names[generator_saved_local]; let field_name_maybe = coroutine_layout.field_names[coroutine_saved_local];
let field_name = field_name_maybe let field_name = field_name_maybe
.as_ref() .as_ref()
.map(|s| Cow::from(s.as_str())) .map(|s| Cow::from(s.as_str()))
@ -377,7 +377,7 @@ pub fn build_generator_variant_struct_type_di_node<'ll, 'tcx>(
.collect(); .collect();
// Fields that are common to all states // Fields that are common to all states
let common_fields: SmallVec<_> = generator_args let common_fields: SmallVec<_> = coroutine_args
.prefix_tys() .prefix_tys()
.iter() .iter()
.zip(common_upvar_names) .zip(common_upvar_names)
@ -388,7 +388,7 @@ pub fn build_generator_variant_struct_type_di_node<'ll, 'tcx>(
variant_struct_type_di_node, variant_struct_type_di_node,
upvar_name.as_str(), upvar_name.as_str(),
cx.size_and_align_of(upvar_ty), cx.size_and_align_of(upvar_ty),
generator_type_and_layout.fields.offset(index), coroutine_type_and_layout.fields.offset(index),
DIFlags::FlagZero, DIFlags::FlagZero,
type_di_node(cx, upvar_ty), type_di_node(cx, upvar_ty),
) )
@ -397,7 +397,7 @@ pub fn build_generator_variant_struct_type_di_node<'ll, 'tcx>(
state_specific_fields.into_iter().chain(common_fields.into_iter()).collect() state_specific_fields.into_iter().chain(common_fields.into_iter()).collect()
}, },
|cx| build_generic_type_param_di_nodes(cx, generator_type_and_layout.ty), |cx| build_generic_type_param_di_nodes(cx, coroutine_type_and_layout.ty),
) )
.di_node .di_node
} }

View File

@ -110,12 +110,12 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
) )
} }
/// Build the debuginfo node for a generator environment. It looks the same as the debuginfo for /// Build the debuginfo node for a coroutine environment. It looks the same as the debuginfo for
/// an enum. See [build_enum_type_di_node] for more information. /// an enum. See [build_enum_type_di_node] for more information.
/// ///
/// ```txt /// ```txt
/// ///
/// ---> DW_TAG_structure_type (top-level type for the generator) /// ---> DW_TAG_structure_type (top-level type for the coroutine)
/// DW_TAG_variant_part (variant part) /// DW_TAG_variant_part (variant part)
/// DW_AT_discr (reference to discriminant DW_TAG_member) /// DW_AT_discr (reference to discriminant DW_TAG_member)
/// DW_TAG_member (discriminant member) /// DW_TAG_member (discriminant member)
@ -127,21 +127,21 @@ pub(super) fn build_enum_type_di_node<'ll, 'tcx>(
/// DW_TAG_structure_type (type of variant 3) /// DW_TAG_structure_type (type of variant 3)
/// ///
/// ``` /// ```
pub(super) fn build_generator_di_node<'ll, 'tcx>( pub(super) fn build_coroutine_di_node<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>, cx: &CodegenCx<'ll, 'tcx>,
unique_type_id: UniqueTypeId<'tcx>, unique_type_id: UniqueTypeId<'tcx>,
) -> DINodeCreationResult<'ll> { ) -> DINodeCreationResult<'ll> {
let generator_type = unique_type_id.expect_ty(); let coroutine_type = unique_type_id.expect_ty();
let &ty::Coroutine(generator_def_id, _, _) = generator_type.kind() else { let &ty::Coroutine(coroutine_def_id, _, _) = coroutine_type.kind() else {
bug!("build_generator_di_node() called with non-generator type: `{:?}`", generator_type) bug!("build_coroutine_di_node() called with non-coroutine type: `{:?}`", coroutine_type)
}; };
let containing_scope = get_namespace_for_item(cx, generator_def_id); let containing_scope = get_namespace_for_item(cx, coroutine_def_id);
let generator_type_and_layout = cx.layout_of(generator_type); let coroutine_type_and_layout = cx.layout_of(coroutine_type);
debug_assert!(!wants_c_like_enum_debuginfo(generator_type_and_layout)); debug_assert!(!wants_c_like_enum_debuginfo(coroutine_type_and_layout));
let generator_type_name = compute_debuginfo_type_name(cx.tcx, generator_type, false); let coroutine_type_name = compute_debuginfo_type_name(cx.tcx, coroutine_type, false);
type_map::build_type_with_children( type_map::build_type_with_children(
cx, cx,
@ -149,26 +149,26 @@ pub(super) fn build_generator_di_node<'ll, 'tcx>(
cx, cx,
Stub::Struct, Stub::Struct,
unique_type_id, unique_type_id,
&generator_type_name, &coroutine_type_name,
size_and_align_of(generator_type_and_layout), size_and_align_of(coroutine_type_and_layout),
Some(containing_scope), Some(containing_scope),
DIFlags::FlagZero, DIFlags::FlagZero,
), ),
|cx, generator_type_di_node| { |cx, coroutine_type_di_node| {
let generator_layout = let coroutine_layout =
cx.tcx.optimized_mir(generator_def_id).generator_layout().unwrap(); cx.tcx.optimized_mir(coroutine_def_id).coroutine_layout().unwrap();
let Variants::Multiple { tag_encoding: TagEncoding::Direct, ref variants, .. } = let Variants::Multiple { tag_encoding: TagEncoding::Direct, ref variants, .. } =
generator_type_and_layout.variants coroutine_type_and_layout.variants
else { else {
bug!( bug!(
"Encountered generator with non-direct-tag layout: {:?}", "Encountered coroutine with non-direct-tag layout: {:?}",
generator_type_and_layout coroutine_type_and_layout
) )
}; };
let common_upvar_names = let common_upvar_names =
cx.tcx.closure_saved_names_of_captured_variables(generator_def_id); cx.tcx.closure_saved_names_of_captured_variables(coroutine_def_id);
// Build variant struct types // Build variant struct types
let variant_struct_type_di_nodes: SmallVec<_> = variants let variant_struct_type_di_nodes: SmallVec<_> = variants
@ -179,7 +179,7 @@ pub(super) fn build_generator_di_node<'ll, 'tcx>(
// with enums? // with enums?
let variant_name = format!("{}", variant_index.as_usize()).into(); let variant_name = format!("{}", variant_index.as_usize()).into();
let span = generator_layout.variant_source_info[variant_index].span; let span = coroutine_layout.variant_source_info[variant_index].span;
let source_info = if !span.is_dummy() { let source_info = if !span.is_dummy() {
let loc = cx.lookup_debug_loc(span.lo()); let loc = cx.lookup_debug_loc(span.lo());
Some((file_metadata(cx, &loc.file), loc.line)) Some((file_metadata(cx, &loc.file), loc.line))
@ -191,12 +191,12 @@ pub(super) fn build_generator_di_node<'ll, 'tcx>(
variant_index, variant_index,
variant_name, variant_name,
variant_struct_type_di_node: variant_struct_type_di_node:
super::build_generator_variant_struct_type_di_node( super::build_coroutine_variant_struct_type_di_node(
cx, cx,
variant_index, variant_index,
generator_type_and_layout, coroutine_type_and_layout,
generator_type_di_node, coroutine_type_di_node,
generator_layout, coroutine_layout,
&common_upvar_names, &common_upvar_names,
), ),
source_info, source_info,
@ -206,18 +206,18 @@ pub(super) fn build_generator_di_node<'ll, 'tcx>(
smallvec![build_enum_variant_part_di_node( smallvec![build_enum_variant_part_di_node(
cx, cx,
generator_type_and_layout, coroutine_type_and_layout,
generator_type_di_node, coroutine_type_di_node,
&variant_struct_type_di_nodes[..], &variant_struct_type_di_nodes[..],
)] )]
}, },
// We don't seem to be emitting generic args on the generator type, it seems. Rather // We don't seem to be emitting generic args on the coroutine type, it seems. Rather
// they get attached to the struct type of each variant. // they get attached to the struct type of each variant.
NO_GENERICS, NO_GENERICS,
) )
} }
/// Builds the DW_TAG_variant_part of an enum or generator debuginfo node: /// Builds the DW_TAG_variant_part of an enum or coroutine debuginfo node:
/// ///
/// ```txt /// ```txt
/// DW_TAG_structure_type (top-level type for enum) /// DW_TAG_structure_type (top-level type for enum)
@ -306,10 +306,10 @@ fn build_enum_variant_part_di_node<'ll, 'tcx>(
/// ``` /// ```
fn build_discr_member_di_node<'ll, 'tcx>( fn build_discr_member_di_node<'ll, 'tcx>(
cx: &CodegenCx<'ll, 'tcx>, cx: &CodegenCx<'ll, 'tcx>,
enum_or_generator_type_and_layout: TyAndLayout<'tcx>, enum_or_coroutine_type_and_layout: TyAndLayout<'tcx>,
enum_or_generator_type_di_node: &'ll DIType, enum_or_coroutine_type_di_node: &'ll DIType,
) -> Option<&'ll DIType> { ) -> Option<&'ll DIType> {
let tag_name = match enum_or_generator_type_and_layout.ty.kind() { let tag_name = match enum_or_coroutine_type_and_layout.ty.kind() {
ty::Coroutine(..) => "__state", ty::Coroutine(..) => "__state",
_ => "", _ => "",
}; };
@ -320,14 +320,14 @@ fn build_discr_member_di_node<'ll, 'tcx>(
// In LLVM IR the wrong scope will be listed but when DWARF is // In LLVM IR the wrong scope will be listed but when DWARF is
// generated from it, the DW_TAG_member will be a child the // generated from it, the DW_TAG_member will be a child the
// DW_TAG_variant_part. // DW_TAG_variant_part.
let containing_scope = enum_or_generator_type_di_node; let containing_scope = enum_or_coroutine_type_di_node;
match enum_or_generator_type_and_layout.layout.variants() { match enum_or_coroutine_type_and_layout.layout.variants() {
// A single-variant enum has no discriminant. // A single-variant enum has no discriminant.
&Variants::Single { .. } => None, &Variants::Single { .. } => None,
&Variants::Multiple { tag_field, .. } => { &Variants::Multiple { tag_field, .. } => {
let tag_base_type = tag_base_type(cx, enum_or_generator_type_and_layout); let tag_base_type = tag_base_type(cx, enum_or_coroutine_type_and_layout);
let (size, align) = cx.size_and_align_of(tag_base_type); let (size, align) = cx.size_and_align_of(tag_base_type);
unsafe { unsafe {
@ -340,7 +340,7 @@ fn build_discr_member_di_node<'ll, 'tcx>(
UNKNOWN_LINE_NUMBER, UNKNOWN_LINE_NUMBER,
size.bits(), size.bits(),
align.bits() as u32, align.bits() as u32,
enum_or_generator_type_and_layout.fields.offset(tag_field).bits(), enum_or_coroutine_type_and_layout.fields.offset(tag_field).bits(),
DIFlags::FlagArtificial, DIFlags::FlagArtificial,
type_di_node(cx, tag_base_type), type_di_node(cx, tag_base_type),
)) ))

View File

@ -43,7 +43,7 @@ pub(super) enum UniqueTypeId<'tcx> {
/// The ID of a regular type as it shows up at the language level. /// The ID of a regular type as it shows up at the language level.
Ty(Ty<'tcx>, private::HiddenZst), Ty(Ty<'tcx>, private::HiddenZst),
/// The ID for the single DW_TAG_variant_part nested inside the top-level /// The ID for the single DW_TAG_variant_part nested inside the top-level
/// DW_TAG_structure_type that describes enums and generators. /// DW_TAG_structure_type that describes enums and coroutines.
VariantPart(Ty<'tcx>, private::HiddenZst), VariantPart(Ty<'tcx>, private::HiddenZst),
/// The ID for the artificial struct type describing a single enum variant. /// The ID for the artificial struct type describing a single enum variant.
VariantStructType(Ty<'tcx>, VariantIdx, private::HiddenZst), VariantStructType(Ty<'tcx>, VariantIdx, private::HiddenZst),

View File

@ -342,7 +342,7 @@ impl<'ll, 'tcx> DebugInfoMethods<'tcx> for CodegenCx<'ll, 'tcx> {
// We look up the generics of the enclosing function and truncate the args // We look up the generics of the enclosing function and truncate the args
// to their length in order to cut off extra stuff that might be in there for // to their length in order to cut off extra stuff that might be in there for
// closures or generators. // closures or coroutines.
let generics = tcx.generics_of(enclosing_fn_def_id); let generics = tcx.generics_of(enclosing_fn_def_id);
let args = instance.args.truncate_to(tcx, generics); let args = instance.args.truncate_to(tcx, generics);

View File

@ -399,22 +399,22 @@ fn push_debuginfo_type_name<'tcx>(
visited.remove(&t); visited.remove(&t);
} }
ty::Closure(def_id, args) | ty::Coroutine(def_id, args, ..) => { ty::Closure(def_id, args) | ty::Coroutine(def_id, args, ..) => {
// Name will be "{closure_env#0}<T1, T2, ...>", "{generator_env#0}<T1, T2, ...>", or // Name will be "{closure_env#0}<T1, T2, ...>", "{coroutine_env#0}<T1, T2, ...>", or
// "{async_fn_env#0}<T1, T2, ...>", etc. // "{async_fn_env#0}<T1, T2, ...>", etc.
// In the case of cpp-like debuginfo, the name additionally gets wrapped inside of // In the case of cpp-like debuginfo, the name additionally gets wrapped inside of
// an artificial `enum2$<>` type, as defined in msvc_enum_fallback(). // an artificial `enum2$<>` type, as defined in msvc_enum_fallback().
if cpp_like_debuginfo && t.is_generator() { if cpp_like_debuginfo && t.is_coroutine() {
let ty_and_layout = tcx.layout_of(ParamEnv::reveal_all().and(t)).unwrap(); let ty_and_layout = tcx.layout_of(ParamEnv::reveal_all().and(t)).unwrap();
msvc_enum_fallback( msvc_enum_fallback(
ty_and_layout, ty_and_layout,
&|output, visited| { &|output, visited| {
push_closure_or_generator_name(tcx, def_id, args, true, output, visited); push_closure_or_coroutine_name(tcx, def_id, args, true, output, visited);
}, },
output, output,
visited, visited,
); );
} else { } else {
push_closure_or_generator_name(tcx, def_id, args, qualified, output, visited); push_closure_or_coroutine_name(tcx, def_id, args, qualified, output, visited);
} }
} }
// Type parameters from polymorphized functions. // Type parameters from polymorphized functions.
@ -558,12 +558,12 @@ pub fn push_item_name(tcx: TyCtxt<'_>, def_id: DefId, qualified: bool, output: &
push_unqualified_item_name(tcx, def_id, def_key.disambiguated_data, output); push_unqualified_item_name(tcx, def_id, def_key.disambiguated_data, output);
} }
fn generator_kind_label(generator_kind: Option<CoroutineKind>) -> &'static str { fn coroutine_kind_label(coroutine_kind: Option<CoroutineKind>) -> &'static str {
match generator_kind { match coroutine_kind {
Some(CoroutineKind::Async(AsyncCoroutineKind::Block)) => "async_block", Some(CoroutineKind::Async(AsyncCoroutineKind::Block)) => "async_block",
Some(CoroutineKind::Async(AsyncCoroutineKind::Closure)) => "async_closure", Some(CoroutineKind::Async(AsyncCoroutineKind::Closure)) => "async_closure",
Some(CoroutineKind::Async(AsyncCoroutineKind::Fn)) => "async_fn", Some(CoroutineKind::Async(AsyncCoroutineKind::Fn)) => "async_fn",
Some(CoroutineKind::Gen) => "generator", Some(CoroutineKind::Gen) => "coroutine",
None => "closure", None => "closure",
} }
} }
@ -592,7 +592,7 @@ fn push_unqualified_item_name(
output.push_str(tcx.crate_name(def_id.krate).as_str()); output.push_str(tcx.crate_name(def_id.krate).as_str());
} }
DefPathData::ClosureExpr => { DefPathData::ClosureExpr => {
let label = generator_kind_label(tcx.generator_kind(def_id)); let label = coroutine_kind_label(tcx.coroutine_kind(def_id));
push_disambiguated_special_name( push_disambiguated_special_name(
label, label,
@ -707,7 +707,7 @@ pub fn push_generic_params<'tcx>(
push_generic_params_internal(tcx, args, def_id, output, &mut visited); push_generic_params_internal(tcx, args, def_id, output, &mut visited);
} }
fn push_closure_or_generator_name<'tcx>( fn push_closure_or_coroutine_name<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
def_id: DefId, def_id: DefId,
args: GenericArgsRef<'tcx>, args: GenericArgsRef<'tcx>,
@ -715,10 +715,10 @@ fn push_closure_or_generator_name<'tcx>(
output: &mut String, output: &mut String,
visited: &mut FxHashSet<Ty<'tcx>>, visited: &mut FxHashSet<Ty<'tcx>>,
) { ) {
// Name will be "{closure_env#0}<T1, T2, ...>", "{generator_env#0}<T1, T2, ...>", or // Name will be "{closure_env#0}<T1, T2, ...>", "{coroutine_env#0}<T1, T2, ...>", or
// "{async_fn_env#0}<T1, T2, ...>", etc. // "{async_fn_env#0}<T1, T2, ...>", etc.
let def_key = tcx.def_key(def_id); let def_key = tcx.def_key(def_id);
let generator_kind = tcx.generator_kind(def_id); let coroutine_kind = tcx.coroutine_kind(def_id);
if qualified { if qualified {
let parent_def_id = DefId { index: def_key.parent.unwrap(), ..def_id }; let parent_def_id = DefId { index: def_key.parent.unwrap(), ..def_id };
@ -727,7 +727,7 @@ fn push_closure_or_generator_name<'tcx>(
} }
let mut label = String::with_capacity(20); let mut label = String::with_capacity(20);
write!(&mut label, "{}_env", generator_kind_label(generator_kind)).unwrap(); write!(&mut label, "{}_env", coroutine_kind_label(coroutine_kind)).unwrap();
push_disambiguated_special_name( push_disambiguated_special_name(
&label, &label,
@ -736,7 +736,7 @@ fn push_closure_or_generator_name<'tcx>(
output, output,
); );
// We also need to add the generic arguments of the async fn/generator or // We also need to add the generic arguments of the async fn/coroutine or
// the enclosing function (for closures or async blocks), so that we end // the enclosing function (for closures or async blocks), so that we end
// up with a unique name for every instantiation. // up with a unique name for every instantiation.
@ -745,7 +745,7 @@ fn push_closure_or_generator_name<'tcx>(
let generics = tcx.generics_of(enclosing_fn_def_id); let generics = tcx.generics_of(enclosing_fn_def_id);
// Truncate the args to the length of the above generics. This will cut off // Truncate the args to the length of the above generics. This will cut off
// anything closure- or generator-specific. // anything closure- or coroutine-specific.
let args = args.truncate_to(tcx, generics); let args = args.truncate_to(tcx, generics);
push_generic_params_internal(tcx, args, enclosing_fn_def_id, output, visited); push_generic_params_internal(tcx, args, enclosing_fn_def_id, output, visited);
} }

View File

@ -1266,7 +1266,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
mergeable_succ(), mergeable_succ(),
), ),
mir::TerminatorKind::CoroutineDrop | mir::TerminatorKind::Yield { .. } => { mir::TerminatorKind::CoroutineDrop | mir::TerminatorKind::Yield { .. } => {
bug!("generator ops in codegen") bug!("coroutine ops in codegen")
} }
mir::TerminatorKind::FalseEdge { .. } | mir::TerminatorKind::FalseUnwind { .. } => { mir::TerminatorKind::FalseEdge { .. } | mir::TerminatorKind::FalseUnwind { .. } => {
bug!("borrowck false edges in codegen") bug!("borrowck false edges in codegen")

View File

@ -534,8 +534,8 @@ impl<'mir, 'tcx> interpret::Machine<'mir, 'tcx> for CompileTimeInterpreter<'mir,
OverflowNeg(op) => OverflowNeg(eval_to_int(op)?), OverflowNeg(op) => OverflowNeg(eval_to_int(op)?),
DivisionByZero(op) => DivisionByZero(eval_to_int(op)?), DivisionByZero(op) => DivisionByZero(eval_to_int(op)?),
RemainderByZero(op) => RemainderByZero(eval_to_int(op)?), RemainderByZero(op) => RemainderByZero(eval_to_int(op)?),
ResumedAfterReturn(generator_kind) => ResumedAfterReturn(*generator_kind), ResumedAfterReturn(coroutine_kind) => ResumedAfterReturn(*coroutine_kind),
ResumedAfterPanic(generator_kind) => ResumedAfterPanic(*generator_kind), ResumedAfterPanic(coroutine_kind) => ResumedAfterPanic(*coroutine_kind),
MisalignedPointerDereference { ref required, ref found } => { MisalignedPointerDereference { ref required, ref found } => {
MisalignedPointerDereference { MisalignedPointerDereference {
required: eval_to_int(required)?, required: eval_to_int(required)?,

View File

@ -1,4 +1,4 @@
//! Functions for reading and writing discriminants of multi-variant layouts (enums and generators). //! Functions for reading and writing discriminants of multi-variant layouts (enums and coroutines).
use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt, TyAndLayout}; use rustc_middle::ty::layout::{LayoutOf, PrimitiveExt, TyAndLayout};
use rustc_middle::{mir, ty}; use rustc_middle::{mir, ty};
@ -171,10 +171,10 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
adt.discriminants(*self.tcx).find(|(_, var)| var.val == discr_bits) adt.discriminants(*self.tcx).find(|(_, var)| var.val == discr_bits)
} }
ty::Coroutine(def_id, args, _) => { ty::Coroutine(def_id, args, _) => {
let args = args.as_generator(); let args = args.as_coroutine();
args.discriminants(def_id, *self.tcx).find(|(_, var)| var.val == discr_bits) args.discriminants(def_id, *self.tcx).find(|(_, var)| var.val == discr_bits)
} }
_ => span_bug!(self.cur_span(), "tagged layout for non-adt non-generator"), _ => span_bug!(self.cur_span(), "tagged layout for non-adt non-coroutine"),
} }
.ok_or_else(|| err_ub!(InvalidTag(Scalar::from_uint(tag_bits, tag_layout.size))))?; .ok_or_else(|| err_ub!(InvalidTag(Scalar::from_uint(tag_bits, tag_layout.size))))?;
// Return the cast value, and the index. // Return the cast value, and the index.

View File

@ -42,10 +42,10 @@ where
let index = index let index = index
.try_into() .try_into()
.expect("more generic parameters than can fit into a `u32`"); .expect("more generic parameters than can fit into a `u32`");
// Only recurse when generic parameters in fns, closures and generators // Only recurse when generic parameters in fns, closures and coroutines
// are used and have to be instantiated. // are used and have to be instantiated.
// //
// Just in case there are closures or generators within this subst, // Just in case there are closures or coroutines within this subst,
// recurse. // recurse.
if unused_params.is_used(index) && subst.has_param() { if unused_params.is_used(index) && subst.has_param() {
return subst.visit_with(self); return subst.visit_with(self);

View File

@ -171,8 +171,8 @@ fn write_path(out: &mut String, path: &[PathElem]) {
Field(name) => write!(out, ".{name}"), Field(name) => write!(out, ".{name}"),
EnumTag => write!(out, ".<enum-tag>"), EnumTag => write!(out, ".<enum-tag>"),
Variant(name) => write!(out, ".<enum-variant({name})>"), Variant(name) => write!(out, ".<enum-variant({name})>"),
CoroutineTag => write!(out, ".<generator-tag>"), CoroutineTag => write!(out, ".<coroutine-tag>"),
CoroutineState(idx) => write!(out, ".<generator-state({})>", idx.index()), CoroutineState(idx) => write!(out, ".<coroutine-state({})>", idx.index()),
CapturedVar(name) => write!(out, ".<captured-var({name})>"), CapturedVar(name) => write!(out, ".<captured-var({name})>"),
TupleElem(idx) => write!(out, ".{idx}"), TupleElem(idx) => write!(out, ".{idx}"),
ArrayElem(idx) => write!(out, "[{idx}]"), ArrayElem(idx) => write!(out, "[{idx}]"),
@ -216,7 +216,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
// Now we know we are projecting to a field, so figure out which one. // Now we know we are projecting to a field, so figure out which one.
match layout.ty.kind() { match layout.ty.kind() {
// generators and closures. // coroutines and closures.
ty::Closure(def_id, _) | ty::Coroutine(def_id, _, _) => { ty::Closure(def_id, _) | ty::Coroutine(def_id, _, _) => {
let mut name = None; let mut name = None;
// FIXME this should be more descriptive i.e. CapturePlace instead of CapturedVar // FIXME this should be more descriptive i.e. CapturePlace instead of CapturedVar
@ -225,7 +225,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
let captures = self.ecx.tcx.closure_captures(local_def_id); let captures = self.ecx.tcx.closure_captures(local_def_id);
if let Some(captured_place) = captures.get(field) { if let Some(captured_place) = captures.get(field) {
// Sometimes the index is beyond the number of upvars (seen // Sometimes the index is beyond the number of upvars (seen
// for a generator). // for a coroutine).
let var_hir_id = captured_place.get_root_variable(); let var_hir_id = captured_place.get_root_variable();
let node = self.ecx.tcx.hir().get(var_hir_id); let node = self.ecx.tcx.hir().get(var_hir_id);
if let hir::Node::Pat(pat) = node { if let hir::Node::Pat(pat) = node {

View File

@ -247,7 +247,7 @@ impl<'mir, 'tcx> Checker<'mir, 'tcx> {
// `async` functions cannot be `const fn`. This is checked during AST lowering, so there's // `async` functions cannot be `const fn`. This is checked during AST lowering, so there's
// no need to emit duplicate errors here. // no need to emit duplicate errors here.
if self.ccx.is_async() || body.generator.is_some() { if self.ccx.is_async() || body.coroutine.is_some() {
tcx.sess.delay_span_bug(body.span, "`async` functions cannot be `const fn`"); tcx.sess.delay_span_bug(body.span, "`async` functions cannot be `const fn`");
return; return;
} }
@ -464,10 +464,10 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
Rvalue::Aggregate(kind, ..) => { Rvalue::Aggregate(kind, ..) => {
if let AggregateKind::Coroutine(def_id, ..) = kind.as_ref() if let AggregateKind::Coroutine(def_id, ..) = kind.as_ref()
&& let Some(generator_kind @ hir::CoroutineKind::Async(..)) = && let Some(coroutine_kind @ hir::CoroutineKind::Async(..)) =
self.tcx.generator_kind(def_id) self.tcx.coroutine_kind(def_id)
{ {
self.check_op(ops::Coroutine(generator_kind)); self.check_op(ops::Coroutine(coroutine_kind));
} }
} }

View File

@ -970,7 +970,7 @@ pub fn promote_candidates<'tcx>(
0, 0,
vec![], vec![],
body.span, body.span,
body.generator_kind(), body.coroutine_kind(),
body.tainted_by_errors, body.tainted_by_errors,
); );
promoted.phase = MirPhase::Analysis(AnalysisPhase::Initial); promoted.phase = MirPhase::Analysis(AnalysisPhase::Initial);

View File

@ -472,11 +472,11 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
self.check_unwind_edge(location, *unwind); self.check_unwind_edge(location, *unwind);
} }
TerminatorKind::Yield { resume, drop, .. } => { TerminatorKind::Yield { resume, drop, .. } => {
if self.body.generator.is_none() { if self.body.coroutine.is_none() {
self.fail(location, "`Yield` cannot appear outside generator bodies"); self.fail(location, "`Yield` cannot appear outside coroutine bodies");
} }
if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) { if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
self.fail(location, "`Yield` should have been replaced by generator lowering"); self.fail(location, "`Yield` should have been replaced by coroutine lowering");
} }
self.check_edge(location, *resume, EdgeKind::Normal); self.check_edge(location, *resume, EdgeKind::Normal);
if let Some(drop) = drop { if let Some(drop) = drop {
@ -510,13 +510,13 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
self.check_unwind_edge(location, *unwind); self.check_unwind_edge(location, *unwind);
} }
TerminatorKind::CoroutineDrop => { TerminatorKind::CoroutineDrop => {
if self.body.generator.is_none() { if self.body.coroutine.is_none() {
self.fail(location, "`CoroutineDrop` cannot appear outside generator bodies"); self.fail(location, "`CoroutineDrop` cannot appear outside coroutine bodies");
} }
if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) { if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
self.fail( self.fail(
location, location,
"`CoroutineDrop` should have been replaced by generator lowering", "`CoroutineDrop` should have been replaced by coroutine lowering",
); );
} }
} }
@ -724,10 +724,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
self.tcx.optimized_mir(def_id) self.tcx.optimized_mir(def_id)
}; };
let Some(layout) = gen_body.generator_layout() else { let Some(layout) = gen_body.coroutine_layout() else {
self.fail( self.fail(
location, location,
format!("No generator layout for {parent_ty:?}"), format!("No coroutine layout for {parent_ty:?}"),
); );
return; return;
}; };
@ -747,7 +747,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
ty::EarlyBinder::bind(f_ty.ty).instantiate(self.tcx, args) ty::EarlyBinder::bind(f_ty.ty).instantiate(self.tcx, args)
} else { } else {
let Some(&f_ty) = args.as_generator().prefix_tys().get(f.index()) let Some(&f_ty) = args.as_coroutine().prefix_tys().get(f.index())
else { else {
fail_out_of_bounds(self, location); fail_out_of_bounds(self, location);
return; return;
@ -1215,7 +1215,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
self.fail( self.fail(
location, location,
format!( format!(
"`SetDiscriminant` is only allowed on ADTs and generators, not {pty:?}" "`SetDiscriminant` is only allowed on ADTs and coroutines, not {pty:?}"
), ),
); );
} }

View File

@ -42,7 +42,7 @@ declare_features! (
Some("subsumed by `.await` syntax")), Some("subsumed by `.await` syntax")),
/// Allows using the `box $expr` syntax. /// Allows using the `box $expr` syntax.
(removed, box_syntax, "1.70.0", Some(49733), None, Some("replaced with `#[rustc_box]`")), (removed, box_syntax, "1.70.0", Some(49733), None, Some("replaced with `#[rustc_box]`")),
/// Allows capturing disjoint fields in a closure/generator (RFC 2229). /// Allows capturing disjoint fields in a closure/coroutine (RFC 2229).
(removed, capture_disjoint_fields, "1.49.0", Some(53488), None, Some("stabilized in Rust 2021")), (removed, capture_disjoint_fields, "1.49.0", Some(53488), None, Some("stabilized in Rust 2021")),
/// Allows comparing raw pointers during const eval. /// Allows comparing raw pointers during const eval.
(removed, const_compare_raw_pointers, "1.46.0", Some(53020), None, (removed, const_compare_raw_pointers, "1.46.0", Some(53020), None,

View File

@ -371,9 +371,9 @@ declare_features! (
(unstable, cfg_version, "1.45.0", Some(64796), None), (unstable, cfg_version, "1.45.0", Some(64796), None),
/// Allows to use the `#[cfi_encoding = ""]` attribute. /// Allows to use the `#[cfi_encoding = ""]` attribute.
(unstable, cfi_encoding, "1.71.0", Some(89653), None), (unstable, cfi_encoding, "1.71.0", Some(89653), None),
/// Allows `for<...>` on closures and generators. /// Allows `for<...>` on closures and coroutines.
(unstable, closure_lifetime_binder, "1.64.0", Some(97362), None), (unstable, closure_lifetime_binder, "1.64.0", Some(97362), None),
/// Allows `#[track_caller]` on closures and generators. /// Allows `#[track_caller]` on closures and coroutines.
(unstable, closure_track_caller, "1.57.0", Some(87417), None), (unstable, closure_track_caller, "1.57.0", Some(87417), None),
/// Allows to use the `#[cmse_nonsecure_entry]` attribute. /// Allows to use the `#[cmse_nonsecure_entry]` attribute.
(unstable, cmse_nonsecure_entry, "1.48.0", Some(75835), None), (unstable, cmse_nonsecure_entry, "1.48.0", Some(75835), None),
@ -399,6 +399,10 @@ declare_features! (
(unstable, const_trait_impl, "1.42.0", Some(67792), None), (unstable, const_trait_impl, "1.42.0", Some(67792), None),
/// Allows the `?` operator in const contexts. /// Allows the `?` operator in const contexts.
(unstable, const_try, "1.56.0", Some(74935), None), (unstable, const_try, "1.56.0", Some(74935), None),
/// Allows coroutines to be cloned.
(unstable, coroutine_clone, "1.65.0", Some(95360), None),
/// Allows defining coroutines.
(unstable, coroutines, "1.21.0", Some(43122), None),
/// Allows function attribute `#[coverage(on/off)]`, to control coverage /// Allows function attribute `#[coverage(on/off)]`, to control coverage
/// instrumentation of that function. /// instrumentation of that function.
(unstable, coverage_attribute, "1.74.0", Some(84605), None), (unstable, coverage_attribute, "1.74.0", Some(84605), None),
@ -451,10 +455,6 @@ declare_features! (
(unstable, ffi_returns_twice, "1.34.0", Some(58314), None), (unstable, ffi_returns_twice, "1.34.0", Some(58314), None),
/// Allows using `#[repr(align(...))]` on function items /// Allows using `#[repr(align(...))]` on function items
(unstable, fn_align, "1.53.0", Some(82232), None), (unstable, fn_align, "1.53.0", Some(82232), None),
/// Allows generators to be cloned.
(unstable, generator_clone, "1.65.0", Some(95360), None),
/// Allows defining generators.
(unstable, generators, "1.21.0", Some(43122), None),
/// Infer generic args for both consts and types. /// Infer generic args for both consts and types.
(unstable, generic_arg_infer, "1.55.0", Some(85077), None), (unstable, generic_arg_infer, "1.55.0", Some(85077), None),
/// An extension to the `generic_associated_types` feature, allowing incomplete features. /// An extension to the `generic_associated_types` feature, allowing incomplete features.

View File

@ -126,7 +126,7 @@ impl DefKind {
/// ///
/// If you have access to `TyCtxt`, use `TyCtxt::def_descr` or /// If you have access to `TyCtxt`, use `TyCtxt::def_descr` or
/// `TyCtxt::def_kind_descr` instead, because they give better /// `TyCtxt::def_kind_descr` instead, because they give better
/// information for generators and associated functions. /// information for coroutines and associated functions.
pub fn descr(self, def_id: DefId) -> &'static str { pub fn descr(self, def_id: DefId) -> &'static str {
match self { match self {
DefKind::Fn => "function", DefKind::Fn => "function",
@ -161,7 +161,7 @@ impl DefKind {
DefKind::Field => "field", DefKind::Field => "field",
DefKind::Impl { .. } => "implementation", DefKind::Impl { .. } => "implementation",
DefKind::Closure => "closure", DefKind::Closure => "closure",
DefKind::Coroutine => "generator", DefKind::Coroutine => "coroutine",
DefKind::ExternCrate => "extern crate", DefKind::ExternCrate => "extern crate",
DefKind::GlobalAsm => "global assembly block", DefKind::GlobalAsm => "global assembly block",
} }
@ -171,7 +171,7 @@ impl DefKind {
/// ///
/// If you have access to `TyCtxt`, use `TyCtxt::def_descr_article` or /// If you have access to `TyCtxt`, use `TyCtxt::def_descr_article` or
/// `TyCtxt::def_kind_descr_article` instead, because they give better /// `TyCtxt::def_kind_descr_article` instead, because they give better
/// information for generators and associated functions. /// information for coroutines and associated functions.
pub fn article(&self) -> &'static str { pub fn article(&self) -> &'static str {
match *self { match *self {
DefKind::AssocTy DefKind::AssocTy

View File

@ -1485,7 +1485,7 @@ pub struct BodyId {
/// ///
/// - an `params` array containing the `(x, y)` pattern /// - an `params` array containing the `(x, y)` pattern
/// - a `value` containing the `x + y` expression (maybe wrapped in a block) /// - a `value` containing the `x + y` expression (maybe wrapped in a block)
/// - `generator_kind` would be `None` /// - `coroutine_kind` would be `None`
/// ///
/// All bodies have an **owner**, which can be accessed via the HIR /// All bodies have an **owner**, which can be accessed via the HIR
/// map using `body_owner_def_id()`. /// map using `body_owner_def_id()`.
@ -1493,7 +1493,7 @@ pub struct BodyId {
pub struct Body<'hir> { pub struct Body<'hir> {
pub params: &'hir [Param<'hir>], pub params: &'hir [Param<'hir>],
pub value: &'hir Expr<'hir>, pub value: &'hir Expr<'hir>,
pub generator_kind: Option<CoroutineKind>, pub coroutine_kind: Option<CoroutineKind>,
} }
impl<'hir> Body<'hir> { impl<'hir> Body<'hir> {
@ -1501,19 +1501,19 @@ impl<'hir> Body<'hir> {
BodyId { hir_id: self.value.hir_id } BodyId { hir_id: self.value.hir_id }
} }
pub fn generator_kind(&self) -> Option<CoroutineKind> { pub fn coroutine_kind(&self) -> Option<CoroutineKind> {
self.generator_kind self.coroutine_kind
} }
} }
/// The type of source expression that caused this generator to be created. /// The type of source expression that caused this coroutine to be created.
#[derive(Clone, PartialEq, Eq, Debug, Copy, Hash)] #[derive(Clone, PartialEq, Eq, Debug, Copy, Hash)]
#[derive(HashStable_Generic, Encodable, Decodable)] #[derive(HashStable_Generic, Encodable, Decodable)]
pub enum CoroutineKind { pub enum CoroutineKind {
/// An explicit `async` block or the body of an async function. /// An explicit `async` block or the body of an async function.
Async(AsyncCoroutineKind), Async(AsyncCoroutineKind),
/// A generator literal created via a `yield` inside a closure. /// A coroutine literal created via a `yield` inside a closure.
Gen, Gen,
} }
@ -1521,7 +1521,7 @@ impl fmt::Display for CoroutineKind {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
match self { match self {
CoroutineKind::Async(k) => fmt::Display::fmt(k, f), CoroutineKind::Async(k) => fmt::Display::fmt(k, f),
CoroutineKind::Gen => f.write_str("generator"), CoroutineKind::Gen => f.write_str("coroutine"),
} }
} }
} }
@ -1530,12 +1530,12 @@ impl CoroutineKind {
pub fn descr(&self) -> &'static str { pub fn descr(&self) -> &'static str {
match self { match self {
CoroutineKind::Async(ask) => ask.descr(), CoroutineKind::Async(ask) => ask.descr(),
CoroutineKind::Gen => "generator", CoroutineKind::Gen => "coroutine",
} }
} }
} }
/// In the case of a generator created as part of an async construct, /// In the case of a coroutine created as part of an async construct,
/// which kind of async construct caused it to be created? /// which kind of async construct caused it to be created?
/// ///
/// This helps error messages but is also used to drive coercions in /// This helps error messages but is also used to drive coercions in
@ -2004,7 +2004,7 @@ pub enum ExprKind<'hir> {
/// ///
/// The `Span` is the argument block `|...|`. /// The `Span` is the argument block `|...|`.
/// ///
/// This may also be a generator literal or an `async block` as indicated by the /// This may also be a coroutine literal or an `async block` as indicated by the
/// `Option<Movability>`. /// `Option<Movability>`.
Closure(&'hir Closure<'hir>), Closure(&'hir Closure<'hir>),
/// A block (e.g., `'label: { ... }`). /// A block (e.g., `'label: { ... }`).
@ -2055,7 +2055,7 @@ pub enum ExprKind<'hir> {
/// to be repeated; the second is the number of times to repeat it. /// to be repeated; the second is the number of times to repeat it.
Repeat(&'hir Expr<'hir>, ArrayLen), Repeat(&'hir Expr<'hir>, ArrayLen),
/// A suspension point for generators (i.e., `yield <expr>`). /// A suspension point for coroutines (i.e., `yield <expr>`).
Yield(&'hir Expr<'hir>, YieldSource), Yield(&'hir Expr<'hir>, YieldSource),
/// A placeholder for an expression that wasn't syntactically well formed in some way. /// A placeholder for an expression that wasn't syntactically well formed in some way.
@ -2250,7 +2250,7 @@ impl fmt::Display for YieldSource {
impl From<CoroutineKind> for YieldSource { impl From<CoroutineKind> for YieldSource {
fn from(kind: CoroutineKind) -> Self { fn from(kind: CoroutineKind) -> Self {
match kind { match kind {
// Guess based on the kind of the current generator. // Guess based on the kind of the current coroutine.
CoroutineKind::Gen => Self::Yield, CoroutineKind::Gen => Self::Yield,
CoroutineKind::Async(_) => Self::Await { expr: None }, CoroutineKind::Async(_) => Self::Await { expr: None },
} }

View File

@ -62,7 +62,7 @@
//! respectively. (This follows from RPO respecting CFG domination). //! respectively. (This follows from RPO respecting CFG domination).
//! //!
//! This order consistency is required in a few places in rustc, for //! This order consistency is required in a few places in rustc, for
//! example generator inference, and possibly also HIR borrowck. //! example coroutine inference, and possibly also HIR borrowck.
use crate::hir::*; use crate::hir::*;
use rustc_ast::walk_list; use rustc_ast::walk_list;

View File

@ -211,8 +211,8 @@ language_item_table! {
FnOnceOutput, sym::fn_once_output, fn_once_output, Target::AssocTy, GenericRequirement::None; FnOnceOutput, sym::fn_once_output, fn_once_output, Target::AssocTy, GenericRequirement::None;
Future, sym::future_trait, future_trait, Target::Trait, GenericRequirement::Exact(0); Future, sym::future_trait, future_trait, Target::Trait, GenericRequirement::Exact(0);
CoroutineState, sym::generator_state, gen_state, Target::Enum, GenericRequirement::None; CoroutineState, sym::coroutine_state, gen_state, Target::Enum, GenericRequirement::None;
Coroutine, sym::generator, gen_trait, Target::Trait, GenericRequirement::Minimum(1); Coroutine, sym::coroutine, gen_trait, Target::Trait, GenericRequirement::Minimum(1);
Unpin, sym::unpin, unpin_trait, Target::Trait, GenericRequirement::None; Unpin, sym::unpin, unpin_trait, Target::Trait, GenericRequirement::None;
Pin, sym::pin, pin_type, Target::Struct, GenericRequirement::None; Pin, sym::pin, pin_type, Target::Struct, GenericRequirement::None;

View File

@ -291,7 +291,7 @@ fn check_opaque_meets_bounds<'tcx>(
let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args); let opaque_ty = Ty::new_opaque(tcx, def_id.to_def_id(), args);
// `ReErased` regions appear in the "parent_args" of closures/generators. // `ReErased` regions appear in the "parent_args" of closures/coroutines.
// We're ignoring them here and replacing them with fresh region variables. // We're ignoring them here and replacing them with fresh region variables.
// See tests in ui/type-alias-impl-trait/closure_{parent_args,wf_outlives}.rs. // See tests in ui/type-alias-impl-trait/closure_{parent_args,wf_outlives}.rs.
// //
@ -1446,11 +1446,11 @@ fn opaque_type_cycle_error(
{ {
label_match(capture.place.ty(), capture.get_path_span(tcx)); label_match(capture.place.ty(), capture.get_path_span(tcx));
} }
// Label any generator locals that capture the opaque // Label any coroutine locals that capture the opaque
if let DefKind::Coroutine = tcx.def_kind(closure_def_id) if let DefKind::Coroutine = tcx.def_kind(closure_def_id)
&& let Some(generator_layout) = tcx.mir_generator_witnesses(closure_def_id) && let Some(coroutine_layout) = tcx.mir_coroutine_witnesses(closure_def_id)
{ {
for interior_ty in &generator_layout.field_tys { for interior_ty in &coroutine_layout.field_tys {
label_match(interior_ty.ty, interior_ty.source_info.span); label_match(interior_ty.ty, interior_ty.source_info.span);
} }
} }
@ -1464,14 +1464,14 @@ fn opaque_type_cycle_error(
err.emit() err.emit()
} }
pub(super) fn check_generator_obligations(tcx: TyCtxt<'_>, def_id: LocalDefId) { pub(super) fn check_coroutine_obligations(tcx: TyCtxt<'_>, def_id: LocalDefId) {
debug_assert!(matches!(tcx.def_kind(def_id), DefKind::Coroutine)); debug_assert!(matches!(tcx.def_kind(def_id), DefKind::Coroutine));
let typeck = tcx.typeck(def_id); let typeck = tcx.typeck(def_id);
let param_env = tcx.param_env(def_id); let param_env = tcx.param_env(def_id);
let generator_interior_predicates = &typeck.generator_interior_predicates[&def_id]; let coroutine_interior_predicates = &typeck.coroutine_interior_predicates[&def_id];
debug!(?generator_interior_predicates); debug!(?coroutine_interior_predicates);
let infcx = tcx let infcx = tcx
.infer_ctxt() .infer_ctxt()
@ -1483,15 +1483,15 @@ pub(super) fn check_generator_obligations(tcx: TyCtxt<'_>, def_id: LocalDefId) {
.build(); .build();
let mut fulfillment_cx = <dyn TraitEngine<'_>>::new(&infcx); let mut fulfillment_cx = <dyn TraitEngine<'_>>::new(&infcx);
for (predicate, cause) in generator_interior_predicates { for (predicate, cause) in coroutine_interior_predicates {
let obligation = Obligation::new(tcx, cause.clone(), param_env, *predicate); let obligation = Obligation::new(tcx, cause.clone(), param_env, *predicate);
fulfillment_cx.register_predicate_obligation(&infcx, obligation); fulfillment_cx.register_predicate_obligation(&infcx, obligation);
} }
if (tcx.features().unsized_locals || tcx.features().unsized_fn_params) if (tcx.features().unsized_locals || tcx.features().unsized_fn_params)
&& let Some(generator) = tcx.mir_generator_witnesses(def_id) && let Some(coroutine) = tcx.mir_coroutine_witnesses(def_id)
{ {
for field_ty in generator.field_tys.iter() { for field_ty in coroutine.field_tys.iter() {
fulfillment_cx.register_bound( fulfillment_cx.register_bound(
&infcx, &infcx,
param_env, param_env,

View File

@ -114,7 +114,7 @@ pub fn provide(providers: &mut Providers) {
region_scope_tree, region_scope_tree,
collect_return_position_impl_trait_in_trait_tys, collect_return_position_impl_trait_in_trait_tys,
compare_impl_const: compare_impl_item::compare_impl_const_raw, compare_impl_const: compare_impl_item::compare_impl_const_raw,
check_generator_obligations: check::check_generator_obligations, check_coroutine_obligations: check::check_coroutine_obligations,
..*providers ..*providers
}; };
} }

View File

@ -598,7 +598,7 @@ fn resolve_local<'tcx>(
} }
// Make sure we visit the initializer first, so expr_and_pat_count remains correct. // Make sure we visit the initializer first, so expr_and_pat_count remains correct.
// The correct order, as shared between generator_interior, drop_ranges and intravisitor, // The correct order, as shared between coroutine_interior, drop_ranges and intravisitor,
// is to walk initializer, followed by pattern bindings, finally followed by the `else` block. // is to walk initializer, followed by pattern bindings, finally followed by the `else` block.
if let Some(expr) = init { if let Some(expr) = init {
visitor.visit_expr(expr); visitor.visit_expr(expr);
@ -825,7 +825,7 @@ impl<'tcx> Visitor<'tcx> for RegionResolutionVisitor<'tcx> {
resolve_local(self, None, Some(&body.value)); resolve_local(self, None, Some(&body.value));
} }
if body.generator_kind.is_some() { if body.coroutine_kind.is_some() {
self.scope_tree.body_expr_count.insert(body_id, self.expr_and_pat_count); self.scope_tree.body_expr_count.insert(body_id, self.expr_and_pat_count);
} }

View File

@ -76,7 +76,7 @@ pub fn provide(providers: &mut Providers) {
fn_sig, fn_sig,
impl_trait_ref, impl_trait_ref,
impl_polarity, impl_polarity,
generator_kind, coroutine_kind,
collect_mod_item_types, collect_mod_item_types,
is_type_alias_impl_trait, is_type_alias_impl_trait,
..*providers ..*providers
@ -1548,12 +1548,12 @@ fn compute_sig_of_foreign_fn_decl<'tcx>(
fty fty
} }
fn generator_kind(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<hir::CoroutineKind> { fn coroutine_kind(tcx: TyCtxt<'_>, def_id: LocalDefId) -> Option<hir::CoroutineKind> {
match tcx.hir().get_by_def_id(def_id) { match tcx.hir().get_by_def_id(def_id) {
Node::Expr(&rustc_hir::Expr { Node::Expr(&rustc_hir::Expr {
kind: rustc_hir::ExprKind::Closure(&rustc_hir::Closure { body, .. }), kind: rustc_hir::ExprKind::Closure(&rustc_hir::Closure { body, .. }),
.. ..
}) => tcx.hir().body(body).generator_kind(), }) => tcx.hir().body(body).coroutine_kind(),
_ => None, _ => None,
} }
} }

View File

@ -150,5 +150,5 @@ hir_typeck_union_pat_multiple_fields = union patterns should have exactly one fi
hir_typeck_use_is_empty = hir_typeck_use_is_empty =
consider using the `is_empty` method on `{$expr_ty}` to determine if it contains anything consider using the `is_empty` method on `{$expr_ty}` to determine if it contains anything
hir_typeck_yield_expr_outside_of_generator = hir_typeck_yield_expr_outside_of_coroutine =
yield expression outside of generator literal yield expression outside of coroutine literal

View File

@ -304,7 +304,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
hir::ExprKind::Block(..), hir::ExprKind::Block(..),
) = (parent_node, callee_node) ) = (parent_node, callee_node)
{ {
let fn_decl_span = if hir.body(body).generator_kind let fn_decl_span = if hir.body(body).coroutine_kind
== Some(hir::CoroutineKind::Async(hir::AsyncCoroutineKind::Closure)) == Some(hir::CoroutineKind::Async(hir::AsyncCoroutineKind::Closure))
{ {
// Actually need to unwrap one more layer of HIR to get to // Actually need to unwrap one more layer of HIR to get to

View File

@ -31,7 +31,7 @@ pub(super) fn check_fn<'a, 'tcx>(
decl: &'tcx hir::FnDecl<'tcx>, decl: &'tcx hir::FnDecl<'tcx>,
fn_def_id: LocalDefId, fn_def_id: LocalDefId,
body: &'tcx hir::Body<'tcx>, body: &'tcx hir::Body<'tcx>,
can_be_generator: Option<hir::Movability>, can_be_coroutine: Option<hir::Movability>,
params_can_be_unsized: bool, params_can_be_unsized: bool,
) -> Option<CoroutineTypes<'tcx>> { ) -> Option<CoroutineTypes<'tcx>> {
let fn_id = fcx.tcx.hir().local_def_id_to_hir_id(fn_def_id); let fn_id = fcx.tcx.hir().local_def_id_to_hir_id(fn_def_id);
@ -55,8 +55,8 @@ pub(super) fn check_fn<'a, 'tcx>(
fn_maybe_err(tcx, span, fn_sig.abi); fn_maybe_err(tcx, span, fn_sig.abi);
if let Some(kind) = body.generator_kind if let Some(kind) = body.coroutine_kind
&& can_be_generator.is_some() && can_be_coroutine.is_some()
{ {
let yield_ty = if kind == hir::CoroutineKind::Gen { let yield_ty = if kind == hir::CoroutineKind::Gen {
let yield_ty = fcx.next_ty_var(TypeVariableOrigin { let yield_ty = fcx.next_ty_var(TypeVariableOrigin {
@ -69,7 +69,7 @@ pub(super) fn check_fn<'a, 'tcx>(
Ty::new_unit(tcx) Ty::new_unit(tcx)
}; };
// Resume type defaults to `()` if the generator has no argument. // Resume type defaults to `()` if the coroutine has no argument.
let resume_ty = fn_sig.inputs().get(0).copied().unwrap_or_else(|| Ty::new_unit(tcx)); let resume_ty = fn_sig.inputs().get(0).copied().unwrap_or_else(|| Ty::new_unit(tcx));
fcx.resume_yield_tys = Some((resume_ty, yield_ty)); fcx.resume_yield_tys = Some((resume_ty, yield_ty));
@ -124,13 +124,13 @@ pub(super) fn check_fn<'a, 'tcx>(
fcx.require_type_is_sized(declared_ret_ty, return_or_body_span, traits::SizedReturnType); fcx.require_type_is_sized(declared_ret_ty, return_or_body_span, traits::SizedReturnType);
fcx.check_return_expr(&body.value, false); fcx.check_return_expr(&body.value, false);
// We insert the deferred_generator_interiors entry after visiting the body. // We insert the deferred_coroutine_interiors entry after visiting the body.
// This ensures that all nested generators appear before the entry of this generator. // This ensures that all nested coroutines appear before the entry of this coroutine.
// resolve_generator_interiors relies on this property. // resolve_coroutine_interiors relies on this property.
let gen_ty = if let (Some(_), Some(gen_kind)) = (can_be_generator, body.generator_kind) { let gen_ty = if let (Some(_), Some(gen_kind)) = (can_be_coroutine, body.coroutine_kind) {
let interior = fcx let interior = fcx
.next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span }); .next_ty_var(TypeVariableOrigin { kind: TypeVariableOriginKind::MiscVariable, span });
fcx.deferred_generator_interiors.borrow_mut().push(( fcx.deferred_coroutine_interiors.borrow_mut().push((
fn_def_id, fn_def_id,
body.id(), body.id(),
interior, interior,
@ -142,7 +142,7 @@ pub(super) fn check_fn<'a, 'tcx>(
resume_ty, resume_ty,
yield_ty, yield_ty,
interior, interior,
movability: can_be_generator.unwrap(), movability: can_be_coroutine.unwrap(),
}) })
} else { } else {
None None

View File

@ -84,7 +84,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
debug!(?bound_sig, ?liberated_sig); debug!(?bound_sig, ?liberated_sig);
let mut fcx = FnCtxt::new(self, self.param_env, closure.def_id); let mut fcx = FnCtxt::new(self, self.param_env, closure.def_id);
let generator_types = check_fn( let coroutine_types = check_fn(
&mut fcx, &mut fcx,
liberated_sig, liberated_sig,
closure.fn_decl, closure.fn_decl,
@ -105,9 +105,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
span: self.tcx.def_span(expr_def_id), span: self.tcx.def_span(expr_def_id),
}); });
if let Some(CoroutineTypes { resume_ty, yield_ty, interior, movability }) = generator_types if let Some(CoroutineTypes { resume_ty, yield_ty, interior, movability }) = coroutine_types
{ {
let generator_args = ty::CoroutineArgs::new( let coroutine_args = ty::CoroutineArgs::new(
self.tcx, self.tcx,
ty::CoroutineArgsParts { ty::CoroutineArgsParts {
parent_args, parent_args,
@ -119,10 +119,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
}, },
); );
return Ty::new_generator( return Ty::new_coroutine(
self.tcx, self.tcx,
expr_def_id.to_def_id(), expr_def_id.to_def_id(),
generator_args.args, coroutine_args.args,
movability, movability,
); );
} }
@ -285,7 +285,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
/// Given a projection like "<F as Fn(X)>::Result == Y", we can deduce /// Given a projection like "<F as Fn(X)>::Result == Y", we can deduce
/// everything we need to know about a closure or generator. /// everything we need to know about a closure or coroutine.
/// ///
/// The `cause_span` should be the span that caused us to /// The `cause_span` should be the span that caused us to
/// have this expected signature, or `None` if we can't readily /// have this expected signature, or `None` if we can't readily
@ -306,7 +306,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let is_gen = gen_trait == Some(trait_def_id); let is_gen = gen_trait == Some(trait_def_id);
if !is_fn && !is_gen { if !is_fn && !is_gen {
debug!("not fn or generator"); debug!("not fn or coroutine");
return None; return None;
} }
@ -623,7 +623,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let astconv: &dyn AstConv<'_> = self; let astconv: &dyn AstConv<'_> = self;
trace!("decl = {:#?}", decl); trace!("decl = {:#?}", decl);
debug!(?body.generator_kind); debug!(?body.coroutine_kind);
let hir_id = self.tcx.hir().local_def_id_to_hir_id(expr_def_id); let hir_id = self.tcx.hir().local_def_id_to_hir_id(expr_def_id);
let bound_vars = self.tcx.late_bound_vars(hir_id); let bound_vars = self.tcx.late_bound_vars(hir_id);
@ -632,7 +632,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
let supplied_arguments = decl.inputs.iter().map(|a| astconv.ast_ty_to_ty(a)); let supplied_arguments = decl.inputs.iter().map(|a| astconv.ast_ty_to_ty(a));
let supplied_return = match decl.output { let supplied_return = match decl.output {
hir::FnRetTy::Return(ref output) => astconv.ast_ty_to_ty(&output), hir::FnRetTy::Return(ref output) => astconv.ast_ty_to_ty(&output),
hir::FnRetTy::DefaultReturn(_) => match body.generator_kind { hir::FnRetTy::DefaultReturn(_) => match body.coroutine_kind {
// In the case of the async block that we create for a function body, // In the case of the async block that we create for a function body,
// we expect the return type of the block to match that of the enclosing // we expect the return type of the block to match that of the enclosing
// function. // function.
@ -675,7 +675,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.normalize(self.tcx.hir().span(hir_id), result) self.normalize(self.tcx.hir().span(hir_id), result)
} }
/// Invoked when we are translating the generator that results /// Invoked when we are translating the coroutine that results
/// from desugaring an `async fn`. Returns the "sugared" return /// from desugaring an `async fn`. Returns the "sugared" return
/// type of the `async fn` -- that is, the return type that the /// type of the `async fn` -- that is, the return type that the
/// user specified. The "desugared" return type is an `impl /// user specified. The "desugared" return type is an `impl
@ -688,7 +688,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
body_def_id: LocalDefId, body_def_id: LocalDefId,
) -> Option<Ty<'tcx>> { ) -> Option<Ty<'tcx>> {
let ret_coercion = self.ret_coercion.as_ref().unwrap_or_else(|| { let ret_coercion = self.ret_coercion.as_ref().unwrap_or_else(|| {
span_bug!(self.tcx.def_span(expr_def_id), "async fn generator outside of a fn") span_bug!(self.tcx.def_span(expr_def_id), "async fn coroutine outside of a fn")
}); });
let closure_span = self.tcx.def_span(expr_def_id); let closure_span = self.tcx.def_span(expr_def_id);
@ -729,7 +729,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
ty::Error(_) => return None, ty::Error(_) => return None,
_ => span_bug!( _ => span_bug!(
closure_span, closure_span,
"async fn generator return type not an inference variable: {ret_ty}" "async fn coroutine return type not an inference variable: {ret_ty}"
), ),
}; };

View File

@ -62,7 +62,7 @@ pub struct RustCallIncorrectArgs {
} }
#[derive(Diagnostic)] #[derive(Diagnostic)]
#[diag(hir_typeck_yield_expr_outside_of_generator, code = "E0627")] #[diag(hir_typeck_yield_expr_outside_of_coroutine, code = "E0627")]
pub struct YieldExprOutsideOfCoroutine { pub struct YieldExprOutsideOfCoroutine {
#[primary_span] #[primary_span]
pub span: Span, pub span: Span,

View File

@ -779,7 +779,7 @@ impl<'a, 'tcx> ExprUseVisitor<'a, 'tcx> {
let closure_def_id = closure_expr.def_id; let closure_def_id = closure_expr.def_id;
let upvars = tcx.upvars_mentioned(self.body_owner); let upvars = tcx.upvars_mentioned(self.body_owner);
// For purposes of this function, generator and closures are equivalent. // For purposes of this function, coroutine and closures are equivalent.
let body_owner_is_closure = let body_owner_is_closure =
matches!(tcx.hir().body_owner_kind(self.body_owner), hir::BodyOwnerKind::Closure,); matches!(tcx.hir().body_owner_kind(self.body_owner), hir::BodyOwnerKind::Closure,);

View File

@ -509,25 +509,25 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
typeck_results.rvalue_scopes = rvalue_scopes; typeck_results.rvalue_scopes = rvalue_scopes;
} }
/// Unify the inference variables corresponding to generator witnesses, and save all the /// Unify the inference variables corresponding to coroutine witnesses, and save all the
/// predicates that were stalled on those inference variables. /// predicates that were stalled on those inference variables.
/// ///
/// This process allows to conservatively save all predicates that do depend on the generator /// This process allows to conservatively save all predicates that do depend on the coroutine
/// interior types, for later processing by `check_generator_obligations`. /// interior types, for later processing by `check_coroutine_obligations`.
/// ///
/// We must not attempt to select obligations after this method has run, or risk query cycle /// We must not attempt to select obligations after this method has run, or risk query cycle
/// ICE. /// ICE.
#[instrument(level = "debug", skip(self))] #[instrument(level = "debug", skip(self))]
pub(in super::super) fn resolve_generator_interiors(&self, def_id: DefId) { pub(in super::super) fn resolve_coroutine_interiors(&self, def_id: DefId) {
// Try selecting all obligations that are not blocked on inference variables. // Try selecting all obligations that are not blocked on inference variables.
// Once we start unifying generator witnesses, trying to select obligations on them will // Once we start unifying coroutine witnesses, trying to select obligations on them will
// trigger query cycle ICEs, as doing so requires MIR. // trigger query cycle ICEs, as doing so requires MIR.
self.select_obligations_where_possible(|_| {}); self.select_obligations_where_possible(|_| {});
let generators = std::mem::take(&mut *self.deferred_generator_interiors.borrow_mut()); let coroutines = std::mem::take(&mut *self.deferred_coroutine_interiors.borrow_mut());
debug!(?generators); debug!(?coroutines);
for &(expr_def_id, body_id, interior, _) in generators.iter() { for &(expr_def_id, body_id, interior, _) in coroutines.iter() {
debug!(?expr_def_id); debug!(?expr_def_id);
// Create the `CoroutineWitness` type that we will unify with `interior`. // Create the `CoroutineWitness` type that we will unify with `interior`.
@ -535,14 +535,14 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
self.tcx, self.tcx,
self.tcx.typeck_root_def_id(expr_def_id.to_def_id()), self.tcx.typeck_root_def_id(expr_def_id.to_def_id()),
); );
let witness = Ty::new_generator_witness(self.tcx, expr_def_id.to_def_id(), args); let witness = Ty::new_coroutine_witness(self.tcx, expr_def_id.to_def_id(), args);
// Unify `interior` with `witness` and collect all the resulting obligations. // Unify `interior` with `witness` and collect all the resulting obligations.
let span = self.tcx.hir().body(body_id).value.span; let span = self.tcx.hir().body(body_id).value.span;
let ok = self let ok = self
.at(&self.misc(span), self.param_env) .at(&self.misc(span), self.param_env)
.eq(DefineOpaqueTypes::No, interior, witness) .eq(DefineOpaqueTypes::No, interior, witness)
.expect("Failed to unify generator interior type"); .expect("Failed to unify coroutine interior type");
let mut obligations = ok.obligations; let mut obligations = ok.obligations;
// Also collect the obligations that were unstalled by this unification. // Also collect the obligations that were unstalled by this unification.
@ -553,7 +553,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
debug!(?obligations); debug!(?obligations);
self.typeck_results self.typeck_results
.borrow_mut() .borrow_mut()
.generator_interior_predicates .coroutine_interior_predicates
.insert(expr_def_id, obligations); .insert(expr_def_id, obligations);
} }
} }

View File

@ -367,13 +367,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
continue; continue;
} }
// For this check, we do *not* want to treat async generator closures (async blocks) // For this check, we do *not* want to treat async coroutine closures (async blocks)
// as proper closures. Doing so would regress type inference when feeding // as proper closures. Doing so would regress type inference when feeding
// the return value of an argument-position async block to an argument-position // the return value of an argument-position async block to an argument-position
// closure wrapped in a block. // closure wrapped in a block.
// See <https://github.com/rust-lang/rust/issues/112225>. // See <https://github.com/rust-lang/rust/issues/112225>.
let is_closure = if let ExprKind::Closure(closure) = arg.kind { let is_closure = if let ExprKind::Closure(closure) = arg.kind {
!tcx.generator_is_async(closure.def_id.to_def_id()) !tcx.coroutine_is_async(closure.def_id.to_def_id())
} else { } else {
false false
}; };

View File

@ -534,7 +534,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
} }
ty::Coroutine(def_id, ..) ty::Coroutine(def_id, ..)
if matches!( if matches!(
self.tcx.generator_kind(def_id), self.tcx.coroutine_kind(def_id),
Some(CoroutineKind::Async(AsyncCoroutineKind::Closure)) Some(CoroutineKind::Async(AsyncCoroutineKind::Closure))
) => ) =>
{ {

View File

@ -55,7 +55,7 @@ pub struct Inherited<'tcx> {
pub(super) deferred_asm_checks: RefCell<Vec<(&'tcx hir::InlineAsm<'tcx>, hir::HirId)>>, pub(super) deferred_asm_checks: RefCell<Vec<(&'tcx hir::InlineAsm<'tcx>, hir::HirId)>>,
pub(super) deferred_generator_interiors: pub(super) deferred_coroutine_interiors:
RefCell<Vec<(LocalDefId, hir::BodyId, Ty<'tcx>, hir::CoroutineKind)>>, RefCell<Vec<(LocalDefId, hir::BodyId, Ty<'tcx>, hir::CoroutineKind)>>,
/// Whenever we introduce an adjustment from `!` into a type variable, /// Whenever we introduce an adjustment from `!` into a type variable,
@ -94,7 +94,7 @@ impl<'tcx> Inherited<'tcx> {
deferred_cast_checks: RefCell::new(Vec::new()), deferred_cast_checks: RefCell::new(Vec::new()),
deferred_transmute_checks: RefCell::new(Vec::new()), deferred_transmute_checks: RefCell::new(Vec::new()),
deferred_asm_checks: RefCell::new(Vec::new()), deferred_asm_checks: RefCell::new(Vec::new()),
deferred_generator_interiors: RefCell::new(Vec::new()), deferred_coroutine_interiors: RefCell::new(Vec::new()),
diverging_type_vars: RefCell::new(Default::default()), diverging_type_vars: RefCell::new(Default::default()),
infer_var_info: RefCell::new(Default::default()), infer_var_info: RefCell::new(Default::default()),
} }

View File

@ -255,11 +255,11 @@ fn typeck_with_fallback<'tcx>(
fcx.check_casts(); fcx.check_casts();
fcx.select_obligations_where_possible(|_| {}); fcx.select_obligations_where_possible(|_| {});
// Closure and generator analysis may run after fallback // Closure and coroutine analysis may run after fallback
// because they don't constrain other type variables. // because they don't constrain other type variables.
fcx.closure_analyze(body); fcx.closure_analyze(body);
assert!(fcx.deferred_call_resolutions.borrow().is_empty()); assert!(fcx.deferred_call_resolutions.borrow().is_empty());
// Before the generator analysis, temporary scopes shall be marked to provide more // Before the coroutine analysis, temporary scopes shall be marked to provide more
// precise information on types to be captured. // precise information on types to be captured.
fcx.resolve_rvalue_scopes(def_id.to_def_id()); fcx.resolve_rvalue_scopes(def_id.to_def_id());
@ -273,7 +273,7 @@ fn typeck_with_fallback<'tcx>(
debug!(pending_obligations = ?fcx.fulfillment_cx.borrow().pending_obligations()); debug!(pending_obligations = ?fcx.fulfillment_cx.borrow().pending_obligations());
// This must be the last thing before `report_ambiguity_errors`. // This must be the last thing before `report_ambiguity_errors`.
fcx.resolve_generator_interiors(def_id.to_def_id()); fcx.resolve_coroutine_interiors(def_id.to_def_id());
debug!(pending_obligations = ?fcx.fulfillment_cx.borrow().pending_obligations()); debug!(pending_obligations = ?fcx.fulfillment_cx.borrow().pending_obligations());
@ -298,11 +298,11 @@ fn typeck_with_fallback<'tcx>(
typeck_results typeck_results
} }
/// When `check_fn` is invoked on a generator (i.e., a body that /// When `check_fn` is invoked on a coroutine (i.e., a body that
/// includes yield), it returns back some information about the yield /// includes yield), it returns back some information about the yield
/// points. /// points.
struct CoroutineTypes<'tcx> { struct CoroutineTypes<'tcx> {
/// Type of generator argument / values returned by `yield`. /// Type of coroutine argument / values returned by `yield`.
resume_ty: Ty<'tcx>, resume_ty: Ty<'tcx>,
/// Type of value that is yielded. /// Type of value that is yielded.
@ -311,7 +311,7 @@ struct CoroutineTypes<'tcx> {
/// Types that are captured (see `CoroutineInterior` for more). /// Types that are captured (see `CoroutineInterior` for more).
interior: Ty<'tcx>, interior: Ty<'tcx>,
/// Indicates if the generator is movable or static (immovable). /// Indicates if the coroutine is movable or static (immovable).
movability: hir::Movability, movability: hir::Movability,
} }

View File

@ -366,7 +366,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
/// Note that we *always* infer a minimal kind, even if /// Note that we *always* infer a minimal kind, even if
/// we don't always *use* that in the final result (i.e., sometimes /// we don't always *use* that in the final result (i.e., sometimes
/// we've taken the closure kind from the expectations instead, and /// we've taken the closure kind from the expectations instead, and
/// for generators we don't even implement the closure traits /// for coroutines we don't even implement the closure traits
/// really). /// really).
/// ///
/// If we inferred that the closure needs to be FnMut/FnOnce, last element of the returned tuple /// If we inferred that the closure needs to be FnMut/FnOnce, last element of the returned tuple

View File

@ -63,7 +63,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
wbcx.visit_coercion_casts(); wbcx.visit_coercion_casts();
wbcx.visit_user_provided_tys(); wbcx.visit_user_provided_tys();
wbcx.visit_user_provided_sigs(); wbcx.visit_user_provided_sigs();
wbcx.visit_generator_interior(); wbcx.visit_coroutine_interior();
wbcx.visit_offset_of_container_types(); wbcx.visit_offset_of_container_types();
wbcx.typeck_results.rvalue_scopes = wbcx.typeck_results.rvalue_scopes =
@ -540,16 +540,16 @@ impl<'cx, 'tcx> WritebackCx<'cx, 'tcx> {
); );
} }
fn visit_generator_interior(&mut self) { fn visit_coroutine_interior(&mut self) {
let fcx_typeck_results = self.fcx.typeck_results.borrow(); let fcx_typeck_results = self.fcx.typeck_results.borrow();
assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner); assert_eq!(fcx_typeck_results.hir_owner, self.typeck_results.hir_owner);
self.tcx().with_stable_hashing_context(move |ref hcx| { self.tcx().with_stable_hashing_context(move |ref hcx| {
for (&expr_def_id, predicates) in for (&expr_def_id, predicates) in
fcx_typeck_results.generator_interior_predicates.to_sorted(hcx, false).into_iter() fcx_typeck_results.coroutine_interior_predicates.to_sorted(hcx, false).into_iter()
{ {
let predicates = let predicates =
self.resolve(predicates.clone(), &self.fcx.tcx.def_span(expr_def_id)); self.resolve(predicates.clone(), &self.fcx.tcx.def_span(expr_def_id));
self.typeck_results.generator_interior_predicates.insert(expr_def_id, predicates); self.typeck_results.coroutine_interior_predicates.insert(expr_def_id, predicates);
} }
}) })
} }

View File

@ -181,19 +181,19 @@ infer_more_targeted = {$has_param_name ->
infer_msl_introduces_static = introduces a `'static` lifetime requirement infer_msl_introduces_static = introduces a `'static` lifetime requirement
infer_msl_unmet_req = because this has an unmet lifetime requirement infer_msl_unmet_req = because this has an unmet lifetime requirement
infer_need_type_info_in_generator = infer_need_type_info_in_coroutine =
type inside {$generator_kind -> type inside {$coroutine_kind ->
[async_block] `async` block [async_block] `async` block
[async_closure] `async` closure [async_closure] `async` closure
[async_fn] `async fn` body [async_fn] `async fn` body
*[generator] generator *[coroutine] coroutine
} must be known in this context } must be known in this context
infer_nothing = {""} infer_nothing = {""}
infer_oc_cant_coerce = cannot coerce intrinsics to function pointers infer_oc_cant_coerce = cannot coerce intrinsics to function pointers
infer_oc_closure_selfref = closure/generator type that references itself infer_oc_closure_selfref = closure/coroutine type that references itself
infer_oc_const_compat = const not compatible with trait infer_oc_const_compat = const not compatible with trait
infer_oc_fn_lang_correct_type = {$lang_item_name -> infer_oc_fn_lang_correct_type = {$lang_item_name ->
[panic_impl] `#[panic_handler]` [panic_impl] `#[panic_handler]`
@ -284,7 +284,7 @@ infer_sbfrit_change_return_type = you could change the return type to be a boxed
infer_source_kind_closure_return = infer_source_kind_closure_return =
try giving this closure an explicit return type try giving this closure an explicit return type
# generator_kind may need to be translated # coroutine_kind may need to be translated
infer_source_kind_fully_qualified = infer_source_kind_fully_qualified =
try using a fully qualified path to specify the expected types try using a fully qualified path to specify the expected types

View File

@ -2821,7 +2821,7 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
// say, also take a look at the error code, maybe we can // say, also take a look at the error code, maybe we can
// tailor to that. // tailor to that.
_ => match terr { _ => match terr {
TypeError::CyclicTy(ty) if ty.is_closure() || ty.is_generator() => Error0644, TypeError::CyclicTy(ty) if ty.is_closure() || ty.is_coroutine() => Error0644,
TypeError::IntrinsicCast => Error0308, TypeError::IntrinsicCast => Error0308,
_ => Error0308, _ => Error0308,
}, },
@ -2868,7 +2868,7 @@ impl<'tcx> ObligationCauseExt<'tcx> for ObligationCause<'tcx> {
// say, also take a look at the error code, maybe we can // say, also take a look at the error code, maybe we can
// tailor to that. // tailor to that.
_ => match terr { _ => match terr {
TypeError::CyclicTy(ty) if ty.is_closure() || ty.is_generator() => { TypeError::CyclicTy(ty) if ty.is_closure() || ty.is_coroutine() => {
ObligationCauseFailureCode::ClosureSelfref { span } ObligationCauseFailureCode::ClosureSelfref { span }
} }
TypeError::IntrinsicCast => { TypeError::IntrinsicCast => {
@ -2960,7 +2960,7 @@ impl TyCategory {
Some((kind, def_id)) Some((kind, def_id))
} }
ty::Coroutine(def_id, ..) => { ty::Coroutine(def_id, ..) => {
Some((Self::Coroutine(tcx.generator_kind(def_id).unwrap()), def_id)) Some((Self::Coroutine(tcx.coroutine_kind(def_id).unwrap()), def_id))
} }
ty::Foreign(def_id) => Some((Self::Foreign, def_id)), ty::Foreign(def_id) => Some((Self::Foreign, def_id)),
_ => None, _ => None,

View File

@ -868,7 +868,7 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
) { ) {
// Opaque types can't be named by the user right now. // Opaque types can't be named by the user right now.
// //
// Both the generic arguments of closures and generators can // Both the generic arguments of closures and coroutines can
// also not be named. We may want to only look into the closure // also not be named. We may want to only look into the closure
// signature in case it has no captures, as that can be represented // signature in case it has no captures, as that can be represented
// using `fn(T) -> R`. // using `fn(T) -> R`.

View File

@ -325,7 +325,7 @@ impl<T> Trait<T> for X {
} }
CyclicTy(ty) => { CyclicTy(ty) => {
// Watch out for various cases of cyclic types and try to explain. // Watch out for various cases of cyclic types and try to explain.
if ty.is_closure() || ty.is_generator() { if ty.is_closure() || ty.is_coroutine() {
diag.note( diag.note(
"closures cannot capture themselves or take themselves as argument;\n\ "closures cannot capture themselves or take themselves as argument;\n\
this error may be the result of a recent compiler bug-fix,\n\ this error may be the result of a recent compiler bug-fix,\n\

View File

@ -458,12 +458,12 @@ where
// Skip lifetime parameters of the enclosing item(s) // Skip lifetime parameters of the enclosing item(s)
// Also skip the witness type, because that has no free regions. // Also skip the witness type, because that has no free regions.
for upvar in args.as_generator().upvar_tys() { for upvar in args.as_coroutine().upvar_tys() {
upvar.visit_with(self); upvar.visit_with(self);
} }
args.as_generator().return_ty().visit_with(self); args.as_coroutine().return_ty().visit_with(self);
args.as_generator().yield_ty().visit_with(self); args.as_coroutine().yield_ty().visit_with(self);
args.as_generator().resume_ty().visit_with(self); args.as_coroutine().resume_ty().visit_with(self);
} }
ty::Alias(ty::Opaque, ty::AliasTy { def_id, ref args, .. }) => { ty::Alias(ty::Opaque, ty::AliasTy { def_id, ref args, .. }) => {

View File

@ -104,10 +104,10 @@ fn compute_components<'tcx>(
ty::Coroutine(_, ref args, _) => { ty::Coroutine(_, ref args, _) => {
// Same as the closure case // Same as the closure case
let tupled_ty = args.as_generator().tupled_upvars_ty(); let tupled_ty = args.as_coroutine().tupled_upvars_ty();
compute_components(tcx, tupled_ty, out, visited); compute_components(tcx, tupled_ty, out, visited);
// We ignore regions in the generator interior as we don't // We ignore regions in the coroutine interior as we don't
// want these to affect region inference // want these to affect region inference
} }

View File

@ -800,8 +800,8 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
tcx.hir().par_body_owners(|def_id| { tcx.hir().par_body_owners(|def_id| {
if let rustc_hir::def::DefKind::Coroutine = tcx.def_kind(def_id) { if let rustc_hir::def::DefKind::Coroutine = tcx.def_kind(def_id) {
tcx.ensure().mir_generator_witnesses(def_id); tcx.ensure().mir_coroutine_witnesses(def_id);
tcx.ensure().check_generator_obligations(def_id); tcx.ensure().check_coroutine_obligations(def_id);
} }
}); });

View File

@ -551,19 +551,19 @@ lint_unused_closure =
lint_unused_comparisons = comparison is useless due to type limits lint_unused_comparisons = comparison is useless due to type limits
lint_unused_coroutine =
unused {$pre}{$count ->
[one] coroutine
*[other] coroutine
}{$post} that must be used
.note = coroutines are lazy and do nothing unless resumed
lint_unused_def = unused {$pre}`{$def}`{$post} that must be used lint_unused_def = unused {$pre}`{$def}`{$post} that must be used
.suggestion = use `let _ = ...` to ignore the resulting value .suggestion = use `let _ = ...` to ignore the resulting value
lint_unused_delim = unnecessary {$delim} around {$item} lint_unused_delim = unnecessary {$delim} around {$item}
.suggestion = remove these {$delim} .suggestion = remove these {$delim}
lint_unused_generator =
unused {$pre}{$count ->
[one] generator
*[other] generator
}{$post} that must be used
.note = generators are lazy and do nothing unless resumed
lint_unused_import_braces = braces around {$node} is unnecessary lint_unused_import_braces = braces around {$node} is unnecessary
lint_unused_op = unused {$op} that must be used lint_unused_op = unused {$op} that must be used

View File

@ -1700,7 +1700,7 @@ pub struct UnusedClosure<'a> {
// FIXME(davidtwco): this isn't properly translatable because of the // FIXME(davidtwco): this isn't properly translatable because of the
// pre/post strings // pre/post strings
#[derive(LintDiagnostic)] #[derive(LintDiagnostic)]
#[diag(lint_unused_generator)] #[diag(lint_unused_coroutine)]
#[note] #[note]
pub struct UnusedCoroutine<'a> { pub struct UnusedCoroutine<'a> {
pub count: usize, pub count: usize,

View File

@ -257,7 +257,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
Array(Box<Self>, u64), Array(Box<Self>, u64),
/// The root of the unused_closures lint. /// The root of the unused_closures lint.
Closure(Span), Closure(Span),
/// The root of the unused_generators lint. /// The root of the unused_coroutines lint.
Coroutine(Span), Coroutine(Span),
} }
@ -352,7 +352,7 @@ impl<'tcx> LateLintPass<'tcx> for UnusedResults {
ty::Closure(..) => Some(MustUsePath::Closure(span)), ty::Closure(..) => Some(MustUsePath::Closure(span)),
ty::Coroutine(def_id, ..) => { ty::Coroutine(def_id, ..) => {
// async fn should be treated as "implementor of `Future`" // async fn should be treated as "implementor of `Future`"
let must_use = if cx.tcx.generator_is_async(def_id) { let must_use = if cx.tcx.coroutine_is_async(def_id) {
let def_id = cx.tcx.lang_items().future_trait()?; let def_id = cx.tcx.lang_items().future_trait()?;
is_def_must_use(cx, def_id, span) is_def_must_use(cx, def_id, span)
.map(|inner| MustUsePath::Opaque(Box::new(inner))) .map(|inner| MustUsePath::Opaque(Box::new(inner)))

View File

@ -4,8 +4,9 @@
#![cfg_attr(not(bootstrap), allow(internal_features))] #![cfg_attr(not(bootstrap), allow(internal_features))]
#![feature(decl_macro)] #![feature(decl_macro)]
#![feature(extract_if)] #![feature(extract_if)]
#![feature(generators)] #![cfg_attr(bootstrap, feature(generators))]
#![feature(iter_from_generator)] #![cfg_attr(not(bootstrap), feature(coroutines))]
#![feature(iter_from_coroutine)]
#![feature(let_chains)] #![feature(let_chains)]
#![feature(proc_macro_internals)] #![feature(proc_macro_internals)]
#![feature(macro_metavar_expr)] #![feature(macro_metavar_expr)]

View File

@ -1239,7 +1239,7 @@ impl<'a, 'tcx> CrateMetadataRef<'a> {
id: DefIndex, id: DefIndex,
sess: &'a Session, sess: &'a Session,
) -> impl Iterator<Item = ModChild> + 'a { ) -> impl Iterator<Item = ModChild> + 'a {
iter::from_generator(move || { iter::from_coroutine(move || {
if let Some(data) = &self.root.proc_macro_data { if let Some(data) = &self.root.proc_macro_data {
// If we are loading as a proc macro, we want to return // If we are loading as a proc macro, we want to return
// the view of this crate as a proc macro crate. // the view of this crate as a proc macro crate.

View File

@ -221,7 +221,7 @@ provide! { tcx, def_id, other, cdata,
optimized_mir => { table } optimized_mir => { table }
mir_for_ctfe => { table } mir_for_ctfe => { table }
closure_saved_names_of_captured_variables => { table } closure_saved_names_of_captured_variables => { table }
mir_generator_witnesses => { table } mir_coroutine_witnesses => { table }
promoted_mir => { table } promoted_mir => { table }
def_span => { table } def_span => { table }
def_ident_span => { table } def_ident_span => { table }
@ -241,7 +241,7 @@ provide! { tcx, def_id, other, cdata,
rendered_const => { table } rendered_const => { table }
asyncness => { table_direct } asyncness => { table_direct }
fn_arg_names => { table } fn_arg_names => { table }
generator_kind => { table } coroutine_kind => { table }
trait_def => { table } trait_def => { table }
deduced_param_attrs => { table } deduced_param_attrs => { table }
is_type_alias_impl_trait => { is_type_alias_impl_trait => {

View File

@ -1447,8 +1447,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
} }
} }
if let DefKind::Coroutine = def_kind { if let DefKind::Coroutine = def_kind {
let data = self.tcx.generator_kind(def_id).unwrap(); let data = self.tcx.coroutine_kind(def_id).unwrap();
record!(self.tables.generator_kind[def_id] <- data); record!(self.tables.coroutine_kind[def_id] <- data);
} }
if let DefKind::Enum | DefKind::Struct | DefKind::Union = def_kind { if let DefKind::Enum | DefKind::Struct | DefKind::Union = def_kind {
self.encode_info_for_adt(local_id); self.encode_info_for_adt(local_id);
@ -1630,9 +1630,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
<- tcx.closure_saved_names_of_captured_variables(def_id)); <- tcx.closure_saved_names_of_captured_variables(def_id));
if let DefKind::Coroutine = self.tcx.def_kind(def_id) if let DefKind::Coroutine = self.tcx.def_kind(def_id)
&& let Some(witnesses) = tcx.mir_generator_witnesses(def_id) && let Some(witnesses) = tcx.mir_coroutine_witnesses(def_id)
{ {
record!(self.tables.mir_generator_witnesses[def_id.to_def_id()] <- witnesses); record!(self.tables.mir_coroutine_witnesses[def_id.to_def_id()] <- witnesses);
} }
} }
if encode_const { if encode_const {
@ -1657,9 +1657,9 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
record!(self.tables.promoted_mir[def_id.to_def_id()] <- tcx.promoted_mir(def_id)); record!(self.tables.promoted_mir[def_id.to_def_id()] <- tcx.promoted_mir(def_id));
if let DefKind::Coroutine = self.tcx.def_kind(def_id) if let DefKind::Coroutine = self.tcx.def_kind(def_id)
&& let Some(witnesses) = tcx.mir_generator_witnesses(def_id) && let Some(witnesses) = tcx.mir_coroutine_witnesses(def_id)
{ {
record!(self.tables.mir_generator_witnesses[def_id.to_def_id()] <- witnesses); record!(self.tables.mir_coroutine_witnesses[def_id.to_def_id()] <- witnesses);
} }
let instance = ty::InstanceDef::Item(def_id.to_def_id()); let instance = ty::InstanceDef::Item(def_id.to_def_id());

View File

@ -429,7 +429,7 @@ define_tables! {
mir_for_ctfe: Table<DefIndex, LazyValue<mir::Body<'static>>>, mir_for_ctfe: Table<DefIndex, LazyValue<mir::Body<'static>>>,
cross_crate_inlinable: Table<DefIndex, bool>, cross_crate_inlinable: Table<DefIndex, bool>,
closure_saved_names_of_captured_variables: Table<DefIndex, LazyValue<IndexVec<FieldIdx, Symbol>>>, closure_saved_names_of_captured_variables: Table<DefIndex, LazyValue<IndexVec<FieldIdx, Symbol>>>,
mir_generator_witnesses: Table<DefIndex, LazyValue<mir::CoroutineLayout<'static>>>, mir_coroutine_witnesses: Table<DefIndex, LazyValue<mir::CoroutineLayout<'static>>>,
promoted_mir: Table<DefIndex, LazyValue<IndexVec<mir::Promoted, mir::Body<'static>>>>, promoted_mir: Table<DefIndex, LazyValue<IndexVec<mir::Promoted, mir::Body<'static>>>>,
thir_abstract_const: Table<DefIndex, LazyValue<ty::EarlyBinder<ty::Const<'static>>>>, thir_abstract_const: Table<DefIndex, LazyValue<ty::EarlyBinder<ty::Const<'static>>>>,
impl_parent: Table<DefIndex, RawDefId>, impl_parent: Table<DefIndex, RawDefId>,
@ -442,7 +442,7 @@ define_tables! {
rendered_const: Table<DefIndex, LazyValue<String>>, rendered_const: Table<DefIndex, LazyValue<String>>,
asyncness: Table<DefIndex, ty::Asyncness>, asyncness: Table<DefIndex, ty::Asyncness>,
fn_arg_names: Table<DefIndex, LazyArray<Ident>>, fn_arg_names: Table<DefIndex, LazyArray<Ident>>,
generator_kind: Table<DefIndex, LazyValue<hir::CoroutineKind>>, coroutine_kind: Table<DefIndex, LazyValue<hir::CoroutineKind>>,
trait_def: Table<DefIndex, LazyValue<ty::TraitDef>>, trait_def: Table<DefIndex, LazyValue<ty::TraitDef>>,
trait_item_def_id: Table<DefIndex, RawDefId>, trait_item_def_id: Table<DefIndex, RawDefId>,
expn_that_defined: Table<DefIndex, LazyValue<ExpnId>>, expn_that_defined: Table<DefIndex, LazyValue<ExpnId>>,

View File

@ -5,13 +5,13 @@ middle_assert_async_resume_after_panic = `async fn` resumed after panicking
middle_assert_async_resume_after_return = `async fn` resumed after completion middle_assert_async_resume_after_return = `async fn` resumed after completion
middle_assert_coroutine_resume_after_panic = coroutine resumed after panicking
middle_assert_coroutine_resume_after_return = coroutine resumed after completion
middle_assert_divide_by_zero = middle_assert_divide_by_zero =
attempt to divide `{$val}` by zero attempt to divide `{$val}` by zero
middle_assert_generator_resume_after_panic = generator resumed after panicking
middle_assert_generator_resume_after_return = generator resumed after completion
middle_assert_misaligned_ptr_deref = middle_assert_misaligned_ptr_deref =
misaligned pointer dereference: address must be a multiple of {$required} but is {$found} misaligned pointer dereference: address must be a multiple of {$required} but is {$found}

View File

@ -4,7 +4,7 @@ use rustc_hir::intravisit::nested_filter::NestedFilter;
/// that are inside of an item-like. /// that are inside of an item-like.
/// ///
/// Notably, possible occurrences of bodies in non-item-like things /// Notably, possible occurrences of bodies in non-item-like things
/// include: closures/generators, inline `const {}` blocks, and /// include: closures/coroutines, inline `const {}` blocks, and
/// constant arguments of types, e.g. in `let _: [(); /* HERE */];`. /// constant arguments of types, e.g. in `let _: [(); /* HERE */];`.
/// ///
/// **This is the most common choice.** A very common pattern is /// **This is the most common choice.** A very common pattern is

View File

@ -32,11 +32,12 @@
#![feature(core_intrinsics)] #![feature(core_intrinsics)]
#![feature(discriminant_kind)] #![feature(discriminant_kind)]
#![feature(exhaustive_patterns)] #![feature(exhaustive_patterns)]
#![feature(generators)] #![cfg_attr(bootstrap, feature(generators))]
#![cfg_attr(not(bootstrap), feature(coroutines))]
#![feature(get_mut_unchecked)] #![feature(get_mut_unchecked)]
#![feature(if_let_guard)] #![feature(if_let_guard)]
#![feature(inline_const)] #![feature(inline_const)]
#![feature(iter_from_generator)] #![feature(iter_from_coroutine)]
#![feature(negative_impls)] #![feature(negative_impls)]
#![feature(never_type)] #![feature(never_type)]
#![feature(extern_types)] #![feature(extern_types)]

View File

@ -308,7 +308,7 @@ pub struct ScopeTree {
/// The number of visit_expr and visit_pat calls done in the body. /// The number of visit_expr and visit_pat calls done in the body.
/// Used to sanity check visit_expr/visit_pat call count when /// Used to sanity check visit_expr/visit_pat call count when
/// calculating generator interiors. /// calculating coroutine interiors.
pub body_expr_count: FxHashMap<hir::BodyId, usize>, pub body_expr_count: FxHashMap<hir::BodyId, usize>,
} }
@ -413,7 +413,7 @@ impl ScopeTree {
/// Gives the number of expressions visited in a body. /// Gives the number of expressions visited in a body.
/// Used to sanity check visit_expr call count when /// Used to sanity check visit_expr call count when
/// calculating generator interiors. /// calculating coroutine interiors.
pub fn body_expr_count(&self, body_id: hir::BodyId) -> Option<usize> { pub fn body_expr_count(&self, body_id: hir::BodyId) -> Option<usize> {
self.body_expr_count.get(&body_id).copied() self.body_expr_count.get(&body_id).copied()
} }

View File

@ -247,18 +247,18 @@ impl<'tcx> MirSource<'tcx> {
#[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable, TypeFoldable, TypeVisitable)] #[derive(Clone, TyEncodable, TyDecodable, Debug, HashStable, TypeFoldable, TypeVisitable)]
pub struct CoroutineInfo<'tcx> { pub struct CoroutineInfo<'tcx> {
/// The yield type of the function, if it is a generator. /// The yield type of the function, if it is a coroutine.
pub yield_ty: Option<Ty<'tcx>>, pub yield_ty: Option<Ty<'tcx>>,
/// Coroutine drop glue. /// Coroutine drop glue.
pub generator_drop: Option<Body<'tcx>>, pub coroutine_drop: Option<Body<'tcx>>,
/// The layout of a generator. Produced by the state transformation. /// The layout of a coroutine. Produced by the state transformation.
pub generator_layout: Option<CoroutineLayout<'tcx>>, pub coroutine_layout: Option<CoroutineLayout<'tcx>>,
/// If this is a generator then record the type of source expression that caused this generator /// If this is a coroutine then record the type of source expression that caused this coroutine
/// to be created. /// to be created.
pub generator_kind: CoroutineKind, pub coroutine_kind: CoroutineKind,
} }
/// The lowered representation of a single function. /// The lowered representation of a single function.
@ -284,7 +284,7 @@ pub struct Body<'tcx> {
/// and used for debuginfo. Indexed by a `SourceScope`. /// and used for debuginfo. Indexed by a `SourceScope`.
pub source_scopes: IndexVec<SourceScope, SourceScopeData<'tcx>>, pub source_scopes: IndexVec<SourceScope, SourceScopeData<'tcx>>,
pub generator: Option<Box<CoroutineInfo<'tcx>>>, pub coroutine: Option<Box<CoroutineInfo<'tcx>>>,
/// Declarations of locals. /// Declarations of locals.
/// ///
@ -365,7 +365,7 @@ impl<'tcx> Body<'tcx> {
arg_count: usize, arg_count: usize,
var_debug_info: Vec<VarDebugInfo<'tcx>>, var_debug_info: Vec<VarDebugInfo<'tcx>>,
span: Span, span: Span,
generator_kind: Option<CoroutineKind>, coroutine_kind: Option<CoroutineKind>,
tainted_by_errors: Option<ErrorGuaranteed>, tainted_by_errors: Option<ErrorGuaranteed>,
) -> Self { ) -> Self {
// We need `arg_count` locals, and one for the return place. // We need `arg_count` locals, and one for the return place.
@ -382,12 +382,12 @@ impl<'tcx> Body<'tcx> {
source, source,
basic_blocks: BasicBlocks::new(basic_blocks), basic_blocks: BasicBlocks::new(basic_blocks),
source_scopes, source_scopes,
generator: generator_kind.map(|generator_kind| { coroutine: coroutine_kind.map(|coroutine_kind| {
Box::new(CoroutineInfo { Box::new(CoroutineInfo {
yield_ty: None, yield_ty: None,
generator_drop: None, coroutine_drop: None,
generator_layout: None, coroutine_layout: None,
generator_kind, coroutine_kind,
}) })
}), }),
local_decls, local_decls,
@ -418,7 +418,7 @@ impl<'tcx> Body<'tcx> {
source: MirSource::item(CRATE_DEF_ID.to_def_id()), source: MirSource::item(CRATE_DEF_ID.to_def_id()),
basic_blocks: BasicBlocks::new(basic_blocks), basic_blocks: BasicBlocks::new(basic_blocks),
source_scopes: IndexVec::new(), source_scopes: IndexVec::new(),
generator: None, coroutine: None,
local_decls: IndexVec::new(), local_decls: IndexVec::new(),
user_type_annotations: IndexVec::new(), user_type_annotations: IndexVec::new(),
arg_count: 0, arg_count: 0,
@ -548,22 +548,22 @@ impl<'tcx> Body<'tcx> {
#[inline] #[inline]
pub fn yield_ty(&self) -> Option<Ty<'tcx>> { pub fn yield_ty(&self) -> Option<Ty<'tcx>> {
self.generator.as_ref().and_then(|generator| generator.yield_ty) self.coroutine.as_ref().and_then(|coroutine| coroutine.yield_ty)
} }
#[inline] #[inline]
pub fn generator_layout(&self) -> Option<&CoroutineLayout<'tcx>> { pub fn coroutine_layout(&self) -> Option<&CoroutineLayout<'tcx>> {
self.generator.as_ref().and_then(|generator| generator.generator_layout.as_ref()) self.coroutine.as_ref().and_then(|coroutine| coroutine.coroutine_layout.as_ref())
} }
#[inline] #[inline]
pub fn generator_drop(&self) -> Option<&Body<'tcx>> { pub fn coroutine_drop(&self) -> Option<&Body<'tcx>> {
self.generator.as_ref().and_then(|generator| generator.generator_drop.as_ref()) self.coroutine.as_ref().and_then(|coroutine| coroutine.coroutine_drop.as_ref())
} }
#[inline] #[inline]
pub fn generator_kind(&self) -> Option<CoroutineKind> { pub fn coroutine_kind(&self) -> Option<CoroutineKind> {
self.generator.as_ref().map(|generator| generator.generator_kind) self.coroutine.as_ref().map(|coroutine| coroutine.coroutine_kind)
} }
#[inline] #[inline]

View File

@ -130,8 +130,8 @@ fn dump_matched_mir_node<'tcx, F>(
Some(promoted) => write!(file, "::{promoted:?}`")?, Some(promoted) => write!(file, "::{promoted:?}`")?,
} }
writeln!(file, " {disambiguator} {pass_name}")?; writeln!(file, " {disambiguator} {pass_name}")?;
if let Some(ref layout) = body.generator_layout() { if let Some(ref layout) = body.coroutine_layout() {
writeln!(file, "/* generator_layout = {layout:#?} */")?; writeln!(file, "/* coroutine_layout = {layout:#?} */")?;
} }
writeln!(file)?; writeln!(file)?;
extra_data(PassWhere::BeforeCFG, &mut file)?; extra_data(PassWhere::BeforeCFG, &mut file)?;
@ -782,7 +782,7 @@ impl<'tcx> TerminatorKind<'tcx> {
Goto { .. } => write!(fmt, "goto"), Goto { .. } => write!(fmt, "goto"),
SwitchInt { discr, .. } => write!(fmt, "switchInt({discr:?})"), SwitchInt { discr, .. } => write!(fmt, "switchInt({discr:?})"),
Return => write!(fmt, "return"), Return => write!(fmt, "return"),
CoroutineDrop => write!(fmt, "generator_drop"), CoroutineDrop => write!(fmt, "coroutine_drop"),
UnwindResume => write!(fmt, "resume"), UnwindResume => write!(fmt, "resume"),
UnwindTerminate(reason) => { UnwindTerminate(reason) => {
write!(fmt, "abort({})", reason.as_short_str()) write!(fmt, "abort({})", reason.as_short_str())
@ -1047,7 +1047,7 @@ impl<'tcx> Debug for Rvalue<'tcx> {
}), }),
AggregateKind::Coroutine(def_id, _, _) => ty::tls::with(|tcx| { AggregateKind::Coroutine(def_id, _, _) => ty::tls::with(|tcx| {
let name = format!("{{generator@{:?}}}", tcx.def_span(def_id)); let name = format!("{{coroutine@{:?}}}", tcx.def_span(def_id));
let mut struct_fmt = fmt.debug_struct(&name); let mut struct_fmt = fmt.debug_struct(&name);
// FIXME(project-rfc-2229#48): This should be a list of capture names/places // FIXME(project-rfc-2229#48): This should be a list of capture names/places
@ -1302,7 +1302,7 @@ impl<'tcx> Visitor<'tcx> for ExtraComments<'tcx> {
} }
AggregateKind::Coroutine(def_id, args, movability) => { AggregateKind::Coroutine(def_id, args, movability) => {
self.push("generator"); self.push("coroutine");
self.push(&format!("+ def_id: {def_id:?}")); self.push(&format!("+ def_id: {def_id:?}"));
self.push(&format!("+ args: {args:#?}")); self.push(&format!("+ args: {args:#?}"));
self.push(&format!("+ movability: {movability:?}")); self.push(&format!("+ movability: {movability:?}"));

View File

@ -145,10 +145,10 @@ pub struct CoroutineSavedTy<'tcx> {
pub ignore_for_traits: bool, pub ignore_for_traits: bool,
} }
/// The layout of generator state. /// The layout of coroutine state.
#[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)] #[derive(Clone, TyEncodable, TyDecodable, HashStable, TypeFoldable, TypeVisitable)]
pub struct CoroutineLayout<'tcx> { pub struct CoroutineLayout<'tcx> {
/// The type of every local stored inside the generator. /// The type of every local stored inside the coroutine.
pub field_tys: IndexVec<CoroutineSavedLocal, CoroutineSavedTy<'tcx>>, pub field_tys: IndexVec<CoroutineSavedLocal, CoroutineSavedTy<'tcx>>,
/// The name for debuginfo. /// The name for debuginfo.
@ -185,7 +185,7 @@ impl Debug for CoroutineLayout<'_> {
} }
} }
/// Prints the generator variant name. /// Prints the coroutine variant name.
struct GenVariantPrinter(VariantIdx); struct GenVariantPrinter(VariantIdx);
impl From<VariantIdx> for GenVariantPrinter { impl From<VariantIdx> for GenVariantPrinter {
fn from(idx: VariantIdx) -> Self { fn from(idx: VariantIdx) -> Self {
@ -259,7 +259,7 @@ pub struct ConstQualifs {
/// ///
/// The requirements are listed as being between various `RegionVid`. The 0th /// The requirements are listed as being between various `RegionVid`. The 0th
/// region refers to `'static`; subsequent region vids refer to the free /// region refers to `'static`; subsequent region vids refer to the free
/// regions that appear in the closure (or generator's) type, in order of /// regions that appear in the closure (or coroutine's) type, in order of
/// appearance. (This numbering is actually defined by the `UniversalRegions` /// appearance. (This numbering is actually defined by the `UniversalRegions`
/// struct in the NLL region checker. See for example /// struct in the NLL region checker. See for example
/// `UniversalRegions::closure_mapping`.) Note the free regions in the /// `UniversalRegions::closure_mapping`.) Note the free regions in the

View File

@ -83,9 +83,9 @@ pub enum MirPhase {
/// don't document this here. Runtime MIR has most retags explicit (though implicit retags /// don't document this here. Runtime MIR has most retags explicit (though implicit retags
/// can still occur at `Rvalue::{Ref,AddrOf}`). /// can still occur at `Rvalue::{Ref,AddrOf}`).
/// - Coroutine bodies: In analysis MIR, locals may actually be behind a pointer that user code has /// - Coroutine bodies: In analysis MIR, locals may actually be behind a pointer that user code has
/// access to. This occurs in generator bodies. Such locals do not behave like other locals, /// access to. This occurs in coroutine bodies. Such locals do not behave like other locals,
/// because they eg may be aliased in surprising ways. Runtime MIR has no such special locals - /// because they eg may be aliased in surprising ways. Runtime MIR has no such special locals -
/// all generator bodies are lowered and so all places that look like locals really are locals. /// all coroutine bodies are lowered and so all places that look like locals really are locals.
/// ///
/// Also note that the lint pass which reports eg `200_u8 + 200_u8` as an error is run as a part /// Also note that the lint pass which reports eg `200_u8 + 200_u8` as an error is run as a part
/// of analysis to runtime MIR lowering. To ensure lints are reported reliably, this means that /// of analysis to runtime MIR lowering. To ensure lints are reported reliably, this means that
@ -292,7 +292,7 @@ pub enum StatementKind<'tcx> {
/// Write the discriminant for a variant to the enum Place. /// Write the discriminant for a variant to the enum Place.
/// ///
/// This is permitted for both generators and ADTs. This does not necessarily write to the /// This is permitted for both coroutines and ADTs. This does not necessarily write to the
/// entire place; instead, it writes to the minimum set of bytes as required by the layout for /// entire place; instead, it writes to the minimum set of bytes as required by the layout for
/// the type. /// the type.
SetDiscriminant { place: Box<Place<'tcx>>, variant_index: VariantIdx }, SetDiscriminant { place: Box<Place<'tcx>>, variant_index: VariantIdx },
@ -626,7 +626,7 @@ pub enum TerminatorKind<'tcx> {
/// `dest = move _0`. It might additionally do other things, like have side-effects in the /// `dest = move _0`. It might additionally do other things, like have side-effects in the
/// aliasing model. /// aliasing model.
/// ///
/// If the body is a generator body, this has slightly different semantics; it instead causes a /// If the body is a coroutine body, this has slightly different semantics; it instead causes a
/// `CoroutineState::Returned(_0)` to be created (as if by an `Aggregate` rvalue) and assigned /// `CoroutineState::Returned(_0)` to be created (as if by an `Aggregate` rvalue) and assigned
/// to the return place. /// to the return place.
Return, Return,
@ -709,14 +709,14 @@ pub enum TerminatorKind<'tcx> {
/// Marks a suspend point. /// Marks a suspend point.
/// ///
/// Like `Return` terminators in generator bodies, this computes `value` and then a /// Like `Return` terminators in coroutine bodies, this computes `value` and then a
/// `CoroutineState::Yielded(value)` as if by `Aggregate` rvalue. That value is then assigned to /// `CoroutineState::Yielded(value)` as if by `Aggregate` rvalue. That value is then assigned to
/// the return place of the function calling this one, and execution continues in the calling /// the return place of the function calling this one, and execution continues in the calling
/// function. When next invoked with the same first argument, execution of this function /// function. When next invoked with the same first argument, execution of this function
/// continues at the `resume` basic block, with the second argument written to the `resume_arg` /// continues at the `resume` basic block, with the second argument written to the `resume_arg`
/// place. If the generator is dropped before then, the `drop` basic block is invoked. /// place. If the coroutine is dropped before then, the `drop` basic block is invoked.
/// ///
/// Not permitted in bodies that are not generator bodies, or after generator lowering. /// Not permitted in bodies that are not coroutine bodies, or after coroutine lowering.
/// ///
/// **Needs clarification**: What about the evaluation order of the `resume_arg` and `value`? /// **Needs clarification**: What about the evaluation order of the `resume_arg` and `value`?
Yield { Yield {
@ -726,16 +726,16 @@ pub enum TerminatorKind<'tcx> {
resume: BasicBlock, resume: BasicBlock,
/// The place to store the resume argument in. /// The place to store the resume argument in.
resume_arg: Place<'tcx>, resume_arg: Place<'tcx>,
/// Cleanup to be done if the generator is dropped at this suspend point. /// Cleanup to be done if the coroutine is dropped at this suspend point.
drop: Option<BasicBlock>, drop: Option<BasicBlock>,
}, },
/// Indicates the end of dropping a generator. /// Indicates the end of dropping a coroutine.
/// ///
/// Semantically just a `return` (from the generators drop glue). Only permitted in the same situations /// Semantically just a `return` (from the coroutines drop glue). Only permitted in the same situations
/// as `yield`. /// as `yield`.
/// ///
/// **Needs clarification**: Is that even correct? The generator drop code is always confusing /// **Needs clarification**: Is that even correct? The coroutine drop code is always confusing
/// to me, because it's not even really in the current body. /// to me, because it's not even really in the current body.
/// ///
/// **Needs clarification**: Are there type system constraints on these terminators? Should /// **Needs clarification**: Are there type system constraints on these terminators? Should
@ -961,8 +961,8 @@ pub type AssertMessage<'tcx> = AssertKind<Operand<'tcx>>;
/// was unsized and so had metadata associated with it, then the metadata is retained if the /// was unsized and so had metadata associated with it, then the metadata is retained if the
/// field is unsized and thrown out if it is sized. /// field is unsized and thrown out if it is sized.
/// ///
/// These projections are only legal for tuples, ADTs, closures, and generators. If the ADT or /// These projections are only legal for tuples, ADTs, closures, and coroutines. If the ADT or
/// generator has more than one variant, the parent place's variant index must be set, indicating /// coroutine has more than one variant, the parent place's variant index must be set, indicating
/// which variant is being used. If it has just one variant, the variant index may or may not be /// which variant is being used. If it has just one variant, the variant index may or may not be
/// included - the single possible variant is inferred if it is not included. /// included - the single possible variant is inferred if it is not included.
/// - [`OpaqueCast`](ProjectionElem::OpaqueCast): This projection changes the place's type to the /// - [`OpaqueCast`](ProjectionElem::OpaqueCast): This projection changes the place's type to the
@ -1068,7 +1068,7 @@ pub enum ProjectionElem<V, T> {
from_end: bool, from_end: bool,
}, },
/// "Downcast" to a variant of an enum or a generator. /// "Downcast" to a variant of an enum or a coroutine.
/// ///
/// The included Symbol is the name of the variant, used for printing MIR. /// The included Symbol is the name of the variant, used for printing MIR.
Downcast(Option<Symbol>, VariantIdx), Downcast(Option<Symbol>, VariantIdx),
@ -1279,7 +1279,7 @@ pub enum Rvalue<'tcx> {
/// has a destructor. /// has a destructor.
/// ///
/// Disallowed after deaggregation for all aggregate kinds except `Array` and `Coroutine`. After /// Disallowed after deaggregation for all aggregate kinds except `Array` and `Coroutine`. After
/// generator lowering, `Coroutine` aggregate kinds are disallowed too. /// coroutine lowering, `Coroutine` aggregate kinds are disallowed too.
Aggregate(Box<AggregateKind<'tcx>>, IndexVec<FieldIdx, Operand<'tcx>>), Aggregate(Box<AggregateKind<'tcx>>, IndexVec<FieldIdx, Operand<'tcx>>),
/// Transmutes a `*mut u8` into shallow-initialized `Box<T>`. /// Transmutes a `*mut u8` into shallow-initialized `Box<T>`.

View File

@ -11,7 +11,7 @@ use rustc_target::abi::{FieldIdx, VariantIdx};
#[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable)] #[derive(Copy, Clone, Debug, TypeFoldable, TypeVisitable)]
pub struct PlaceTy<'tcx> { pub struct PlaceTy<'tcx> {
pub ty: Ty<'tcx>, pub ty: Ty<'tcx>,
/// Downcast to a particular variant of an enum or a generator, if included. /// Downcast to a particular variant of an enum or a coroutine, if included.
pub variant_index: Option<VariantIdx>, pub variant_index: Option<VariantIdx>,
} }
@ -206,7 +206,7 @@ impl<'tcx> Rvalue<'tcx> {
AggregateKind::Adt(did, _, args, _, _) => tcx.type_of(did).instantiate(tcx, args), AggregateKind::Adt(did, _, args, _, _) => tcx.type_of(did).instantiate(tcx, args),
AggregateKind::Closure(did, args) => Ty::new_closure(tcx, did, args), AggregateKind::Closure(did, args) => Ty::new_closure(tcx, did, args),
AggregateKind::Coroutine(did, args, movability) => { AggregateKind::Coroutine(did, args, movability) => {
Ty::new_generator(tcx, did, args, movability) Ty::new_coroutine(tcx, did, args, movability)
} }
}, },
Rvalue::ShallowInitBox(_, ty) => Ty::new_box(tcx, ty), Rvalue::ShallowInitBox(_, ty) => Ty::new_box(tcx, ty),

View File

@ -139,9 +139,9 @@ impl<O> AssertKind<O> {
Overflow(op, _, _) => bug!("{:?} cannot overflow", op), Overflow(op, _, _) => bug!("{:?} cannot overflow", op),
DivisionByZero(_) => "attempt to divide by zero", DivisionByZero(_) => "attempt to divide by zero",
RemainderByZero(_) => "attempt to calculate the remainder with a divisor of zero", RemainderByZero(_) => "attempt to calculate the remainder with a divisor of zero",
ResumedAfterReturn(CoroutineKind::Gen) => "generator resumed after completion", ResumedAfterReturn(CoroutineKind::Gen) => "coroutine resumed after completion",
ResumedAfterReturn(CoroutineKind::Async(_)) => "`async fn` resumed after completion", ResumedAfterReturn(CoroutineKind::Async(_)) => "`async fn` resumed after completion",
ResumedAfterPanic(CoroutineKind::Gen) => "generator resumed after panicking", ResumedAfterPanic(CoroutineKind::Gen) => "coroutine resumed after panicking",
ResumedAfterPanic(CoroutineKind::Async(_)) => "`async fn` resumed after panicking", ResumedAfterPanic(CoroutineKind::Async(_)) => "`async fn` resumed after panicking",
BoundsCheck { .. } | MisalignedPointerDereference { .. } => { BoundsCheck { .. } | MisalignedPointerDereference { .. } => {
bug!("Unexpected AssertKind") bug!("Unexpected AssertKind")
@ -229,9 +229,9 @@ impl<O> AssertKind<O> {
DivisionByZero(_) => middle_assert_divide_by_zero, DivisionByZero(_) => middle_assert_divide_by_zero,
RemainderByZero(_) => middle_assert_remainder_by_zero, RemainderByZero(_) => middle_assert_remainder_by_zero,
ResumedAfterReturn(CoroutineKind::Async(_)) => middle_assert_async_resume_after_return, ResumedAfterReturn(CoroutineKind::Async(_)) => middle_assert_async_resume_after_return,
ResumedAfterReturn(CoroutineKind::Gen) => middle_assert_generator_resume_after_return, ResumedAfterReturn(CoroutineKind::Gen) => middle_assert_coroutine_resume_after_return,
ResumedAfterPanic(CoroutineKind::Async(_)) => middle_assert_async_resume_after_panic, ResumedAfterPanic(CoroutineKind::Async(_)) => middle_assert_async_resume_after_panic,
ResumedAfterPanic(CoroutineKind::Gen) => middle_assert_generator_resume_after_panic, ResumedAfterPanic(CoroutineKind::Gen) => middle_assert_coroutine_resume_after_panic,
MisalignedPointerDereference { .. } => middle_assert_misaligned_ptr_deref, MisalignedPointerDereference { .. } => middle_assert_misaligned_ptr_deref,
} }

View File

@ -737,10 +737,10 @@ macro_rules! make_mir_visitor {
} }
AggregateKind::Coroutine( AggregateKind::Coroutine(
_, _,
generator_args, coroutine_args,
_movability, _movability,
) => { ) => {
self.visit_args(generator_args, location); self.visit_args(coroutine_args, location);
} }
} }
@ -992,7 +992,7 @@ macro_rules! extra_body_methods {
macro_rules! super_body { macro_rules! super_body {
($self:ident, $body:ident, $($mutability:ident, $invalidate:tt)?) => { ($self:ident, $body:ident, $($mutability:ident, $invalidate:tt)?) => {
let span = $body.span; let span = $body.span;
if let Some(gen) = &$($mutability)? $body.generator { if let Some(gen) = &$($mutability)? $body.coroutine {
if let Some(yield_ty) = $(& $mutability)? gen.yield_ty { if let Some(yield_ty) = $(& $mutability)? gen.yield_ty {
$self.visit_ty( $self.visit_ty(
yield_ty, yield_ty,

View File

@ -541,28 +541,28 @@ rustc_queries! {
} }
} }
/// Returns names of captured upvars for closures and generators. /// Returns names of captured upvars for closures and coroutines.
/// ///
/// Here are some examples: /// Here are some examples:
/// - `name__field1__field2` when the upvar is captured by value. /// - `name__field1__field2` when the upvar is captured by value.
/// - `_ref__name__field` when the upvar is captured by reference. /// - `_ref__name__field` when the upvar is captured by reference.
/// ///
/// For generators this only contains upvars that are shared by all states. /// For coroutines this only contains upvars that are shared by all states.
query closure_saved_names_of_captured_variables(def_id: DefId) -> &'tcx IndexVec<abi::FieldIdx, Symbol> { query closure_saved_names_of_captured_variables(def_id: DefId) -> &'tcx IndexVec<abi::FieldIdx, Symbol> {
arena_cache arena_cache
desc { |tcx| "computing debuginfo for closure `{}`", tcx.def_path_str(def_id) } desc { |tcx| "computing debuginfo for closure `{}`", tcx.def_path_str(def_id) }
separate_provide_extern separate_provide_extern
} }
query mir_generator_witnesses(key: DefId) -> &'tcx Option<mir::CoroutineLayout<'tcx>> { query mir_coroutine_witnesses(key: DefId) -> &'tcx Option<mir::CoroutineLayout<'tcx>> {
arena_cache arena_cache
desc { |tcx| "generator witness types for `{}`", tcx.def_path_str(key) } desc { |tcx| "coroutine witness types for `{}`", tcx.def_path_str(key) }
cache_on_disk_if { key.is_local() } cache_on_disk_if { key.is_local() }
separate_provide_extern separate_provide_extern
} }
query check_generator_obligations(key: LocalDefId) { query check_coroutine_obligations(key: LocalDefId) {
desc { |tcx| "verify auto trait bounds for generator interior type `{}`", tcx.def_path_str(key) } desc { |tcx| "verify auto trait bounds for coroutine interior type `{}`", tcx.def_path_str(key) }
} }
/// MIR after our optimization passes have run. This is MIR that is ready /// MIR after our optimization passes have run. This is MIR that is ready
@ -743,9 +743,9 @@ rustc_queries! {
desc { |tcx| "checking if item is promotable: `{}`", tcx.def_path_str(key) } desc { |tcx| "checking if item is promotable: `{}`", tcx.def_path_str(key) }
} }
/// Returns `Some(generator_kind)` if the node pointed to by `def_id` is a generator. /// Returns `Some(coroutine_kind)` if the node pointed to by `def_id` is a coroutine.
query generator_kind(def_id: DefId) -> Option<hir::CoroutineKind> { query coroutine_kind(def_id: DefId) -> Option<hir::CoroutineKind> {
desc { |tcx| "looking up generator kind of `{}`", tcx.def_path_str(def_id) } desc { |tcx| "looking up coroutine kind of `{}`", tcx.def_path_str(def_id) }
separate_provide_extern separate_provide_extern
} }

View File

@ -382,9 +382,9 @@ pub enum ExprKind<'tcx> {
VarRef { VarRef {
id: LocalVarId, id: LocalVarId,
}, },
/// Used to represent upvars mentioned in a closure/generator /// Used to represent upvars mentioned in a closure/coroutine
UpvarRef { UpvarRef {
/// DefId of the closure/generator /// DefId of the closure/coroutine
closure_def_id: DefId, closure_def_id: DefId,
/// HirId of the root variable /// HirId of the root variable

View File

@ -301,7 +301,7 @@ pub enum ObligationCauseCode<'tcx> {
InlineAsmSized, InlineAsmSized,
/// Captured closure type must be `Sized`. /// Captured closure type must be `Sized`.
SizedClosureCapture(LocalDefId), SizedClosureCapture(LocalDefId),
/// Types live across generator yields must be `Sized`. /// Types live across coroutine yields must be `Sized`.
SizedCoroutineInterior(LocalDefId), SizedCoroutineInterior(LocalDefId),
/// `[expr; N]` requires `type_of(expr): Copy`. /// `[expr; N]` requires `type_of(expr): Copy`.
RepeatElementCopy { RepeatElementCopy {

View File

@ -137,10 +137,10 @@ pub enum SelectionCandidate<'tcx> {
}, },
/// Implementation of a `Coroutine` trait by one of the anonymous types /// Implementation of a `Coroutine` trait by one of the anonymous types
/// generated for a generator. /// generated for a coroutine.
CoroutineCandidate, CoroutineCandidate,
/// Implementation of a `Future` trait by one of the generator types /// Implementation of a `Future` trait by one of the coroutine types
/// generated for an async construct. /// generated for an async construct.
FutureCandidate, FutureCandidate,

View File

@ -761,9 +761,9 @@ impl<'tcx> TyCtxt<'tcx> {
self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did) self.diagnostic_items(did.krate).name_to_id.get(&name) == Some(&did)
} }
/// Returns `true` if the node pointed to by `def_id` is a generator for an async construct. /// Returns `true` if the node pointed to by `def_id` is a coroutine for an async construct.
pub fn generator_is_async(self, def_id: DefId) -> bool { pub fn coroutine_is_async(self, def_id: DefId) -> bool {
matches!(self.generator_kind(def_id), Some(hir::CoroutineKind::Async(_))) matches!(self.coroutine_kind(def_id), Some(hir::CoroutineKind::Async(_)))
} }
pub fn stability(self) -> &'tcx stability::Index { pub fn stability(self) -> &'tcx stability::Index {
@ -951,7 +951,7 @@ impl<'tcx> TyCtxt<'tcx> {
self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE); self.dep_graph.read_index(DepNodeIndex::FOREVER_RED_NODE);
let definitions = &self.untracked.definitions; let definitions = &self.untracked.definitions;
std::iter::from_generator(|| { std::iter::from_coroutine(|| {
let mut i = 0; let mut i = 0;
// Recompute the number of definitions each time, because our caller may be creating // Recompute the number of definitions each time, because our caller may be creating

View File

@ -241,8 +241,8 @@ impl<'tcx> Ty<'tcx> {
} }
ty::Dynamic(..) => "trait object".into(), ty::Dynamic(..) => "trait object".into(),
ty::Closure(..) => "closure".into(), ty::Closure(..) => "closure".into(),
ty::Coroutine(def_id, ..) => tcx.generator_kind(def_id).unwrap().descr().into(), ty::Coroutine(def_id, ..) => tcx.coroutine_kind(def_id).unwrap().descr().into(),
ty::CoroutineWitness(..) => "generator witness".into(), ty::CoroutineWitness(..) => "coroutine witness".into(),
ty::Infer(ty::TyVar(_)) => "inferred type".into(), ty::Infer(ty::TyVar(_)) => "inferred type".into(),
ty::Infer(ty::IntVar(_)) => "integer".into(), ty::Infer(ty::IntVar(_)) => "integer".into(),
ty::Infer(ty::FloatVar(_)) => "floating-point number".into(), ty::Infer(ty::FloatVar(_)) => "floating-point number".into(),
@ -299,8 +299,8 @@ impl<'tcx> Ty<'tcx> {
ty::FnPtr(_) => "fn pointer".into(), ty::FnPtr(_) => "fn pointer".into(),
ty::Dynamic(..) => "trait object".into(), ty::Dynamic(..) => "trait object".into(),
ty::Closure(..) => "closure".into(), ty::Closure(..) => "closure".into(),
ty::Coroutine(def_id, ..) => tcx.generator_kind(def_id).unwrap().descr().into(), ty::Coroutine(def_id, ..) => tcx.coroutine_kind(def_id).unwrap().descr().into(),
ty::CoroutineWitness(..) => "generator witness".into(), ty::CoroutineWitness(..) => "coroutine witness".into(),
ty::Tuple(..) => "tuple".into(), ty::Tuple(..) => "tuple".into(),
ty::Placeholder(..) => "higher-ranked type".into(), ty::Placeholder(..) => "higher-ranked type".into(),
ty::Bound(..) => "bound type variable".into(), ty::Bound(..) => "bound type variable".into(),

View File

@ -112,7 +112,7 @@ impl FlagComputation {
} }
ty::Coroutine(_, args, _) => { ty::Coroutine(_, args, _) => {
let args = args.as_generator(); let args = args.as_coroutine();
let should_remove_further_specializable = let should_remove_further_specializable =
!self.flags.contains(TypeFlags::STILL_FURTHER_SPECIALIZABLE); !self.flags.contains(TypeFlags::STILL_FURTHER_SPECIALIZABLE);
self.add_args(args.parent_args()); self.add_args(args.parent_args());

View File

@ -266,11 +266,11 @@ impl<'tcx> GenericArgs<'tcx> {
ClosureArgs { args: self } ClosureArgs { args: self }
} }
/// Interpret these generic args as the args of a generator type. /// Interpret these generic args as the args of a coroutine type.
/// Coroutine args have a particular structure controlled by the /// Coroutine args have a particular structure controlled by the
/// compiler that encodes information like the signature and generator kind; /// compiler that encodes information like the signature and coroutine kind;
/// see `ty::CoroutineArgs` struct for more comments. /// see `ty::CoroutineArgs` struct for more comments.
pub fn as_generator(&'tcx self) -> CoroutineArgs<'tcx> { pub fn as_coroutine(&'tcx self) -> CoroutineArgs<'tcx> {
CoroutineArgs { args: self } CoroutineArgs { args: self }
} }

View File

@ -36,7 +36,7 @@ pub enum InstanceDef<'tcx> {
/// This includes: /// This includes:
/// - `fn` items /// - `fn` items
/// - closures /// - closures
/// - generators /// - coroutines
Item(DefId), Item(DefId),
/// An intrinsic `fn` item (with `"rust-intrinsic"` or `"platform-intrinsic"` ABI). /// An intrinsic `fn` item (with `"rust-intrinsic"` or `"platform-intrinsic"` ABI).
@ -653,15 +653,15 @@ fn polymorphize<'tcx>(
let unused = tcx.unused_generic_params(instance); let unused = tcx.unused_generic_params(instance);
debug!("polymorphize: unused={:?}", unused); debug!("polymorphize: unused={:?}", unused);
// If this is a closure or generator then we need to handle the case where another closure // If this is a closure or coroutine then we need to handle the case where another closure
// from the function is captured as an upvar and hasn't been polymorphized. In this case, // from the function is captured as an upvar and hasn't been polymorphized. In this case,
// the unpolymorphized upvar closure would result in a polymorphized closure producing // the unpolymorphized upvar closure would result in a polymorphized closure producing
// multiple mono items (and eventually symbol clashes). // multiple mono items (and eventually symbol clashes).
let def_id = instance.def_id(); let def_id = instance.def_id();
let upvars_ty = if tcx.is_closure(def_id) { let upvars_ty = if tcx.is_closure(def_id) {
Some(args.as_closure().tupled_upvars_ty()) Some(args.as_closure().tupled_upvars_ty())
} else if tcx.type_of(def_id).skip_binder().is_generator() { } else if tcx.type_of(def_id).skip_binder().is_coroutine() {
Some(args.as_generator().tupled_upvars_ty()) Some(args.as_coroutine().tupled_upvars_ty())
} else { } else {
None None
}; };
@ -695,7 +695,7 @@ fn polymorphize<'tcx>(
if args == polymorphized_args { if args == polymorphized_args {
ty ty
} else { } else {
Ty::new_generator(self.tcx, def_id, polymorphized_args, movability) Ty::new_coroutine(self.tcx, def_id, polymorphized_args, movability)
} }
} }
_ => ty.super_fold_with(self), _ => ty.super_fold_with(self),
@ -715,7 +715,7 @@ fn polymorphize<'tcx>(
upvars_ty == Some(args[param.index as usize].expect_ty()) => { upvars_ty == Some(args[param.index as usize].expect_ty()) => {
// ..then double-check that polymorphization marked it used.. // ..then double-check that polymorphization marked it used..
debug_assert!(!is_unused); debug_assert!(!is_unused);
// ..and polymorphize any closures/generators captured as upvars. // ..and polymorphize any closures/coroutines captured as upvars.
let upvars_ty = upvars_ty.unwrap(); let upvars_ty = upvars_ty.unwrap();
let polymorphized_upvars_ty = upvars_ty.fold_with( let polymorphized_upvars_ty = upvars_ty.fold_with(
&mut PolymorphizationFolder { tcx }); &mut PolymorphizationFolder { tcx });

View File

@ -898,7 +898,7 @@ where
ty::Array(element, _) | ty::Slice(element) => TyMaybeWithLayout::Ty(element), ty::Array(element, _) | ty::Slice(element) => TyMaybeWithLayout::Ty(element),
ty::Str => TyMaybeWithLayout::Ty(tcx.types.u8), ty::Str => TyMaybeWithLayout::Ty(tcx.types.u8),
// Tuples, generators and closures. // Tuples, coroutines and closures.
ty::Closure(_, ref args) => field_ty_or_layout( ty::Closure(_, ref args) => field_ty_or_layout(
TyAndLayout { ty: args.as_closure().tupled_upvars_ty(), ..this }, TyAndLayout { ty: args.as_closure().tupled_upvars_ty(), ..this },
cx, cx,
@ -907,7 +907,7 @@ where
ty::Coroutine(def_id, ref args, _) => match this.variants { ty::Coroutine(def_id, ref args, _) => match this.variants {
Variants::Single { index } => TyMaybeWithLayout::Ty( Variants::Single { index } => TyMaybeWithLayout::Ty(
args.as_generator() args.as_coroutine()
.state_tys(def_id, tcx) .state_tys(def_id, tcx)
.nth(index.as_usize()) .nth(index.as_usize())
.unwrap() .unwrap()
@ -918,7 +918,7 @@ where
if i == tag_field { if i == tag_field {
return TyMaybeWithLayout::TyAndLayout(tag_layout(tag)); return TyMaybeWithLayout::TyAndLayout(tag_layout(tag));
} }
TyMaybeWithLayout::Ty(args.as_generator().prefix_tys()[i]) TyMaybeWithLayout::Ty(args.as_coroutine().prefix_tys()[i])
} }
}, },

Some files were not shown because too many files have changed in this diff Show More