| // 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() {} |