Skip to content

Commit

Permalink
Explain that coroutine can be marked static
Browse files Browse the repository at this point in the history
And also point out the def span of the coroutine
  • Loading branch information
compiler-errors committed Jul 22, 2024
1 parent 023b583 commit 6dfc9f8
Show file tree
Hide file tree
Showing 9 changed files with 91 additions and 3 deletions.
30 changes: 27 additions & 3 deletions compiler/rustc_borrowck/src/borrowck_errors.rs
Original file line number Diff line number Diff line change
@@ -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;
Expand Down Expand Up @@ -382,13 +384,35 @@ impl<'infcx, 'tcx> crate::MirBorrowckCtxt<'_, '_, 'infcx, 'tcx> {
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> {
Expand Down
8 changes: 8 additions & 0 deletions tests/ui/coroutine/coroutine-with-nll.stderr
Original file line number Diff line number Diff line change
@@ -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

Expand Down
8 changes: 8 additions & 0 deletions tests/ui/coroutine/issue-48048.stderr
Original file line number Diff line number Diff line change
@@ -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

Expand Down
7 changes: 7 additions & 0 deletions tests/ui/coroutine/pattern-borrow.stderr
Original file line number Diff line number Diff line change
@@ -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

Expand Down
3 changes: 3 additions & 0 deletions tests/ui/coroutine/self_referential_gen_block.stderr
Original file line number Diff line number Diff line change
@@ -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;
Expand Down
8 changes: 8 additions & 0 deletions tests/ui/coroutine/yield-in-args.stderr
Original file line number Diff line number Diff line change
@@ -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

Expand Down
7 changes: 7 additions & 0 deletions tests/ui/coroutine/yield-while-iterating.stderr
Original file line number Diff line number Diff line change
@@ -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
Expand Down
15 changes: 15 additions & 0 deletions tests/ui/coroutine/yield-while-local-borrowed.stderr
Original file line number Diff line number Diff line change
@@ -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

Expand Down
8 changes: 8 additions & 0 deletions tests/ui/nll/issue-55850.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down

0 comments on commit 6dfc9f8

Please # to comment.