-
Notifications
You must be signed in to change notification settings - Fork 13.4k
Problem with GATs, async, and Send-bounds #90696
New issue
Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? # to your account
Comments
@rustbot label F-generic_associated_types |
@rustbot label A-lifetimes, A-associated-items, A-traits, A-async-await, T-compiler, requires-nightly |
This looks like a tricky bug and will take some time to look into. There were some recent closure changes that might be causing this, and this sounds potentially related to #71723, #71671, and #87425. Bisection would let us narrow down the change that caused the problem. @rustbot label E-needs-bisection E-needs-mcve AsyncAwait-Triaged |
Also: #70263 |
The issue already contains a minimal example, #![feature(generic_associated_types)]
use std::{future::Future, marker::PhantomData};
trait Trait {
type Associated<'a>: Send
where
Self: 'a;
}
fn future<'a, S: Trait + 'a, F>(f: F) -> F
where
F: Future<Output = ()> + Send,
{
f
}
fn foo<'a, S: Trait + 'a>() {
future::<'a, S, _>(async move {
let result: PhantomData<S::Associated<'a>> = PhantomData;
async {}.await;
});
} at least for one of the (potentially multiple?) issues described here.
I didn’t consider checking whether this is a regression yet. It's not necessarily related to closures though; it’s an #![feature(generic_associated_types)]
use std::{future::Future, marker::PhantomData};
trait Trait {
type Associated<'a>: Send
where
Self: 'a;
}
fn future<'a, S: Trait + 'a, F>(f: F) -> F
where
F: Future<Output = ()> + Send,
{
f
}
async fn f<'a, S: Trait + 'a>() {
let result: PhantomData<S::Associated<'a>> = PhantomData;
async {}.await;
}
fn foo<'a, S: Trait + 'a>() {
future::<'a, S, _>(f::<'a, S>());
} Let me do some bisecting... okay, so it is a regression! (But not a very recent one.)
warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes
--> src/main.rs:1:12
|
1 | #![feature(generic_associated_types)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
error[E0311]: the parameter type `S` may not live long enough
--> src/main.rs:23:5
|
22 | fn foo<'a, S: Trait + 'a>() {
| -- help: consider adding an explicit lifetime bound...: `S: 'b +`
23 | future::<'a, S, _>(f::<'a, S>());
| ^^^^^^^^^^^^^^^^^^
|
= note: the parameter type `S` must be valid for any other region...
= note: ...so that the type `S` will meet its required lifetime bounds
error: aborting due to previous error; 1 warning emitted
warning: the feature `generic_associated_types` is incomplete and may not be safe to use and/or cause compiler crashes
--> src/main.rs:1:12
|
1 | #![feature(generic_associated_types)]
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(incomplete_features)]` on by default
= note: see issue #44265 <https://github.com/rust-lang/rust/issues/44265> for more information
warning: unused variable: `result`
--> src/main.rs:18:9
|
18 | let result: PhantomData<S::Associated<'a>> = PhantomData;
| ^^^^^^ help: if this is intentional, prefix it with an underscore: `_result`
|
= note: `#[warn(unused_variables)]` on by default
warning: function is never used: `future`
--> src/main.rs:10:4
|
10 | fn future<'a, S: Trait + 'a, F>(f: F) -> F
| ^^^^^^
|
= note: `#[warn(dead_code)]` on by default
warning: function is never used: `f`
--> src/main.rs:17:10
|
17 | async fn f<'a, S: Trait + 'a>() {
| ^
warning: function is never used: `foo`
--> src/main.rs:22:4
|
22 | fn foo<'a, S: Trait + 'a>() {
| ^^^
warning: unused implementer of `Future` that must be used
--> src/main.rs:23:5
|
23 | future::<'a, S, _>(f::<'a, S>());
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
= note: `#[warn(unused_must_use)]` on by default
= note: futures do nothing unless you `.await` or poll them
warning: 6 warnings emitted
Finished dev [unoptimized + debuginfo] target(s) in 0.30s
@rustbot label -E-needs-bisection -E-needs-mcve |
Regression most likely from |
The issue of confusing/unnecessary HRTB-requirements is demonstrated by something like #![feature(generic_associated_types)]
use std::{future::Future, marker::PhantomData};
trait Trait {
type Associated<'a>
where
Self: 'a;
}
fn future<'a, S: Trait + 'a, F>(f: F) -> F
where
F: Future<Output = ()> + Send,
{
f
}
async fn f<'a, S: Trait + 'a>() {
let result: PhantomData<S::Associated<'a>> = PhantomData;
async {}.await;
}
fn foo<'a, S: Trait + 'a>()
where
S::Associated<'a>: Send,
{
future::<'a, S, _>(f::<'a, S>());
} (At least from my understanding, the
which also fails before #73905, e.g. with
Looking further back... at some point (around
so there's no regression on this issue – it never worked. |
Changing the where clause to |
GATs issue triage: not blocking. The examples here do use GATs, but the underlying issue seems to have roots in generality and generator capture (from what I can surmise). There also seem to be related issues that don't use GATs. |
I should mention that third approach from this article doesn't suffer from this problem, as I was able to remove those bounds and make code compile. |
Removing |
I have experienced problems with
Send
bounds on GATs. The original code where the problem occurred uses theasync-trait
crate and looks as follows:Using the Rust playground with Nightly version: 1.58.0-nightly (2021-11-07 46b8e74), I get:
If I follow the compiler's advice literally, then of course I'll get:
If I declare 'c as a lifetime parameter, then the compiler demands I should add a bound S: 'd, and so on.
This code worked with some earlier version of nightly Rust (without the
where Self: 'a
bound, and beforewhere Self: 'a
was required in the GAT). Unfortunately I do not remember which version that was (a few weeks ago).However, even before the update of rustc, I had difficulties to remove the
Send
bound from the GATs definition and to include a bound in another method that uses the GATs. This problem still persists and can be demonstrated with the following code:Using again Rust playground with Nightly version: 1.58.0-nightly (2021-11-07 46b8e74), I get:
If I try to use a HRTB (
for<'z> <S as Source>::Wrapper<'z>: Send
), then I get:I'm not sure if these problems are related, but there seem to be a link. There has been a discussion on the Rust users forum where another smaller example (without
async-trait
macros) was created:This results (using the same compiler version) in:
If I replace
Send
withSomeTrait
withimpl<T> SomeTrait for T {}
, the code will compile. We guessed the problem might be auto-trait related?See also:
where Self: 'a
#87479The text was updated successfully, but these errors were encountered: