-
-
Notifications
You must be signed in to change notification settings - Fork 14.7k
Open
Labels
A-async-awaitArea: Async & AwaitArea: Async & AwaitA-higher-rankedArea: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs)Area: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs)A-lifetimesArea: Lifetimes / regionsArea: Lifetimes / regionsAsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.Async-await issues that have been triaged during a working group meeting.C-bugCategory: This is a bug.Category: This is a bug.E-needs-mcveCall for participation: This issue has a repro, but needs a Minimal Complete and Verifiable ExampleCall for participation: This issue has a repro, but needs a Minimal Complete and Verifiable ExampleT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Description
In this code, two generators are defined. Their definitions should be equivalent. The async-fn variant where lifetimes are elided works fine, but the variant where the lifetimes are defined explicitly with an impl-trait return fails to compile against the HRTB.
Playground with more definitions to actually build.
trait AsyncFnOnce<Arg> {}
impl<F, A, B, R: Future> AsyncFnOnce<(A, B, )> for F
where
F: FnOnce(A, B) -> R,
{}
pub unsafe trait RemitWithLifetime<T, X> {}
unsafe impl<T, X, F> RemitWithLifetime<T, (X, )> for F
where
F: for<'a> AsyncFnOnce<(X, Remit<'a, T>, )>,
{}
impl<T, P> Generator<T, P> {
pub fn parameterized<'s, G, X>(
self: Pin<&'s mut Self>,
_gen: G,
_parameter: X,
) -> GeneratorIterator<'s, T, P>
where
// insures fn is not implemented only for 'static
G: RemitWithLifetime<T, (X,)>,
// insures P is properly defined, even if it actually has a lifetime
G: FnOnce(X, Remit<'static, T>) -> P,
{
unimplemented!();
}
}
use std::pin::pin;
fn only_build() {
let data = String::from("hi");
/// Implicit elision works
async fn gen_implicit(data: &str, remit: Remit<'_, usize>) {
remit.value(data.len()).await;
remit.value(data.len()).await;
}
for item in pin!(Generator::new()).parameterized(gen_implicit, &data) {
dbg!(item);
}
/// Does not work, as explicit lifetime definitions fail HRTB.
fn gen_explicit<'a: 'c, 'b: 'c, 'c>(data: &'a str, remit: Remit<'b, usize>) -> impl std::future::Future<Output=()> + 'c {
async move {
remit.value(data.len()).await;
remit.value(data.len()).await;
}
}
for item in pin!(Generator::new()).parameterized(gen_explicit, &data) {
dbg!(item);
}
}Both gen_implicit and gen_explicit should have been able to be used successfully.
Instead, there is a compiler error:
error: implementation of `FnOnce` is not general enough
--> src/lib.rs:49:17
|
49 | for item in pin!(Generator::new()).parameterized(gen_explicit, &data) {
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ implementation of `FnOnce` is not general enough
|
= note: `fn(&str, Remit<'2, usize>) -> impl Future<Output = ()> + '_ {gen_explicit::<'_, '2, '_>}` must implement `FnOnce<(&str, Remit<'1, usize>)>`, for any lifetime `'1`...
= note: ...but it actually implements `FnOnce<(&str, Remit<'2, usize>)>`, for some specific lifetime `'2`
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
A-async-awaitArea: Async & AwaitArea: Async & AwaitA-higher-rankedArea: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs)Area: Higher-ranked things (e.g., lifetimes, types, trait bounds aka HRTBs)A-lifetimesArea: Lifetimes / regionsArea: Lifetimes / regionsAsyncAwait-TriagedAsync-await issues that have been triaged during a working group meeting.Async-await issues that have been triaged during a working group meeting.C-bugCategory: This is a bug.Category: This is a bug.E-needs-mcveCall for participation: This issue has a repro, but needs a Minimal Complete and Verifiable ExampleCall for participation: This issue has a repro, but needs a Minimal Complete and Verifiable ExampleT-compilerRelevant to the compiler team, which will review and decide on the PR/issue.Relevant to the compiler team, which will review and decide on the PR/issue.
Type
Fields
Give feedbackNo fields configured for issues without a type.