Last active
July 17, 2019 18:58
-
-
Save roblabla/588e31f63b1fb835da1b5063fe7029ae to your computer and use it in GitHub Desktop.
reproducer
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
[roblabla@roblab kfs]$ cargo script test.rs | |
Updating crates.io index | |
Compiling test v0.1.0 (/home/roblabla/.cargo/script-cache/file-test-5e1527e420b8259e) | |
error[E0308]: mismatched types | |
--> test.rs:18:5 | |
| | |
18 | ForceSend(wrapper); | |
| ^^^^^^^^^ one type is more general than the other | |
| | |
= note: expected type `std::ops::FnOnce<(&mut Test, &mut [u8])>` | |
found type `for<'a> std::ops::FnOnce<(&'a mut Test, &'a mut [u8])>` | |
error: implementation of `std::ops::FnOnce` is not general enough | |
--> test.rs:18:5 | |
| | |
18 | ForceSend(wrapper); | |
| ^^^^^^^^^ | |
| | |
= note: `std::ops::FnOnce<(&'0 mut Test, &'0 mut [u8])>` would have to be implemented for the type `for<'a> fn(&'a mut Test, &'a mut [u8]) -> futures_core::future::future_obj::FutureObj<'a, std::result::Result<(), ()>> {Test::dispatch}`, for some specific lifetime `'0` | |
= note: but `std::ops::FnOnce<(&mut Test, &mut [u8])>` is actually implemented for the type `for<'a> fn(&'a mut Test, &'a mut [u8]) -> futures_core::future::future_obj::FutureObj<'a, std::result::Result<(), ()>> {Test::dispatch}` | |
error[E0308]: mismatched types | |
--> test.rs:18:5 | |
| | |
18 | ForceSend(wrapper); | |
| ^^^^^^^^^ one type is more general than the other | |
| | |
= note: expected type `std::ops::FnMut<(&mut Test, &mut [u8])>` | |
found type `for<'a> std::ops::FnMut<(&'a mut Test, &'a mut [u8])>` | |
error: aborting due to 3 previous errors | |
For more information about this error, try `rustc --explain E0308`. | |
error: Could not compile `test`. | |
To learn more, run the command again with --verbose. | |
internal error: cargo failed with status 101 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//! ```cargo | |
//! [package] | |
//! edition = "2018" | |
//! | |
//! [dependencies] | |
//! futures-preview = { version = "0.3.0-alpha.16", default-features = false, features = ["nightly", "alloc"] } | |
//! ``` | |
#![feature(unboxed_closures, fn_traits)] | |
#![feature(async_await)] | |
use core::future::Future; | |
use futures::future::FutureObj; | |
struct ForceSend<T: Send>(T); | |
fn main() { | |
let wrapper = new_session_wrapper(Test(0), Test::dispatch); | |
ForceSend(wrapper); | |
} | |
struct Test(u8); | |
impl Test { | |
fn dispatch<'a>(&'a mut self, buf: &'a mut [u8]) -> FutureObj<'a, Result<(), ()>> { | |
FutureObj::new(Box::new(futures::future::lazy(|_| { | |
buf[0] = 1; | |
self.0 = 2; | |
Ok(()) | |
}))) | |
} | |
} | |
async fn new_session_wrapper<T, DISPATCH>(mut object: T, mut dispatch: DISPATCH) -> () | |
where | |
DISPATCH: for<'b> FutureCallback<(&'b mut T, &'b mut [u8]), Result<(), ()>>, | |
DISPATCH: Unpin + Send + 'static, | |
T: Unpin + Send + 'static, | |
{ | |
let mut buf = [0u8; 0x100]; | |
ForceSend(buf); | |
dispatch.call((&mut object, &mut buf[..],)).await; | |
} | |
// BOILERPLATE: HRTB workaround | |
trait FutureCallback<T, O>: FnMut<T> { | |
type Ret: Future<Output = O> + Send; | |
fn call(&mut self, x: T) -> Self::Ret; | |
} | |
// Implement it for all FnMut with Ret = Output | |
impl<T, O, F: FnMut<T>> FutureCallback<T, O> for F | |
where | |
F::Output: Future<Output = O> + Send, | |
{ | |
type Ret = F::Output; | |
fn call(&mut self, x: T) -> Self::Ret { | |
self.call_mut(x) | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment