Explain that coroutine can be marked static

And also point out the def span of the coroutine
This commit is contained in:
Michael Goulet 2024-07-21 21:37:22 -04:00
parent 023b583f6a
commit 6dfc9f8886
9 changed files with 91 additions and 3 deletions

View File

@ -1,7 +1,9 @@
#![allow(rustc::diagnostic_outside_of_impl)]
#![allow(rustc::untranslatable_diagnostic)]
use rustc_errors::Applicability;
use rustc_errors::{codes::*, struct_span_code_err, Diag, DiagCtxtHandle};
use rustc_hir as hir;
use rustc_middle::span_bug;
use rustc_middle::ty::{self, Ty, TyCtxt};
use rustc_span::Span;
@ -382,13 +384,35 @@ pub(crate) fn cannot_borrow_across_coroutine_yield(
yield_span: Span,
) -> Diag<'infcx> {
let coroutine_kind = self.body.coroutine.as_ref().unwrap().coroutine_kind;
struct_span_code_err!(
let mut diag = struct_span_code_err!(
self.dcx(),
span,
E0626,
"borrow may still be in use when {coroutine_kind:#} yields",
)
.with_span_label(yield_span, "possible yield occurs here")
);
diag.span_label(
self.infcx.tcx.def_span(self.body.source.def_id()),
format!("within this {coroutine_kind:#}"),
);
diag.span_label(yield_span, "possible yield occurs here");
if matches!(coroutine_kind, hir::CoroutineKind::Coroutine(_)) {
let hir::Closure { capture_clause, fn_decl_span, .. } = self
.infcx
.tcx
.hir_node_by_def_id(self.body.source.def_id().expect_local())
.expect_closure();
let span = match capture_clause {
rustc_hir::CaptureBy::Value { move_kw } => move_kw.shrink_to_lo(),
rustc_hir::CaptureBy::Ref => fn_decl_span.shrink_to_lo(),
};
diag.span_suggestion_verbose(
span,
"add `static` to mark this coroutine as unmovable",
"static ",
Applicability::MaybeIncorrect,
);
}
diag
}
pub(crate) fn cannot_borrow_across_destructor(&self, borrow_span: Span) -> Diag<'infcx> {

View File

@ -1,11 +1,19 @@
error[E0626]: borrow may still be in use when coroutine yields
--> $DIR/coroutine-with-nll.rs:8:17
|
LL | || {
| -- within this coroutine
...
LL | let b = &mut true;
| ^^^^^^^^^
LL |
LL | yield ();
| -------- possible yield occurs here
|
help: add `static` to mark this coroutine as unmovable
|
LL | static || {
| ++++++
error: aborting due to 1 previous error

View File

@ -1,10 +1,18 @@
error[E0626]: borrow may still be in use when coroutine yields
--> $DIR/issue-48048.rs:9:9
|
LL | #[coroutine] || {
| -- within this coroutine
...
LL | x.0({
| ^^^
LL | yield;
| ----- possible yield occurs here
|
help: add `static` to mark this coroutine as unmovable
|
LL | #[coroutine] static || {
| ++++++
error: aborting due to 1 previous error

View File

@ -1,10 +1,17 @@
error[E0626]: borrow may still be in use when coroutine yields
--> $DIR/pattern-borrow.rs:9:24
|
LL | #[coroutine] move || {
| ------- within this coroutine
LL | if let Test::A(ref _a) = test {
| ^^^^^^
LL | yield ();
| -------- possible yield occurs here
|
help: add `static` to mark this coroutine as unmovable
|
LL | #[coroutine] static move || {
| ++++++
error: aborting due to 1 previous error

View File

@ -1,6 +1,9 @@
error[E0626]: borrow may still be in use when `gen` block yields
--> $DIR/self_referential_gen_block.rs:9:21
|
LL | let mut x = gen {
| --- within this `gen` block
LL | let y = 42;
LL | let z = &y;
| ^^
LL | yield 43;

View File

@ -1,8 +1,16 @@
error[E0626]: borrow may still be in use when coroutine yields
--> $DIR/yield-in-args.rs:9:13
|
LL | || {
| -- within this coroutine
LL | let b = true;
LL | foo(&b, yield);
| ^^ ----- possible yield occurs here
|
help: add `static` to mark this coroutine as unmovable
|
LL | static || {
| ++++++
error: aborting due to 1 previous error

View File

@ -1,10 +1,17 @@
error[E0626]: borrow may still be in use when coroutine yields
--> $DIR/yield-while-iterating.rs:13:18
|
LL | let _b =#[coroutine] move || {
| ------- within this coroutine
LL | for p in &x {
| ^^
LL | yield();
| ------- possible yield occurs here
|
help: add `static` to mark this coroutine as unmovable
|
LL | let _b =#[coroutine] static move || {
| ++++++
error[E0502]: cannot borrow `x` as immutable because it is also borrowed as mutable
--> $DIR/yield-while-iterating.rs:58:20

View File

@ -1,20 +1,35 @@
error[E0626]: borrow may still be in use when coroutine yields
--> $DIR/yield-while-local-borrowed.rs:13:17
|
LL | let mut b = #[coroutine] move || {
| ------- within this coroutine
LL | let a = &mut 3;
| ^^^^^^
LL |
LL | yield ();
| -------- possible yield occurs here
|
help: add `static` to mark this coroutine as unmovable
|
LL | let mut b = #[coroutine] static move || {
| ++++++
error[E0626]: borrow may still be in use when coroutine yields
--> $DIR/yield-while-local-borrowed.rs:40:21
|
LL | let mut b = #[coroutine] move || {
| ------- within this coroutine
...
LL | let b = &a;
| ^^
LL |
LL | yield ();
| -------- possible yield occurs here
|
help: add `static` to mark this coroutine as unmovable
|
LL | let mut b = #[coroutine] static move || {
| ++++++
error: aborting due to 2 previous errors

View File

@ -10,8 +10,16 @@ LL | yield &s[..]
error[E0626]: borrow may still be in use when coroutine yields
--> $DIR/issue-55850.rs:28:16
|
LL | GenIter(#[coroutine] move || {
| ------- within this coroutine
LL | let mut s = String::new();
LL | yield &s[..]
| -------^---- possible yield occurs here
|
help: add `static` to mark this coroutine as unmovable
|
LL | GenIter(#[coroutine] static move || {
| ++++++
error: aborting due to 2 previous errors