-
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
Spurious "implementation of FnOnce
is not general enough" error
#99492
Comments
Update: I found an even simpler workaround for the bug, which may be telling: mystenmark/sui@82e936b (available as branch |
* Use a single NodeSyncState owned by ActiveAuthority * Refactor node_sync to support execution driver * Execution driver uses NodeSync for cert execution * Work around rust-lang/rust#99492 * Increase limit so tests pass
@rustbot label t-compiler I-nominated A-async-await |
@rustbot label AsyncAwait-triaged |
t-compiler: I nominated this for discussion because of the following:
This points to deeper compiler issues and is probably at least P-high. @rustbot label +I-prioritize +E-needs-mcve +E-needs-bisection |
Reduced (but can presumably be reduced further from here): use futures::{stream, StreamExt};
use std::sync::Arc;
use tokio::task::JoinHandle;
async fn execution_process<A>(active_authority: &ActiveAuthority<A>)
where
A: Send + Sync + 'static,
{
stream::empty::<Result<(), ()>>()
.zip(stream::iter(Vec::<u64>::new().iter().map(|seq| *seq)))
.filter_map(|(result, seq)| async move { result.ok().map(|_| seq) })
.collect::<Vec<_>>()
.await;
}
struct ActiveAuthority<A> {
node_sync_state: A,
}
impl<A> ActiveAuthority<A>
where
A: Send + Sync + 'static,
{
async fn spawn_execute_process(self: Arc<Self>) -> JoinHandle<()> {
tokio::task::spawn(async move {
execution_process(&self).await;
})
}
} [dependencies]
futures = "0.3.23"
tokio = { version = "1.20.1", features = ["rt"] } output 1.62.1
output 1.63.0
E.g. using |
Reducing further, I came across a second similar error message. This is what I’ve got at the moment: use std::marker::PhantomData;
#[rustfmt::skip]
pub struct Struct<I, T, F, B>(
PhantomData<fn() -> (I, T, F, B)>,
PhantomData<<Self as It>::Item>,
)
where
I: It<Item = T>, // xxx
F: FnMut(T) -> B, // yyy
;
impl<I, T, F, B> Struct<I, T, F, B>
where
I: It<Item = T>, // xxx
F: FnMut(T) -> B, // yyy
{
fn new(_: F) -> Self {
Self(PhantomData, PhantomData)
}
}
impl<B, I, T, F> It for Struct<I, T, F, B>
where
I: It<Item = T>, // xxx
F: FnMut(T) -> B, // yyy
{
type Item = B;
}
pub trait It {
type Item;
}
async fn execution_process() {
let _x = Struct::<Empty<&u64>, &u64, _, u64>::new(|seq: &u64| *seq);
async {}.await;
}
fn spawn_execute_process() {
spawn(execution_process());
}
fn spawn<T>(_: T)
where
T: Send, // zzz
{
}
struct FnReturning<T>(fn() -> T);
pub struct Empty<T>(PhantomData<FnReturning<T>>);
impl<T> It for Empty<T> {
type Item = T;
}
Commenting out all the In this reduced example, the errors stay the same between 1.62 and 1.63. As well as older versions and nightly, so there’s nothing to bisect (at least in this reduced example; the original did produce a “higher-ranked lifetime error” instead starting from @rustbot label -E-needs-mcve, -E-needs-bisection |
Here’s a further reduction to the non-closure-involving error use std::marker::PhantomData;
pub struct Struct<I, T>(PhantomData<fn() -> <Self as It>::Item>)
where
Self: It;
impl<I> It for Struct<I, I::Item>
where
I: It,
{
type Item = ();
}
pub trait It {
type Item;
}
fn f() -> impl Send {
async {
let _x = Struct::<Empty<&'static ()>, _>(PhantomData);
async {}.await;
}
}
pub struct Empty<T>(PhantomData<fn() -> T>);
impl<T> It for Empty<T> {
type Item = T;
} error in 1.62
error in 1.63
|
The original code example from #90656 seems to be behaving similar to the code in this issue, including the change to a “higher-ranked lifetime error” in 1.63. |
Note that even though the code that changed was “in another file”, this action-at-a-distance is explainable due to auto-traits. The |
Ah, I see – thanks @steffahn! At first read it looked like these were totally unrelated, but I hadn't looked too closely at the code. In that case I'm going to put this back through async triage and skip the t-compiler nomination for now. Maybe this is the same as another issue, like #90656 as you said. @rustbot label -AsyncAwait-Triaged -I-compiler-nominated -I-prioritize |
These issues (this and #90656) seem pretty deep in the type / borrow checker and not all that specific to async. I think we should involve the types team for these. See the MCVE and surrounding conversation for more context. @rustbot label +T-types +I-types-nominated +AsyncAwait-Triaged (Not sure if nominating is the correct process here, please let me know if not) |
We've had some spurious errors similar to this around async functions for a while -- I have to find the citations -- is it likely that this is a duplicate? Searching the repo I see a lot of related issues, I can't quite find the one I'm thinking of. It also feels related to the implied bounds on GATs, in that the "right fix" is similar. |
I got the same eror for a custom struct saying = note: `RdfSourceConnegRepDerefLayer<(dyn RepDerefService<RepData = either::Either<Pin<Box<dyn Stream<Item = Result<bytes::Bytes, Box<dyn StdError + Sync + std::marker::Send>>> + std::marker::Send>>, Pin<Box<dyn Stream<Item = Result<Quad, Box<dyn StdError + Sync + std::marker::Send>>> + std::marker::Send>>>, Error = HttpApiProblem, Response = Representation<either::Either<Pin<Box<dyn Stream<Item = Result<bytes::Bytes, Box<dyn StdError + Sync + std::marker::Send>>> + std::marker::Send>>, Pin<Box<dyn Stream<Item = Result<Quad, Box<dyn StdError + Sync + std::marker::Send>>> + std::marker::Send>>>>> + '0)>` must implement `RepDerefLayer<(dyn RepDerefService<RepData = either::Either<Pin<Box<dyn Stream<Item = Result<bytes::Bytes, Box<dyn StdError + Sync + std::marker::Send>>> + std::marker::Send>>, Pin<Box<dyn Stream<Item = Result<Quad, Box<dyn StdError + Sync + std::marker::Send>>> + std::marker::Send>>>, Error = HttpApiProblem, Response = Representation<either::Either<Pin<Box<dyn Stream<Item = Result<bytes::Bytes, Box<dyn StdError + Sync + std::marker::Send>>> + std::marker::Send>>, Pin<Box<dyn Stream<Item = Result<Quad, Box<dyn StdError + Sync + std::marker::Send>>> + std::marker::Send>>>>> + '1)>`, for any two lifetimes `'0` and `'
but it actually implements `RepDerefLayer<dyn RepDerefService<RepData = either::Either<Pin<Box<dyn Stream<Item = Result<bytes::Bytes, Box<dyn StdError + Sync + std::marker::Send>>> + std::marker::Send>>, Pin<Box<dyn Stream<Item = Result<Quad, Box<dyn StdError + Sync + std::marker::Send>>> + std::marker::Send>>>, Error = HttpApiProblem, Response = Representation<either::Either<Pin<Box<dyn Stream<Item = Result<bytes::Bytes, Box<dyn StdError + Sync + std::marker::Send>>> + std::marker::Send>>, Pin<Box<dyn Stream<Item = Result<Quad, Box<dyn StdError + Sync + std::marker::Send>>> + std::marker::Send>>>>>>`
Essentially it says not general enough over lifetime param in a BoxError |
For each type alias with a dyn object in it's definition explicitly marked with |
We talked about this today in a types team meeting (https://rust-lang.zulipchat.com/#narrow/stream/326132-t-types.2Fmeetings/topic/2022-10-07.20Planning.20meeting/near/302848792). We don't think we learn anything new from this issue (that isn't already a known limitation). We have ongoing work that should help this, but nothing immediate. |
…imulacrum Add a few known-bug tests The labels of these tests should be changed from `S-bug-has-mcve` to `S-bug-has-test` once this is merged. cc: rust-lang#101518 rust-lang#99492 rust-lang#90950 rust-lang#89196 rust-lang#104034 rust-lang#101350 rust-lang#103705 rust-lang#103899 I couldn't reproduce the failures in rust-lang#101962 and rust-lang#100772 (so either these have started passing, or I didn't repro properly), so leaving those out for now. rust-lang#102065 was a bit more complicated, since it uses `rustc_private` and I didn't want to mess with that.
Are there any known workarounds for this issue? I'm running into this error message when using trait objects, similar to #99492 (comment). This occurred when adding an explicit |
@jackh726 would you mind linking to that known limitation? I read the Zulip thread you listed, and it's not in there. We're still hitting this and trying to figure out how to work around it and/or if there's anything we can do to help. |
I believe #64552 is the parent issue. |
Hello rustaceans, I'll start with the brief overview and provide repro instructions at the end:
Given the following code:
The current output is:
This is pretty fishy looking already - as you can see there is no closure in the code above, and the async block doesn't look anything like
(u64, TransactionDigest) -> u64
I did however add such a closure in another file. And sure enough if I remove that closure from that other file, this problem goes away.
Unfortunately I don't have time to try to pare this down to a minimal repro right now, but I can provide a repo link.
Instructions:
git clone https://github.com/mystenmark/sui.git
cd sui
git checkout rust-bug-repro
(commit description is "Reproduce the error at this commit")cargo check
git checkout rust-bug-repro-workaround
(commit description is "Make the error magically go away")cargo check
As you can see the commit that fixes the error isn't even in the same file, nor does it alter any public function signatures or type defintions: mystenmark/sui@73302e1
Lastly, this is happens on both rust 1.62.0 and 1.62.1 - the branch above uses 1.62.1
The text was updated successfully, but these errors were encountered: