-
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
Problem with GATs, async, and Send-bounds #90696
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: