mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-07 20:58:39 +00:00
Auto merge of #116958 - oli-obk:coro, r=pnkfelix
rename Generator to Coroutine implements https://github.com/rust-lang/compiler-team/issues/682 While I did an automated replacement, I went through all changes manually to avoid renaming things like "id generators", "code generator", ... I renamed files where that was necessary due to the contents referring to the crate name itself (mir opt, codegen or debuginfo tests), or required by tidy (feature gate docs) * [x] rename various remaining abbreviated references to generators. * [x] rename files * [x] rename folders * [x] add renamed feature: `generators`, ... r? `@ghost`
This commit is contained in:
commit
249624b504
@ -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.
|
||||||
|
@ -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
|
||||||
|
@ -131,8 +131,8 @@ 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 GeneratorTooManyParameters {
|
pub struct CoroutineTooManyParameters {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub fn_decl_span: Span,
|
pub fn_decl_span: Span,
|
||||||
}
|
}
|
||||||
@ -161,8 +161,8 @@ 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 AsyncGeneratorsNotSupported {
|
pub struct AsyncCoroutinesNotSupported {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use super::errors::{
|
use super::errors::{
|
||||||
AsyncGeneratorsNotSupported, AsyncNonMoveClosureNotSupported, AwaitOnlyInAsyncFnAndBlocks,
|
AsyncCoroutinesNotSupported, AsyncNonMoveClosureNotSupported, AwaitOnlyInAsyncFnAndBlocks,
|
||||||
BaseExpressionDoubleDot, ClosureCannotBeStatic, FunctionalRecordUpdateDestructuringAssignment,
|
BaseExpressionDoubleDot, ClosureCannotBeStatic, CoroutineTooManyParameters,
|
||||||
GeneratorTooManyParameters, InclusiveRangeWithNoEnd, NotSupportedForLifetimeBinderAsyncClosure,
|
FunctionalRecordUpdateDestructuringAssignment, InclusiveRangeWithNoEnd,
|
||||||
UnderscoreExprLhsAssign,
|
NotSupportedForLifetimeBinderAsyncClosure, UnderscoreExprLhsAssign,
|
||||||
};
|
};
|
||||||
use super::ResolverAstLoweringExt;
|
use super::ResolverAstLoweringExt;
|
||||||
use super::{ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs};
|
use super::{ImplTraitContext, LoweringContext, ParamMode, ParenthesizedGenericArgs};
|
||||||
@ -188,7 +188,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
e.id,
|
e.id,
|
||||||
None,
|
None,
|
||||||
e.span,
|
e.span,
|
||||||
hir::AsyncGeneratorKind::Block,
|
hir::AsyncCoroutineKind::Block,
|
||||||
|this| this.with_new_scopes(|this| this.lower_block_expr(block)),
|
|this| this.with_new_scopes(|this| this.lower_block_expr(block)),
|
||||||
),
|
),
|
||||||
ExprKind::Await(expr, await_kw_span) => self.lower_expr_await(*await_kw_span, expr),
|
ExprKind::Await(expr, await_kw_span) => self.lower_expr_await(*await_kw_span, expr),
|
||||||
@ -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:
|
||||||
///
|
///
|
||||||
@ -598,7 +598,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
closure_node_id: NodeId,
|
closure_node_id: NodeId,
|
||||||
ret_ty: Option<hir::FnRetTy<'hir>>,
|
ret_ty: Option<hir::FnRetTy<'hir>>,
|
||||||
span: Span,
|
span: Span,
|
||||||
async_gen_kind: hir::AsyncGeneratorKind,
|
async_gen_kind: hir::AsyncCoroutineKind,
|
||||||
body: impl FnOnce(&mut Self) -> hir::Expr<'hir>,
|
body: impl FnOnce(&mut Self) -> hir::Expr<'hir>,
|
||||||
) -> hir::ExprKind<'hir> {
|
) -> hir::ExprKind<'hir> {
|
||||||
let output = ret_ty.unwrap_or_else(|| hir::FnRetTy::DefaultReturn(self.lower_span(span)));
|
let output = ret_ty.unwrap_or_else(|| hir::FnRetTy::DefaultReturn(self.lower_span(span)));
|
||||||
@ -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::GeneratorKind::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,9 +710,9 @@ 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::GeneratorKind::Async(_)) => {}
|
Some(hir::CoroutineKind::Async(_)) => {}
|
||||||
Some(hir::GeneratorKind::Gen) | None => {
|
Some(hir::CoroutineKind::Coroutine) | None => {
|
||||||
self.tcx.sess.emit_err(AwaitOnlyInAsyncFnAndBlocks {
|
self.tcx.sess.emit_err(AwaitOnlyInAsyncFnAndBlocks {
|
||||||
await_kw_span,
|
await_kw_span,
|
||||||
item_span: self.current_item,
|
item_span: self.current_item,
|
||||||
@ -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,28 +915,28 @@ 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::GeneratorKind>,
|
coroutine_kind: Option<hir::CoroutineKind>,
|
||||||
movability: Movability,
|
movability: Movability,
|
||||||
) -> Option<hir::Movability> {
|
) -> Option<hir::Movability> {
|
||||||
match generator_kind {
|
match coroutine_kind {
|
||||||
Some(hir::GeneratorKind::Gen) => {
|
Some(hir::CoroutineKind::Coroutine) => {
|
||||||
if decl.inputs.len() > 1 {
|
if decl.inputs.len() > 1 {
|
||||||
self.tcx.sess.emit_err(GeneratorTooManyParameters { fn_decl_span });
|
self.tcx.sess.emit_err(CoroutineTooManyParameters { fn_decl_span });
|
||||||
}
|
}
|
||||||
Some(movability)
|
Some(movability)
|
||||||
}
|
}
|
||||||
Some(hir::GeneratorKind::Async(_)) => {
|
Some(hir::CoroutineKind::Async(_)) => {
|
||||||
panic!("non-`async` closure body turned `async` during lowering");
|
panic!("non-`async` closure body turned `async` during lowering");
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
@ -1005,7 +1005,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
inner_closure_id,
|
inner_closure_id,
|
||||||
async_ret_ty,
|
async_ret_ty,
|
||||||
body.span,
|
body.span,
|
||||||
hir::AsyncGeneratorKind::Closure,
|
hir::AsyncCoroutineKind::Closure,
|
||||||
|this| this.with_new_scopes(|this| this.lower_expr_mut(body)),
|
|this| this.with_new_scopes(|this| this.lower_expr_mut(body)),
|
||||||
);
|
);
|
||||||
let hir_id = this.lower_node_id(inner_closure_id);
|
let hir_id = this.lower_node_id(inner_closure_id);
|
||||||
@ -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::GeneratorKind::Gen) => {}
|
Some(hir::CoroutineKind::Coroutine) => {}
|
||||||
Some(hir::GeneratorKind::Async(_)) => {
|
Some(hir::CoroutineKind::Async(_)) => {
|
||||||
self.tcx.sess.emit_err(AsyncGeneratorsNotSupported { span });
|
self.tcx.sess.emit_err(AsyncCoroutinesNotSupported { span });
|
||||||
}
|
}
|
||||||
None => self.generator_kind = Some(hir::GeneratorKind::Gen),
|
None => self.coroutine_kind = Some(hir::CoroutineKind::Coroutine),
|
||||||
}
|
}
|
||||||
|
|
||||||
let expr =
|
let expr =
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1206,7 +1206,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
closure_id,
|
closure_id,
|
||||||
None,
|
None,
|
||||||
body.span,
|
body.span,
|
||||||
hir::AsyncGeneratorKind::Fn,
|
hir::AsyncCoroutineKind::Fn,
|
||||||
|this| {
|
|this| {
|
||||||
// Create a block from the user's function body:
|
// Create a block from the user's function body:
|
||||||
let user_body = this.lower_block_expr(body);
|
let user_body = this.lower_block_expr(body);
|
||||||
|
@ -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::GeneratorKind>,
|
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`
|
||||||
|
@ -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!(
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
@ -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) |
|
||||||
|
@ -8,7 +8,7 @@ use rustc_errors::{
|
|||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::{DefKind, Res};
|
use rustc_hir::def::{DefKind, Res};
|
||||||
use rustc_hir::intravisit::{walk_block, walk_expr, Visitor};
|
use rustc_hir::intravisit::{walk_block, walk_expr, Visitor};
|
||||||
use rustc_hir::{AsyncGeneratorKind, GeneratorKind, LangItem};
|
use rustc_hir::{AsyncCoroutineKind, CoroutineKind, LangItem};
|
||||||
use rustc_infer::traits::ObligationCause;
|
use rustc_infer::traits::ObligationCause;
|
||||||
use rustc_middle::hir::nested_filter::OnlyBodies;
|
use rustc_middle::hir::nested_filter::OnlyBodies;
|
||||||
use rustc_middle::mir::tcx::PlaceTy;
|
use rustc_middle::mir::tcx::PlaceTy;
|
||||||
@ -848,7 +848,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||||||
move_spans.var_subdiag(None, &mut err, None, |kind, var_span| {
|
move_spans.var_subdiag(None, &mut err, None, |kind, var_span| {
|
||||||
use crate::session_diagnostics::CaptureVarCause::*;
|
use crate::session_diagnostics::CaptureVarCause::*;
|
||||||
match kind {
|
match kind {
|
||||||
Some(_) => MoveUseInGenerator { var_span },
|
Some(_) => MoveUseInCoroutine { var_span },
|
||||||
None => MoveUseInClosure { var_span },
|
None => MoveUseInClosure { var_span },
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -894,7 +894,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||||||
let desc_place = self.describe_any_place(place.as_ref());
|
let desc_place = self.describe_any_place(place.as_ref());
|
||||||
match kind {
|
match kind {
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
BorrowUsePlaceGenerator { place: desc_place, var_span, is_single_var: true }
|
BorrowUsePlaceCoroutine { place: desc_place, var_span, is_single_var: true }
|
||||||
}
|
}
|
||||||
None => BorrowUsePlaceClosure { place: desc_place, var_span, is_single_var: true },
|
None => BorrowUsePlaceClosure { place: desc_place, var_span, is_single_var: true },
|
||||||
}
|
}
|
||||||
@ -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"
|
||||||
};
|
};
|
||||||
@ -1040,7 +1040,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||||||
|kind, var_span| {
|
|kind, var_span| {
|
||||||
use crate::session_diagnostics::CaptureVarCause::*;
|
use crate::session_diagnostics::CaptureVarCause::*;
|
||||||
match kind {
|
match kind {
|
||||||
Some(_) => BorrowUsePlaceGenerator {
|
Some(_) => BorrowUsePlaceCoroutine {
|
||||||
place: desc_place,
|
place: desc_place,
|
||||||
var_span,
|
var_span,
|
||||||
is_single_var: true,
|
is_single_var: true,
|
||||||
@ -1125,7 +1125,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||||||
borrow_spans.var_subdiag(None, &mut err, Some(gen_borrow_kind), |kind, var_span| {
|
borrow_spans.var_subdiag(None, &mut err, Some(gen_borrow_kind), |kind, var_span| {
|
||||||
use crate::session_diagnostics::CaptureVarCause::*;
|
use crate::session_diagnostics::CaptureVarCause::*;
|
||||||
match kind {
|
match kind {
|
||||||
Some(_) => BorrowUsePlaceGenerator {
|
Some(_) => BorrowUsePlaceCoroutine {
|
||||||
place: desc_place,
|
place: desc_place,
|
||||||
var_span,
|
var_span,
|
||||||
is_single_var: false,
|
is_single_var: false,
|
||||||
@ -1146,7 +1146,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||||||
let borrow_place_desc = self.describe_any_place(borrow_place.as_ref());
|
let borrow_place_desc = self.describe_any_place(borrow_place.as_ref());
|
||||||
match kind {
|
match kind {
|
||||||
Some(_) => {
|
Some(_) => {
|
||||||
FirstBorrowUsePlaceGenerator { place: borrow_place_desc, var_span }
|
FirstBorrowUsePlaceCoroutine { place: borrow_place_desc, var_span }
|
||||||
}
|
}
|
||||||
None => FirstBorrowUsePlaceClosure { place: borrow_place_desc, var_span },
|
None => FirstBorrowUsePlaceClosure { place: borrow_place_desc, var_span },
|
||||||
}
|
}
|
||||||
@ -1160,7 +1160,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||||||
|kind, var_span| {
|
|kind, var_span| {
|
||||||
use crate::session_diagnostics::CaptureVarCause::*;
|
use crate::session_diagnostics::CaptureVarCause::*;
|
||||||
match kind {
|
match kind {
|
||||||
Some(_) => SecondBorrowUsePlaceGenerator { place: desc_place, var_span },
|
Some(_) => SecondBorrowUsePlaceCoroutine { place: desc_place, var_span },
|
||||||
None => SecondBorrowUsePlaceClosure { place: desc_place, var_span },
|
None => SecondBorrowUsePlaceClosure { place: desc_place, var_span },
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
@ -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::Generator => "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 {
|
||||||
GeneratorKind::Async(async_kind) => match async_kind {
|
CoroutineKind::Async(async_kind) => match async_kind {
|
||||||
AsyncGeneratorKind::Block => "async block",
|
AsyncCoroutineKind::Block => "async block",
|
||||||
AsyncGeneratorKind::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."),
|
||||||
},
|
},
|
||||||
GeneratorKind::Gen => "generator",
|
CoroutineKind::Coroutine => "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(GeneratorKind::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",
|
||||||
@ -2785,7 +2785,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||||||
loan_spans.var_subdiag(None, &mut err, Some(loan.kind), |kind, var_span| {
|
loan_spans.var_subdiag(None, &mut err, Some(loan.kind), |kind, var_span| {
|
||||||
use crate::session_diagnostics::CaptureVarCause::*;
|
use crate::session_diagnostics::CaptureVarCause::*;
|
||||||
match kind {
|
match kind {
|
||||||
Some(_) => BorrowUseInGenerator { var_span },
|
Some(_) => BorrowUseInCoroutine { var_span },
|
||||||
None => BorrowUseInClosure { var_span },
|
None => BorrowUseInClosure { var_span },
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@ -2801,7 +2801,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||||||
loan_spans.var_subdiag(None, &mut err, Some(loan.kind), |kind, var_span| {
|
loan_spans.var_subdiag(None, &mut err, Some(loan.kind), |kind, var_span| {
|
||||||
use crate::session_diagnostics::CaptureVarCause::*;
|
use crate::session_diagnostics::CaptureVarCause::*;
|
||||||
match kind {
|
match kind {
|
||||||
Some(_) => BorrowUseInGenerator { var_span },
|
Some(_) => BorrowUseInCoroutine { var_span },
|
||||||
None => BorrowUseInClosure { var_span },
|
None => BorrowUseInClosure { var_span },
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -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::Generator(..) => ("destructor", "generator".to_owned()),
|
ty::Coroutine(..) => ("destructor", "coroutine".to_owned()),
|
||||||
|
|
||||||
_ => ("destructor", format!("type `{}`", local_decl.ty)),
|
_ => ("destructor", format!("type `{}`", local_decl.ty)),
|
||||||
};
|
};
|
||||||
|
@ -8,7 +8,7 @@ use itertools::Itertools;
|
|||||||
use rustc_errors::{Applicability, Diagnostic};
|
use rustc_errors::{Applicability, Diagnostic};
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::{CtorKind, Namespace};
|
use rustc_hir::def::{CtorKind, Namespace};
|
||||||
use rustc_hir::GeneratorKind;
|
use rustc_hir::CoroutineKind;
|
||||||
use rustc_index::IndexSlice;
|
use rustc_index::IndexSlice;
|
||||||
use rustc_infer::infer::LateBoundRegionConversionTime;
|
use rustc_infer::infer::LateBoundRegionConversionTime;
|
||||||
use rustc_middle::mir::tcx::PlaceTy;
|
use rustc_middle::mir::tcx::PlaceTy;
|
||||||
@ -369,7 +369,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||||||
ty::Array(ty, _) | ty::Slice(ty) => {
|
ty::Array(ty, _) | ty::Slice(ty) => {
|
||||||
self.describe_field_from_ty(ty, field, variant_index, including_tuple_field)
|
self.describe_field_from_ty(ty, field, variant_index, including_tuple_field)
|
||||||
}
|
}
|
||||||
ty::Closure(def_id, _) | ty::Generator(def_id, _, _) => {
|
ty::Closure(def_id, _) | ty::Coroutine(def_id, _, _) => {
|
||||||
// We won't be borrowck'ing here if the closure came from another crate,
|
// We won't be borrowck'ing here if the closure came from another crate,
|
||||||
// so it's safe to call `expect_local`.
|
// so it's safe to call `expect_local`.
|
||||||
//
|
//
|
||||||
@ -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<GeneratorKind>,
|
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<GeneratorKind> {
|
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,14 +596,14 @@ 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 => BorrowInGenerator { path_span },
|
Borrow => BorrowInCoroutine { path_span },
|
||||||
MatchOn | Use => UseInGenerator { path_span },
|
MatchOn | Use => UseInCoroutine { path_span },
|
||||||
Assignment => AssignInGenerator { path_span },
|
Assignment => AssignInCoroutine { path_span },
|
||||||
PartialAssignment => AssignPartInGenerator { path_span },
|
PartialAssignment => AssignPartInCoroutine { path_span },
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
@ -624,9 +624,9 @@ impl UseSpans<'_> {
|
|||||||
handler: Option<&rustc_errors::Handler>,
|
handler: Option<&rustc_errors::Handler>,
|
||||||
err: &mut Diagnostic,
|
err: &mut Diagnostic,
|
||||||
kind: Option<rustc_middle::mir::BorrowKind>,
|
kind: Option<rustc_middle::mir::BorrowKind>,
|
||||||
f: impl FnOnce(Option<GeneratorKind>, 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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -780,15 +780,15 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||||||
|
|
||||||
debug!("move_spans: moved_place={:?} location={:?} stmt={:?}", moved_place, location, stmt);
|
debug!("move_spans: moved_place={:?} location={:?} stmt={:?}", moved_place, location, stmt);
|
||||||
if let StatementKind::Assign(box (_, Rvalue::Aggregate(kind, places))) = &stmt.kind
|
if let StatementKind::Assign(box (_, Rvalue::Aggregate(kind, places))) = &stmt.kind
|
||||||
&& let AggregateKind::Closure(def_id, _) | AggregateKind::Generator(def_id, _, _) =
|
&& let AggregateKind::Closure(def_id, _) | AggregateKind::Coroutine(def_id, _, _) =
|
||||||
**kind
|
**kind
|
||||||
{
|
{
|
||||||
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,21 +914,21 @@ 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::Generator(def_id, _, _) => (def_id, true),
|
box AggregateKind::Coroutine(def_id, _, _) => (def_id, true),
|
||||||
_ => continue,
|
_ => continue,
|
||||||
};
|
};
|
||||||
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(
|
||||||
@ -950,7 +950,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||||||
def_id: LocalDefId,
|
def_id: LocalDefId,
|
||||||
target_place: PlaceRef<'tcx>,
|
target_place: PlaceRef<'tcx>,
|
||||||
places: &IndexSlice<FieldIdx, Operand<'tcx>>,
|
places: &IndexSlice<FieldIdx, Operand<'tcx>>,
|
||||||
) -> Option<(Span, Option<GeneratorKind>, Span, Span)> {
|
) -> Option<(Span, Option<CoroutineKind>, Span, Span)> {
|
||||||
debug!(
|
debug!(
|
||||||
"closure_span: def_id={:?} target_place={:?} places={:?}",
|
"closure_span: def_id={:?} target_place={:?} places={:?}",
|
||||||
def_id, target_place, places
|
def_id, target_place, places
|
||||||
@ -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),
|
||||||
));
|
));
|
||||||
@ -1188,7 +1188,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||||||
// another message for the same span
|
// another message for the same span
|
||||||
if !is_loop_message {
|
if !is_loop_message {
|
||||||
move_spans.var_subdiag(None, err, None, |kind, var_span| match kind {
|
move_spans.var_subdiag(None, err, None, |kind, var_span| match kind {
|
||||||
Some(_) => CaptureVarCause::PartialMoveUseInGenerator { var_span, is_partial },
|
Some(_) => CaptureVarCause::PartialMoveUseInCoroutine { var_span, is_partial },
|
||||||
None => CaptureVarCause::PartialMoveUseInClosure { var_span, is_partial },
|
None => CaptureVarCause::PartialMoveUseInClosure { var_span, is_partial },
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -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.
|
||||||
|
@ -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::Generator(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::GeneratorKind::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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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,16 +680,16 @@ 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::GeneratorKind::Async(gen)) => match gen {
|
Some(hir::CoroutineKind::Async(gen)) => match gen {
|
||||||
hir::AsyncGeneratorKind::Block => " of async block",
|
hir::AsyncCoroutineKind::Block => " of async block",
|
||||||
hir::AsyncGeneratorKind::Closure => " of async closure",
|
hir::AsyncCoroutineKind::Closure => " of async closure",
|
||||||
hir::AsyncGeneratorKind::Fn => {
|
hir::AsyncCoroutineKind::Fn => {
|
||||||
let parent_item =
|
let parent_item =
|
||||||
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::GeneratorKind::Gen) => " of generator",
|
Some(hir::CoroutineKind::Coroutine) => " 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);
|
||||||
|
@ -161,7 +161,7 @@ impl<'cx, 'tcx> Visitor<'tcx> for InvalidationGenerator<'cx, 'tcx> {
|
|||||||
}
|
}
|
||||||
TerminatorKind::UnwindResume
|
TerminatorKind::UnwindResume
|
||||||
| TerminatorKind::Return
|
| TerminatorKind::Return
|
||||||
| TerminatorKind::GeneratorDrop => {
|
| TerminatorKind::CoroutineDrop => {
|
||||||
// Invalidate all borrows of local places
|
// Invalidate all borrows of local places
|
||||||
let borrow_set = self.borrow_set;
|
let borrow_set = self.borrow_set;
|
||||||
let start = self.location_table.start_index(location);
|
let start = self.location_table.start_index(location);
|
||||||
|
@ -302,11 +302,11 @@ 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::Generator(_, _, hir::Movability::Static) = local.ty.kind()
|
&& let ty::Coroutine(_, _, hir::Movability::Static) = local.ty.kind()
|
||||||
{
|
{
|
||||||
false
|
false
|
||||||
} else {
|
} else {
|
||||||
@ -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.
|
||||||
@ -778,7 +778,7 @@ impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorro
|
|||||||
| TerminatorKind::Unreachable
|
| TerminatorKind::Unreachable
|
||||||
| TerminatorKind::UnwindResume
|
| TerminatorKind::UnwindResume
|
||||||
| TerminatorKind::Return
|
| TerminatorKind::Return
|
||||||
| TerminatorKind::GeneratorDrop
|
| TerminatorKind::CoroutineDrop
|
||||||
| TerminatorKind::FalseEdge { real_target: _, imaginary_target: _ }
|
| TerminatorKind::FalseEdge { real_target: _, imaginary_target: _ }
|
||||||
| TerminatorKind::FalseUnwind { real_target: _, unwind: _ } => {
|
| TerminatorKind::FalseUnwind { real_target: _, unwind: _ } => {
|
||||||
// no data used, thus irrelevant to borrowck
|
// no data used, thus irrelevant to borrowck
|
||||||
@ -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() {
|
||||||
@ -809,7 +809,7 @@ impl<'cx, 'tcx, R> rustc_mir_dataflow::ResultsVisitor<'cx, 'tcx, R> for MirBorro
|
|||||||
|
|
||||||
TerminatorKind::UnwindResume
|
TerminatorKind::UnwindResume
|
||||||
| TerminatorKind::Return
|
| TerminatorKind::Return
|
||||||
| TerminatorKind::GeneratorDrop => {
|
| TerminatorKind::CoroutineDrop => {
|
||||||
// Returning from the function implicitly kills storage for all locals and statics.
|
// Returning from the function implicitly kills storage for all locals and statics.
|
||||||
// Often, the storage will already have been killed by an explicit
|
// Often, the storage will already have been killed by an explicit
|
||||||
// StorageDead, but we don't always emit those (notably on unwind paths),
|
// StorageDead, but we don't always emit those (notably on unwind paths),
|
||||||
@ -1326,7 +1326,7 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
|
|||||||
// moved into the closure and subsequently used by the closure,
|
// moved into the closure and subsequently used by the closure,
|
||||||
// in order to populate our used_mut set.
|
// in order to populate our used_mut set.
|
||||||
match **aggregate_kind {
|
match **aggregate_kind {
|
||||||
AggregateKind::Closure(def_id, _) | AggregateKind::Generator(def_id, _, _) => {
|
AggregateKind::Closure(def_id, _) | AggregateKind::Coroutine(def_id, _, _) => {
|
||||||
let def_id = def_id.expect_local();
|
let def_id = def_id.expect_local();
|
||||||
let BorrowCheckResult { used_mut_upvars, .. } =
|
let BorrowCheckResult { used_mut_upvars, .. } =
|
||||||
self.infcx.tcx.mir_borrowck(def_id);
|
self.infcx.tcx.mir_borrowck(def_id);
|
||||||
@ -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,
|
||||||
);
|
);
|
||||||
|
@ -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)
|
||||||
|
@ -139,23 +139,23 @@ 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)]
|
||||||
BorrowInGenerator {
|
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)]
|
||||||
UseInGenerator {
|
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)]
|
||||||
AssignInGenerator {
|
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)]
|
||||||
AssignPartInGenerator {
|
AssignPartInCoroutine {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
path_span: Span,
|
path_span: Span,
|
||||||
},
|
},
|
||||||
@ -202,8 +202,8 @@ 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)]
|
||||||
BorrowUsePlaceGenerator {
|
BorrowUsePlaceCoroutine {
|
||||||
is_single_var: bool,
|
is_single_var: bool,
|
||||||
place: String,
|
place: String,
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
@ -216,8 +216,8 @@ 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)]
|
||||||
BorrowUseInGenerator {
|
BorrowUseInCoroutine {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
var_span: Span,
|
var_span: Span,
|
||||||
},
|
},
|
||||||
@ -226,8 +226,8 @@ 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)]
|
||||||
MoveUseInGenerator {
|
MoveUseInCoroutine {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
var_span: Span,
|
var_span: Span,
|
||||||
},
|
},
|
||||||
@ -236,8 +236,8 @@ 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)]
|
||||||
FirstBorrowUsePlaceGenerator {
|
FirstBorrowUsePlaceCoroutine {
|
||||||
place: String,
|
place: String,
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
var_span: Span,
|
var_span: Span,
|
||||||
@ -248,8 +248,8 @@ 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)]
|
||||||
SecondBorrowUsePlaceGenerator {
|
SecondBorrowUsePlaceCoroutine {
|
||||||
place: String,
|
place: String,
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
var_span: Span,
|
var_span: Span,
|
||||||
@ -266,8 +266,8 @@ 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)]
|
||||||
PartialMoveUseInGenerator {
|
PartialMoveUseInCoroutine {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
var_span: Span,
|
var_span: Span,
|
||||||
is_partial: bool,
|
is_partial: bool,
|
||||||
|
@ -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(
|
||||||
|
@ -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>,
|
||||||
|
@ -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!(
|
||||||
@ -774,13 +774,13 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
|||||||
let (variant, args) = match base_ty {
|
let (variant, args) = match base_ty {
|
||||||
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::Generator(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() => {
|
||||||
@ -802,13 +802,13 @@ impl<'a, 'b, 'tcx> TypeVerifier<'a, 'b, 'tcx> {
|
|||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
ty::Generator(_, 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(),
|
||||||
}),
|
}),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -1351,7 +1351,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||||||
| TerminatorKind::UnwindResume
|
| TerminatorKind::UnwindResume
|
||||||
| TerminatorKind::UnwindTerminate(_)
|
| TerminatorKind::UnwindTerminate(_)
|
||||||
| TerminatorKind::Return
|
| TerminatorKind::Return
|
||||||
| TerminatorKind::GeneratorDrop
|
| TerminatorKind::CoroutineDrop
|
||||||
| TerminatorKind::Unreachable
|
| TerminatorKind::Unreachable
|
||||||
| TerminatorKind::Drop { .. }
|
| TerminatorKind::Drop { .. }
|
||||||
| TerminatorKind::FalseEdge { .. }
|
| TerminatorKind::FalseEdge { .. }
|
||||||
@ -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,
|
||||||
@ -1648,9 +1648,9 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||||||
span_mirbug!(self, block_data, "return on cleanup block")
|
span_mirbug!(self, block_data, "return on cleanup block")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
TerminatorKind::GeneratorDrop { .. } => {
|
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, .. } => {
|
||||||
@ -1797,14 +1797,14 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
AggregateKind::Generator(_, args, _) => {
|
AggregateKind::Coroutine(_, args, _) => {
|
||||||
// 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(),
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2397,7 +2397,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||||||
AggregateKind::Array(_) => None,
|
AggregateKind::Array(_) => None,
|
||||||
AggregateKind::Tuple => None,
|
AggregateKind::Tuple => None,
|
||||||
AggregateKind::Closure(_, _) => None,
|
AggregateKind::Closure(_, _) => None,
|
||||||
AggregateKind::Generator(_, _, _) => None,
|
AggregateKind::Coroutine(_, _, _) => None,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2625,7 +2625,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
|
|||||||
// desugaring. A closure gets desugared to a struct, and
|
// desugaring. A closure gets desugared to a struct, and
|
||||||
// these extra requirements are basically like where
|
// these extra requirements are basically like where
|
||||||
// clauses on the struct.
|
// clauses on the struct.
|
||||||
AggregateKind::Closure(def_id, args) | AggregateKind::Generator(def_id, args, _) => {
|
AggregateKind::Closure(def_id, args) | AggregateKind::Coroutine(def_id, args, _) => {
|
||||||
(def_id, self.prove_closure_bounds(tcx, def_id.expect_local(), args, location))
|
(def_id, self.prove_closure_bounds(tcx, def_id.expect_local(), args, location))
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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::Generator => 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),
|
||||||
};
|
};
|
||||||
|
@ -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,10 +91,10 @@ 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`.
|
||||||
Generator(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
|
||||||
/// of the function can be bound then with the `fn_sig` query.
|
/// of the function can be bound then with the `fn_sig` query.
|
||||||
@ -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::Generator(_, 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()
|
||||||
}
|
}
|
||||||
@ -130,7 +130,7 @@ impl<'tcx> DefiningTy<'tcx> {
|
|||||||
/// user's code.
|
/// user's code.
|
||||||
pub fn implicit_inputs(self) -> usize {
|
pub fn implicit_inputs(self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
DefiningTy::Closure(..) | DefiningTy::Generator(..) => 1,
|
DefiningTy::Closure(..) | DefiningTy::Coroutine(..) => 1,
|
||||||
DefiningTy::FnDef(..) | DefiningTy::Const(..) | DefiningTy::InlineConst(..) => 0,
|
DefiningTy::FnDef(..) | DefiningTy::Const(..) | DefiningTy::InlineConst(..) => 0,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -146,7 +146,7 @@ impl<'tcx> DefiningTy<'tcx> {
|
|||||||
pub fn def_id(&self) -> DefId {
|
pub fn def_id(&self) -> DefId {
|
||||||
match *self {
|
match *self {
|
||||||
DefiningTy::Closure(def_id, ..)
|
DefiningTy::Closure(def_id, ..)
|
||||||
| DefiningTy::Generator(def_id, ..)
|
| DefiningTy::Coroutine(def_id, ..)
|
||||||
| DefiningTy::FnDef(def_id, ..)
|
| DefiningTy::FnDef(def_id, ..)
|
||||||
| DefiningTy::Const(def_id, ..)
|
| DefiningTy::Const(def_id, ..)
|
||||||
| DefiningTy::InlineConst(def_id, ..) => def_id,
|
| DefiningTy::InlineConst(def_id, ..) => def_id,
|
||||||
@ -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,
|
||||||
|
|
||||||
@ -354,7 +354,7 @@ impl<'tcx> UniversalRegions<'tcx> {
|
|||||||
err.note(format!("late-bound region is {:?}", self.to_region_vid(r)));
|
err.note(format!("late-bound region is {:?}", self.to_region_vid(r)));
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
DefiningTy::Generator(def_id, args, _) => {
|
DefiningTy::Coroutine(def_id, args, _) => {
|
||||||
let v = with_no_trimmed_paths!(
|
let v = with_no_trimmed_paths!(
|
||||||
args[tcx.generics_of(def_id).parent_count..]
|
args[tcx.generics_of(def_id).parent_count..]
|
||||||
.iter()
|
.iter()
|
||||||
@ -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::Generator(_, args, _) => Some(args.as_generator().yield_ty()),
|
DefiningTy::Coroutine(_, args, _) => Some(args.as_coroutine().yield_ty()),
|
||||||
_ => None,
|
_ => None,
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -563,8 +563,8 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
|||||||
|
|
||||||
match *defining_ty.kind() {
|
match *defining_ty.kind() {
|
||||||
ty::Closure(def_id, args) => DefiningTy::Closure(def_id, args),
|
ty::Closure(def_id, args) => DefiningTy::Closure(def_id, args),
|
||||||
ty::Generator(def_id, args, movability) => {
|
ty::Coroutine(def_id, args, movability) => {
|
||||||
DefiningTy::Generator(def_id, args, movability)
|
DefiningTy::Coroutine(def_id, args, movability)
|
||||||
}
|
}
|
||||||
ty::FnDef(def_id, args) => DefiningTy::FnDef(def_id, args),
|
ty::FnDef(def_id, args) => DefiningTy::FnDef(def_id, args),
|
||||||
_ => span_bug!(
|
_ => span_bug!(
|
||||||
@ -621,7 +621,7 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
|||||||
let identity_args = GenericArgs::identity_for_item(tcx, typeck_root_def_id);
|
let identity_args = GenericArgs::identity_for_item(tcx, typeck_root_def_id);
|
||||||
let fr_args = match defining_ty {
|
let fr_args = match defining_ty {
|
||||||
DefiningTy::Closure(_, args)
|
DefiningTy::Closure(_, args)
|
||||||
| DefiningTy::Generator(_, args, _)
|
| DefiningTy::Coroutine(_, args, _)
|
||||||
| DefiningTy::InlineConst(_, args) => {
|
| DefiningTy::InlineConst(_, args) => {
|
||||||
// In the case of closures, we rely on the fact that
|
// In the case of closures, we rely on the fact that
|
||||||
// the first N elements in the ClosureArgs are
|
// the first N elements in the ClosureArgs are
|
||||||
@ -686,13 +686,13 @@ impl<'cx, 'tcx> UniversalRegionsBuilder<'cx, 'tcx> {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
DefiningTy::Generator(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)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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,
|
||||||
|
@ -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,
|
||||||
@ -12,7 +12,7 @@
|
|||||||
use std::arch::x86_64::*;
|
use std::arch::x86_64::*;
|
||||||
use std::hint::black_box;
|
use std::hint::black_box;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::ops::Generator;
|
use std::ops::Coroutine;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("{:?}", std::env::args().collect::<Vec<_>>());
|
println!("{:?}", std::env::args().collect::<Vec<_>>());
|
||||||
|
@ -157,7 +157,7 @@ rm -r tests/run-make/compressed-debuginfo
|
|||||||
|
|
||||||
rm -r tests/run-make/extern-fn-explicit-align # argument alignment not yet supported
|
rm -r tests/run-make/extern-fn-explicit-align # argument alignment not yet supported
|
||||||
|
|
||||||
rm tests/ui/codegen/subtyping-enforces-type-equality.rs # assert_assignable bug with Generator's
|
rm tests/ui/codegen/subtyping-enforces-type-equality.rs # assert_assignable bug with Coroutine's
|
||||||
|
|
||||||
# bugs in the test suite
|
# bugs in the test suite
|
||||||
# ======================
|
# ======================
|
||||||
|
@ -478,7 +478,7 @@ fn codegen_fn_body(fx: &mut FunctionCx<'_, '_, '_>, start_block: Block) {
|
|||||||
TerminatorKind::Yield { .. }
|
TerminatorKind::Yield { .. }
|
||||||
| TerminatorKind::FalseEdge { .. }
|
| TerminatorKind::FalseEdge { .. }
|
||||||
| TerminatorKind::FalseUnwind { .. }
|
| TerminatorKind::FalseUnwind { .. }
|
||||||
| TerminatorKind::GeneratorDrop => {
|
| TerminatorKind::CoroutineDrop => {
|
||||||
bug!("shouldn't exist at codegen {:?}", bb_data.terminator());
|
bug!("shouldn't exist at codegen {:?}", bb_data.terminator());
|
||||||
}
|
}
|
||||||
TerminatorKind::Drop { place, target, unwind: _, replace: _ } => {
|
TerminatorKind::Drop { place, target, unwind: _, replace: _ } => {
|
||||||
|
@ -510,7 +510,7 @@ pub(crate) fn mir_operand_get_const_val<'tcx>(
|
|||||||
| TerminatorKind::Drop { .. }
|
| TerminatorKind::Drop { .. }
|
||||||
| TerminatorKind::Assert { .. } => {}
|
| TerminatorKind::Assert { .. } => {}
|
||||||
TerminatorKind::Yield { .. }
|
TerminatorKind::Yield { .. }
|
||||||
| TerminatorKind::GeneratorDrop
|
| TerminatorKind::CoroutineDrop
|
||||||
| TerminatorKind::FalseEdge { .. }
|
| TerminatorKind::FalseEdge { .. }
|
||||||
| TerminatorKind::FalseUnwind { .. } => unreachable!(),
|
| TerminatorKind::FalseUnwind { .. } => unreachable!(),
|
||||||
TerminatorKind::InlineAsm { .. } => return None,
|
TerminatorKind::InlineAsm { .. } => return None,
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
#![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::*;
|
||||||
use std::io::Write;
|
use std::io::Write;
|
||||||
use std::ops::Generator;
|
use std::ops::Coroutine;
|
||||||
|
|
||||||
extern {
|
extern {
|
||||||
pub fn printf(format: *const i8, ...) -> i32;
|
pub fn printf(format: *const i8, ...) -> i32;
|
||||||
|
@ -87,7 +87,7 @@ fn uncached_gcc_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLayout
|
|||||||
// FIXME(eddyb) producing readable type names for trait objects can result
|
// FIXME(eddyb) producing readable type names for trait objects can result
|
||||||
// in problematically distinct types due to HRTB and subtyping (see #47638).
|
// in problematically distinct types due to HRTB and subtyping (see #47638).
|
||||||
// ty::Dynamic(..) |
|
// ty::Dynamic(..) |
|
||||||
ty::Adt(..) | ty::Closure(..) | ty::Foreign(..) | ty::Generator(..) | ty::Str
|
ty::Adt(..) | ty::Closure(..) | ty::Foreign(..) | ty::Coroutine(..) | ty::Str
|
||||||
if !cx.sess().fewer_names() =>
|
if !cx.sess().fewer_names() =>
|
||||||
{
|
{
|
||||||
let mut name = with_no_trimmed_paths!(layout.ty.to_string());
|
let mut name = with_no_trimmed_paths!(layout.ty.to_string());
|
||||||
@ -98,10 +98,10 @@ fn uncached_gcc_type<'gcc, 'tcx>(cx: &CodegenCx<'gcc, 'tcx>, layout: TyAndLayout
|
|||||||
write!(&mut name, "::{}", def.variant(index).name).unwrap();
|
write!(&mut name, "::{}", def.variant(index).name).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let (&ty::Generator(_, _, _), &Variants::Single { index }) =
|
if let (&ty::Coroutine(_, _, _), &Variants::Single { index }) =
|
||||||
(layout.ty.kind(), &layout.variants)
|
(layout.ty.kind(), &layout.variants)
|
||||||
{
|
{
|
||||||
write!(&mut name, "::{}", ty::GeneratorArgs::variant_name(index)).unwrap();
|
write!(&mut name, "::{}", ty::CoroutineArgs::variant_name(index)).unwrap();
|
||||||
}
|
}
|
||||||
Some(name)
|
Some(name)
|
||||||
}
|
}
|
||||||
|
@ -313,7 +313,7 @@ fn add_unused_functions(cx: &CodegenCx<'_, '_>) {
|
|||||||
// generic functions from consideration as well.
|
// generic functions from consideration as well.
|
||||||
if !matches!(
|
if !matches!(
|
||||||
kind,
|
kind,
|
||||||
DefKind::Fn | DefKind::AssocFn | DefKind::Closure | DefKind::Generator
|
DefKind::Fn | DefKind::AssocFn | DefKind::Closure | DefKind::Coroutine
|
||||||
) {
|
) {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
@ -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::Generator(..) => 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::Generator(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),
|
||||||
|
@ -12,7 +12,7 @@ use rustc_middle::{
|
|||||||
ty::{
|
ty::{
|
||||||
self,
|
self,
|
||||||
layout::{LayoutOf, TyAndLayout},
|
layout::{LayoutOf, TyAndLayout},
|
||||||
AdtDef, GeneratorArgs, Ty,
|
AdtDef, CoroutineArgs, Ty,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use rustc_target::abi::{Align, Endian, Size, TagEncoding, VariantIdx, Variants};
|
use rustc_target::abi::{Align, Endian, Size, TagEncoding, VariantIdx, Variants};
|
||||||
@ -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::Generator(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, GeneratorArgs::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,
|
||||||
|
@ -6,11 +6,11 @@ use rustc_hir::def::CtorKind;
|
|||||||
use rustc_index::IndexSlice;
|
use rustc_index::IndexSlice;
|
||||||
use rustc_middle::{
|
use rustc_middle::{
|
||||||
bug,
|
bug,
|
||||||
mir::GeneratorLayout,
|
mir::CoroutineLayout,
|
||||||
ty::{
|
ty::{
|
||||||
self,
|
self,
|
||||||
layout::{IntegerExt, LayoutOf, PrimitiveExt, TyAndLayout},
|
layout::{IntegerExt, LayoutOf, PrimitiveExt, TyAndLayout},
|
||||||
AdtDef, GeneratorArgs, Ty, VariantDef,
|
AdtDef, CoroutineArgs, Ty, VariantDef,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
use rustc_span::Symbol;
|
use rustc_span::Symbol;
|
||||||
@ -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,13 +101,13 @@ 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>,
|
||||||
) -> Ty<'tcx> {
|
) -> Ty<'tcx> {
|
||||||
debug_assert!(match enum_type_and_layout.ty.kind() {
|
debug_assert!(match enum_type_and_layout.ty.kind() {
|
||||||
ty::Generator(..) => true,
|
ty::Coroutine(..) => true,
|
||||||
ty::Adt(adt_def, _) => adt_def.is_enum(),
|
ty::Adt(adt_def, _) => adt_def.is_enum(),
|
||||||
_ => false,
|
_ => false,
|
||||||
});
|
});
|
||||||
@ -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: &GeneratorLayout<'tcx>,
|
coroutine_layout: &CoroutineLayout<'tcx>,
|
||||||
common_upvar_names: &IndexSlice<FieldIdx, Symbol>,
|
common_upvar_names: &IndexSlice<FieldIdx, Symbol>,
|
||||||
) -> &'ll DIType {
|
) -> &'ll DIType {
|
||||||
let variant_name = GeneratorArgs::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::Generator(_, 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
|
||||||
}
|
}
|
||||||
|
@ -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::Generator(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,37 +149,37 @@ 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
|
||||||
.indices()
|
.indices()
|
||||||
.map(|variant_index| {
|
.map(|variant_index| {
|
||||||
// FIXME: This is problematic because just a number is not a valid identifier.
|
// FIXME: This is problematic because just a number is not a valid identifier.
|
||||||
// GeneratorArgs::variant_name(variant_index), would be consistent
|
// CoroutineArgs::variant_name(variant_index), would be consistent
|
||||||
// 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,11 +306,11 @@ 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::Generator(..) => "__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),
|
||||||
))
|
))
|
||||||
|
@ -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),
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ fn uncached_llvm_type<'a, 'tcx>(
|
|||||||
// FIXME(eddyb) producing readable type names for trait objects can result
|
// FIXME(eddyb) producing readable type names for trait objects can result
|
||||||
// in problematically distinct types due to HRTB and subtyping (see #47638).
|
// in problematically distinct types due to HRTB and subtyping (see #47638).
|
||||||
// ty::Dynamic(..) |
|
// ty::Dynamic(..) |
|
||||||
ty::Adt(..) | ty::Closure(..) | ty::Foreign(..) | ty::Generator(..) | ty::Str
|
ty::Adt(..) | ty::Closure(..) | ty::Foreign(..) | ty::Coroutine(..) | ty::Str
|
||||||
// For performance reasons we use names only when emitting LLVM IR.
|
// For performance reasons we use names only when emitting LLVM IR.
|
||||||
if !cx.sess().fewer_names() =>
|
if !cx.sess().fewer_names() =>
|
||||||
{
|
{
|
||||||
@ -54,10 +54,10 @@ fn uncached_llvm_type<'a, 'tcx>(
|
|||||||
write!(&mut name, "::{}", def.variant(index).name).unwrap();
|
write!(&mut name, "::{}", def.variant(index).name).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if let (&ty::Generator(_, _, _), &Variants::Single { index }) =
|
if let (&ty::Coroutine(_, _, _), &Variants::Single { index }) =
|
||||||
(layout.ty.kind(), &layout.variants)
|
(layout.ty.kind(), &layout.variants)
|
||||||
{
|
{
|
||||||
write!(&mut name, "::{}", ty::GeneratorArgs::variant_name(index)).unwrap();
|
write!(&mut name, "::{}", ty::CoroutineArgs::variant_name(index)).unwrap();
|
||||||
}
|
}
|
||||||
Some(name)
|
Some(name)
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ use rustc_data_structures::fx::FxHashSet;
|
|||||||
use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{Hash64, HashStable, StableHasher};
|
||||||
use rustc_hir::def_id::DefId;
|
use rustc_hir::def_id::DefId;
|
||||||
use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathData};
|
use rustc_hir::definitions::{DefPathData, DefPathDataName, DisambiguatedDefPathData};
|
||||||
use rustc_hir::{AsyncGeneratorKind, GeneratorKind, Mutability};
|
use rustc_hir::{AsyncCoroutineKind, CoroutineKind, Mutability};
|
||||||
use rustc_middle::ty::layout::{IntegerExt, TyAndLayout};
|
use rustc_middle::ty::layout::{IntegerExt, TyAndLayout};
|
||||||
use rustc_middle::ty::{self, ExistentialProjection, ParamEnv, Ty, TyCtxt};
|
use rustc_middle::ty::{self, ExistentialProjection, ParamEnv, Ty, TyCtxt};
|
||||||
use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
|
use rustc_middle::ty::{GenericArgKind, GenericArgsRef};
|
||||||
@ -398,23 +398,23 @@ fn push_debuginfo_type_name<'tcx>(
|
|||||||
// processing
|
// processing
|
||||||
visited.remove(&t);
|
visited.remove(&t);
|
||||||
}
|
}
|
||||||
ty::Closure(def_id, args) | ty::Generator(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.
|
||||||
@ -426,7 +426,7 @@ fn push_debuginfo_type_name<'tcx>(
|
|||||||
| ty::Placeholder(..)
|
| ty::Placeholder(..)
|
||||||
| ty::Alias(..)
|
| ty::Alias(..)
|
||||||
| ty::Bound(..)
|
| ty::Bound(..)
|
||||||
| ty::GeneratorWitness(..) => {
|
| ty::CoroutineWitness(..) => {
|
||||||
bug!(
|
bug!(
|
||||||
"debuginfo: Trying to create type name for \
|
"debuginfo: Trying to create type name for \
|
||||||
unexpected type: {:?}",
|
unexpected type: {:?}",
|
||||||
@ -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<GeneratorKind>) -> &'static str {
|
fn coroutine_kind_label(coroutine_kind: Option<CoroutineKind>) -> &'static str {
|
||||||
match generator_kind {
|
match coroutine_kind {
|
||||||
Some(GeneratorKind::Async(AsyncGeneratorKind::Block)) => "async_block",
|
Some(CoroutineKind::Async(AsyncCoroutineKind::Block)) => "async_block",
|
||||||
Some(GeneratorKind::Async(AsyncGeneratorKind::Closure)) => "async_closure",
|
Some(CoroutineKind::Async(AsyncCoroutineKind::Closure)) => "async_closure",
|
||||||
Some(GeneratorKind::Async(AsyncGeneratorKind::Fn)) => "async_fn",
|
Some(CoroutineKind::Async(AsyncCoroutineKind::Fn)) => "async_fn",
|
||||||
Some(GeneratorKind::Gen) => "generator",
|
Some(CoroutineKind::Coroutine) => "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);
|
||||||
}
|
}
|
||||||
|
@ -272,7 +272,7 @@ pub fn cleanup_kinds(mir: &mir::Body<'_>) -> IndexVec<mir::BasicBlock, CleanupKi
|
|||||||
| TerminatorKind::UnwindResume
|
| TerminatorKind::UnwindResume
|
||||||
| TerminatorKind::UnwindTerminate(_)
|
| TerminatorKind::UnwindTerminate(_)
|
||||||
| TerminatorKind::Return
|
| TerminatorKind::Return
|
||||||
| TerminatorKind::GeneratorDrop
|
| TerminatorKind::CoroutineDrop
|
||||||
| TerminatorKind::Unreachable
|
| TerminatorKind::Unreachable
|
||||||
| TerminatorKind::SwitchInt { .. }
|
| TerminatorKind::SwitchInt { .. }
|
||||||
| TerminatorKind::Yield { .. }
|
| TerminatorKind::Yield { .. }
|
||||||
|
@ -1265,8 +1265,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
|||||||
fn_span,
|
fn_span,
|
||||||
mergeable_succ(),
|
mergeable_succ(),
|
||||||
),
|
),
|
||||||
mir::TerminatorKind::GeneratorDrop | 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")
|
||||||
|
@ -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)?,
|
||||||
|
@ -151,8 +151,8 @@ pub(crate) fn const_to_valtree_inner<'tcx>(
|
|||||||
| ty::Infer(_)
|
| ty::Infer(_)
|
||||||
// FIXME(oli-obk): we can probably encode closures just like structs
|
// FIXME(oli-obk): we can probably encode closures just like structs
|
||||||
| ty::Closure(..)
|
| ty::Closure(..)
|
||||||
| ty::Generator(..)
|
| ty::Coroutine(..)
|
||||||
| ty::GeneratorWitness(..) => Err(ValTreeCreationError::NonSupportedType),
|
| ty::CoroutineWitness(..) => Err(ValTreeCreationError::NonSupportedType),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -278,8 +278,8 @@ pub fn valtree_to_const_value<'tcx>(
|
|||||||
| ty::Placeholder(..)
|
| ty::Placeholder(..)
|
||||||
| ty::Infer(_)
|
| ty::Infer(_)
|
||||||
| ty::Closure(..)
|
| ty::Closure(..)
|
||||||
| ty::Generator(..)
|
| ty::Coroutine(..)
|
||||||
| ty::GeneratorWitness(..)
|
| ty::CoroutineWitness(..)
|
||||||
| ty::FnPtr(_)
|
| ty::FnPtr(_)
|
||||||
| ty::RawPtr(_)
|
| ty::RawPtr(_)
|
||||||
| ty::Str
|
| ty::Str
|
||||||
|
@ -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};
|
||||||
@ -170,11 +170,11 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||||||
ty::Adt(adt, _) => {
|
ty::Adt(adt, _) => {
|
||||||
adt.discriminants(*self.tcx).find(|(_, var)| var.val == discr_bits)
|
adt.discriminants(*self.tcx).find(|(_, var)| var.val == discr_bits)
|
||||||
}
|
}
|
||||||
ty::Generator(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.
|
||||||
|
@ -963,8 +963,8 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||||||
| ty::RawPtr(..)
|
| ty::RawPtr(..)
|
||||||
| ty::Char
|
| ty::Char
|
||||||
| ty::Ref(..)
|
| ty::Ref(..)
|
||||||
| ty::Generator(..)
|
| ty::Coroutine(..)
|
||||||
| ty::GeneratorWitness(..)
|
| ty::CoroutineWitness(..)
|
||||||
| ty::Array(..)
|
| ty::Array(..)
|
||||||
| ty::Closure(..)
|
| ty::Closure(..)
|
||||||
| ty::Never
|
| ty::Never
|
||||||
|
@ -99,8 +99,8 @@ pub(crate) fn eval_nullary_intrinsic<'tcx>(
|
|||||||
| ty::FnPtr(_)
|
| ty::FnPtr(_)
|
||||||
| ty::Dynamic(_, _, _)
|
| ty::Dynamic(_, _, _)
|
||||||
| ty::Closure(_, _)
|
| ty::Closure(_, _)
|
||||||
| ty::Generator(_, _, _)
|
| ty::Coroutine(_, _, _)
|
||||||
| ty::GeneratorWitness(..)
|
| ty::CoroutineWitness(..)
|
||||||
| ty::Never
|
| ty::Never
|
||||||
| ty::Tuple(_)
|
| ty::Tuple(_)
|
||||||
| ty::Error(_) => ConstValue::from_target_usize(0u64, &tcx),
|
| ty::Error(_) => ConstValue::from_target_usize(0u64, &tcx),
|
||||||
|
@ -218,7 +218,7 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
|
|||||||
Unreachable => throw_ub!(Unreachable),
|
Unreachable => throw_ub!(Unreachable),
|
||||||
|
|
||||||
// These should never occur for MIR we actually run.
|
// These should never occur for MIR we actually run.
|
||||||
FalseEdge { .. } | FalseUnwind { .. } | Yield { .. } | GeneratorDrop => span_bug!(
|
FalseEdge { .. } | FalseUnwind { .. } | Yield { .. } | CoroutineDrop => span_bug!(
|
||||||
terminator.source_info.span,
|
terminator.source_info.span,
|
||||||
"{:#?} should have been eliminated by MIR pass",
|
"{:#?} should have been eliminated by MIR pass",
|
||||||
terminator.kind
|
terminator.kind
|
||||||
|
@ -34,7 +34,7 @@ where
|
|||||||
match *ty.kind() {
|
match *ty.kind() {
|
||||||
ty::Param(_) => ControlFlow::Break(FoundParam),
|
ty::Param(_) => ControlFlow::Break(FoundParam),
|
||||||
ty::Closure(def_id, args)
|
ty::Closure(def_id, args)
|
||||||
| ty::Generator(def_id, args, ..)
|
| ty::Coroutine(def_id, args, ..)
|
||||||
| ty::FnDef(def_id, args) => {
|
| ty::FnDef(def_id, args) => {
|
||||||
let instance = ty::InstanceDef::Item(def_id);
|
let instance = ty::InstanceDef::Item(def_id);
|
||||||
let unused_params = self.tcx.unused_generic_params(instance);
|
let unused_params = self.tcx.unused_generic_params(instance);
|
||||||
@ -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);
|
||||||
|
@ -112,13 +112,13 @@ macro_rules! try_validation {
|
|||||||
pub enum PathElem {
|
pub enum PathElem {
|
||||||
Field(Symbol),
|
Field(Symbol),
|
||||||
Variant(Symbol),
|
Variant(Symbol),
|
||||||
GeneratorState(VariantIdx),
|
CoroutineState(VariantIdx),
|
||||||
CapturedVar(Symbol),
|
CapturedVar(Symbol),
|
||||||
ArrayElem(usize),
|
ArrayElem(usize),
|
||||||
TupleElem(usize),
|
TupleElem(usize),
|
||||||
Deref,
|
Deref,
|
||||||
EnumTag,
|
EnumTag,
|
||||||
GeneratorTag,
|
CoroutineTag,
|
||||||
DynDowncast,
|
DynDowncast,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -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})>"),
|
||||||
GeneratorTag => write!(out, ".<generator-tag>"),
|
CoroutineTag => write!(out, ".<coroutine-tag>"),
|
||||||
GeneratorState(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}]"),
|
||||||
@ -206,7 +206,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
|||||||
if tag_field == field {
|
if tag_field == field {
|
||||||
return match layout.ty.kind() {
|
return match layout.ty.kind() {
|
||||||
ty::Adt(def, ..) if def.is_enum() => PathElem::EnumTag,
|
ty::Adt(def, ..) if def.is_enum() => PathElem::EnumTag,
|
||||||
ty::Generator(..) => PathElem::GeneratorTag,
|
ty::Coroutine(..) => PathElem::CoroutineTag,
|
||||||
_ => bug!("non-variant type {:?}", layout.ty),
|
_ => bug!("non-variant type {:?}", layout.ty),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -216,8 +216,8 @@ 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::Generator(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
|
||||||
// https://github.com/rust-lang/project-rfc-2229/issues/46
|
// https://github.com/rust-lang/project-rfc-2229/issues/46
|
||||||
@ -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 {
|
||||||
@ -580,7 +580,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
|||||||
| ty::Str
|
| ty::Str
|
||||||
| ty::Dynamic(..)
|
| ty::Dynamic(..)
|
||||||
| ty::Closure(..)
|
| ty::Closure(..)
|
||||||
| ty::Generator(..) => Ok(false),
|
| ty::Coroutine(..) => Ok(false),
|
||||||
// Some types only occur during typechecking, they have no layout.
|
// Some types only occur during typechecking, they have no layout.
|
||||||
// We should not see them here and we could not check them anyway.
|
// We should not see them here and we could not check them anyway.
|
||||||
ty::Error(_)
|
ty::Error(_)
|
||||||
@ -589,7 +589,7 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValidityVisitor<'rt, 'mir, '
|
|||||||
| ty::Bound(..)
|
| ty::Bound(..)
|
||||||
| ty::Param(..)
|
| ty::Param(..)
|
||||||
| ty::Alias(..)
|
| ty::Alias(..)
|
||||||
| ty::GeneratorWitness(..) => bug!("Encountered invalid type {:?}", ty),
|
| ty::CoroutineWitness(..) => bug!("Encountered invalid type {:?}", ty),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -692,8 +692,8 @@ impl<'rt, 'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> ValueVisitor<'mir, 'tcx, M>
|
|||||||
) -> InterpResult<'tcx> {
|
) -> InterpResult<'tcx> {
|
||||||
let name = match old_op.layout.ty.kind() {
|
let name = match old_op.layout.ty.kind() {
|
||||||
ty::Adt(adt, _) => PathElem::Variant(adt.variant(variant_id).name),
|
ty::Adt(adt, _) => PathElem::Variant(adt.variant(variant_id).name),
|
||||||
// Generators also have variants
|
// Coroutines also have variants
|
||||||
ty::Generator(..) => PathElem::GeneratorState(variant_id),
|
ty::Coroutine(..) => PathElem::CoroutineState(variant_id),
|
||||||
_ => bug!("Unexpected type with variant: {:?}", old_op.layout.ty),
|
_ => bug!("Unexpected type with variant: {:?}", old_op.layout.ty),
|
||||||
};
|
};
|
||||||
self.with_elem(name, move |this| this.visit_value(new_op))
|
self.with_elem(name, move |this| this.visit_value(new_op))
|
||||||
|
@ -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;
|
||||||
}
|
}
|
||||||
@ -463,11 +463,11 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
|||||||
| Rvalue::Len(_) => {}
|
| Rvalue::Len(_) => {}
|
||||||
|
|
||||||
Rvalue::Aggregate(kind, ..) => {
|
Rvalue::Aggregate(kind, ..) => {
|
||||||
if let AggregateKind::Generator(def_id, ..) = kind.as_ref()
|
if let AggregateKind::Coroutine(def_id, ..) = kind.as_ref()
|
||||||
&& let Some(generator_kind @ hir::GeneratorKind::Async(..)) =
|
&& let Some(coroutine_kind @ hir::CoroutineKind::Async(..)) =
|
||||||
self.tcx.generator_kind(def_id)
|
self.tcx.coroutine_kind(def_id)
|
||||||
{
|
{
|
||||||
self.check_op(ops::Generator(generator_kind));
|
self.check_op(ops::Coroutine(coroutine_kind));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1042,8 +1042,8 @@ impl<'tcx> Visitor<'tcx> for Checker<'_, 'tcx> {
|
|||||||
|
|
||||||
TerminatorKind::InlineAsm { .. } => self.check_op(ops::InlineAsm),
|
TerminatorKind::InlineAsm { .. } => self.check_op(ops::InlineAsm),
|
||||||
|
|
||||||
TerminatorKind::GeneratorDrop | TerminatorKind::Yield { .. } => {
|
TerminatorKind::CoroutineDrop | TerminatorKind::Yield { .. } => {
|
||||||
self.check_op(ops::Generator(hir::GeneratorKind::Gen))
|
self.check_op(ops::Coroutine(hir::CoroutineKind::Coroutine))
|
||||||
}
|
}
|
||||||
|
|
||||||
TerminatorKind::UnwindTerminate(_) => {
|
TerminatorKind::UnwindTerminate(_) => {
|
||||||
|
@ -357,10 +357,10 @@ impl<'tcx> NonConstOp<'tcx> for FnCallUnstable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Generator(pub hir::GeneratorKind);
|
pub struct Coroutine(pub hir::CoroutineKind);
|
||||||
impl<'tcx> NonConstOp<'tcx> for Generator {
|
impl<'tcx> NonConstOp<'tcx> for Coroutine {
|
||||||
fn status_in_item(&self, _: &ConstCx<'_, 'tcx>) -> Status {
|
fn status_in_item(&self, _: &ConstCx<'_, 'tcx>) -> Status {
|
||||||
if let hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Block) = self.0 {
|
if let hir::CoroutineKind::Async(hir::AsyncCoroutineKind::Block) = self.0 {
|
||||||
Status::Unstable(sym::const_async_blocks)
|
Status::Unstable(sym::const_async_blocks)
|
||||||
} else {
|
} else {
|
||||||
Status::Forbidden
|
Status::Forbidden
|
||||||
@ -373,7 +373,7 @@ impl<'tcx> NonConstOp<'tcx> for Generator {
|
|||||||
span: Span,
|
span: Span,
|
||||||
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
|
) -> DiagnosticBuilder<'tcx, ErrorGuaranteed> {
|
||||||
let msg = format!("{}s are not allowed in {}s", self.0.descr(), ccx.const_kind());
|
let msg = format!("{}s are not allowed in {}s", self.0.descr(), ccx.const_kind());
|
||||||
if let hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Block) = self.0 {
|
if let hir::CoroutineKind::Async(hir::AsyncCoroutineKind::Block) = self.0 {
|
||||||
ccx.tcx.sess.create_feature_err(
|
ccx.tcx.sess.create_feature_err(
|
||||||
errors::UnallowedOpInConstContext { span, msg },
|
errors::UnallowedOpInConstContext { span, msg },
|
||||||
sym::const_async_blocks,
|
sym::const_async_blocks,
|
||||||
|
@ -111,7 +111,7 @@ impl<'tcx> Visitor<'tcx> for CheckLiveDrops<'_, 'tcx> {
|
|||||||
| mir::TerminatorKind::Assert { .. }
|
| mir::TerminatorKind::Assert { .. }
|
||||||
| mir::TerminatorKind::FalseEdge { .. }
|
| mir::TerminatorKind::FalseEdge { .. }
|
||||||
| mir::TerminatorKind::FalseUnwind { .. }
|
| mir::TerminatorKind::FalseUnwind { .. }
|
||||||
| mir::TerminatorKind::GeneratorDrop
|
| mir::TerminatorKind::CoroutineDrop
|
||||||
| mir::TerminatorKind::Goto { .. }
|
| mir::TerminatorKind::Goto { .. }
|
||||||
| mir::TerminatorKind::InlineAsm { .. }
|
| mir::TerminatorKind::InlineAsm { .. }
|
||||||
| mir::TerminatorKind::UnwindResume
|
| mir::TerminatorKind::UnwindResume
|
||||||
|
@ -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);
|
||||||
|
@ -67,7 +67,7 @@ impl<'tcx> MirPass<'tcx> for Validator {
|
|||||||
let body_abi = match body_ty.kind() {
|
let body_abi = match body_ty.kind() {
|
||||||
ty::FnDef(..) => body_ty.fn_sig(tcx).abi(),
|
ty::FnDef(..) => body_ty.fn_sig(tcx).abi(),
|
||||||
ty::Closure(..) => Abi::RustCall,
|
ty::Closure(..) => Abi::RustCall,
|
||||||
ty::Generator(..) => Abi::Rust,
|
ty::Coroutine(..) => Abi::Rust,
|
||||||
_ => {
|
_ => {
|
||||||
span_bug!(body.span, "unexpected body ty: {:?} phase {:?}", body_ty, mir_phase)
|
span_bug!(body.span, "unexpected body ty: {:?} phase {:?}", body_ty, mir_phase)
|
||||||
}
|
}
|
||||||
@ -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 {
|
||||||
@ -509,14 +509,14 @@ impl<'a, 'tcx> Visitor<'tcx> for CfgChecker<'a, 'tcx> {
|
|||||||
}
|
}
|
||||||
self.check_unwind_edge(location, *unwind);
|
self.check_unwind_edge(location, *unwind);
|
||||||
}
|
}
|
||||||
TerminatorKind::GeneratorDrop => {
|
TerminatorKind::CoroutineDrop => {
|
||||||
if self.body.generator.is_none() {
|
if self.body.coroutine.is_none() {
|
||||||
self.fail(location, "`GeneratorDrop` 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,
|
||||||
"`GeneratorDrop` should have been replaced by generator lowering",
|
"`CoroutineDrop` should have been replaced by coroutine lowering",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -716,7 +716,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||||||
};
|
};
|
||||||
check_equal(self, location, f_ty);
|
check_equal(self, location, f_ty);
|
||||||
}
|
}
|
||||||
&ty::Generator(def_id, args, _) => {
|
&ty::Coroutine(def_id, args, _) => {
|
||||||
let f_ty = if let Some(var) = parent_ty.variant_index {
|
let f_ty = if let Some(var) = parent_ty.variant_index {
|
||||||
let gen_body = if def_id == self.body.source.def_id() {
|
let gen_body = if def_id == self.body.source.def_id() {
|
||||||
self.body
|
self.body
|
||||||
@ -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;
|
||||||
@ -1211,11 +1211,11 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||||||
self.fail(location, "`SetDiscriminant`is not allowed until deaggregation");
|
self.fail(location, "`SetDiscriminant`is not allowed until deaggregation");
|
||||||
}
|
}
|
||||||
let pty = place.ty(&self.body.local_decls, self.tcx).ty.kind();
|
let pty = place.ty(&self.body.local_decls, self.tcx).ty.kind();
|
||||||
if !matches!(pty, ty::Adt(..) | ty::Generator(..) | ty::Alias(ty::Opaque, ..)) {
|
if !matches!(pty, ty::Adt(..) | ty::Coroutine(..) | ty::Alias(ty::Opaque, ..)) {
|
||||||
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:?}"
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
@ -1295,7 +1295,7 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
|
|||||||
| TerminatorKind::FalseEdge { .. }
|
| TerminatorKind::FalseEdge { .. }
|
||||||
| TerminatorKind::FalseUnwind { .. }
|
| TerminatorKind::FalseUnwind { .. }
|
||||||
| TerminatorKind::InlineAsm { .. }
|
| TerminatorKind::InlineAsm { .. }
|
||||||
| TerminatorKind::GeneratorDrop
|
| TerminatorKind::CoroutineDrop
|
||||||
| TerminatorKind::UnwindResume
|
| TerminatorKind::UnwindResume
|
||||||
| TerminatorKind::UnwindTerminate(_)
|
| TerminatorKind::UnwindTerminate(_)
|
||||||
| TerminatorKind::Return
|
| TerminatorKind::Return
|
||||||
|
@ -51,12 +51,12 @@ impl<'tcx> Printer<'tcx> for AbsolutePathPrinter<'tcx> {
|
|||||||
| ty::FnDef(def_id, args)
|
| ty::FnDef(def_id, args)
|
||||||
| ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, args, .. })
|
| ty::Alias(ty::Projection | ty::Opaque, ty::AliasTy { def_id, args, .. })
|
||||||
| ty::Closure(def_id, args)
|
| ty::Closure(def_id, args)
|
||||||
| ty::Generator(def_id, args, _) => self.print_def_path(def_id, args),
|
| ty::Coroutine(def_id, args, _) => self.print_def_path(def_id, args),
|
||||||
ty::Foreign(def_id) => self.print_def_path(def_id, &[]),
|
ty::Foreign(def_id) => self.print_def_path(def_id, &[]),
|
||||||
|
|
||||||
ty::Alias(ty::Weak, _) => bug!("type_name: unexpected weak projection"),
|
ty::Alias(ty::Weak, _) => bug!("type_name: unexpected weak projection"),
|
||||||
ty::Alias(ty::Inherent, _) => bug!("type_name: unexpected inherent projection"),
|
ty::Alias(ty::Inherent, _) => bug!("type_name: unexpected inherent projection"),
|
||||||
ty::GeneratorWitness(..) => bug!("type_name: unexpected `GeneratorWitness`"),
|
ty::CoroutineWitness(..) => bug!("type_name: unexpected `CoroutineWitness`"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,11 +1,11 @@
|
|||||||
This error occurs because a borrow in a generator persists across a
|
This error occurs because a borrow in a coroutine persists across a
|
||||||
yield point.
|
yield point.
|
||||||
|
|
||||||
Erroneous code example:
|
Erroneous code example:
|
||||||
|
|
||||||
```compile_fail,E0626
|
```compile_fail,E0626
|
||||||
# #![feature(generators, generator_trait, pin)]
|
# #![feature(coroutines, coroutine_trait, pin)]
|
||||||
# use std::ops::Generator;
|
# use std::ops::Coroutine;
|
||||||
# use std::pin::Pin;
|
# use std::pin::Pin;
|
||||||
let mut b = || {
|
let mut b = || {
|
||||||
let a = &String::new(); // <-- This borrow...
|
let a = &String::new(); // <-- This borrow...
|
||||||
@ -23,8 +23,8 @@ resolve the previous example by removing the borrow and just storing
|
|||||||
the integer by value:
|
the integer by value:
|
||||||
|
|
||||||
```
|
```
|
||||||
# #![feature(generators, generator_trait, pin)]
|
# #![feature(coroutines, coroutine_trait, pin)]
|
||||||
# use std::ops::Generator;
|
# use std::ops::Coroutine;
|
||||||
# use std::pin::Pin;
|
# use std::pin::Pin;
|
||||||
let mut b = || {
|
let mut b = || {
|
||||||
let a = 3;
|
let a = 3;
|
||||||
@ -41,8 +41,8 @@ in those cases, something like the `Rc` or `Arc` types may be useful.
|
|||||||
This error also frequently arises with iteration:
|
This error also frequently arises with iteration:
|
||||||
|
|
||||||
```compile_fail,E0626
|
```compile_fail,E0626
|
||||||
# #![feature(generators, generator_trait, pin)]
|
# #![feature(coroutines, coroutine_trait, pin)]
|
||||||
# use std::ops::Generator;
|
# use std::ops::Coroutine;
|
||||||
# use std::pin::Pin;
|
# use std::pin::Pin;
|
||||||
let mut b = || {
|
let mut b = || {
|
||||||
let v = vec![1,2,3];
|
let v = vec![1,2,3];
|
||||||
@ -57,8 +57,8 @@ Such cases can sometimes be resolved by iterating "by value" (or using
|
|||||||
`into_iter()`) to avoid borrowing:
|
`into_iter()`) to avoid borrowing:
|
||||||
|
|
||||||
```
|
```
|
||||||
# #![feature(generators, generator_trait, pin)]
|
# #![feature(coroutines, coroutine_trait, pin)]
|
||||||
# use std::ops::Generator;
|
# use std::ops::Coroutine;
|
||||||
# use std::pin::Pin;
|
# use std::pin::Pin;
|
||||||
let mut b = || {
|
let mut b = || {
|
||||||
let v = vec![1,2,3];
|
let v = vec![1,2,3];
|
||||||
@ -72,8 +72,8 @@ Pin::new(&mut b).resume(());
|
|||||||
If taking ownership is not an option, using indices can work too:
|
If taking ownership is not an option, using indices can work too:
|
||||||
|
|
||||||
```
|
```
|
||||||
# #![feature(generators, generator_trait, pin)]
|
# #![feature(coroutines, coroutine_trait, pin)]
|
||||||
# use std::ops::Generator;
|
# use std::ops::Coroutine;
|
||||||
# use std::pin::Pin;
|
# use std::pin::Pin;
|
||||||
let mut b = || {
|
let mut b = || {
|
||||||
let v = vec![1,2,3];
|
let v = vec![1,2,3];
|
||||||
|
@ -1,28 +1,28 @@
|
|||||||
A yield expression was used outside of the generator literal.
|
A yield expression was used outside of the coroutine literal.
|
||||||
|
|
||||||
Erroneous code example:
|
Erroneous code example:
|
||||||
|
|
||||||
```compile_fail,E0627
|
```compile_fail,E0627
|
||||||
#![feature(generators, generator_trait)]
|
#![feature(coroutines, coroutine_trait)]
|
||||||
|
|
||||||
fn fake_generator() -> &'static str {
|
fn fake_coroutine() -> &'static str {
|
||||||
yield 1;
|
yield 1;
|
||||||
return "foo"
|
return "foo"
|
||||||
}
|
}
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut generator = fake_generator;
|
let mut coroutine = fake_coroutine;
|
||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
The error occurs because keyword `yield` can only be used inside the generator
|
The error occurs because keyword `yield` can only be used inside the coroutine
|
||||||
literal. This can be fixed by constructing the generator correctly.
|
literal. This can be fixed by constructing the coroutine correctly.
|
||||||
|
|
||||||
```
|
```
|
||||||
#![feature(generators, generator_trait)]
|
#![feature(coroutines, coroutine_trait)]
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut generator = || {
|
let mut coroutine = || {
|
||||||
yield 1;
|
yield 1;
|
||||||
return "foo"
|
return "foo"
|
||||||
};
|
};
|
||||||
|
@ -1,13 +1,13 @@
|
|||||||
More than one parameter was used for a generator.
|
More than one parameter was used for a coroutine.
|
||||||
|
|
||||||
Erroneous code example:
|
Erroneous code example:
|
||||||
|
|
||||||
```compile_fail,E0628
|
```compile_fail,E0628
|
||||||
#![feature(generators, generator_trait)]
|
#![feature(coroutines, coroutine_trait)]
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let generator = |a: i32, b: i32| {
|
let coroutine = |a: i32, b: i32| {
|
||||||
// error: too many parameters for a generator
|
// error: too many parameters for a coroutine
|
||||||
// Allowed only 0 or 1 parameter
|
// Allowed only 0 or 1 parameter
|
||||||
yield a;
|
yield a;
|
||||||
};
|
};
|
||||||
@ -15,15 +15,15 @@ fn main() {
|
|||||||
```
|
```
|
||||||
|
|
||||||
At present, it is not permitted to pass more than one explicit
|
At present, it is not permitted to pass more than one explicit
|
||||||
parameter for a generator.This can be fixed by using
|
parameter for a coroutine.This can be fixed by using
|
||||||
at most 1 parameter for the generator. For example, we might resolve
|
at most 1 parameter for the coroutine. For example, we might resolve
|
||||||
the previous example by passing only one parameter.
|
the previous example by passing only one parameter.
|
||||||
|
|
||||||
```
|
```
|
||||||
#![feature(generators, generator_trait)]
|
#![feature(coroutines, coroutine_trait)]
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let generator = |a: i32| {
|
let coroutine = |a: i32| {
|
||||||
yield a;
|
yield a;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
#### Note: this error code is no longer emitted by the compiler.
|
#### Note: this error code is no longer emitted by the compiler.
|
||||||
|
|
||||||
When using generators (or async) all type variables must be bound so a
|
When using coroutines (or async) all type variables must be bound so a
|
||||||
generator can be constructed.
|
coroutine can be constructed.
|
||||||
|
|
||||||
Erroneous code example:
|
Erroneous code example:
|
||||||
|
|
||||||
@ -15,7 +15,7 @@ async fn foo() {
|
|||||||
|
|
||||||
In the above example `T` is unknowable by the compiler.
|
In the above example `T` is unknowable by the compiler.
|
||||||
To fix this you must bind `T` to a concrete type such as `String`
|
To fix this you must bind `T` to a concrete type such as `String`
|
||||||
so that a generator can then be constructed:
|
so that a coroutine can then be constructed:
|
||||||
|
|
||||||
```edition2018
|
```edition2018
|
||||||
async fn bar<T>() -> () {}
|
async fn bar<T>() -> () {}
|
||||||
|
@ -3,10 +3,10 @@ A `yield` clause was used in an `async` context.
|
|||||||
Erroneous code example:
|
Erroneous code example:
|
||||||
|
|
||||||
```compile_fail,E0727,edition2018
|
```compile_fail,E0727,edition2018
|
||||||
#![feature(generators)]
|
#![feature(coroutines)]
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let generator = || {
|
let coroutine = || {
|
||||||
async {
|
async {
|
||||||
yield;
|
yield;
|
||||||
}
|
}
|
||||||
@ -20,10 +20,10 @@ which is not yet supported.
|
|||||||
To fix this error, you have to move `yield` out of the `async` block:
|
To fix this error, you have to move `yield` out of the `async` block:
|
||||||
|
|
||||||
```edition2018
|
```edition2018
|
||||||
#![feature(generators)]
|
#![feature(coroutines)]
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let generator = || {
|
let coroutine = || {
|
||||||
yield;
|
yield;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -4,24 +4,24 @@ method.
|
|||||||
Erroneous code example:
|
Erroneous code example:
|
||||||
|
|
||||||
```compile_fail,E0790
|
```compile_fail,E0790
|
||||||
trait Generator {
|
trait Coroutine {
|
||||||
fn create() -> u32;
|
fn create() -> u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Impl;
|
struct Impl;
|
||||||
|
|
||||||
impl Generator for Impl {
|
impl Coroutine for Impl {
|
||||||
fn create() -> u32 { 1 }
|
fn create() -> u32 { 1 }
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AnotherImpl;
|
struct AnotherImpl;
|
||||||
|
|
||||||
impl Generator for AnotherImpl {
|
impl Coroutine for AnotherImpl {
|
||||||
fn create() -> u32 { 2 }
|
fn create() -> u32 { 2 }
|
||||||
}
|
}
|
||||||
|
|
||||||
let cont: u32 = Generator::create();
|
let cont: u32 = Coroutine::create();
|
||||||
// error, impossible to choose one of Generator trait implementation
|
// error, impossible to choose one of Coroutine trait implementation
|
||||||
// Should it be Impl or AnotherImpl, maybe something else?
|
// Should it be Impl or AnotherImpl, maybe something else?
|
||||||
```
|
```
|
||||||
|
|
||||||
@ -30,18 +30,18 @@ information to the compiler. In this case, the solution is to use a concrete
|
|||||||
type:
|
type:
|
||||||
|
|
||||||
```
|
```
|
||||||
trait Generator {
|
trait Coroutine {
|
||||||
fn create() -> u32;
|
fn create() -> u32;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct AnotherImpl;
|
struct AnotherImpl;
|
||||||
|
|
||||||
impl Generator for AnotherImpl {
|
impl Coroutine for AnotherImpl {
|
||||||
fn create() -> u32 { 2 }
|
fn create() -> u32 { 2 }
|
||||||
}
|
}
|
||||||
|
|
||||||
let gen1 = AnotherImpl::create();
|
let gen1 = AnotherImpl::create();
|
||||||
|
|
||||||
// if there are multiple methods with same name (different traits)
|
// if there are multiple methods with same name (different traits)
|
||||||
let gen2 = <AnotherImpl as Generator>::create();
|
let gen2 = <AnotherImpl as Coroutine>::create();
|
||||||
```
|
```
|
||||||
|
@ -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,
|
||||||
@ -96,6 +96,10 @@ declare_features! (
|
|||||||
/// Allows `#[doc(include = "some-file")]`.
|
/// Allows `#[doc(include = "some-file")]`.
|
||||||
(removed, external_doc, "1.54.0", Some(44732), None,
|
(removed, external_doc, "1.54.0", Some(44732), None,
|
||||||
Some("use #[doc = include_str!(\"filename\")] instead, which handles macro invocations")),
|
Some("use #[doc = include_str!(\"filename\")] instead, which handles macro invocations")),
|
||||||
|
/// Allows generators to be cloned.
|
||||||
|
(removed, generator_clone, "1.65.0", Some(95360), None, Some("renamed to `coroutine_clone`")),
|
||||||
|
/// Allows defining generators.
|
||||||
|
(removed, generators, "1.21.0", Some(43122), None, Some("renamed to `coroutine`")),
|
||||||
/// Allows `impl Trait` in bindings (`let`, `const`, `static`).
|
/// Allows `impl Trait` in bindings (`let`, `const`, `static`).
|
||||||
(removed, impl_trait_in_bindings, "1.55.0", Some(63065), None,
|
(removed, impl_trait_in_bindings, "1.55.0", Some(63065), None,
|
||||||
Some("the implementation was not maintainable, the feature may get reintroduced once the current refactorings are done")),
|
Some("the implementation was not maintainable, the feature may get reintroduced once the current refactorings are done")),
|
||||||
|
@ -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.
|
||||||
|
@ -118,7 +118,7 @@ pub enum DefKind {
|
|||||||
of_trait: bool,
|
of_trait: bool,
|
||||||
},
|
},
|
||||||
Closure,
|
Closure,
|
||||||
Generator,
|
Coroutine,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl DefKind {
|
impl DefKind {
|
||||||
@ -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::Generator => "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
|
||||||
@ -220,7 +220,7 @@ impl DefKind {
|
|||||||
| DefKind::LifetimeParam
|
| DefKind::LifetimeParam
|
||||||
| DefKind::ExternCrate
|
| DefKind::ExternCrate
|
||||||
| DefKind::Closure
|
| DefKind::Closure
|
||||||
| DefKind::Generator
|
| DefKind::Coroutine
|
||||||
| DefKind::Use
|
| DefKind::Use
|
||||||
| DefKind::ForeignMod
|
| DefKind::ForeignMod
|
||||||
| DefKind::GlobalAsm
|
| DefKind::GlobalAsm
|
||||||
@ -230,7 +230,7 @@ impl DefKind {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_fn_like(self) -> bool {
|
pub fn is_fn_like(self) -> bool {
|
||||||
matches!(self, DefKind::Fn | DefKind::AssocFn | DefKind::Closure | DefKind::Generator)
|
matches!(self, DefKind::Fn | DefKind::AssocFn | DefKind::Closure | DefKind::Coroutine)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Whether `query get_codegen_attrs` should be used with this definition.
|
/// Whether `query get_codegen_attrs` should be used with this definition.
|
||||||
@ -240,7 +240,7 @@ impl DefKind {
|
|||||||
| DefKind::AssocFn
|
| DefKind::AssocFn
|
||||||
| DefKind::Ctor(..)
|
| DefKind::Ctor(..)
|
||||||
| DefKind::Closure
|
| DefKind::Closure
|
||||||
| DefKind::Generator
|
| DefKind::Coroutine
|
||||||
| DefKind::Static(_) => true,
|
| DefKind::Static(_) => true,
|
||||||
DefKind::Mod
|
DefKind::Mod
|
||||||
| DefKind::Struct
|
| DefKind::Struct
|
||||||
|
@ -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<GeneratorKind>,
|
pub coroutine_kind: Option<CoroutineKind>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'hir> Body<'hir> {
|
impl<'hir> Body<'hir> {
|
||||||
@ -1501,48 +1501,48 @@ impl<'hir> Body<'hir> {
|
|||||||
BodyId { hir_id: self.value.hir_id }
|
BodyId { hir_id: self.value.hir_id }
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn generator_kind(&self) -> Option<GeneratorKind> {
|
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 GeneratorKind {
|
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(AsyncGeneratorKind),
|
Async(AsyncCoroutineKind),
|
||||||
|
|
||||||
/// A generator literal created via a `yield` inside a closure.
|
/// A coroutine literal created via a `yield` inside a closure.
|
||||||
Gen,
|
Coroutine,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for GeneratorKind {
|
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 {
|
||||||
GeneratorKind::Async(k) => fmt::Display::fmt(k, f),
|
CoroutineKind::Async(k) => fmt::Display::fmt(k, f),
|
||||||
GeneratorKind::Gen => f.write_str("generator"),
|
CoroutineKind::Coroutine => f.write_str("coroutine"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl GeneratorKind {
|
impl CoroutineKind {
|
||||||
pub fn descr(&self) -> &'static str {
|
pub fn descr(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
GeneratorKind::Async(ask) => ask.descr(),
|
CoroutineKind::Async(ask) => ask.descr(),
|
||||||
GeneratorKind::Gen => "generator",
|
CoroutineKind::Coroutine => "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
|
||||||
/// type-checking (see #60424).
|
/// type-checking (see #60424).
|
||||||
#[derive(Clone, PartialEq, Eq, Hash, Debug, Copy)]
|
#[derive(Clone, PartialEq, Eq, Hash, Debug, Copy)]
|
||||||
#[derive(HashStable_Generic, Encodable, Decodable)]
|
#[derive(HashStable_Generic, Encodable, Decodable)]
|
||||||
pub enum AsyncGeneratorKind {
|
pub enum AsyncCoroutineKind {
|
||||||
/// An explicit `async` block written by the user.
|
/// An explicit `async` block written by the user.
|
||||||
Block,
|
Block,
|
||||||
|
|
||||||
@ -1553,22 +1553,22 @@ pub enum AsyncGeneratorKind {
|
|||||||
Fn,
|
Fn,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for AsyncGeneratorKind {
|
impl fmt::Display for AsyncCoroutineKind {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||||
f.write_str(match self {
|
f.write_str(match self {
|
||||||
AsyncGeneratorKind::Block => "async block",
|
AsyncCoroutineKind::Block => "async block",
|
||||||
AsyncGeneratorKind::Closure => "async closure body",
|
AsyncCoroutineKind::Closure => "async closure body",
|
||||||
AsyncGeneratorKind::Fn => "async fn body",
|
AsyncCoroutineKind::Fn => "async fn body",
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl AsyncGeneratorKind {
|
impl AsyncCoroutineKind {
|
||||||
pub fn descr(&self) -> &'static str {
|
pub fn descr(&self) -> &'static str {
|
||||||
match self {
|
match self {
|
||||||
AsyncGeneratorKind::Block => "`async` block",
|
AsyncCoroutineKind::Block => "`async` block",
|
||||||
AsyncGeneratorKind::Closure => "`async` closure body",
|
AsyncCoroutineKind::Closure => "`async` closure body",
|
||||||
AsyncGeneratorKind::Fn => "`async fn` body",
|
AsyncCoroutineKind::Fn => "`async fn` body",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -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.
|
||||||
@ -2247,12 +2247,12 @@ impl fmt::Display for YieldSource {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<GeneratorKind> for YieldSource {
|
impl From<CoroutineKind> for YieldSource {
|
||||||
fn from(kind: GeneratorKind) -> 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.
|
||||||
GeneratorKind::Gen => Self::Yield,
|
CoroutineKind::Coroutine => Self::Yield,
|
||||||
GeneratorKind::Async(_) => Self::Await { expr: None },
|
CoroutineKind::Async(_) => Self::Await { expr: None },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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);
|
||||||
GeneratorState, sym::generator_state, gen_state, Target::Enum, GenericRequirement::None;
|
CoroutineState, sym::coroutine_state, gen_state, Target::Enum, GenericRequirement::None;
|
||||||
Generator, 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;
|
||||||
|
|
||||||
|
@ -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.
|
||||||
//
|
//
|
||||||
@ -1394,7 +1394,7 @@ fn opaque_type_cycle_error(
|
|||||||
self.opaques.push(def);
|
self.opaques.push(def);
|
||||||
ControlFlow::Continue(())
|
ControlFlow::Continue(())
|
||||||
}
|
}
|
||||||
ty::Closure(def_id, ..) | ty::Generator(def_id, ..) => {
|
ty::Closure(def_id, ..) | ty::Coroutine(def_id, ..) => {
|
||||||
self.closures.push(def_id);
|
self.closures.push(def_id);
|
||||||
t.super_visit_with(self)
|
t.super_visit_with(self)
|
||||||
}
|
}
|
||||||
@ -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::Generator = 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::Generator));
|
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,
|
||||||
@ -1500,7 +1500,7 @@ pub(super) fn check_generator_obligations(tcx: TyCtxt<'_>, def_id: LocalDefId) {
|
|||||||
ObligationCause::new(
|
ObligationCause::new(
|
||||||
field_ty.source_info.span,
|
field_ty.source_info.span,
|
||||||
def_id,
|
def_id,
|
||||||
ObligationCauseCode::SizedGeneratorInterior(def_id),
|
ObligationCauseCode::SizedCoroutineInterior(def_id),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -155,8 +155,8 @@ impl<'tcx> InherentCollect<'tcx> {
|
|||||||
}
|
}
|
||||||
ty::FnDef(..)
|
ty::FnDef(..)
|
||||||
| ty::Closure(..)
|
| ty::Closure(..)
|
||||||
| ty::Generator(..)
|
| ty::Coroutine(..)
|
||||||
| ty::GeneratorWitness(..)
|
| ty::CoroutineWitness(..)
|
||||||
| ty::Bound(..)
|
| ty::Bound(..)
|
||||||
| ty::Placeholder(_)
|
| ty::Placeholder(_)
|
||||||
| ty::Infer(_) => {
|
| ty::Infer(_) => {
|
||||||
|
@ -243,8 +243,8 @@ fn do_orphan_check_impl<'tcx>(
|
|||||||
| ty::Tuple(..) => (LocalImpl::Allow, NonlocalImpl::DisallowOther),
|
| ty::Tuple(..) => (LocalImpl::Allow, NonlocalImpl::DisallowOther),
|
||||||
|
|
||||||
ty::Closure(..)
|
ty::Closure(..)
|
||||||
| ty::Generator(..)
|
| ty::Coroutine(..)
|
||||||
| ty::GeneratorWitness(..)
|
| ty::CoroutineWitness(..)
|
||||||
| ty::Bound(..)
|
| ty::Bound(..)
|
||||||
| ty::Placeholder(..)
|
| ty::Placeholder(..)
|
||||||
| ty::Infer(..) => {
|
| ty::Infer(..) => {
|
||||||
|
@ -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::GeneratorKind> {
|
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,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -235,7 +235,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||||||
// leaf type -- noop
|
// leaf type -- noop
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::FnDef(..) | ty::Generator(..) | ty::Closure(..) => {
|
ty::FnDef(..) | ty::Coroutine(..) | ty::Closure(..) => {
|
||||||
bug!("Unexpected closure type in variance computation");
|
bug!("Unexpected closure type in variance computation");
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -312,7 +312,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
|
|||||||
// types, where we use Error as the Self type
|
// types, where we use Error as the Self type
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::Placeholder(..) | ty::GeneratorWitness(..) | ty::Bound(..) | ty::Infer(..) => {
|
ty::Placeholder(..) | ty::CoroutineWitness(..) | ty::Bound(..) | ty::Infer(..) => {
|
||||||
bug!("unexpected type encountered in variance inference: {}", ty);
|
bug!("unexpected type encountered in variance inference: {}", ty);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
@ -304,8 +304,8 @@ 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::GeneratorKind::Async(hir::AsyncGeneratorKind::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
|
||||||
// the _real_ closure...
|
// the _real_ closure...
|
||||||
|
@ -128,13 +128,13 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
| ty::Uint(..)
|
| ty::Uint(..)
|
||||||
| ty::Float(_)
|
| ty::Float(_)
|
||||||
| ty::Array(..)
|
| ty::Array(..)
|
||||||
| ty::GeneratorWitness(..)
|
| ty::CoroutineWitness(..)
|
||||||
| ty::RawPtr(_)
|
| ty::RawPtr(_)
|
||||||
| ty::Ref(..)
|
| ty::Ref(..)
|
||||||
| ty::FnDef(..)
|
| ty::FnDef(..)
|
||||||
| ty::FnPtr(..)
|
| ty::FnPtr(..)
|
||||||
| ty::Closure(..)
|
| ty::Closure(..)
|
||||||
| ty::Generator(..)
|
| ty::Coroutine(..)
|
||||||
| ty::Adt(..)
|
| ty::Adt(..)
|
||||||
| ty::Never
|
| ty::Never
|
||||||
| ty::Dynamic(_, _, ty::DynStar)
|
| ty::Dynamic(_, _, ty::DynStar)
|
||||||
|
@ -2,8 +2,8 @@ use std::cell::RefCell;
|
|||||||
|
|
||||||
use crate::coercion::CoerceMany;
|
use crate::coercion::CoerceMany;
|
||||||
use crate::gather_locals::GatherLocalsVisitor;
|
use crate::gather_locals::GatherLocalsVisitor;
|
||||||
|
use crate::CoroutineTypes;
|
||||||
use crate::FnCtxt;
|
use crate::FnCtxt;
|
||||||
use crate::GeneratorTypes;
|
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def::DefKind;
|
use rustc_hir::def::DefKind;
|
||||||
use rustc_hir::intravisit::Visitor;
|
use rustc_hir::intravisit::Visitor;
|
||||||
@ -31,9 +31,9 @@ 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<GeneratorTypes<'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);
|
||||||
|
|
||||||
let tcx = fcx.tcx;
|
let tcx = fcx.tcx;
|
||||||
@ -55,10 +55,10 @@ 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::GeneratorKind::Gen {
|
let yield_ty = if kind == hir::CoroutineKind::Coroutine {
|
||||||
let yield_ty = fcx.next_ty_var(TypeVariableOrigin {
|
let yield_ty = fcx.next_ty_var(TypeVariableOrigin {
|
||||||
kind: TypeVariableOriginKind::TypeInference,
|
kind: TypeVariableOriginKind::TypeInference,
|
||||||
span,
|
span,
|
||||||
@ -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,
|
||||||
@ -138,11 +138,11 @@ pub(super) fn check_fn<'a, 'tcx>(
|
|||||||
));
|
));
|
||||||
|
|
||||||
let (resume_ty, yield_ty) = fcx.resume_yield_tys.unwrap();
|
let (resume_ty, yield_ty) = fcx.resume_yield_tys.unwrap();
|
||||||
Some(GeneratorTypes {
|
Some(CoroutineTypes {
|
||||||
resume_ty,
|
resume_ty,
|
||||||
yield_ty,
|
yield_ty,
|
||||||
interior,
|
interior,
|
||||||
movability: can_be_generator.unwrap(),
|
movability: can_be_coroutine.unwrap(),
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
//! Code for type-checking closure expressions.
|
//! Code for type-checking closure expressions.
|
||||||
|
|
||||||
use super::{check_fn, Expectation, FnCtxt, GeneratorTypes};
|
use super::{check_fn, CoroutineTypes, Expectation, FnCtxt};
|
||||||
|
|
||||||
use rustc_errors::ErrorGuaranteed;
|
use rustc_errors::ErrorGuaranteed;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
@ -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,11 +105,11 @@ 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(GeneratorTypes { resume_ty, yield_ty, interior, movability }) = generator_types
|
if let Some(CoroutineTypes { resume_ty, yield_ty, interior, movability }) = coroutine_types
|
||||||
{
|
{
|
||||||
let generator_args = ty::GeneratorArgs::new(
|
let coroutine_args = ty::CoroutineArgs::new(
|
||||||
self.tcx,
|
self.tcx,
|
||||||
ty::GeneratorArgsParts {
|
ty::CoroutineArgsParts {
|
||||||
parent_args,
|
parent_args,
|
||||||
resume_ty,
|
resume_ty,
|
||||||
yield_ty,
|
yield_ty,
|
||||||
@ -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,14 +306,14 @@ 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;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Check that we deduce the signature from the `<_ as std::ops::Generator>::Return`
|
// Check that we deduce the signature from the `<_ as std::ops::Coroutine>::Return`
|
||||||
// associated item and not yield.
|
// associated item and not yield.
|
||||||
if is_gen && self.tcx.associated_item(projection.projection_def_id()).name != sym::Return {
|
if is_gen && self.tcx.associated_item(projection.projection_def_id()).name != sym::Return {
|
||||||
debug!("not `Return` assoc item of `Generator`");
|
debug!("not `Return` assoc item of `Coroutine`");
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -327,7 +327,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
_ => return None,
|
_ => return None,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Generators with a `()` resume type may be defined with 0 or 1 explicit arguments,
|
// Coroutines with a `()` resume type may be defined with 0 or 1 explicit arguments,
|
||||||
// else they must have exactly 1 argument. For now though, just give up in this case.
|
// else they must have exactly 1 argument. For now though, just give up in this case.
|
||||||
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,11 +632,11 @@ 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.
|
||||||
Some(hir::GeneratorKind::Async(hir::AsyncGeneratorKind::Fn)) => {
|
Some(hir::CoroutineKind::Async(hir::AsyncCoroutineKind::Fn)) => {
|
||||||
debug!("closure is async fn body");
|
debug!("closure is async fn body");
|
||||||
let def_id = self.tcx.hir().body_owner_def_id(body.id());
|
let def_id = self.tcx.hir().body_owner_def_id(body.id());
|
||||||
self.deduce_future_output_from_obligations(expr_def_id, def_id).unwrap_or_else(
|
self.deduce_future_output_from_obligations(expr_def_id, def_id).unwrap_or_else(
|
||||||
@ -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}"
|
||||||
),
|
),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -62,8 +62,8 @@ 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 YieldExprOutsideOfGenerator {
|
pub struct YieldExprOutsideOfCoroutine {
|
||||||
#[primary_span]
|
#[primary_span]
|
||||||
pub span: Span,
|
pub span: Span,
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,7 @@ use crate::errors::TypeMismatchFruTypo;
|
|||||||
use crate::errors::{AddressOfTemporaryTaken, ReturnStmtOutsideOfFnBody, StructExprNonExhaustive};
|
use crate::errors::{AddressOfTemporaryTaken, ReturnStmtOutsideOfFnBody, StructExprNonExhaustive};
|
||||||
use crate::errors::{
|
use crate::errors::{
|
||||||
FieldMultiplySpecifiedInInitializer, FunctionalRecordUpdateOnNonStruct, HelpUseLatestEdition,
|
FieldMultiplySpecifiedInInitializer, FunctionalRecordUpdateOnNonStruct, HelpUseLatestEdition,
|
||||||
YieldExprOutsideOfGenerator,
|
YieldExprOutsideOfCoroutine,
|
||||||
};
|
};
|
||||||
use crate::fatally_break_rust;
|
use crate::fatally_break_rust;
|
||||||
use crate::method::{MethodCallComponents, SelfSource};
|
use crate::method::{MethodCallComponents, SelfSource};
|
||||||
@ -3019,7 +3019,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
Ty::new_unit(self.tcx)
|
Ty::new_unit(self.tcx)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
self.tcx.sess.emit_err(YieldExprOutsideOfGenerator { span: expr.span });
|
self.tcx.sess.emit_err(YieldExprOutsideOfCoroutine { span: expr.span });
|
||||||
// Avoid expressions without types during writeback (#78653).
|
// Avoid expressions without types during writeback (#78653).
|
||||||
self.check_expr(value);
|
self.check_expr(value);
|
||||||
Ty::new_unit(self.tcx)
|
Ty::new_unit(self.tcx)
|
||||||
|
@ -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,);
|
||||||
|
|
||||||
|
@ -509,40 +509,40 @@ 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 `GeneratorWitness` type that we will unify with `interior`.
|
// Create the `CoroutineWitness` type that we will unify with `interior`.
|
||||||
let args = ty::GenericArgs::identity_for_item(
|
let args = ty::GenericArgs::identity_for_item(
|
||||||
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -366,7 +366,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
box traits::SelectionOutputTypeParameterMismatch { expected_trait_ref, .. },
|
box traits::SelectionOutputTypeParameterMismatch { expected_trait_ref, .. },
|
||||||
),
|
),
|
||||||
) = error.code
|
) = error.code
|
||||||
&& let ty::Closure(def_id, _) | ty::Generator(def_id, ..) =
|
&& let ty::Closure(def_id, _) | ty::Coroutine(def_id, ..) =
|
||||||
expected_trait_ref.skip_binder().self_ty().kind()
|
expected_trait_ref.skip_binder().self_ty().kind()
|
||||||
&& span.overlaps(self.tcx.def_span(*def_id))
|
&& span.overlaps(self.tcx.def_span(*def_id))
|
||||||
{
|
{
|
||||||
|
@ -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
|
||||||
};
|
};
|
||||||
|
@ -9,7 +9,7 @@ use rustc_hir as hir;
|
|||||||
use rustc_hir::def::{CtorKind, CtorOf, DefKind};
|
use rustc_hir::def::{CtorKind, CtorOf, DefKind};
|
||||||
use rustc_hir::lang_items::LangItem;
|
use rustc_hir::lang_items::LangItem;
|
||||||
use rustc_hir::{
|
use rustc_hir::{
|
||||||
AsyncGeneratorKind, Expr, ExprKind, GeneratorKind, GenericBound, HirId, Node, Path, QPath,
|
AsyncCoroutineKind, CoroutineKind, Expr, ExprKind, GenericBound, HirId, Node, Path, QPath,
|
||||||
Stmt, StmtKind, TyKind, WherePredicate,
|
Stmt, StmtKind, TyKind, WherePredicate,
|
||||||
};
|
};
|
||||||
use rustc_hir_analysis::astconv::AstConv;
|
use rustc_hir_analysis::astconv::AstConv;
|
||||||
@ -532,10 +532,10 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
ty::Tuple(tuple) if tuple.is_empty() => {
|
ty::Tuple(tuple) if tuple.is_empty() => {
|
||||||
errors::SuggestBoxing::Unit { start: span.shrink_to_lo(), end: span }
|
errors::SuggestBoxing::Unit { start: span.shrink_to_lo(), end: span }
|
||||||
}
|
}
|
||||||
ty::Generator(def_id, ..)
|
ty::Coroutine(def_id, ..)
|
||||||
if matches!(
|
if matches!(
|
||||||
self.tcx.generator_kind(def_id),
|
self.tcx.coroutine_kind(def_id),
|
||||||
Some(GeneratorKind::Async(AsyncGeneratorKind::Closure))
|
Some(CoroutineKind::Async(AsyncCoroutineKind::Closure))
|
||||||
) =>
|
) =>
|
||||||
{
|
{
|
||||||
errors::SuggestBoxing::AsyncBody
|
errors::SuggestBoxing::AsyncBody
|
||||||
|
@ -55,8 +55,8 @@ 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::GeneratorKind)>>,
|
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,
|
||||||
/// we record that type variable here. This is later used to inform
|
/// we record that type variable here. This is later used to inform
|
||||||
@ -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()),
|
||||||
}
|
}
|
||||||
|
@ -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,20 +298,20 @@ 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 GeneratorTypes<'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.
|
||||||
yield_ty: Ty<'tcx>,
|
yield_ty: Ty<'tcx>,
|
||||||
|
|
||||||
/// Types that are captured (see `GeneratorInterior` 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,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -172,7 +172,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> {
|
|||||||
let ty = self.node_ty(closure_hir_id);
|
let ty = self.node_ty(closure_hir_id);
|
||||||
let (closure_def_id, args) = match *ty.kind() {
|
let (closure_def_id, args) = match *ty.kind() {
|
||||||
ty::Closure(def_id, args) => (def_id, UpvarArgs::Closure(args)),
|
ty::Closure(def_id, args) => (def_id, UpvarArgs::Closure(args)),
|
||||||
ty::Generator(def_id, args, _) => (def_id, UpvarArgs::Generator(args)),
|
ty::Coroutine(def_id, args, _) => (def_id, UpvarArgs::Coroutine(args)),
|
||||||
ty::Error(_) => {
|
ty::Error(_) => {
|
||||||
// #51714: skip analysis when we have already encountered type errors
|
// #51714: skip analysis when we have already encountered type errors
|
||||||
return;
|
return;
|
||||||
@ -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
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
|
||||||
|
@ -457,8 +457,8 @@ impl<'cx, 'tcx> TypeFolder<TyCtxt<'tcx>> for Canonicalizer<'cx, 'tcx> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
ty::Closure(..)
|
ty::Closure(..)
|
||||||
| ty::Generator(..)
|
| ty::Coroutine(..)
|
||||||
| ty::GeneratorWitness(..)
|
| ty::CoroutineWitness(..)
|
||||||
| ty::Bool
|
| ty::Bool
|
||||||
| ty::Char
|
| ty::Char
|
||||||
| ty::Int(..)
|
| ty::Int(..)
|
||||||
|
@ -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 => {
|
||||||
@ -2936,7 +2936,7 @@ pub enum TyCategory {
|
|||||||
Closure,
|
Closure,
|
||||||
Opaque,
|
Opaque,
|
||||||
OpaqueFuture,
|
OpaqueFuture,
|
||||||
Generator(hir::GeneratorKind),
|
Coroutine(hir::CoroutineKind),
|
||||||
Foreign,
|
Foreign,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2946,7 +2946,7 @@ impl TyCategory {
|
|||||||
Self::Closure => "closure",
|
Self::Closure => "closure",
|
||||||
Self::Opaque => "opaque type",
|
Self::Opaque => "opaque type",
|
||||||
Self::OpaqueFuture => "future",
|
Self::OpaqueFuture => "future",
|
||||||
Self::Generator(gk) => gk.descr(),
|
Self::Coroutine(gk) => gk.descr(),
|
||||||
Self::Foreign => "foreign type",
|
Self::Foreign => "foreign type",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -2959,8 +2959,8 @@ impl TyCategory {
|
|||||||
if tcx.ty_is_opaque_future(ty) { Self::OpaqueFuture } else { Self::Opaque };
|
if tcx.ty_is_opaque_future(ty) { Self::OpaqueFuture } else { Self::Opaque };
|
||||||
Some((kind, def_id))
|
Some((kind, def_id))
|
||||||
}
|
}
|
||||||
ty::Generator(def_id, ..) => {
|
ty::Coroutine(def_id, ..) => {
|
||||||
Some((Self::Generator(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,
|
||||||
|
@ -864,11 +864,11 @@ impl<'a, 'tcx> FindInferSourceVisitor<'a, 'tcx> {
|
|||||||
GenericArgKind::Type(ty) => {
|
GenericArgKind::Type(ty) => {
|
||||||
if matches!(
|
if matches!(
|
||||||
ty.kind(),
|
ty.kind(),
|
||||||
ty::Alias(ty::Opaque, ..) | ty::Closure(..) | ty::Generator(..)
|
ty::Alias(ty::Opaque, ..) | ty::Closure(..) | ty::Coroutine(..)
|
||||||
) {
|
) {
|
||||||
// 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`.
|
||||||
|
@ -215,7 +215,7 @@ impl<T> Trait<T> for X {
|
|||||||
#traits-as-parameters",
|
#traits-as-parameters",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
(ty::Param(p), ty::Closure(..) | ty::Generator(..)) => {
|
(ty::Param(p), ty::Closure(..) | ty::Coroutine(..)) => {
|
||||||
let generics = tcx.generics_of(body_owner_def_id);
|
let generics = tcx.generics_of(body_owner_def_id);
|
||||||
let p_span = tcx.def_span(generics.type_param(p, tcx).def_id);
|
let p_span = tcx.def_span(generics.type_param(p, tcx).def_id);
|
||||||
if !sp.contains(p_span) {
|
if !sp.contains(p_span) {
|
||||||
@ -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\
|
||||||
|
@ -454,16 +454,16 @@ where
|
|||||||
args.as_closure().sig_as_fn_ptr_ty().visit_with(self);
|
args.as_closure().sig_as_fn_ptr_ty().visit_with(self);
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::Generator(_, ref args, _) => {
|
ty::Coroutine(_, ref args, _) => {
|
||||||
// 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, .. }) => {
|
||||||
|
@ -102,17 +102,17 @@ fn compute_components<'tcx>(
|
|||||||
compute_components(tcx, tupled_ty, out, visited);
|
compute_components(tcx, tupled_ty, out, visited);
|
||||||
}
|
}
|
||||||
|
|
||||||
ty::Generator(_, 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
|
||||||
}
|
}
|
||||||
|
|
||||||
// All regions are bound inside a witness
|
// All regions are bound inside a witness
|
||||||
ty::GeneratorWitness(..) => (),
|
ty::CoroutineWitness(..) => (),
|
||||||
|
|
||||||
// OutlivesTypeParameterEnv -- the actual checking that `X:'a`
|
// OutlivesTypeParameterEnv -- the actual checking that `X:'a`
|
||||||
// is implied by the environment is done in regionck.
|
// is implied by the environment is done in regionck.
|
||||||
|
@ -799,9 +799,9 @@ 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::Generator = 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);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user