Rollup merge of #139871 - GuillaumeGomez:async-gen-move, r=compiler-errors
Fix wrong "move keyword" suggestion for async gen block Fixes #139839. It was just missing a string comparison with `async gen`.
This commit is contained in:
commit
a1de2a2d05
4 changed files with 126 additions and 4 deletions
|
@ -3376,10 +3376,15 @@ impl<'infcx, 'tcx> MirBorrowckCtxt<'_, 'infcx, 'tcx> {
|
||||||
|
|
||||||
let (sugg_span, suggestion) = match tcx.sess.source_map().span_to_snippet(args_span) {
|
let (sugg_span, suggestion) = match tcx.sess.source_map().span_to_snippet(args_span) {
|
||||||
Ok(string) => {
|
Ok(string) => {
|
||||||
let coro_prefix = if string.starts_with("async") {
|
let coro_prefix = if let Some(sub) = string.strip_prefix("async") {
|
||||||
// `async` is 5 chars long. Not using `.len()` to avoid the cast from `usize`
|
let trimmed_sub = sub.trim_end();
|
||||||
// to `u32`.
|
if trimmed_sub.ends_with("gen") {
|
||||||
Some(5)
|
// `async` is 5 chars long.
|
||||||
|
Some((trimmed_sub.len() + 5) as _)
|
||||||
|
} else {
|
||||||
|
// `async` is 5 chars long.
|
||||||
|
Some(5)
|
||||||
|
}
|
||||||
} else if string.starts_with("gen") {
|
} else if string.starts_with("gen") {
|
||||||
// `gen` is 3 chars long
|
// `gen` is 3 chars long
|
||||||
Some(3)
|
Some(3)
|
||||||
|
|
35
tests/ui/async-await/async-gen-move-suggestion.fixed
Normal file
35
tests/ui/async-await/async-gen-move-suggestion.fixed
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
// This is a regression test for <https://github.com/rust-lang/rust/issues/139839>.
|
||||||
|
// It ensures that the "add `move` keyword" suggestion is valid.
|
||||||
|
|
||||||
|
//@ run-rustfix
|
||||||
|
//@ edition:2024
|
||||||
|
|
||||||
|
#![feature(coroutines)]
|
||||||
|
#![feature(gen_blocks)]
|
||||||
|
#![feature(async_iterator)]
|
||||||
|
|
||||||
|
use std::async_iter::AsyncIterator;
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn moved() -> impl AsyncIterator<Item = u32> {
|
||||||
|
let mut x = "foo".to_string();
|
||||||
|
|
||||||
|
async gen move { //~ ERROR
|
||||||
|
x.clear();
|
||||||
|
for x in 3..6 { yield x }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn check_with_whitespace_chars() -> impl AsyncIterator<Item = u32> {
|
||||||
|
let mut x = "foo".to_string();
|
||||||
|
|
||||||
|
async // Just to check that whitespace characters are correctly handled
|
||||||
|
gen move { //~^ ERROR
|
||||||
|
x.clear();
|
||||||
|
for x in 3..6 { yield x }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
}
|
35
tests/ui/async-await/async-gen-move-suggestion.rs
Normal file
35
tests/ui/async-await/async-gen-move-suggestion.rs
Normal file
|
@ -0,0 +1,35 @@
|
||||||
|
// This is a regression test for <https://github.com/rust-lang/rust/issues/139839>.
|
||||||
|
// It ensures that the "add `move` keyword" suggestion is valid.
|
||||||
|
|
||||||
|
//@ run-rustfix
|
||||||
|
//@ edition:2024
|
||||||
|
|
||||||
|
#![feature(coroutines)]
|
||||||
|
#![feature(gen_blocks)]
|
||||||
|
#![feature(async_iterator)]
|
||||||
|
|
||||||
|
use std::async_iter::AsyncIterator;
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn moved() -> impl AsyncIterator<Item = u32> {
|
||||||
|
let mut x = "foo".to_string();
|
||||||
|
|
||||||
|
async gen { //~ ERROR
|
||||||
|
x.clear();
|
||||||
|
for x in 3..6 { yield x }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[allow(dead_code)]
|
||||||
|
fn check_with_whitespace_chars() -> impl AsyncIterator<Item = u32> {
|
||||||
|
let mut x = "foo".to_string();
|
||||||
|
|
||||||
|
async // Just to check that whitespace characters are correctly handled
|
||||||
|
gen { //~^ ERROR
|
||||||
|
x.clear();
|
||||||
|
for x in 3..6 { yield x }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
}
|
47
tests/ui/async-await/async-gen-move-suggestion.stderr
Normal file
47
tests/ui/async-await/async-gen-move-suggestion.stderr
Normal file
|
@ -0,0 +1,47 @@
|
||||||
|
error[E0373]: async gen block may outlive the current function, but it borrows `x`, which is owned by the current function
|
||||||
|
--> $DIR/async-gen-move-suggestion.rs:17:5
|
||||||
|
|
|
||||||
|
LL | async gen {
|
||||||
|
| ^^^^^^^^^ may outlive borrowed value `x`
|
||||||
|
LL | x.clear();
|
||||||
|
| - `x` is borrowed here
|
||||||
|
|
|
||||||
|
note: async gen block is returned here
|
||||||
|
--> $DIR/async-gen-move-suggestion.rs:17:5
|
||||||
|
|
|
||||||
|
LL | / async gen {
|
||||||
|
LL | | x.clear();
|
||||||
|
LL | | for x in 3..6 { yield x }
|
||||||
|
LL | | }
|
||||||
|
| |_____^
|
||||||
|
help: to force the async gen block to take ownership of `x` (and any other referenced variables), use the `move` keyword
|
||||||
|
|
|
||||||
|
LL | async gen move {
|
||||||
|
| ++++
|
||||||
|
|
||||||
|
error[E0373]: async gen block may outlive the current function, but it borrows `x`, which is owned by the current function
|
||||||
|
--> $DIR/async-gen-move-suggestion.rs:27:5
|
||||||
|
|
|
||||||
|
LL | / async // Just to check that whitespace characters are correctly handled
|
||||||
|
LL | | gen {
|
||||||
|
| |_______^ may outlive borrowed value `x`
|
||||||
|
LL | x.clear();
|
||||||
|
| - `x` is borrowed here
|
||||||
|
|
|
||||||
|
note: async gen block is returned here
|
||||||
|
--> $DIR/async-gen-move-suggestion.rs:27:5
|
||||||
|
|
|
||||||
|
LL | / async // Just to check that whitespace characters are correctly handled
|
||||||
|
LL | | gen {
|
||||||
|
LL | | x.clear();
|
||||||
|
LL | | for x in 3..6 { yield x }
|
||||||
|
LL | | }
|
||||||
|
| |_____^
|
||||||
|
help: to force the async gen block to take ownership of `x` (and any other referenced variables), use the `move` keyword
|
||||||
|
|
|
||||||
|
LL | gen move {
|
||||||
|
| ++++
|
||||||
|
|
||||||
|
error: aborting due to 2 previous errors
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0373`.
|
Loading…
Add table
Add a link
Reference in a new issue