Skip to content

Commit a1de2a2

Browse files
authored
Rollup merge of rust-lang#139871 - GuillaumeGomez:async-gen-move, r=compiler-errors
Fix wrong "move keyword" suggestion for async gen block Fixes rust-lang#139839. It was just missing a string comparison with `async gen`.
2 parents b65e6b7 + 2020adb commit a1de2a2

File tree

4 files changed

+126
-4
lines changed

4 files changed

+126
-4
lines changed

Diff for: compiler/rustc_borrowck/src/diagnostics/conflict_errors.rs

+9-4
Original file line numberDiff line numberDiff line change
@@ -3376,10 +3376,15 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
33763376

33773377
let (sugg_span, suggestion) = match tcx.sess.source_map().span_to_snippet(args_span) {
33783378
Ok(string) => {
3379-
let coro_prefix = if string.starts_with("async") {
3380-
// `async` is 5 chars long. Not using `.len()` to avoid the cast from `usize`
3381-
// to `u32`.
3382-
Some(5)
3379+
let coro_prefix = if let Some(sub) = string.strip_prefix("async") {
3380+
let trimmed_sub = sub.trim_end();
3381+
if trimmed_sub.ends_with("gen") {
3382+
// `async` is 5 chars long.
3383+
Some((trimmed_sub.len() + 5) as _)
3384+
} else {
3385+
// `async` is 5 chars long.
3386+
Some(5)
3387+
}
33833388
} else if string.starts_with("gen") {
33843389
// `gen` is 3 chars long
33853390
Some(3)

Diff for: tests/ui/async-await/async-gen-move-suggestion.fixed

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// This is a regression test for <https://github.com/rust-lang/rust/issues/139839>.
2+
// It ensures that the "add `move` keyword" suggestion is valid.
3+
4+
//@ run-rustfix
5+
//@ edition:2024
6+
7+
#![feature(coroutines)]
8+
#![feature(gen_blocks)]
9+
#![feature(async_iterator)]
10+
11+
use std::async_iter::AsyncIterator;
12+
13+
#[allow(dead_code)]
14+
fn moved() -> impl AsyncIterator<Item = u32> {
15+
let mut x = "foo".to_string();
16+
17+
async gen move { //~ ERROR
18+
x.clear();
19+
for x in 3..6 { yield x }
20+
}
21+
}
22+
23+
#[allow(dead_code)]
24+
fn check_with_whitespace_chars() -> impl AsyncIterator<Item = u32> {
25+
let mut x = "foo".to_string();
26+
27+
async // Just to check that whitespace characters are correctly handled
28+
gen move { //~^ ERROR
29+
x.clear();
30+
for x in 3..6 { yield x }
31+
}
32+
}
33+
34+
fn main() {
35+
}

Diff for: tests/ui/async-await/async-gen-move-suggestion.rs

+35
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
// This is a regression test for <https://github.com/rust-lang/rust/issues/139839>.
2+
// It ensures that the "add `move` keyword" suggestion is valid.
3+
4+
//@ run-rustfix
5+
//@ edition:2024
6+
7+
#![feature(coroutines)]
8+
#![feature(gen_blocks)]
9+
#![feature(async_iterator)]
10+
11+
use std::async_iter::AsyncIterator;
12+
13+
#[allow(dead_code)]
14+
fn moved() -> impl AsyncIterator<Item = u32> {
15+
let mut x = "foo".to_string();
16+
17+
async gen { //~ ERROR
18+
x.clear();
19+
for x in 3..6 { yield x }
20+
}
21+
}
22+
23+
#[allow(dead_code)]
24+
fn check_with_whitespace_chars() -> impl AsyncIterator<Item = u32> {
25+
let mut x = "foo".to_string();
26+
27+
async // Just to check that whitespace characters are correctly handled
28+
gen { //~^ ERROR
29+
x.clear();
30+
for x in 3..6 { yield x }
31+
}
32+
}
33+
34+
fn main() {
35+
}
+47
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
error[E0373]: async gen block may outlive the current function, but it borrows `x`, which is owned by the current function
2+
--> $DIR/async-gen-move-suggestion.rs:17:5
3+
|
4+
LL | async gen {
5+
| ^^^^^^^^^ may outlive borrowed value `x`
6+
LL | x.clear();
7+
| - `x` is borrowed here
8+
|
9+
note: async gen block is returned here
10+
--> $DIR/async-gen-move-suggestion.rs:17:5
11+
|
12+
LL | / async gen {
13+
LL | | x.clear();
14+
LL | | for x in 3..6 { yield x }
15+
LL | | }
16+
| |_____^
17+
help: to force the async gen block to take ownership of `x` (and any other referenced variables), use the `move` keyword
18+
|
19+
LL | async gen move {
20+
| ++++
21+
22+
error[E0373]: async gen block may outlive the current function, but it borrows `x`, which is owned by the current function
23+
--> $DIR/async-gen-move-suggestion.rs:27:5
24+
|
25+
LL | / async // Just to check that whitespace characters are correctly handled
26+
LL | | gen {
27+
| |_______^ may outlive borrowed value `x`
28+
LL | x.clear();
29+
| - `x` is borrowed here
30+
|
31+
note: async gen block is returned here
32+
--> $DIR/async-gen-move-suggestion.rs:27:5
33+
|
34+
LL | / async // Just to check that whitespace characters are correctly handled
35+
LL | | gen {
36+
LL | | x.clear();
37+
LL | | for x in 3..6 { yield x }
38+
LL | | }
39+
| |_____^
40+
help: to force the async gen block to take ownership of `x` (and any other referenced variables), use the `move` keyword
41+
|
42+
LL | gen move {
43+
| ++++
44+
45+
error: aborting due to 2 previous errors
46+
47+
For more information about this error, try `rustc --explain E0373`.

0 commit comments

Comments
 (0)