161 lines
3.6 KiB
Rust
161 lines
3.6 KiB
Rust
// Regression test for #61320
|
|
// This is the same issue as #61311, just a larger test case.
|
|
|
|
// check-pass
|
|
|
|
pub struct AndThen<A, B, F>
|
|
where
|
|
A: Future,
|
|
B: IntoFuture,
|
|
{
|
|
state: (A, B::Future, F),
|
|
}
|
|
|
|
pub struct FutureResult<T, E> {
|
|
inner: Option<Result<T, E>>,
|
|
}
|
|
|
|
impl<T, E> Future for FutureResult<T, E> {
|
|
type Item = T;
|
|
type Error = E;
|
|
|
|
fn poll(&mut self) -> Poll<T, E> {
|
|
unimplemented!()
|
|
}
|
|
}
|
|
|
|
pub type Poll<T, E> = Result<T, E>;
|
|
|
|
impl<A, B, F> Future for AndThen<A, B, F>
|
|
where
|
|
A: Future,
|
|
B: IntoFuture<Error = A::Error>,
|
|
F: FnOnce(A::Item) -> B,
|
|
{
|
|
type Item = B::Item;
|
|
type Error = B::Error;
|
|
|
|
fn poll(&mut self) -> Poll<B::Item, B::Error> {
|
|
unimplemented!()
|
|
}
|
|
}
|
|
|
|
pub trait Future {
|
|
type Item;
|
|
|
|
type Error;
|
|
|
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error>;
|
|
|
|
fn and_then<F, B>(self, f: F) -> AndThen<Self, B, F>
|
|
where
|
|
F: FnOnce(Self::Item) -> B,
|
|
B: IntoFuture<Error = Self::Error>,
|
|
Self: Sized,
|
|
{
|
|
unimplemented!()
|
|
}
|
|
}
|
|
|
|
pub trait IntoFuture {
|
|
/// The future that this type can be converted into.
|
|
type Future: Future<Item = Self::Item, Error = Self::Error>;
|
|
|
|
/// The item that the future may resolve with.
|
|
type Item;
|
|
/// The error that the future may resolve with.
|
|
type Error;
|
|
|
|
/// Consumes this object and produces a future.
|
|
fn into_future(self) -> Self::Future;
|
|
}
|
|
|
|
impl<F: Future> IntoFuture for F {
|
|
type Future = F;
|
|
type Item = F::Item;
|
|
type Error = F::Error;
|
|
|
|
fn into_future(self) -> F {
|
|
self
|
|
}
|
|
}
|
|
|
|
impl<F: ?Sized + Future> Future for ::std::boxed::Box<F> {
|
|
type Item = F::Item;
|
|
type Error = F::Error;
|
|
|
|
fn poll(&mut self) -> Poll<Self::Item, Self::Error> {
|
|
(**self).poll()
|
|
}
|
|
}
|
|
|
|
impl<T, E> IntoFuture for Result<T, E> {
|
|
type Future = FutureResult<T, E>;
|
|
type Item = T;
|
|
type Error = E;
|
|
|
|
fn into_future(self) -> FutureResult<T, E> {
|
|
unimplemented!()
|
|
}
|
|
}
|
|
|
|
struct Request<T>(T);
|
|
|
|
trait RequestContext {}
|
|
impl<T> RequestContext for T {}
|
|
struct NoContext;
|
|
impl AsRef<NoContext> for NoContext {
|
|
fn as_ref(&self) -> &Self {
|
|
&NoContext
|
|
}
|
|
}
|
|
|
|
type BoxedError = Box<dyn std::error::Error + Send + Sync>;
|
|
type DefaultFuture<T, E> = Box<dyn Future<Item = T, Error = E> + Send>;
|
|
|
|
trait Guard: Sized {
|
|
type Result: IntoFuture<Item = Self, Error = BoxedError>;
|
|
fn from_request(request: &Request<()>) -> Self::Result;
|
|
}
|
|
|
|
trait FromRequest: Sized {
|
|
type Context;
|
|
type Future: Future<Item = Self, Error = BoxedError> + Send;
|
|
fn from_request(request: Request<()>) -> Self::Future;
|
|
}
|
|
|
|
struct MyGuard;
|
|
impl Guard for MyGuard {
|
|
type Result = Result<Self, BoxedError>;
|
|
fn from_request(_request: &Request<()>) -> Self::Result {
|
|
Ok(MyGuard)
|
|
}
|
|
}
|
|
|
|
struct Generic<I> {
|
|
_inner: I,
|
|
}
|
|
|
|
impl<I> FromRequest for Generic<I>
|
|
where
|
|
MyGuard: Guard,
|
|
<MyGuard as Guard>::Result: IntoFuture<Item = MyGuard, Error = BoxedError>,
|
|
<<MyGuard as Guard>::Result as IntoFuture>::Future: Send,
|
|
I: FromRequest<Context = NoContext>,
|
|
{
|
|
type Future = DefaultFuture<Self, BoxedError>;
|
|
type Context = NoContext;
|
|
fn from_request(headers: Request<()>) -> DefaultFuture<Self, BoxedError> {
|
|
let _future = <MyGuard as Guard>::from_request(&headers)
|
|
.into_future()
|
|
.and_then(move |_| {
|
|
<I as FromRequest>::from_request(headers)
|
|
.into_future()
|
|
.and_then(move |fld_inner| Ok(Generic { _inner: fld_inner }).into_future())
|
|
});
|
|
panic!();
|
|
}
|
|
}
|
|
|
|
fn main() {}
|