-
Notifications
You must be signed in to change notification settings - Fork 12.8k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
&self
lifetime elision with two parameters does not work with async fn
#63388
Comments
&self
lifetime elision with two arguments does not work with async fn
&self
lifetime elision with two parameters does not work with async fn
The code that calculates |
OK, so, a few thoughts: I agree this is a serious usability bug. It's not a forward a compatibility hazard, though. Regarding the code itself, it's a shame that we have to duplicate the elision code -- there are currently two bits of code doing the same check. The one in lowering is the one giving us the error here. The error is also phrased slightly differently than the one from lifetime resolution. We could probably get this to work correctly for I feel like ultimately I'd hate to hold off on shipping async-await owing to this bug, but it'd be good to fix it. |
@cramertj so I guess the buggy code is this: rust/src/librustc/hir/lowering.rs Lines 2159 to 2163 in 60960a2
presumably the way to make it work for |
Er, my mistake, you can't match on the rust/src/librustc/hir/lowering.rs Lines 2190 to 2214 in 60960a2
|
(TBH I'm not 100% sure this code is right, so I'm doing a quick test locally to see if I'm remembering things correctly.) |
Actually, the behavior of the current code is (I think) worse than the issue suggests. If I understand what it's doing -- it is looking for exactly one lifetime parameter that was not explicitly declared, and using that as the elided lifetime. so for example this code compiles which should not (playground): // build-pass (FIXME(62277): could be check-pass?)
// edition:2018
#![feature(async_await)]
struct Xyz {
a: u64,
}
trait Foo {}
impl Xyz {
async fn do_sth<'a>(
&'a self, foo: &dyn Foo
) -> &dyn Foo
{
foo
}
}
fn main() {} as does this (playground): // build-pass (FIXME(62277): could be check-pass?)
// edition:2018
#![feature(async_await)]
struct Xyz {
a: u64,
}
trait Foo {}
impl Xyz {
async fn do_sth<'a>(
foo: &dyn Foo, bar: &'a dyn Foo
) -> &dyn Foo
{
foo
}
}
fn main() {} |
I have a nice fix now. |
…elision-self-mut-self, r=cramertj handle elision in async fn correctly We now always make fresh lifetimne parameters for all elided lifetimes, whether they are in the inputs or outputs. But then we generate `'_` in the case of elided lifetimes from the outputs. Example: ```rust async fn foo<'a>(x: &'a u32) -> &u32 { .. } ``` becomes ```rust type Foo<'a, 'b> = impl Future<Output = &'b u32>; fn foo<'a>(x: &'a u32) -> Foo<'a, '_> ``` Fixes rust-lang#63388
…elision-self-mut-self, r=cramertj handle elision in async fn correctly We now always make fresh lifetimne parameters for all elided lifetimes, whether they are in the inputs or outputs. But then we generate `'_` in the case of elided lifetimes from the outputs. Example: ```rust async fn foo<'a>(x: &'a u32) -> &u32 { .. } ``` becomes ```rust type Foo<'a, 'b> = impl Future<Output = &'b u32>; fn foo<'a>(x: &'a u32) -> Foo<'a, '_> ``` Fixes rust-lang#63388
…elision-self-mut-self, r=cramertj handle elision in async fn correctly We now always make fresh lifetimne parameters for all elided lifetimes, whether they are in the inputs or outputs. But then we generate `'_` in the case of elided lifetimes from the outputs. Example: ```rust async fn foo<'a>(x: &'a u32) -> &u32 { .. } ``` becomes ```rust type Foo<'a, 'b> = impl Future<Output = &'b u32>; fn foo<'a>(x: &'a u32) -> Foo<'a, '_> ``` Fixes rust-lang#63388
…amertj Stabilize `async_await` in Rust 1.39.0 Here we stabilize: - free and inherent `async fn`s, - the `<expr>.await` expression form, - and the `async move? { ... }` block form. Closes rust-lang#62149. Closes rust-lang#50547. All the blockers are now closed. <details> - [x] FCP in rust-lang#62149 - [x] rust-lang#61949; PR in rust-lang#62849. - [x] rust-lang#62517; PR in rust-lang#63376. - [x] rust-lang#63225; PR in rust-lang#63501 - [x] rust-lang#63388; PR in rust-lang#63499 - [x] rust-lang#63500; PR in rust-lang#63501 - [x] rust-lang#62121 (comment) - [x] Some tests for control flow (PR rust-lang#63387): - `?` - `return` in `async` blocks - `break` - [x] rust-lang#61775 (comment), i.e. tests for rust-lang#60944 with `async fn`s instead). PR in rust-lang#63383 </details> r? @cramertj
Rust previously had a bug [1] where these lifetimes were incorrectly inferred, and required manual annotations. The rust issue has now been resolved, so we can now elide these lifetimes. [1]: rust-lang/rust#63388 Change-Id: I26ceead7fe5e4165b07280705567fbef0e56c7b0
Originally reported in #63383 (comment).
should compile (it does if you remove
async
or writeasync fn foo<'a, 'b>(&'a self, f: &'b u32) -> &'a A
) but does not (playground):This seems like a rather serious usability bug as compared to what you expect from normal Rust.
cc #63209
cc @nikomatsakis @cramertj
The text was updated successfully, but these errors were encountered: