`async fn` can assign to argument to change its lifetime, but normal `fn` and `async` blocks cannot.
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 119k
- Forks
- 16.1k
- PR merge metrics
- PR metrics pending
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 https://github.com/rust-lang/rust/issues/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)
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Reproduce the three snippets on the reported Rust 1.93.0-nightly playground and compare their lifetime behavior and diagnostics. Read the related issues #128225 and #148463 for context; done means the inconsistency is resolved or clearly documented with matching compiler behavior and diagnostics.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- compilers
- Issue type
- Bug
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100