-
Notifications
You must be signed in to change notification settings - Fork 13.9k
Open
Labels
A-async-awaitArea: Async & AwaitArea: Async & AwaitA-borrow-checkerArea: The borrow checkerArea: The borrow checkerA-lifetimesArea: Lifetimes / regionsArea: Lifetimes / regionsC-bugCategory: This is a bug.Category: This is a bug.T-typesRelevant to the types team, which will review and decide on the PR/issue.Relevant to the types team, which will review and decide on the PR/issue.needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.This issue may need triage. Remove it if it has been sufficiently triaged.
Description
I tried this code:
#![allow(unused)]
async fn works<'a>(mut a: &'a i32, b: i32) {
a = &b;
}
fn fails<'a>(mut a: &'a i32, b: i32) {
a = &b;
}
fn also_fails<'a>(mut a: &'a i32, b: i32) -> impl Future<Output = ()> {
async move {
a = &b;
}
}I expected all 3 functions to compile, or all to fail to compile, but instead only the first function compiles:
error[E0521]: borrowed data escapes outside of async block
--> src/lib.rs:10:9
|
8 | fn also_fails<'a>(mut a: &'a i32, b: i32) -> impl Future<Output = ()> {
| ----- `a` declared here, outside of the async block body
9 | async move {
10 | a = &b;
| ^^^^--
| | |
| | borrow is only valid in the async block body
| reference to `b` escapes the async block body here
error[E0597]: `b` does not live long enough
--> src/lib.rs:6:9
|
5 | fn fails<'a>(mut a: &'a i32, b: i32) {
| -- - binding `b` declared here
| |
| lifetime `'a` defined here
6 | a = &b;
| ----^^
| | |
| | borrowed value does not live long enough
| assignment requires that `b` is borrowed for `'a`
7 | }
| - `b` dropped here while still borrowed
Some errors have detailed explanations: E0521, E0597.
For more information about an error, try `rustc --explain E0521`.
Edit: The part below is filed separately as #148401
A different issue that's now filed separately
Additionally, there's this variant which has a very strange diagnostic that I don't understand:
#![allow(unused)]
fn weird<'a, 'b>(mut a: &'a i32, b: &'b i32) -> impl Future<Output = ()> + use<'a, 'b> {
async move {
a = b;
}
}error[E0700]: hidden type for `impl Future<Output = ()>` captures lifetime that does not appear in bounds
--> src/lib.rs:3:5
|
2 | fn weird<'a, 'b>(mut a: &'a i32, b: &'b i32) -> impl Future<Output = ()> + use<'a, 'b> {
| -------------------------------------- opaque type defined here
3 | / async move {
4 | | a = b;
5 | | }
| |_____^
|
= note: hidden type `{async block@src/lib.rs:3:5: 3:15}` captures lifetime `'_`
For more information about this error, try `rustc --explain E0700`.
See also #128225, where a variable can be assigned a value with a different lifetime.
Related to #148463, where a similar inconsistency occurs with patterns in function arguments.
Meta
Reproducible on the playground with version 1.93.0-nightly (2025-11-01 bd3ac0330018c23b111b)
Metadata
Metadata
Assignees
Labels
A-async-awaitArea: Async & AwaitArea: Async & AwaitA-borrow-checkerArea: The borrow checkerArea: The borrow checkerA-lifetimesArea: Lifetimes / regionsArea: Lifetimes / regionsC-bugCategory: This is a bug.Category: This is a bug.T-typesRelevant to the types team, which will review and decide on the PR/issue.Relevant to the types team, which will review and decide on the PR/issue.needs-triageThis issue may need triage. Remove it if it has been sufficiently triaged.This issue may need triage. Remove it if it has been sufficiently triaged.