You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
#![feature(async_await)]pubstructFoo<'a>{pubbar:&'ai32,}impl<'a>Foo<'a>{pubasyncfnnew(bar:&'ai32) -> Self{Foo{
bar
}}}
error[E0495]: cannot infer an appropriate lifetime due to conflicting requirements
--> src/lib.rs:8:22
|
8 | pub async fn new(bar: &'a i32) -> Self {
| ^^^
|
note: first, the lifetime cannot outlive the lifetime 'a as defined on the impl at 7:6...
--> src/lib.rs:7:6
|
7 | impl<'a> Foo<'a> {
| ^^
= note: ...so that the expression is assignable:
expected &i32
found &'a i32
= note: but, the lifetime must be valid for the static lifetime...
= note: ...so that the types are compatible:
expected Foo<'_>
found Foo<'static>
It works to either change the signature to take bar: &'static i32, or to change the body of the fn to use a static borrow like bar: &5. So the compiler really does want the function to return a Foo<'static>, even though Self is a Foo<'a>
jebrosen pointed out on IRC that it also happens with RPIT in general, so this might be the same as #53613 (from async fn expanding to -> impl Future<Output = ...>)
There are some forward compatibility concerns here. In particular, callers can (somewhat incorrectly) assume that the returned futures are 'static. In other words, the callee is committing to returning a future that does not capture 'a in these examples -- right now, that typically means callee doesn't compile, but it could happen that the callee happens to compile, and then callers would be able to use this future in places where 'a is out of scope. If we later fix this bug, those callers will stop compiling.
The bug involving Self is rather straightforward (but grungy) to fix. It's also possible for us to, temporarily, just create an error if you return a type mentioning Self in an async fn.
But fixing the T::Item case is rather more complex. We don't know until type-checking that T::Item resolves to <T as HasItem<'a>>::Item. And, if I had my druthers, we might not know until even later than that. I suppose we could do a forward compatibility restriction of some kind.
An example of something which compiles now but I think should not (and would not, if this were fixed):
#![feature(async_await)]pubstructFoo<'a>{pubbar:&'ai32,}impl<'a>Foo<'a>{pubasyncfnnew(_bar:&'ai32) -> Self{Foo{bar:&22}}}asyncfnfoo(){let x = {let bar = 22;Foo::new(&bar).await};drop(x);}fnmain(){}
the problem here is that the type of x should be Foo<'bar> -- i.e., it should be constrained to the lifetime of bar, but it is actually Foo<'static>.
I just revisited the code that had prompted me to file this issue, and both it and the test case in the OP compile fine today. According to godbolt it didn't compile until 1.73 and started compiling since 1.74.0. Is this still an issue?
Activity
Arnavion commentedon Jun 19, 2019
jebrosen pointed out on IRC that it also happens with RPIT in general, so this might be the same as #53613 (from
async fnexpanding to-> impl Future<Output = ...>)nikomatsakis commentedon Jul 5, 2019
As I pointed out in #53613, there is a more dangerous variant of this involving projections:
Note that this version compiles just fine
nikomatsakis commentedon Jul 5, 2019
There are some forward compatibility concerns here. In particular, callers can (somewhat incorrectly) assume that the returned futures are
'static. In other words, the callee is committing to returning a future that does not capture'ain these examples -- right now, that typically meanscalleedoesn't compile, but it could happen that the callee happens to compile, and then callers would be able to use this future in places where'ais out of scope. If we later fix this bug, those callers will stop compiling.nikomatsakis commentedon Jul 5, 2019
The bug involving
Selfis rather straightforward (but grungy) to fix. It's also possible for us to, temporarily, just create an error if you return a type mentioningSelfin anasync fn.But fixing the
T::Itemcase is rather more complex. We don't know until type-checking thatT::Itemresolves to<T as HasItem<'a>>::Item. And, if I had my druthers, we might not know until even later than that. I suppose we could do a forward compatibility restriction of some kind.nikomatsakis commentedon Jul 9, 2019
An example of something which compiles now but I think should not (and would not, if this were fixed):
the problem here is that the type of
xshould beFoo<'bar>-- i.e., it should be constrained to the lifetime ofbar, but it is actuallyFoo<'static>.nikomatsakis commentedon Jul 9, 2019
I left some notes on how to fix this on Zulip
davidtwco commentedon Jul 9, 2019
@rustbot claim
40 remaining items
Auto merge of rust-lang#91403 - cjgillot:inherit-async, r=oli-obk
Xiretza commentedon Apr 24, 2022
#91403 was reverted (by #94088), I think this should be reopened.
Auto merge of rust-lang#115659 - compiler-errors:itp, r=cjgillot
Auto merge of rust-lang#115659 - compiler-errors:itp, r=cjgillot
Auto merge of #115659 - compiler-errors:itp, r=cjgillot
Auto merge of #115659 - compiler-errors:itp, r=cjgillot
Auto merge of #115659 - compiler-errors:itp, r=cjgillot
Arnavion commentedon Jul 31, 2024
I just revisited the code that had prompted me to file this issue, and both it and the test case in the OP compile fine today. According to godbolt it didn't compile until 1.73 and started compiling since 1.74.0. Is this still an issue?
tmandry commentedon Jul 31, 2024
Looks like this is now accepted after #115659 and we can close the issue. Thanks @Arnavion for commenting!